Snap for 10453563 from 17fad3051142f31d3814b20ca9bf43459b762c2a to mainline-os-statsd-release

Change-Id: I9c6468bfd5346c5bd5cfa8c09da968e76f02c368
diff --git a/Android.mk b/Android.mk
index cb1010a..bba4a38 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,4 +1,8 @@
 #set TARGET_USES_HARDWARE_QCOM_WLAN to false to disable this project.
 ifneq ($(TARGET_USES_HARDWARE_QCOM_WLAN),false)
-include $(call all-subdir-makefiles)
+  ifneq ($(filter wcn6740,$(BOARD_WLAN_CHIP)),)
+    include $(call all-named-subdir-makefiles,wcn6740)
+  else
+	include $(call all-named-subdir-makefiles,legacy)
+  endif
 endif
diff --git a/OWNERS b/OWNERS
index d8c95cc..4ab11f8 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,5 @@
 arabawy@google.com
 etancohen@google.com
 kumachang@google.com
+hsuvictor@google.com
+wangroger@google.com
diff --git a/legacy/Android.mk b/legacy/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/legacy/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/cld80211-lib/Android.mk b/legacy/cld80211-lib/Android.mk
similarity index 100%
rename from cld80211-lib/Android.mk
rename to legacy/cld80211-lib/Android.mk
diff --git a/cld80211-lib/cld80211_lib.c b/legacy/cld80211-lib/cld80211_lib.c
similarity index 99%
rename from cld80211-lib/cld80211_lib.c
rename to legacy/cld80211-lib/cld80211_lib.c
index 5c8255b..b34ed28 100644
--- a/cld80211-lib/cld80211_lib.c
+++ b/legacy/cld80211-lib/cld80211_lib.c
@@ -446,7 +446,7 @@
 }
 
 
-struct cld80211_ctx * cld80211_init()
+struct cld80211_ctx * cld80211_init(void)
 {
 	struct cld80211_ctx *ctx;
 
diff --git a/cld80211-lib/cld80211_lib.h b/legacy/cld80211-lib/cld80211_lib.h
similarity index 93%
rename from cld80211-lib/cld80211_lib.h
rename to legacy/cld80211-lib/cld80211_lib.h
index 3dd53bb..2503f2a 100644
--- a/cld80211-lib/cld80211_lib.h
+++ b/legacy/cld80211-lib/cld80211_lib.h
@@ -58,6 +58,10 @@
  * CLD80211_ATTR_META_DATA: Embed meta data for above data. This will  help
  * wlan driver to peek into request message packet without opening up definition
  * of complete request message.
+ * @CLD80211_ATTR_CMD: cld80211 vendor subcommand in this attribute
+ * @CLD80211_ATTR_CMD_TAG_DATA: cld80211 vendor subcommand data is present in
+ * this attribute. It is a nested attribute with sub attributes of specified
+ * vendor sub command.
  *
  * Any new message in future can be added as another attribute
  */
@@ -65,6 +69,8 @@
 	CLD80211_ATTR_VENDOR_DATA = 1,
 	CLD80211_ATTR_DATA,
 	CLD80211_ATTR_META_DATA,
+	CLD80211_ATTR_CMD,
+	CLD80211_ATTR_CMD_TAG_DATA,
 
 	__CLD80211_ATTR_AFTER_LAST,
 	CLD80211_ATTR_MAX = __CLD80211_ATTR_AFTER_LAST - 1
@@ -75,7 +81,7 @@
  * Retuns valid sock only if socket creation is succesful and cld80211
  * family is present, returns NULL otherwise
  */
-struct cld80211_ctx *cld80211_init();
+struct cld80211_ctx *cld80211_init(void);
 
 /**
  * free the socket created in cld80211_init()
diff --git a/qcwcn/Android.mk b/legacy/qcwcn/Android.mk
similarity index 100%
rename from qcwcn/Android.mk
rename to legacy/qcwcn/Android.mk
diff --git a/qcwcn/config/Android.mk b/legacy/qcwcn/config/Android.mk
similarity index 100%
rename from qcwcn/config/Android.mk
rename to legacy/qcwcn/config/Android.mk
diff --git a/qcwcn/wcnss-service/Android.mk b/legacy/qcwcn/wcnss-service/Android.mk
similarity index 100%
rename from qcwcn/wcnss-service/Android.mk
rename to legacy/qcwcn/wcnss-service/Android.mk
diff --git a/qcwcn/wcnss-service/wcnss_qmi_client.c b/legacy/qcwcn/wcnss-service/wcnss_qmi_client.c
similarity index 100%
rename from qcwcn/wcnss-service/wcnss_qmi_client.c
rename to legacy/qcwcn/wcnss-service/wcnss_qmi_client.c
diff --git a/qcwcn/wcnss-service/wcnss_qmi_client.h b/legacy/qcwcn/wcnss-service/wcnss_qmi_client.h
similarity index 100%
rename from qcwcn/wcnss-service/wcnss_qmi_client.h
rename to legacy/qcwcn/wcnss-service/wcnss_qmi_client.h
diff --git a/qcwcn/wcnss-service/wcnss_service.c b/legacy/qcwcn/wcnss-service/wcnss_service.c
similarity index 100%
rename from qcwcn/wcnss-service/wcnss_service.c
rename to legacy/qcwcn/wcnss-service/wcnss_service.c
diff --git a/qcwcn/wifi_hal/Android.mk b/legacy/qcwcn/wifi_hal/Android.mk
similarity index 100%
rename from qcwcn/wifi_hal/Android.mk
rename to legacy/qcwcn/wifi_hal/Android.mk
diff --git a/qcwcn/wifi_hal/common.cpp b/legacy/qcwcn/wifi_hal/common.cpp
similarity index 100%
rename from qcwcn/wifi_hal/common.cpp
rename to legacy/qcwcn/wifi_hal/common.cpp
diff --git a/qcwcn/wifi_hal/common.h b/legacy/qcwcn/wifi_hal/common.h
similarity index 99%
rename from qcwcn/wifi_hal/common.h
rename to legacy/qcwcn/wifi_hal/common.h
index b0aca97..401921b 100644
--- a/qcwcn/wifi_hal/common.h
+++ b/legacy/qcwcn/wifi_hal/common.h
@@ -174,6 +174,7 @@
     wifi_capa capa;
     struct cld80211_ctx *cldctx;
     bool apf_enabled;
+    bool support_nan_ext_cmd;
     pkt_log_version  pkt_log_ver;
 } hal_info;
 
diff --git a/qcwcn/wifi_hal/cpp_bindings.cpp b/legacy/qcwcn/wifi_hal/cpp_bindings.cpp
similarity index 100%
rename from qcwcn/wifi_hal/cpp_bindings.cpp
rename to legacy/qcwcn/wifi_hal/cpp_bindings.cpp
diff --git a/qcwcn/wifi_hal/cpp_bindings.h b/legacy/qcwcn/wifi_hal/cpp_bindings.h
similarity index 100%
rename from qcwcn/wifi_hal/cpp_bindings.h
rename to legacy/qcwcn/wifi_hal/cpp_bindings.h
diff --git a/qcwcn/wifi_hal/gscan.cpp b/legacy/qcwcn/wifi_hal/gscan.cpp
similarity index 100%
rename from qcwcn/wifi_hal/gscan.cpp
rename to legacy/qcwcn/wifi_hal/gscan.cpp
diff --git a/qcwcn/wifi_hal/gscan_event_handler.cpp b/legacy/qcwcn/wifi_hal/gscan_event_handler.cpp
similarity index 100%
rename from qcwcn/wifi_hal/gscan_event_handler.cpp
rename to legacy/qcwcn/wifi_hal/gscan_event_handler.cpp
diff --git a/qcwcn/wifi_hal/gscan_event_handler.h b/legacy/qcwcn/wifi_hal/gscan_event_handler.h
similarity index 100%
rename from qcwcn/wifi_hal/gscan_event_handler.h
rename to legacy/qcwcn/wifi_hal/gscan_event_handler.h
diff --git a/qcwcn/wifi_hal/gscancommand.h b/legacy/qcwcn/wifi_hal/gscancommand.h
similarity index 100%
rename from qcwcn/wifi_hal/gscancommand.h
rename to legacy/qcwcn/wifi_hal/gscancommand.h
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.cpp b/legacy/qcwcn/wifi_hal/ifaceeventhandler.cpp
similarity index 85%
rename from qcwcn/wifi_hal/ifaceeventhandler.cpp
rename to legacy/qcwcn/wifi_hal/ifaceeventhandler.cpp
index 6e70ab5..82f1add 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.cpp
+++ b/legacy/qcwcn/wifi_hal/ifaceeventhandler.cpp
@@ -205,6 +205,8 @@
     mCapa = &(info->capa);
     mfilter_packet_read_buffer = NULL;
     mfilter_packet_length = 0;
+    res_size = 0;
+    channel_buff = NULL;
     memset(&mDriverFeatures, 0, sizeof(mDriverFeatures));
 }
 
@@ -222,6 +224,119 @@
     return WifiCommand::requestResponse(mMsg);
 }
 
+static u32 get_wifi_iftype_masks(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & BIT(NL80211_IFTYPE_STATION)) {
+        op_mask |= BIT(WIFI_INTERFACE_STA);
+        op_mask |= BIT(WIFI_INTERFACE_TDLS);
+    }
+    if (in_mask & BIT(NL80211_IFTYPE_AP))
+        op_mask |= BIT(WIFI_INTERFACE_SOFTAP);
+    if (in_mask & BIT(NL80211_IFTYPE_P2P_CLIENT))
+        op_mask |= BIT(WIFI_INTERFACE_P2P_CLIENT);
+    if (in_mask & BIT(NL80211_IFTYPE_P2P_GO))
+        op_mask |= BIT(WIFI_INTERFACE_P2P_GO);
+    if (in_mask & BIT(NL80211_IFTYPE_NAN))
+        op_mask |= BIT(WIFI_INTERFACE_NAN);
+
+    return op_mask;
+}
+
+static wifi_channel_width get_channel_width(u32 nl_width)
+{
+    switch(nl_width) {
+    case NL80211_CHAN_WIDTH_20:
+         return WIFI_CHAN_WIDTH_20;
+    case NL80211_CHAN_WIDTH_40:
+         return WIFI_CHAN_WIDTH_40;
+    case NL80211_CHAN_WIDTH_80:
+         return WIFI_CHAN_WIDTH_80;
+    case NL80211_CHAN_WIDTH_160:
+         return WIFI_CHAN_WIDTH_160;
+    case NL80211_CHAN_WIDTH_80P80:
+         return WIFI_CHAN_WIDTH_80P80;
+    case NL80211_CHAN_WIDTH_5:
+         return WIFI_CHAN_WIDTH_5;
+    case NL80211_CHAN_WIDTH_10:
+         return WIFI_CHAN_WIDTH_10;
+    default:
+         return WIFI_CHAN_WIDTH_INVALID;
+    }
+}
+
+int WifihalGeneric::handle_response_usable_channels(struct nlattr *VendorData,
+                                                    u32 mDataLen)
+{
+    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1];
+    struct nlattr *curr_attr;
+    wifi_usable_channel *chan_info = NULL;
+    int rem;
+    u32 currSize = 0;
+
+    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX,
+                  (struct nlattr *)mVendorData, mDataLen, NULL)) {
+         ALOGE("Failed to parse NL channels list");
+         return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO]) {
+         ALOGE("%s: USABLE_CHANNELS_CHAN_INFO not found", __FUNCTION__);
+         return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    for_each_nested_attribute(curr_attr,
+                     tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO], rem) {
+         struct nlattr *ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX + 1];
+
+         if (currSize >= mSetSizeMax) {
+              ALOGE("Got max channels %d completed", mSetSizeMax);
+              break;
+         }
+
+         if (nla_parse_nested(ch_info, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX,
+                              curr_attr, NULL)) {
+              ALOGE("Failed to get usable channel info");
+              return NL_SKIP;
+         }
+
+         chan_info = &channel_buff[currSize];
+         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]) {
+              ALOGE("%s: CHAN_INFO_PRIMARY_FREQ not found",
+                    __FUNCTION__);
+              return NL_SKIP;
+         }
+
+         chan_info->freq = nla_get_u32(ch_info[
+                                  QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]);
+         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]) {
+              ALOGE("%s: CHAN_INFO_BANDWIDTH not found",
+                    __FUNCTION__);
+              return NL_SKIP;
+         }
+
+         chan_info->width = get_channel_width(nla_get_u32(
+                            ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]));
+         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]) {
+              ALOGE("%s: CHAN_INFO_IFACE_MODE_MASK not found",
+                    __FUNCTION__);
+              return NL_SKIP;
+         }
+
+         chan_info->iface_mode_mask = get_wifi_iftype_masks(nla_get_u32(
+                      ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]));
+         ALOGV("Primary freq %d BW %d iface mask %d", chan_info->freq,
+               chan_info->width, chan_info->iface_mode_mask);
+         currSize++;
+    }
+
+    res_size = currSize;
+    ALOGV("%s: Result size %d", __FUNCTION__, res_size);
+
+    return NL_SKIP;
+}
+
 int WifihalGeneric::handleResponse(WifiEvent &reply)
 {
     ALOGV("Got a Wi-Fi HAL module message from Driver");
@@ -436,6 +551,9 @@
                 }
             }
             break;
+        case QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS:
+            return handle_response_usable_channels((struct nlattr *)mVendorData,
+                                                   mDataLen);
         default :
             ALOGE("%s: Wrong Wi-Fi HAL event received %d", __func__, mSubcmd);
     }
@@ -612,6 +730,17 @@
     return firmware_bus_max_size;
 }
 
+void WifihalGeneric::set_channels_buff(wifi_usable_channel* channels)
+{
+    channel_buff = channels;
+    memset(channel_buff, 0, sizeof(wifi_usable_channel) * mSetSizeMax);
+}
+
+u32 WifihalGeneric::get_results_size(void)
+{
+    return res_size;
+}
+
 wifi_error WifihalGeneric::wifiGetCapabilities(wifi_interface_handle handle)
 {
     wifi_error ret;
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.h b/legacy/qcwcn/wifi_hal/ifaceeventhandler.h
similarity index 86%
rename from qcwcn/wifi_hal/ifaceeventhandler.h
rename to legacy/qcwcn/wifi_hal/ifaceeventhandler.h
index c993a7e..d055a1b 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.h
+++ b/legacy/qcwcn/wifi_hal/ifaceeventhandler.h
@@ -94,6 +94,8 @@
     /* Packet Filter buffer and length */
     u8 *mfilter_packet_read_buffer;
     int mfilter_packet_length;
+    u32 res_size;
+    wifi_usable_channel *channel_buff;
     virtual wifi_error wifiParseCapabilities(struct nlattr **tbVendor);
 
 public:
@@ -101,6 +103,8 @@
     virtual ~WifihalGeneric();
     virtual wifi_error requestResponse();
     virtual int handleResponse(WifiEvent &reply);
+    virtual int handle_response_usable_channels(struct nlattr *VendorData,
+                                                u32 mDataLen);
     virtual void getResponseparams(feature_set *pset);
     virtual void getDriverFeatures(features_info *pfeatures);
     virtual void setMaxSetSize(int set_size_max);
@@ -111,7 +115,19 @@
     virtual int getFilterLength();
     virtual int getBusSize();
     virtual wifi_error wifiGetCapabilities(wifi_interface_handle handle);
+    virtual void set_channels_buff(wifi_usable_channel *channels);
+    virtual u32 get_results_size(void);
 };
+
+/**
+ * nla_for_each_nested from libnl is throwing implicit conversion from void*
+ * error. Adding a local definition to avoid it.
+ */
+#define for_each_nested_attribute(pos, nla, rem) \
+    for (pos = (struct nlattr *)nla_data(nla), rem = nla_len(nla); \
+         nla_ok(pos, rem); \
+         pos = nla_next(pos, &(rem)))
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/qcwcn/wifi_hal/list.cpp b/legacy/qcwcn/wifi_hal/list.cpp
similarity index 100%
rename from qcwcn/wifi_hal/list.cpp
rename to legacy/qcwcn/wifi_hal/list.cpp
diff --git a/qcwcn/wifi_hal/list.h b/legacy/qcwcn/wifi_hal/list.h
similarity index 100%
rename from qcwcn/wifi_hal/list.h
rename to legacy/qcwcn/wifi_hal/list.h
diff --git a/qcwcn/wifi_hal/llstats.cpp b/legacy/qcwcn/wifi_hal/llstats.cpp
similarity index 100%
rename from qcwcn/wifi_hal/llstats.cpp
rename to legacy/qcwcn/wifi_hal/llstats.cpp
diff --git a/qcwcn/wifi_hal/llstatscommand.h b/legacy/qcwcn/wifi_hal/llstatscommand.h
similarity index 100%
rename from qcwcn/wifi_hal/llstatscommand.h
rename to legacy/qcwcn/wifi_hal/llstatscommand.h
diff --git a/qcwcn/wifi_hal/nan.cpp b/legacy/qcwcn/wifi_hal/nan.cpp
similarity index 90%
rename from qcwcn/wifi_hal/nan.cpp
rename to legacy/qcwcn/wifi_hal/nan.cpp
index ac378fa..9e74cea 100644
--- a/qcwcn/wifi_hal/nan.cpp
+++ b/legacy/qcwcn/wifi_hal/nan.cpp
@@ -73,10 +73,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -115,10 +123,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -158,10 +174,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -201,10 +225,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -244,10 +276,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -287,10 +327,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -330,10 +378,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -373,10 +429,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -416,10 +480,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -459,10 +531,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -505,10 +585,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -571,10 +659,18 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -615,6 +711,12 @@
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     if (debug_msg_length <= 0) {
         ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
@@ -625,6 +727,8 @@
     nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     if (nanCommand == NULL) {
         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
@@ -795,7 +899,7 @@
 {
     ALOGV("NAN_DP_REQUEST_INITIATOR");
     wifi_error ret;
-    struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
+    struct nlattr *nlData, *nlCfgQos;
     NanCommand *nanCommand = NULL;
 
     if (msg == NULL)
@@ -866,19 +970,6 @@
             goto cleanup;
         }
     }
-    if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
-        nlCfgSecurity =
-            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
-        if (!nlCfgSecurity)
-            goto cleanup;
-
-        if (nanCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
-            0)) {
-            goto cleanup;
-        }
-        nanCommand->attr_end(nlCfgSecurity);
-    }
     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
         nlCfgQos =
             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
@@ -930,7 +1021,7 @@
 {
     ALOGV("NAN_DP_INDICATION_RESPONSE");
     wifi_error ret;
-    struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
+    struct nlattr *nlData, *nlCfgQos;
     NanCommand *nanCommand = NULL;
 
     if (msg == NULL)
@@ -981,19 +1072,6 @@
             goto cleanup;
         }
     }
-    if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
-        nlCfgSecurity =
-            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
-        if (!nlCfgSecurity)
-            goto cleanup;
-        /* Setting value to 0 for now */
-        if (nanCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
-            0)) {
-            goto cleanup;
-        }
-        nanCommand->attr_end(nlCfgSecurity);
-    }
     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
         nlCfgQos =
             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
@@ -1102,13 +1180,23 @@
 
 NanCommand* NanCommand::instance(wifi_handle handle)
 {
+    hal_info *info;
+
     if (handle == NULL) {
         ALOGE("Handle is invalid");
         return NULL;
     }
+    info = getHalInfo(handle);
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return NULL;
+    }
+
     if (mNanCommandInstance == NULL) {
         mNanCommandInstance = new NanCommand(handle, 0,
                                              OUI_QCA,
+                                             info->support_nan_ext_cmd?
+                                             QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                              QCA_NL80211_VENDOR_SUBCMD_NAN);
         ALOGV("NanCommand %p created", mNanCommandInstance);
         return mNanCommandInstance;
diff --git a/qcwcn/wifi_hal/nan_cert.h b/legacy/qcwcn/wifi_hal/nan_cert.h
similarity index 100%
rename from qcwcn/wifi_hal/nan_cert.h
rename to legacy/qcwcn/wifi_hal/nan_cert.h
diff --git a/qcwcn/wifi_hal/nan_i.h b/legacy/qcwcn/wifi_hal/nan_i.h
similarity index 100%
rename from qcwcn/wifi_hal/nan_i.h
rename to legacy/qcwcn/wifi_hal/nan_i.h
diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/legacy/qcwcn/wifi_hal/nan_ind.cpp
similarity index 100%
rename from qcwcn/wifi_hal/nan_ind.cpp
rename to legacy/qcwcn/wifi_hal/nan_ind.cpp
diff --git a/qcwcn/wifi_hal/nan_req.cpp b/legacy/qcwcn/wifi_hal/nan_req.cpp
similarity index 84%
rename from qcwcn/wifi_hal/nan_req.cpp
rename to legacy/qcwcn/wifi_hal/nan_req.cpp
index fd8516f..f411802 100644
--- a/qcwcn/wifi_hal/nan_req.cpp
+++ b/legacy/qcwcn/wifi_hal/nan_req.cpp
@@ -25,12 +25,18 @@
     wifi_error ret;
     ALOGV("NAN_ENABLE");
     size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
+    int freq_24g;
 
     if (pReq == NULL) {
         cleanup();
         return WIFI_ERROR_INVALID_ARGS;
     }
 
+    if (pReq->config_24g_channel == 0)
+        freq_24g = 2437;
+    else
+        freq_24g = pReq->channel_24g_val;
+
     message_len += \
         (
           pReq->config_support_5g ? (SIZEOF_TLV_HDR + \
@@ -117,8 +123,8 @@
           sizeof(pReq->hop_count_force_val)) : 0 \
         ) + \
         (
-          pReq->config_24g_channel ? (SIZEOF_TLV_HDR + \
-          sizeof(u32)) : 0 \
+          /* always include 24g channel/freq */
+          SIZEOF_TLV_HDR +  sizeof(u32) \
         ) + \
         (
           pReq->config_5g_channel ? (SIZEOF_TLV_HDR + \
@@ -288,11 +294,9 @@
                       sizeof(pReq->hop_count_force_val),
                       (const u8*)&pReq->hop_count_force_val, tlvs);
     }
-    if (pReq->config_24g_channel) {
-        tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL,
+    tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL,
                       sizeof(u32),
-                      (const u8*)&pReq->channel_24g_val, tlvs);
-    }
+                      (const u8*)&freq_24g, tlvs);
     if (pReq->config_5g_channel) {
         tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL,
                       sizeof(u32),
@@ -352,12 +356,48 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    //Insert the vendor specific data
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        //Insert the vendor specific data
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE,
+                           QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ) ||
+            mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ,
+                           freq_24g)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (pReq->config_5g_channel) {
+            if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ,
+                               pReq->config_5g_channel)) {
+                ALOGE("%s: put attr error", __func__);
+                cleanup();
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -385,11 +425,32 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE,
+                           QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ) ||
+            mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -645,11 +706,29 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -709,7 +788,7 @@
     if (pReq->publish_id == 0) {
         pFwReq->fwHeader.handle = 0xFFFF;
     } else {
-        pFwReq->fwHeader.handle = pReq->publish_id;
+        pFwReq->fwHeader.handle = (pReq->publish_id & 0xFF);
     }
     pFwReq->fwHeader.transactionId = id;
 
@@ -863,11 +942,29 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -895,17 +992,36 @@
     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
     pFwReq->fwHeader.msgLen = message_len;
-    pFwReq->fwHeader.handle = pReq->publish_id;
+    pFwReq->fwHeader.handle = (pReq->publish_id & 0xFF);
     pFwReq->fwHeader.transactionId = id;
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -969,7 +1085,7 @@
     if (pReq->subscribe_id == 0) {
         pFwReq->fwHeader.handle = 0xFFFF;
     } else {
-        pFwReq->fwHeader.handle = pReq->subscribe_id;
+        pFwReq->fwHeader.handle = (pReq->subscribe_id & 0xFF);
     }
     pFwReq->fwHeader.transactionId = id;
 
@@ -1123,11 +1239,30 @@
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1156,16 +1291,35 @@
     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
     pFwReq->fwHeader.msgLen = message_len;
-    pFwReq->fwHeader.handle = pReq->subscribe_id;
+    pFwReq->fwHeader.handle = (pReq->subscribe_id & 0xFF);
     pFwReq->fwHeader.transactionId = id;
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1201,7 +1355,7 @@
     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
     pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
     pFwReq->fwHeader.msgLen = message_len;
-    pFwReq->fwHeader.handle = pReq->publish_subscribe_id;
+    pFwReq->fwHeader.handle = (pReq->publish_subscribe_id & 0xFF);
     pFwReq->fwHeader.transactionId = id;
 
     pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id;
@@ -1235,11 +1389,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1276,11 +1449,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1332,11 +1524,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1399,11 +1610,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1668,11 +1898,30 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1711,12 +1960,31 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    /* Write the TLVs to the message. */
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        /* Write the TLVs to the message. */
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
diff --git a/qcwcn/wifi_hal/nan_rsp.cpp b/legacy/qcwcn/wifi_hal/nan_rsp.cpp
similarity index 100%
rename from qcwcn/wifi_hal/nan_rsp.cpp
rename to legacy/qcwcn/wifi_hal/nan_rsp.cpp
diff --git a/qcwcn/wifi_hal/nancommand.h b/legacy/qcwcn/wifi_hal/nancommand.h
similarity index 100%
rename from qcwcn/wifi_hal/nancommand.h
rename to legacy/qcwcn/wifi_hal/nancommand.h
diff --git a/qcwcn/wifi_hal/pkt_stats.h b/legacy/qcwcn/wifi_hal/pkt_stats.h
similarity index 100%
rename from qcwcn/wifi_hal/pkt_stats.h
rename to legacy/qcwcn/wifi_hal/pkt_stats.h
diff --git a/qcwcn/wifi_hal/qca-vendor_copy.h b/legacy/qcwcn/wifi_hal/qca-vendor_copy.h
similarity index 81%
rename from qcwcn/wifi_hal/qca-vendor_copy.h
rename to legacy/qcwcn/wifi_hal/qca-vendor_copy.h
index 11442ee..24a31a3 100644
--- a/qcwcn/wifi_hal/qca-vendor_copy.h
+++ b/legacy/qcwcn/wifi_hal/qca-vendor_copy.h
@@ -1,10 +1,7 @@
 /*
  * Qualcomm Atheros OUI and vendor specific assignments
  * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
- * Copyright (c) 2018-2019, The Linux Foundation
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef QCA_VENDOR_H
@@ -512,7 +509,9 @@
  * @QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG: This command is used to
  *	configure parameters per peer to capture Channel Frequency Response
  *	(CFR) and enable Periodic CFR capture. The attributes for this command
- *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr.
+ *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr. This command
+ *	can also be used to send CFR data from the driver to userspace when
+ *	netlink events are used to send CFR data.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: Event to indicate changes
  *	in throughput dynamically. The driver estimates the throughput based on
@@ -620,7 +619,14 @@
  *	This new command is alternative to existing command
  *	QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY since existing command/event
  *	is using stream of bytes instead of structured data using vendor
- *	attributes.
+ *	attributes. User space sends unsafe frequency ranges to the driver using
+ *	a nested attribute %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE. On
+ *	reception of this command, the driver shall check if an interface is
+ *	operating on an unsafe frequency and the driver shall try to move to a
+ *	safe channel when needed. If the driver is not able to find a safe
+ *	channel the interface can keep operating on an unsafe channel with the
+ *	TX power limit derived based on internal configurations	like
+ *	regulatory/SAR rules.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE: This vendor subcommand is used to
  *	add the STA node details in driver/firmware. Attributes for this event
@@ -664,36 +670,95 @@
  *	qca_wlan_vendor_attr_driver_disconnect_reason.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC: This vendor subcommand is used to
- *     add/delete TSPEC for each AC. One command is for one specific AC only.
- *     This command can only be used in STA mode and the STA must be
- *     associated with an AP when the command is issued. Uses attributes
- *     defined in enum qca_wlan_vendor_attr_config_tspec.
+ *	add/delete TSPEC for each AC. One command is for one specific AC only.
+ *	This command can only be used in STA mode and the STA must be
+ *	associated with an AP when the command is issued. Uses attributes
+ *	defined in enum qca_wlan_vendor_attr_config_tspec.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT: Vendor subcommand to configure TWT.
- *     Uses attributes defined in enum qca_wlan_vendor_attr_config_twt.
+ *	Uses attributes defined in enum qca_wlan_vendor_attr_config_twt.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_GETBAND: Command to get the enabled band(s) from
- *     the driver. The band configurations obtained are referred through
- *     QCA_WLAN_VENDOR_ATTR_SETBAND_MASK.
+ *	the driver. The band configurations obtained are referred through
+ *	QCA_WLAN_VENDOR_ATTR_SETBAND_MASK.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS: Vendor subcommand/event for medium
- *     assessment.
- *     Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess.
+ *	assessment.
+ *	Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID: This acts as a vendor event and is
- *     used to update SSID information in hostapd when it is updated in the
- *     driver. Uses the attribute NL80211_ATTR_SSID.
+ *	used to update SSID information in hostapd when it is updated in the
+ *	driver. Uses the attribute NL80211_ATTR_SSID.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS: This vendor subcommand is used by
- *     the driver to send opaque data from the firmware to userspace. The
- *     driver sends an event to userspace whenever such data is received from
- *     the firmware.
+ *	the driver to send opaque data from the firmware to userspace. The
+ *	driver sends an event to userspace whenever such data is received from
+ *	the firmware.
  *
- *     QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to
- *     send this opaque data for this event.
+ *	QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to
+ *	send this opaque data for this event.
  *
- *     The format of the opaque data is specific to the particular firmware
- *     version and there is no guarantee of the format remaining same.
+ *	The format of the opaque data is specific to the particular firmware
+ *	version and there is no guarantee of the format remaining same.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS: This acts as an event.
+ *	The host driver selects Tx VDEV, and notifies user. The attributes
+ *	used with this event are defined in enum
+ *	qca_wlan_vendor_attr_mbssid_tx_vdev_status.
+ *	This event contains Tx VDEV group information, other VDEVs
+ *	interface index, and status information.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY: Vendor command to
+ *	configure the concurrent session policies when multiple STA interfaces
+ *	are (getting) active. The attributes used by this command are defined
+ *	in enum qca_wlan_vendor_attr_concurrent_sta_policy.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS: Userspace can use this command
+ *	to query usable channels for different interface types such as STA,
+ *	AP, P2P GO, P2P Client, NAN, etc. The driver shall report all usable
+ *	channels in the response based on country code, different static
+ *	configurations, concurrency combinations, etc. The attributes used
+ *	with this command are defined in
+ *	enum qca_wlan_vendor_attr_usable_channels.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY: This vendor subcommand is used
+ *	to get DFS radar history from the driver to userspace. The driver
+ *	returns QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES attribute with an
+ *	array of nested entries.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD: Userspace can use this command to
+ *	enable/disable mDNS offload to the firmware. The attributes used with
+ *	this command are defined in enum qca_wlan_vendor_attr_mdns_offload.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used
+ *	to set packet monitor mode that aims to send the specified set of TX and
+ *	RX frames on the current client interface to an active monitor
+ *	interface. If this monitor mode is set, the driver will send the
+ *	configured frames, from the interface on which the command is issued, to
+ *	an active monitor interface. The attributes used with this command are
+ *	defined in enum qca_wlan_vendor_attr_set_monitor_mode.
+ *
+ *	Though the monitor mode is configured for the respective
+ *	Data/Management/Control frames, it is up to the respective WLAN
+ *	driver/firmware/hardware designs to consider the possibility of sending
+ *	these frames over the monitor interface. For example, the Control frames
+ *	are handled within the hardware and thus passing such frames over the
+ *	monitor interface is left to the respective designs.
+ *
+ *	Also, this monitor mode is governed to behave accordingly in
+ *	suspend/resume states. If the firmware handles any of such frames in
+ *	suspend state without waking up the host and if the monitor mode is
+ *	configured to notify all such frames, the firmware is expected to resume
+ *	the host and forward the respective frames to the monitor interface.
+ *	Please note that such a request to get the frames over the monitor
+ *	interface will have a definite power implication.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both
+ *	as a request to set the driver/firmware with the parameters to trigger
+ *	the roaming events, and also used by the driver/firmware to pass on the
+ *	various roam events to userspace.
+ *	Applicable only for the STA mode. The attributes used with this command
+ *	are defined in enum qca_wlan_vendor_attr_roam_events.
  */
 enum qca_nl80211_vendor_subcmds {
 	QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@@ -879,6 +944,14 @@
 	QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS = 193,
 	QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID = 194,
 	QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS = 195,
+	QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS = 196,
+	QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY = 197,
+	QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198,
+	QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY = 199,
+	QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD = 200,
+	/* 201 - reserved for QCA */
+	QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202,
+	QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203,
 };
 
 enum qca_wlan_vendor_attr {
@@ -1117,7 +1190,7 @@
  * @QCA_ROAM_REASON_CONGESTION: Roam triggered considering the connected channel
  * or environment being very noisy or congested.
  *
- * @QCA_ROAM_REASON_EXPLICIT_REQUEST: Roam triggered due to an explicit request
+ * @QCA_ROAM_REASON_USER_TRIGGER: Roam triggered due to an explicit request
  * from the user (user space).
  *
  * @QCA_ROAM_REASON_BTM: Roam triggered due to BTM Request frame received from
@@ -1125,6 +1198,26 @@
  *
  * @QCA_ROAM_REASON_BSS_LOAD: Roam triggered due to the channel utilization
  * breaching out the configured threshold.
+ *
+ * @QCA_ROAM_REASON_WTC: Roam triggered due to Wireless to Cellular BSS
+ * transition request.
+ *
+ * @QCA_ROAM_REASON_IDLE: Roam triggered when device is suspended, there is no
+ * data activity with the AP and the current RSSI falls below a certain
+ * threshold.
+ *
+ * @QCA_ROAM_REASON_DISCONNECTION: Roam triggered due to Deauthentication or
+ * Disassociation frames received from the connected AP.
+ *
+ * @QCA_ROAM_REASON_PERIODIC_TIMER: Roam triggered as part of the periodic scan
+ * that happens when there is no candidate AP found during the poor RSSI scan
+ * trigger.
+ *
+ * @QCA_ROAM_REASON_BACKGROUND_SCAN: Roam triggered based on the scan results
+ * obtained from an external scan (not aimed at roaming).
+ *
+ * @QCA_ROAM_REASON_BT_ACTIVITY: Roam triggered due to Bluetooth connection is
+ * established when the station is connected in the 2.4 GHz band.
  */
 enum qca_roam_reason {
 	QCA_ROAM_REASON_UNKNOWN,
@@ -1136,6 +1229,12 @@
 	QCA_ROAM_REASON_USER_TRIGGER,
 	QCA_ROAM_REASON_BTM,
 	QCA_ROAM_REASON_BSS_LOAD,
+	QCA_ROAM_REASON_WTC,
+	QCA_ROAM_REASON_IDLE,
+	QCA_ROAM_REASON_DISCONNECTION,
+	QCA_ROAM_REASON_PERIODIC_TIMER,
+	QCA_ROAM_REASON_BACKGROUND_SCAN,
+	QCA_ROAM_REASON_BT_ACTIVITY,
 };
 
 enum qca_wlan_vendor_attr_roam_auth {
@@ -1355,6 +1454,11 @@
  * Used with event to notify the EDMG channel number selected in ACS
  * operation.
  * EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP: Optional (u16).
+ * Used with event to notify the puncture pattern selected in ACS operation.
+ * Encoding for this attribute will follow the convention used in the Disabled
+ * Subchannel Bitmap field of the EHT Operation IE.
  */
 enum qca_wlan_vendor_attr_acs_offload {
 	QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
@@ -1375,6 +1479,7 @@
 	QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17,
+	QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP = 18,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
@@ -1438,6 +1543,25 @@
  *	%QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL and
  *	%QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW attributes from
  *	userspace.
+ * @QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R: Device supports Adaptive 11r.
+ *	With Adaptive 11r feature, access points advertise the vendor
+ *	specific IEs and MDE but do not include FT AKM in the RSNE.
+ *	The Adaptive 11r supported stations are expected to identify
+ *	such vendor specific IEs and connect to the AP in FT mode though
+ *	the profile is configured in non-FT mode.
+ *	The driver-based SME cases also need to have this support for
+ *	Adaptive 11r to handle the connection and roaming scenarios.
+ *	This flag indicates the support for the same to the user space.
+ * @QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS: Device supports
+ *	concurrent network sessions on different Wi-Fi bands. This feature
+ *	capability is attributed to the hardware's capability to support
+ *	the same (e.g., DBS).
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT: Flag indicating whether the
+ *	responses for the respective TWT operations are asynchronous (separate
+ *	event message) from the driver. If not specified, the responses are
+ *	synchronous (in vendor command reply) to the request. Each TWT
+ *	operation is specifically mentioned (against its respective
+ *	documentation) to support either of these or both modes.
  * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
  */
 enum qca_wlan_vendor_features {
@@ -1453,6 +1577,9 @@
 	QCA_WLAN_VENDOR_FEATURE_11AX			= 9,
 	QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT		= 10,
 	QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG		= 11,
+	QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R		= 12,
+	QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13,
+	QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT	= 14,
 	NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
 };
 
@@ -1679,11 +1806,22 @@
  * @QCA_TSF_CAPTURE: Initiate TSF Capture
  * @QCA_TSF_GET: Get TSF capture value
  * @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value
+ * @QCA_TSF_AUTO_REPORT_ENABLE: Used in STA mode only. Once set, the target
+ * will automatically send TSF report to the host. To query
+ * QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY, this operation needs to be
+ * initiated first.
+ * @QCA_TSF_AUTO_REPORT_DISABLE: Used in STA mode only. Once set, the target
+ * will not automatically send TSF report to the host. If
+ * QCA_TSF_AUTO_REPORT_ENABLE is initiated and
+ * QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY is not queried anymore, this
+ * operation needs to be initiated.
  */
 enum qca_tsf_cmd {
 	QCA_TSF_CAPTURE,
 	QCA_TSF_GET,
 	QCA_TSF_SYNC_GET,
+	QCA_TSF_AUTO_REPORT_ENABLE,
+	QCA_TSF_AUTO_REPORT_DISABLE,
 };
 
 /**
@@ -1777,6 +1915,23 @@
 };
 
 /**
+ * enum qca_wlan_vendor_scan_priority - Specifies the valid values that the
+ * vendor scan attribute QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY can take.
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW: Very low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW: Low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM: Medium priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH: High priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH: Very high priority
+ */
+enum qca_wlan_vendor_scan_priority {
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW = 0,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW = 1,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM = 2,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH = 3,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH = 4,
+};
+
+/**
  * enum qca_wlan_vendor_attr_scan - Specifies vendor scan attributes
  *
  * @QCA_WLAN_VENDOR_ATTR_SCAN_IE: IEs that should be included as part of scan
@@ -1801,6 +1956,11 @@
  * @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in
  *	microseconds. This is a common value which applies across all
  *	frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES.
+ * @QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY: Priority of vendor scan relative to
+ *	other scan requests. It is a u32 attribute and takes values from enum
+ *	qca_wlan_vendor_scan_priority. This is an optional attribute.
+ *	If this attribute is not configured, the driver shall use
+ *	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH as the priority of vendor scan.
  */
 enum qca_wlan_vendor_attr_scan {
 	QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0,
@@ -1816,6 +1976,7 @@
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10,
 	QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11,
 	QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12,
+	QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13,
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAX =
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1
@@ -2278,6 +2439,10 @@
 	 * frame. The updated NSS value after the connection shall not be
 	 * greater than the one negotiated during the connection. Any such
 	 * higher value configuration shall be returned with a failure.
+	 * Only symmetric NSS configuration (such as 2X2 or 1X1) can be done
+	 * using this attribute. QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes shall be used to
+	 * configure the asymmetric NSS configuration (such as 1X2).
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_NSS = 70,
 	/* 8-bit unsigned value to trigger Optimized Power Management:
@@ -2326,6 +2491,86 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL = 76,
 
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for transmitting the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The TX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver
+	 * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77,
+
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for receiving the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The RX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver
+	 * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78,
+
+	/*
+	 * 8-bit unsigned value. This attribute, when set, indicates whether the
+	 * specified interface is the primary STA interface when there are more
+	 * than one STA interfaces concurrently active.
+	 *
+	 * This configuration helps the firmware/hardware to support certain
+	 * features (e.g., roaming) on this primary interface, if the same
+	 * cannot be supported on the concurrent STA interfaces simultaneously.
+	 *
+	 * This configuration is only applicable for a single STA interface on
+	 * a device and gives the priority for it only over other concurrent STA
+	 * interfaces.
+	 *
+	 * If the device is a multi wiphy/soc, this configuration applies to a
+	 * single STA interface across the wiphys.
+	 *
+	 * 1-Enable (is the primary STA), 0-Disable (is not the primary STA)
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY = 79,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * driver to enable/disable FT-over-DS feature. Possible values for
+	 * this attribute are 1-Enable and 0-Disable.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS = 80,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * firmware to enable/disable ARP/NS offload feature. Possible values
+	 * for this attribute are 0-Disable and 1-Enable.
+	 *
+	 * This attribute is only applicable for STA/P2P-Client interface,
+	 * and is optional, default behavior is ARP/NS offload enabled.
+	 *
+	 * This attribute can be set in disconnected and connected state, and
+	 * will restore to the default behavior if the interface is closed.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD = 81,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@@ -2421,23 +2666,50 @@
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
  * %QCA_WLAN_VENDOR_GPIO_OUTPUT.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Optional (u32)
  * value to specify the GPIO pull type. Please refer to enum qca_gpio_pull_type
  * for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Optional (u32)
  * value to specify the GPIO interrupt mode. Please refer to enum
  * qca_gpio_interrupt_mode for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Optional (u32)
  * value to specify the GPIO direction. Please refer to enum qca_gpio_direction
  * for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG: Optional (u32)
+ * Value to specify the mux config. Meaning of a given value is dependent
+ * on the target chipset and GPIO pin. Must be of the range 0-15.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to 0.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE: Optional (u32)
+ * Value to specify the drive, refer to enum qca_gpio_drive.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to QCA_WLAN_GPIO_DRIVE_2MA(0).
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG: Optional (flag)
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. When present this attribute signals that all
+ * other parameters for the given GPIO will be obtained from internal
+ * configuration. Only %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM must be
+ * specified to indicate the GPIO pin being configured.
  */
 enum qca_wlan_gpio_attr {
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INVALID = 0,
@@ -2453,6 +2725,12 @@
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE = 5,
 	/* Unsigned 32-bit attribute for GPIO direction to configure */
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR = 6,
+	/* Unsigned 32-bit attribute for GPIO mux config */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG = 7,
+	/* Unsigned 32-bit attribute for GPIO drive */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE = 8,
+	/* Flag attribute for using internal GPIO configuration */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG = 9,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST,
@@ -2528,6 +2806,30 @@
 };
 
 /**
+ * enum qca_gpio_drive - GPIO drive
+ * @QCA_WLAN_GPIO_DRIVE_2MA: drive 2MA
+ * @QCA_WLAN_GPIO_DRIVE_4MA: drive 4MA
+ * @QCA_WLAN_GPIO_DRIVE_6MA: drive 6MA
+ * @QCA_WLAN_GPIO_DRIVE_8MA: drive 8MA
+ * @QCA_WLAN_GPIO_DRIVE_10MA: drive 10MA
+ * @QCA_WLAN_GPIO_DRIVE_12MA: drive 12MA
+ * @QCA_WLAN_GPIO_DRIVE_14MA: drive 14MA
+ * @QCA_WLAN_GPIO_DRIVE_16MA: drive 16MA
+ * @QCA_WLAN_GPIO_DRIVE_MAX: invalid GPIO drive
+ */
+enum qca_gpio_drive {
+	QCA_WLAN_GPIO_DRIVE_2MA = 0,
+	QCA_WLAN_GPIO_DRIVE_4MA = 1,
+	QCA_WLAN_GPIO_DRIVE_6MA = 2,
+	QCA_WLAN_GPIO_DRIVE_8MA = 3,
+	QCA_WLAN_GPIO_DRIVE_10MA = 4,
+	QCA_WLAN_GPIO_DRIVE_12MA = 5,
+	QCA_WLAN_GPIO_DRIVE_14MA = 6,
+	QCA_WLAN_GPIO_DRIVE_16MA = 7,
+	QCA_WLAN_GPIO_DRIVE_MAX,
+};
+
+/**
  * qca_wlan_set_qdepth_thresh_attr - Parameters for setting
  * MSDUQ depth threshold per peer per tid in the target
  *
@@ -3688,6 +3990,14 @@
 	 * QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO.
 	 */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85,
+	/* u8 value representing the channel load percentage. Possible values
+	 * are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86,
+	/* u8 value representing the time slicing duty cycle percentage.
+	 * Possible values are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87,
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX =
@@ -4035,6 +4345,30 @@
 	QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_roam_scan_scheme: Scan scheme
+ *
+ * @QCA_ROAM_SCAN_SCHEME_NO_SCAN: No frequencies specified to scan.
+ *     Indicates the driver to not scan on a Roam Trigger scenario, but
+ *     disconnect. E.g., on a BTM request from the AP the driver/firmware shall
+ *     disconnect from the current connected AP by notifying a failure
+ *     code in the BTM response.
+ *
+ * @QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN: Indicates the driver/firmware to
+ *     trigger partial frequency scans. These frequencies are the ones learned
+ *     or maintained by the driver based on the probability of finding the
+ *     BSSIDs in the ESS for which the roaming is triggered.
+ *
+ * @QCA_ROAM_SCAN_SCHEME_FULL_SCAN: Indicates the driver/firmware to
+ *     trigger the scan on all the valid frequencies to find better
+ *     candidates to roam.
+ */
+enum qca_roam_scan_scheme {
+	QCA_ROAM_SCAN_SCHEME_NO_SCAN = 0,
+	QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN = 1,
+	QCA_ROAM_SCAN_SCHEME_FULL_SCAN = 2,
+};
+
 /*
  * enum qca_vendor_roam_triggers: Bitmap of roaming triggers
  *
@@ -4055,6 +4389,18 @@
  *	when BTM Request frame is received from the connected AP.
  * @QCA_ROAM_TRIGGER_REASON_BSS_LOAD: Set if the roam has to be triggered
  *	when the channel utilization is goes above the configured threshold.
+ * @QCA_ROAM_TRIGGER_REASON_USER_TRIGGER: Set if the roam has to be triggered
+ *	based on the request from the user (space).
+ * @QCA_ROAM_TRIGGER_REASON_DEAUTH: Set if the roam has to be triggered when
+ *	device receives Deauthentication/Disassociation frame from connected AP.
+ * @QCA_ROAM_TRIGGER_REASON_IDLE: Set if the roam has to be triggered when the
+ *	device is in idle state (no TX/RX) and suspend mode, if the current RSSI
+ *	is determined to be a poor one.
+ * @QCA_ROAM_TRIGGER_REASON_TX_FAILURES: Set if the roam has to be triggered
+ *	based on continuous TX Data frame failures to the connected AP.
+ * @QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN: Set if the roam has to be triggered
+ *	based on the scan results obtained from an external scan (not triggered
+ *	to aim roaming).
  *
  * Set the corresponding roam trigger reason bit to consider it for roam
  * trigger.
@@ -4070,6 +4416,144 @@
 	QCA_ROAM_TRIGGER_REASON_DENSE		= 1 << 5,
 	QCA_ROAM_TRIGGER_REASON_BTM		= 1 << 6,
 	QCA_ROAM_TRIGGER_REASON_BSS_LOAD	= 1 << 7,
+	QCA_ROAM_TRIGGER_REASON_USER_TRIGGER	= 1 << 8,
+	QCA_ROAM_TRIGGER_REASON_DEAUTH          = 1 << 9,
+	QCA_ROAM_TRIGGER_REASON_IDLE		= 1 << 10,
+	QCA_ROAM_TRIGGER_REASON_TX_FAILURES	= 1 << 11,
+	QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN	= 1 << 12,
+};
+
+/*
+ * enum qca_vendor_roam_fail_reasons: Defines the various roam
+ * fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED: Roam module in the firmware is not
+ * able to trigger the scan.
+ * @QCA_ROAM_FAIL_REASON_NO_AP_FOUND: No roamable APs found during roam scan.
+ * @QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: No candidate APs found during roam
+ * scan.
+ * @QCA_ROAM_FAIL_REASON_HOST: Roam fail due to disconnect issued from host.
+ * @QCA_ROAM_FAIL_REASON_AUTH_SEND: Unable to send Authentication frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_RECV: Received Authentication frame with error
+ * status code.
+ * @QCA_ROAM_FAIL_REASON_NO_AUTH_RESP: Authentication frame not received.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_SEND: Unable to send Reassociation Request
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_RECV: Received Reassociation Response frame
+ * with error status code.
+ * @QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP: Reassociation Response frame not
+ * received.
+ * @QCA_ROAM_FAIL_REASON_SCAN_FAIL: Scan module not able to start scan.
+ * @QCA_ROAM_FAIL_REASON_AUTH_NO_ACK: No ACK is received for Authentication
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: Authentication frame is dropped
+ * internally before transmission.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK: No ACK is received for Reassociation
+ * Request frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: Reassociation Request frame is
+ * dropped internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT: EAPOL-Key M1 is not received and
+ * times out.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND: Unable to send EAPOL-Key M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: EAPOL-Key M2 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: No ACK is received for EAPOL-Key
+ * M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: EAPOL-Key M3 frame is not received.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND: Unable to send EAPOL-Key M4 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: EAPOL-Key M4 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: No ACK is received for EAPOL-Key M4
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS: Roam scan is not
+ * started for final beacon miss case.
+ * @QCA_ROAM_FAIL_REASON_DISCONNECT: Deauthentication or Disassociation frame
+ * received from the AP during roaming handoff.
+ * @QCA_ROAM_FAIL_REASON_RESUME_ABORT: Firmware roams to the AP when the Apps
+ * or host is suspended and gives the indication of the last roamed AP only
+ * when the Apps is resumed. If the Apps is resumed while the roaming is in
+ * progress, this ongoing roaming is aborted and the last roamed AP is
+ * indicated to host.
+ * @QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID: WPA3-SAE invalid PMKID.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: WPA3-SAE pre-authentication times
+ * out.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: WPA3-SAE pre-authentication fails.
+ */
+enum qca_vendor_roam_fail_reasons {
+	QCA_ROAM_FAIL_REASON_NONE = 0,
+	QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED = 1,
+	QCA_ROAM_FAIL_REASON_NO_AP_FOUND = 2,
+	QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND = 3,
+	QCA_ROAM_FAIL_REASON_HOST = 4,
+	QCA_ROAM_FAIL_REASON_AUTH_SEND = 5,
+	QCA_ROAM_FAIL_REASON_AUTH_RECV = 6,
+	QCA_ROAM_FAIL_REASON_NO_AUTH_RESP = 7,
+	QCA_ROAM_FAIL_REASON_REASSOC_SEND = 8,
+	QCA_ROAM_FAIL_REASON_REASSOC_RECV = 9,
+	QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP = 10,
+	QCA_ROAM_FAIL_REASON_SCAN_FAIL = 11,
+	QCA_ROAM_FAIL_REASON_AUTH_NO_ACK = 12,
+	QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP = 13,
+	QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK = 14,
+	QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP = 15,
+	QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT = 16,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND = 17,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP = 18,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK = 19,
+	QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT = 20,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND = 21,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP = 22,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK = 23,
+	QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS = 24,
+	QCA_ROAM_FAIL_REASON_DISCONNECT = 25,
+	QCA_ROAM_FAIL_REASON_RESUME_ABORT = 26,
+	QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID = 27,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT = 28,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL = 29,
+};
+
+/*
+ * enum qca_vendor_roam_invoke_fail_reasons: Defines the various roam
+ * invoke fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_INVOKE_STATUS_IFACE_INVALID: Invalid interface ID is passed
+ * in roam invoke command.
+ * @QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE: Roam offload in firmware is not
+ * enabled.
+ * @QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID: Connected AP profile SSID
+ * length is invalid.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW: Firmware internal roaming is already
+ * in progress.
+ * @QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP: Host sends the Beacon/Probe Response
+ * of the AP in the roam invoke command to firmware. This reason is sent by the
+ * firmware when the given AP is configured to be ignored or SSID/security
+ * does not match.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL: Roam handoff failed because of
+ * firmware internal reasons.
+ * @QCA_ROAM_INVOKE_STATUS_DISALLOW: Roam invoke trigger is not enabled.
+ * @QCA_ROAM_INVOKE_STATUS_SCAN_FAIL: Scan start fail for roam invoke.
+ * @QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL: Roam handoff start fail.
+ * @QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS: Roam invoke parameters are invalid.
+ * @QCA_ROAM_INVOKE_STATUS_NO_CAND_AP: No candidate AP found to roam to.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_FAIL: Roam handoff failed.
+ */
+enum qca_vendor_roam_invoke_fail_reasons {
+	QCA_ROAM_INVOKE_STATUS_NONE = 0,
+	QCA_ROAM_INVOKE_STATUS_IFACE_INVALID = 1,
+	QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE = 2,
+	QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID = 3,
+	QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW = 4,
+	QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP = 5,
+	QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL = 6,
+	QCA_ROAM_INVOKE_STATUS_DISALLOW = 7,
+	QCA_ROAM_INVOKE_STATUS_SCAN_FAIL = 8,
+	QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL = 9,
+	QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS = 10,
+	QCA_ROAM_INVOKE_STATUS_NO_CAND_AP = 11,
+	QCA_ROAM_INVOKE_STATUS_ROAM_FAIL = 12,
+
 };
 
 /**
@@ -4226,6 +4710,109 @@
  *
  *	Clears the selection criteria configured in the driver when specified
  *	with clear command.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME: Unsigned 32-bit value.
+ *	Represents value of the scan frequency scheme from enum
+ *	qca_roam_scan_scheme.
+ *	It's an optional attribute. If this attribute is not configured, the
+ *	driver shall proceed with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD: Signed 32-bit value in dBm,
+ *	signifying the RSSI threshold of the current connected AP, indicating
+ *	the driver to trigger roam only when the current connected AP's RSSI
+ *	is less than this threshold.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD: Signed 32-bit value in dBm,
+ *	signifying the RSSI threshold of the candidate AP, indicating
+ *	the driver to trigger roam only to the candidate AP with RSSI
+ *	better than this threshold. If RSSI thresholds for candidate APs found
+ *	in the 2.4 GHz, 5 GHz, and 6 GHz bands are configured separately using
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ,
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ, and/or
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ, those values will
+ *	take precedence over the value configured using the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_USER_REASON: Unsigned 32-bit value. Represents the
+ *	user defined reason code to be sent to the AP in response to AP's
+ *	request to trigger the roam if the roaming cannot be triggered.
+ *	Applies to all the scenarios of AP assisted roaming (e.g., BTM).
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS: Unsigned 32-bit value.
+ *	Carries a bitmap of the roam triggers specified in
+ *	enum qca_vendor_roam_triggers.
+ *	Represents the roam triggers for which the specific scan scheme from
+ *	enum qca_roam_scan_scheme has to be applied.
+ *	It's an optional attribute. If this attribute is not configured, but
+ *	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is specified, the scan scheme
+ *	specified through QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is applicable for
+ *	all the roams.
+ *	If both QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME and
+ *	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS are not specified, the
+ *	driver shall proceed with the default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ: Signed 32-bit value
+ *	in dBm, signifying the RSSI threshold of the candidate AP found in the
+ *	2.4 GHz band. The driver/firmware shall trigger roaming to the candidate
+ *	AP found in the 2.4 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 5
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 5 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by tge
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 6
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 6 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_BAND_MASK: Unsigned 32-bit value.
+ *	Carries bitmask value of bits from &enum qca_set_band and represents
+ *	all the bands in which roaming is allowed. The configuration is valid
+ *	until next disconnection. If this attribute is not present, the
+ *	existing configuration shall be used. By default, roaming is allowed on
+ *	all bands supported by the local device. When the value is set to
+ *	%QCA_SETBAND_AUTO, all supported bands shall be enabled.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for active channels in the 2.4/5 GHz
+ *	bands. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for passive channels in the 5 GHz
+ *	band. If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME: u16 value in milliseconds.
+ *	Optional parameter. The minimum duration to stay on the connected AP
+ *	channel during the channel scanning. If this attribute is not
+ *	configured, the driver shall proceed with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME: u16 value in milliseconds.
+ *	Optional parameter. The maximum duration for which the radio can scan
+ *	foreign channels consecutively without coming back to home channel. If
+ *	this attribute is not configured, the driver shall proceed with default
+ *	behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Preferred Scanning Channels.
+ *	If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Non Preferred Scanning
+ *	Channels. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
  */
 enum qca_vendor_attr_roam_control {
 	QCA_ATTR_ROAM_CONTROL_ENABLE = 1,
@@ -4236,6 +4823,21 @@
 	QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD = 6,
 	QCA_ATTR_ROAM_CONTROL_TRIGGERS = 7,
 	QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA = 8,
+	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME = 9,
+	QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD = 10,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD = 11,
+	QCA_ATTR_ROAM_CONTROL_USER_REASON = 12,
+	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS = 13,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ = 14,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ = 15,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ = 16,
+	QCA_ATTR_ROAM_CONTROL_BAND_MASK = 17,
+	QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME = 18,
+	QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME = 19,
+	QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME = 20,
+	QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME = 21,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME = 22,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME = 23,
 
 	/* keep last */
 	QCA_ATTR_ROAM_CONTROL_AFTER_LAST,
@@ -5843,6 +6445,14 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2 = 29,
+	/* This attribute specifies the bandwidth to be used for spectral scan
+	 * operation. This is an u8 attribute and uses the values in enum
+	 * nl80211_chan_width. This is an optional attribute.
+	 * If this attribute is not populated, the driver should configure the
+	 * spectral scan bandwidth to the maximum value supported by the target
+	 * for the current operating bandwidth.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH = 30,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX =
@@ -5953,6 +6563,14 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ = 18,
+	/* Flag attribute to indicate agile spectral scan capability
+	 * for 320 MHz mode.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320 = 19,
+	/* Number of spectral detectors used for scan in 320 MHz.
+	 * u32 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ = 20,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX =
@@ -6135,6 +6753,16 @@
 	 * the FW on a specific VDEV.
 	 */
 	QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22,
+	/* WMI sequence mismatch between WMI command and Tx completion */
+	QCA_WLAN_HANG_WMI_BUF_SEQUENCE_MISMATCH = 23,
+	/* Write to Device HAL register failed */
+	QCA_WLAN_HANG_REG_WRITE_FAILURE = 24,
+	/* No credit left to send the wow_wakeup_from_sleep to firmware */
+	QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25,
+	/* Bus failure */
+	QCA_WLAN_HANG_BUS_FAILURE = 26,
+	/* tasklet/credit latency found */
+	QCA_WLAN_HANG_TASKLET_CREDIT_LATENCY_DETECT = 27,
 };
 
 /**
@@ -6801,8 +7429,9 @@
 
 /**
  * enum qca_wlan_vendor_thermal_level - Defines various thermal levels
- * configured by userspace to the driver/firmware. The values will be
- * encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL attribute.
+ * configured by userspace to the driver/firmware.
+ * The values can be encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL or
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL attribute.
  * The driver/firmware takes actions requested by userspace such as throttling
  * wifi TX etc. in order to mitigate high temperature.
  *
@@ -6836,8 +7465,9 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE = 1,
 	/* Userspace uses this attribute to configure thermal level to the
-	 * driver/firmware. Used in request, u32 attribute, possible values
-	 * are defined in enum qca_wlan_vendor_thermal_level.
+	 * driver/firmware, or get thermal level from the driver/firmware.
+	 * Used in request or response, u32 attribute,
+	 * possible values are defined in enum qca_wlan_vendor_thermal_level.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL = 2,
 	/* Userspace uses this attribute to configure the time in which the
@@ -6850,6 +7480,15 @@
 	 * there is any critical ongoing operation.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3,
+	/* Nested attribute, the driver/firmware uses this attribute to report
+	 * thermal statistics of different thermal levels to userspace when
+	 * requested using the
+	 * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command
+	 * type. This attribute contains a nested array of records of thermal
+	 * statistics of multiple levels. The attributes used inside this nested
+	 * attribute are defined in enum qca_wlan_vendor_attr_thermal_stats.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST,
@@ -6875,6 +7514,16 @@
  * resume action.
  * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL: Configure thermal level to
  * the driver/firmware.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current
+ * thermal level from the driver/firmware. The driver should respond with a
+ * thermal level defined in enum qca_wlan_vendor_thermal_level.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the
+ * current thermal statistics from the driver/firmware. The driver should
+ * respond with statistics of all thermal levels encapsulated in the attribute
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear
+ * the current thermal statistics for all thermal levels maintained in the
+ * driver/firmware and start counting from zero again.
  */
 enum qca_wlan_vendor_attr_thermal_cmd_type {
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS,
@@ -6882,6 +7531,9 @@
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS,
 };
 
 /**
@@ -6964,6 +7616,11 @@
 	 * NLA_FLAG attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_RESUME_COMPLETE,
+	/* Thermal level from the driver.
+	 * u32 attribute. Possible values are defined in
+	 * enum qca_wlan_vendor_thermal_level.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL = 3,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST,
@@ -6972,6 +7629,35 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes
+ * to get thermal status from the driver/firmware.
+ * enum values are used for NL attributes encapsulated inside the
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute.
+ *
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each
+ * thermal level in milliseconds. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number
+ * of times the temperature crossed into the temperature range defined by the
+ * thermal level from both higher and lower directions. u32 size.
+ */
+enum qca_wlan_vendor_attr_thermal_stats {
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1,
+};
+
+/**
  * enum he_fragmentation_val - HE fragmentation support values
  * Indicates level of dynamic fragmentation that is supported by
  * a STA as a recipient.
@@ -7130,6 +7816,21 @@
 };
 
 /**
+ * enum qca_wlan_keep_alive_data_type - Keep alive data type configuration
+ *
+ * Indicates the frame types to use for keep alive data.
+ *
+ * @QCA_WLAN_KEEP_ALIVE_DEFAULT: Driver default type used for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_DATA: Data frame type for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_MGMT: Management frame type for keep alive.
+ */
+enum qca_wlan_keep_alive_data_type {
+	QCA_WLAN_KEEP_ALIVE_DEFAULT = 0,
+	QCA_WLAN_KEEP_ALIVE_DATA = 1,
+	QCA_WLAN_KEEP_ALIVE_MGMT = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_he_omi_tx: Represents attributes for
  * HE operating mode control transmit request. These attributes are
  * sent as part of QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX and
@@ -7577,6 +8278,128 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT = 43,
 
+	/* 8-bit unsigned value to configure the driver/firmware to start or
+	 * stop transmitting FILS discovery frames.
+	 * 0 - Stop transmitting FILS discovery frames
+	 * 1 - Start transmitting FILS discovery frames
+	 * This attribute is used to configure the testbed device.
+	 * This attribute can be configured only in AP mode and the
+	 * configuration is valid until AP restart.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX = 44,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable full bandwidth UL MU-MIMO subfield in the HE PHY capabilities
+	 * information field.
+	 * 0 - Disable full bandwidth UL MU-MIMO subfield
+	 * 1 - Enable full bandwidth UL MU-MIMO subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO = 45,
+
+	/* 16-bit unsigned value to configure the driver with a specific BSS
+	 * max idle period to advertise in the BSS Max Idle Period element
+	 * (IEEE Std 802.11-2016, 9.4.2.79) in (Re)Association Request frames.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD = 46,
+
+	/* 8-bit unsigned value to configure the driver to use only RU 242 tone
+	 * for data transmission.
+	 * 0 - Default behavior, 1 - Configure RU 242 tone for data Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX = 47,
+
+	/* 8-bit unsigned value to configure the driver to disable data and
+	 * management response frame transmission to test the BSS max idle
+	 * feature.
+	 * 0 - Default behavior, 1 - Disable data and management response Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX = 48,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Punctured Preamble Rx subfield in the HE PHY capabilities
+	 * information field.
+	 * 0 - Disable Punctured Preamble Rx subfield
+	 * 1 - Enable Punctured Preamble Rx subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX = 49,
+
+	/* 8-bit unsigned value to configure the driver to ignore the SAE H2E
+	 * requirement mismatch for 6 GHz connection.
+	 * 0 - Default behavior, 1 - Ignore SAE H2E requirement mismatch.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE = 50,
+
+	/* 8-bit unsigned value to configure the driver to allow 6 GHz
+	 * connection with all security modes.
+	 * 0 - Default behavior, 1 - Allow 6 GHz connection with all security
+	 * modes.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_6GHZ_SECURITY_TEST_MODE = 51,
+
+	/* 8-bit unsigned value to configure the driver to transmit data with
+	 * ER SU PPDU type.
+	 *
+	 * 0 - Default behavior, 1 - Enable ER SU PPDU type TX.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE = 52,
+
+	/* 8-bit unsigned value to configure the driver to use Data or
+	 * Management frame type for keep alive data.
+	 * Uses enum qca_wlan_keep_alive_data_type values.
+	 *
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE = 53,
+
+	/* 8-bit unsigned value to configure the driver to use scan request
+	 * BSSID value in Probe Request frame RA(A1) during the scan. The
+	 * driver saves this configuration and applies this setting to all user
+	 * space scan requests until the setting is cleared. If this
+	 * configuration is set, the driver uses the BSSID value from the scan
+	 * request to set the RA(A1) in the Probe Request frames during the
+	 * scan.
+	 *
+	 * 0 - Default behavior uses the broadcast RA in Probe Request frames.
+	 * 1 - Uses the scan request BSSID in RA in Probe Request frames.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA = 54,
+
+	/* 8-bit unsigned value to configure the driver to enable/disable the
+	 * BSS max idle period support.
+	 *
+	 * 0 - Disable the BSS max idle support.
+	 * 1 - Enable the BSS max idle support.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Rx control frame to MultiBSS subfield in the HE MAC
+	 * capabilities information field.
+	 * 0 - Disable Rx control frame to MultiBSS subfield
+	 * 1 - Enable Rx control frame to MultiBSS subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS = 56,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Broadcast TWT support subfield in the HE MAC capabilities
+	 * information field.
+	 * 0 - Disable Broadcast TWT support subfield
+	 * 1 - Enable Broadcast TWT support subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT = 57,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@@ -7586,26 +8409,73 @@
 /**
  * enum qca_wlan_twt_operation - Operation of the config TWT request
  * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION.
+ * The response for the respective operations can be either synchronous or
+ * asynchronous (wherever specified). If synchronous, the response to this
+ * operation is obtained in the corresponding vendor command reply to the user
+ * space. For the asynchronous case the response is obtained as an event with
+ * the same operation type.
+ *
+ * Drivers shall support either of these modes but not both simultaneously.
+ * This support for asynchronous mode is advertised through the flag
+ * QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT. If this flag is not advertised,
+ * the driver shall support synchronous mode.
  *
  * @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured
  * through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. Depending upon the
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, this is either a
+ * synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. This is a synchronous operation.
  *
  * @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * This terminate can either get triggered by the user space or can as well be
+ * a notification from the firmware if it initiates a terminate.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * the request from user space can either be a synchronous or asynchronous
+ * operation.
  *
  * @QCA_WLAN_TWT_SUSPEND: Suspend the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * this is either a synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are
  * configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_resume. Valid only after the TWT session is setup.
+ * This can as well be a notification from the firmware on a QCA_WLAN_TWT_NUDGE
+ * request. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_NUDGE: Suspend and resume the TWT session. TWT nudge is a
+ * combination of suspend and resume in a single request. Required parameters
+ * are configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the
+ * enum qca_wlan_vendor_attr_twt_nudge. Valid only after the TWT session is
+ * setup. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_STATS: Get the TWT session traffic statistics information.
+ * Refers the enum qca_wlan_vendor_attr_twt_stats. Valid only after the TWT
+ * session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_CLEAR_STATS: Clear TWT session traffic statistics information.
+ * Valid only after the TWT session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_CAPABILITIES: Get TWT capabilities of this device and its
+ * peer. Refers the enum qca_wlan_vendor_attr_twt_capability. It's a synchronous
+ * operation.
+ *
+ * @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmare is
+ * ready for a new TWT session setup after it issued a TWT teardown.
+ *
+ * @QCA_WLAN_TWT_SET_PARAM: Configure TWT related parameters. Required
+ * parameters are obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refer
+ * the enum qca_wlan_vendor_attr_twt_set_param.
  */
 enum qca_wlan_twt_operation {
 	QCA_WLAN_TWT_SET = 0,
@@ -7613,6 +8483,12 @@
 	QCA_WLAN_TWT_TERMINATE = 2,
 	QCA_WLAN_TWT_SUSPEND = 3,
 	QCA_WLAN_TWT_RESUME = 4,
+	QCA_WLAN_TWT_NUDGE = 5,
+	QCA_WLAN_TWT_GET_STATS = 6,
+	QCA_WLAN_TWT_CLEAR_STATS = 7,
+	QCA_WLAN_TWT_GET_CAPABILITIES = 8,
+	QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9,
+	QCA_WLAN_TWT_SET_PARAM = 10,
 };
 
 /**
@@ -7626,8 +8502,9 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the
  * parameters configured for TWT. These parameters are represented by
- * enum qca_wlan_vendor_attr_twt_setup or enum qca_wlan_vendor_attr_twt_resume
- * based on the operation.
+ * enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume,
+ * enum qca_wlan_vendor_attr_twt_set_param, or
+ * enum qca_wlan_vendor_attr_twt_stats based on the operation.
  */
 enum qca_wlan_vendor_attr_config_twt {
 	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0,
@@ -7788,6 +8665,19 @@
 };
 
 /**
+ * qca_wlan_twt_setup_state: Represents the TWT session states.
+ *
+ * QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: TWT session not established.
+ * QCA_WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active.
+ * QCA_WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is in suspended state.
+ */
+enum qca_wlan_twt_setup_state {
+	QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0,
+	QCA_WLAN_TWT_SETUP_STATE_ACTIVE = 1,
+	QCA_WLAN_TWT_SETUP_STATE_SUSPEND = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_twt_setup: Represents attributes for
  * TWT (Target Wake Time) setup request. These attributes are sent as part of
  * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and
@@ -7837,6 +8727,14 @@
  * 2. TWT GET Request and Response
  * 3. TWT TERMINATE Request and Response
  * 4. TWT SUSPEND Request and Response
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions for the following
+ * 1. TWT TERMINATE Request and Response
+ * 2. TWT SUSPEND Request and Response
+ * 4. TWT CLEAR STATISTICS request
+ * 5. TWT GET STATISTICS request and response
+ * If an invalid dialog ID is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8)
  * This attribute (exp) is used along with the mantissa to derive the
@@ -7887,6 +8785,7 @@
  * 2. TWT TERMINATE Response
  * 3. TWT SUSPEND Response
  * 4. TWT RESUME Response
+ * 5. TWT NUDGE Response
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE: Required (u8)
  * This field is applicable for TWT response only.
@@ -7896,9 +8795,13 @@
  * response.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF: Required (u64)
- * This field is applicable for TWT response only.
- * This field contains absolute TSF value of the wake time received
- * from the TWT responder and is passed to the userspace.
+ * In TWT setup command this field contains absolute TSF that will
+ * be used by TWT requester during setup.
+ * In TWT response this field contains absolute TSF value of the
+ * wake time received from the TWT responder and is passed to
+ * the userspace.
+ * This is an optional parameter for
+ * 1. TWT SET Request
  * This is a required parameter for
  * 1. TWT SET Response
  * 2. TWT GET Response
@@ -7915,14 +8818,87 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer for which the TWT session
  * is being configured. This is used in AP mode to represent the respective
- * client. In AP mode, this is an optional parameter for response and is
- * a required parameter for
- * 1. TWT SET Request
- * 2. TWT GET Request
- * 3. TWT TERMINATE Request
- * 4. TWT SUSPEND Request
+ * client.
+ * In AP mode, this is a required parameter in response for
+ * 1. TWT SET
+ * 2. TWT GET
+ * 3. TWT TERMINATE
+ * 4. TWT SUSPEND
  * In STA mode, this is an optional parameter in request and response for
  * the above four TWT operations.
+ * In AP mode, this is a required parameter in request for
+ * 1. TWT GET
+ * 2. TWT TERMINATE
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL: Optional (u32)
+ * Minimum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL: Optional (u32)
+ * Maximum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION: Optional (u32)
+ * Minimum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION: Optional (u32)
+ * Maximum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE: Optional (u32)
+ * TWT state for the given dialog id. The values for this are represented
+ * by enum qca_wlan_twt_setup_state.
+ * This is obtained through TWT GET operation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA: Optional (u32)
+ * This attribute is used to configure wake interval mantissa.
+ * The unit is microseconds. This attribute, when specified, takes
+ * precedence over QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA.
+ * This parameter is used for
+ * 1. TWT SET Request and Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID: Optional (u8)
+ * This attribute is used to configure Broadcast TWT ID.
+ * The Broadcast TWT ID indicates a specific Broadcast TWT for which the
+ * transmitting STA is providing TWT parameters. The allowed values are 0 to 31.
+ * This parameter is used for
+ * 1. TWT SET Request
+ * 2. TWT TERMINATE Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION: Optional (u8)
+ * This attribute is used to configure Broadcast TWT recommendation.
+ * The Broadcast TWT Recommendation subfield contains a value that indicates
+ * recommendations on the types of frames that are transmitted by TWT
+ * scheduled STAs and scheduling AP during the broadcast TWT SP.
+ * The allowed values are 0 - 3.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE: Optional (u8)
+ * This attribute is used to configure Broadcast TWT Persistence.
+ * The Broadcast TWT Persistence subfield indicates the number of
+ * TBTTs during which the Broadcast TWT SPs corresponding to this
+ * broadcast TWT Parameter set are present. The number of beacon intervals
+ * during which the Broadcast TWT SPs are present is equal to the value in the
+ * Broadcast TWT Persistence subfield plus 1 except that the value 255
+ * indicates that the Broadcast TWT SPs are present until explicitly terminated.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE: Optional (u8)
+ * This attribute contains the value of the Responder PM Mode subfield (0 or 1)
+ * from TWT response frame.
+ * This parameter is used for
+ * 1. TWT SET Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT: Optional (u32)
+ * This attribute is used to configure the announce timeout value (in us) in
+ * the firmware. This timeout value is only applicable for the announced TWT. If
+ * the timeout value is non-zero the firmware waits up to the timeout value to
+ * use Data frame as an announcement frame. If the timeout value is 0 the
+ * firmware sends an explicit QoS NULL frame as the announcement frame on SP
+ * start. The default value in the firmware is 0.
+ * This parameter is used for
+ * 1. TWT SET Request
  */
 enum qca_wlan_vendor_attr_twt_setup {
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0,
@@ -7944,6 +8920,20 @@
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED = 14,
 
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR = 15,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL = 16,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL = 17,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION = 18,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION = 19,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE = 20,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA = 21,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID = 22,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION = 23,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE = 24,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE = 25,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT = 26,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST,
@@ -7971,6 +8961,30 @@
  * @QCA_WLAN_VENDOR_TWT_STATUS_DENIED: AP did not accept the request
  * @QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR: Adding TWT dialog failed due to an
  * unknown reason
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: TWT session already in
+ * suspend state
+ * @QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: FW has dropped the frame due to
+ * invalid IE in the received TWT frame
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: Parameters received from
+ * the responder are not in the specified range
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to request from the responder. Used on the TWT_TERMINATE
+ * notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to roaming. Used on the TWT_TERMINATE notification from the
+ * firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE: FW terminated the
+ * TWT session due to SCC (Single Channel Concurrency) and MCC (Multi Channel
+ * Concurrency). Used on the TWT_TERMINATE notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS: FW rejected the TWT setup
+ * request due to roaming in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS: FW rejected the TWT
+ * setup request due to channel switch in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS: FW rejected the TWT setup
+ * request due to scan in progress.
+ * QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE: The driver requested to
+ * terminate an existing TWT session on power save exit request from userspace.
+ * Used on the TWT_TERMINATE notification from the driver/firmware.
  */
 enum qca_wlan_vendor_twt_status {
 	QCA_WLAN_VENDOR_TWT_STATUS_OK = 0,
@@ -7986,6 +9000,16 @@
 	QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE = 10,
 	QCA_WLAN_VENDOR_TWT_STATUS_DENIED = 11,
 	QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR = 12,
+	QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED = 13,
+	QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID = 14,
+	QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE = 15,
+	QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE = 16,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE = 17,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE = 18,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS = 19,
+	QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS = 20,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS = 21,
+	QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE = 22,
 };
 
 /**
@@ -8012,6 +9036,10 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID: Required (u8).
  * Flow ID is the unique identifier for each TWT session. This attribute
  * represents the respective TWT session to resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer to which TWT Resume is
@@ -8034,6 +9062,231 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_twt_nudge - Represents attributes for
+ * TWT (Target Wake Time) nudge request. TWT nudge is a combination of suspend
+ * and resume in a single request. These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session to suspend and resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in TWT NUDGE request
+ * and response.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME: Required (u32)
+ * This attribute is used as the SP offset which is the offset from
+ * TSF after which the wake happens. The units are in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE: Required (u32)
+ * This attribute represents the next TWT subfield size.
+ * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits,
+ * and 4 for 64 bits.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer to which TWT Suspend and Resume is
+ * being sent. This is used in AP mode to represent the respective
+ * client and is a required parameter. In STA mode, this is an optional
+ * parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF: Optional (u64)
+ * This field contains absolute TSF value of the time at which the TWT
+ * session will be resumed.
+ */
+enum qca_wlan_vendor_attr_twt_nudge {
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE = 3,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_stats: Represents attributes for
+ * TWT (Target Wake Time) get statistics and clear statistics request.
+ * These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session for get and clear TWT statistics.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which TWT Statistics
+ * is required.
+ * In AP mode this is used to represent the respective
+ * client and is a required parameter for
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request and response
+ * In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION: Required (u32)
+ * This is the duration of the service period in microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION: Required (u32)
+ * Average of the actual wake duration observed so far. Unit is microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS: Required (u32)
+ * The number of TWT service periods elapsed so far.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION: Required (u32)
+ * This is the minimum value of the wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION: Required (u32)
+ * This is the maximum value of wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU: Required (u32)
+ * Average number of MPDUs transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU: Required (u32)
+ * Average number of MPDUs received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE: Required (u32)
+ * Average number of bytes transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE: Required (u32)
+ * Average number of bytes received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS: Required (u32)
+ * Status of the TWT GET STATISTICS request.
+ * This contains status values in enum qca_wlan_vendor_twt_status
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ */
+enum qca_wlan_vendor_attr_twt_stats {
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION = 3,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS = 5,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION = 6,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION = 7,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU = 8,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU = 9,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE = 10,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE = 11,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS = 12,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_twt_get_capa  - Represents the bitmap of TWT capabilities
+ * supported by the device and the peer.
+ * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_GET_CAPABILITIES
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by
+ * TWT non-scheduling STA. This capability is advertised in the HE
+ * Capability/Extended Capabilities information element in the
+ * Association Request frame by the device.
+ *
+ * @QCA_WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by
+ * the TWT scheduling AP. This capability is advertised in the Extended
+ * Capabilities/HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_BROADCAST: On the requestor side, this indicates support
+ * for the broadcast TWT functionality. On the responder side, this indicates
+ * support for the role of broadcast TWT scheduling functionality. This
+ * capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_TWT_FLEXIBLE: The device supports flexible TWT schedule.
+ * This capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate
+ * that it mandates the associated HE STAs to support TWT. This capability is
+ * advertised by AP in the HE Operation Parameters field of the HE Operation
+ * information element.
+ */
+enum qca_wlan_twt_capa {
+	QCA_WLAN_TWT_CAPA_REQUESTOR = BIT(0),
+	QCA_WLAN_TWT_CAPA_RESPONDER = BIT(1),
+	QCA_WLAN_TWT_CAPA_BROADCAST = BIT(2),
+	QCA_WLAN_TWT_CAPA_FLEXIBLE =  BIT(3),
+	QCA_WLAN_TWT_CAPA_REQUIRED =  BIT(4),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_capability  - Represents attributes for TWT
+ * get capabilities request type. Used by QCA_WLAN_TWT_GET_CAPABILITIES TWT
+ * operation.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which the TWT capabilities
+ * are being queried. This is used in AP mode to represent the respective
+ * client. In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF: (u16).
+ * Self TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER: (u16).
+ * Peer TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ */
+enum qca_wlan_vendor_attr_twt_capability {
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER = 3,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_set_param: Represents attributes for
+ * TWT (Target Wake Time) related parameters. It is used when
+ * %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to %QCA_WLAN_TWT_SET_PARAM.
+ * These attributes are sent as part of %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE: Optional (u8)
+ * This attribute configures AC parameters to be used for all TWT
+ * sessions in AP mode.
+ * Uses the enum qca_wlan_ac_type values.
+ */
+enum qca_wlan_vendor_attr_twt_set_param {
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST - 1,
+};
+
+/**
  * enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by
  * the TWT responder
  *
@@ -8124,6 +9377,22 @@
 };
 
 /**
+ * enum qca_wlan_vendor_cfr_data_transport_modes - Defines QCA vendor CFR data
+ * transport modes and is used by the attribute
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE as a part of the vendor
+ * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
+ * @QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS: Use relayfs to send CFR data.
+ * @QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS: Use netlink events to send CFR
+ * data. The data shall be encapsulated within
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA along with the vendor sub command
+ * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an asynchronous event.
+ */
+enum qca_wlan_vendor_cfr_data_transport_modes {
+	QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS = 0,
+	QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS = 1,
+};
+
+/**
  * enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by
  * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor
  * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
@@ -8313,6 +9582,27 @@
  * MAC for CFR capture. This is a bitmask in which each bit represents the
  * corresponding Data frame subtype value per IEEE Std 802.11-2016,
  * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE: Optional (u8)
+ * Userspace can use this attribute to specify the driver about which transport
+ * mode shall be used by the driver to send CFR data to userspace. Uses values
+ * from enum qca_wlan_vendor_cfr_data_transport_modes. When this attribute is
+ * not present, the driver shall use the default transport mechanism which is
+ * QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID: Optional (u32)
+ * Userspace can use this attribute to specify the nl port id of the application
+ * which receives the CFR data and processes it further so that the drivers can
+ * unicast the netlink events to a specific application. Optionally included
+ * when QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE is set to
+ * QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS, not required otherwise. The drivers
+ * shall multicast the netlink events when this attribute is not included.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA: Required (NLA_BINARY).
+ * This attribute will be used by the driver to encapsulate and send CFR data
+ * to userspace along with QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an
+ * asynchronous event when the driver is configured to send CFR data using
+ * netlink events with %QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS.
  */
 enum qca_wlan_vendor_peer_cfr_capture_attr {
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0,
@@ -8341,6 +9631,9 @@
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE = 26,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID = 27,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA = 28,
 
 	/* Keep last */
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST,
@@ -9027,20 +10320,48 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE: Required
  * Nested attribute containing multiple ranges with following attributes:
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START,
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, and
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START: Required (u32)
  * Starting center frequency in MHz.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END: Required (u32)
  * Ending center frequency in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM:
+ * s32 attribute, optional. It is a per frequency range attribute.
+ * The maximum TX power limit from user space is to be applied on an
+ * unrestricted interface for corresponding frequency range. It is also
+ * possible that the actual TX power may be even lower than this cap due to
+ * other considerations such as regulatory compliance, SAR, etc. In absence of
+ * this attribute the driver shall follow current behavior which means
+ * interface (SAP/P2P) function can keep operating on an unsafe channel with TX
+ * power derived by the driver based on regulatory/SAR during interface up.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK:
+ * u32 attribute, optional. Indicates all the interface types which are
+ * restricted for all frequency ranges provided in
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ * This attribute encapsulates bitmasks of interface types defined in
+ * enum nl80211_iftype. If an interface is marked as restricted the driver must
+ * move to a safe channel and if no safe channel is available the driver shall
+ * terminate that interface functionality. In absence of this attribute,
+ * interface (SAP/P2P) can still continue operating on an unsafe channel with
+ * TX power limit derived from either
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM or based on
+ * regulatory/SAE limits if %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM
+ * is not provided.
  */
 enum qca_wlan_vendor_attr_avoid_frequency_ext {
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE = 1,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START = 2,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END = 3,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM = 4,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK = 5,
 
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_MAX =
@@ -9366,7 +10687,56 @@
  * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT: u32, used in STA mode
  * only. This represents number of Beacon frames received from this station with
  * the packet number less than or equal to the last received packet number when
- * beacon protection is enabled. 
+ * beacon protection is enabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE: u32, used in
+ * STA mode only. The driver uses this attribute to populate the connection
+ * failure reason codes and the values are defined in
+ * enum qca_sta_connect_fail_reason_codes. Userspace applications can send
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command after receiving
+ * a connection failure indication from the driver. The driver shall not
+ * include this attribute in response to the
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no connection
+ * failure observed in the last attempted connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE: u32, latest TX rate (Kbps)
+ * used by the station in its last TX frame while communicating to the AP in the
+ * connected state. When queried in the disconnected state, this represents the
+ * rate used by the STA in the last TX frame to the AP when it was connected.
+ * This attribute is used for STA mode only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX: u32, used in STA mode only.
+ * This represents the rate index used by the STA for the last TX frame to the
+ * AP. When queried in the disconnected state, this gives the last RIX used by
+ * the STA in the last TX frame to the AP when it was connected.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT: u32, used in STA
+ * mode only. This represents the number of times the STA TSF goes out of sync
+ * from the AP after the connection. If queried in the disconnected state, this
+ * gives the count of TSF out of sync for the last connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. This can be queried either in connected state or
+ * disconnected state. Each bit of this attribute represents the different
+ * roam trigger reason code which are defined in enum qca_vendor_roam_triggers.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON: u32, used in STA mode
+ * only. This represents the roam fail reason for the last failed roaming
+ * attempt by the firmware. Different roam failure reason codes are specified
+ * in enum qca_vendor_roam_fail_reasons. This can be queried either in
+ * connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be
+ * queried either in connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY: u32, used in STA mode only.
+ * This represents the average congestion duration of uplink frames in MAC
+ * queue in unit of ms. This can be queried either in connected state or
+ * disconnected state.
  */
 enum qca_wlan_vendor_attr_get_sta_info {
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0,
@@ -9412,6 +10782,14 @@
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT = 40,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE = 44,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX = 45,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT = 46,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY = 50,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST,
@@ -9842,4 +11220,600 @@
 	QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_wlan_vendor_attr_mbssid_tx_vdev_status - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL:
+ * u8 attribute. Notify the TX VDEV status. Possible values 0, 1
+ * belonging to MBSSID/EMA_AP configuration. 0 means Non-Tx VDEV,
+ * 1 means Tx VDEV. Mandatory attribute for all MBSSID VDEV status events.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT:
+ * u8 attribute, required. 1 means Tx VDEV up event. 0 means Tx VDEV down event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID:
+ * u8 attribute, required. Indicates group id of Tx VDEV.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * group information. The attributes defined in enum
+ * qca_wlan_vendor_attr_mbssid_tx_vdev_group_info
+ * are nested in this attribute.
+ */
+enum qca_wlan_vendor_attr_mbssid_tx_vdev_status {
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT = 2,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID = 3,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_MAX =
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX:
+ * u32 attribute, required. Contains interface index.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS:
+ * u8 attribute, required. 0 - means vdev is in down state.
+ * 1 - means vdev is in up state.
+ */
+enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info {
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS = 2,
+
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO - 1,
+};
+
+/**
+ * enum qca_wlan_concurrent_sta_policy_config - Concurrent STA policies
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY: Preference to the primary
+ * STA interface has to be given while selecting the connection policies
+ * (e.g., BSSID, band, TX/RX chains, etc.) for the subsequent STA interface.
+ * An interface is set as primary through the attribute
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY. This policy is not
+ * applicable if the primary interface has not been set earlier.
+ *
+ * The intention is not to downgrade the primary STA performance, such as:
+ * - Do not reduce the number of TX/RX chains of primary connection.
+ * - Do not optimize DBS vs. MCC/SCC, if DBS ends up reducing the number of
+ *   chains.
+ * - If using MCC, should set the MCC duty cycle of the primary connection to
+ *   be higher than the secondary connection.
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED: The connection policies for the
+ * subsequent STA connection shall be chosen to balance with the existing
+ * concurrent STA's performance.
+ * Such as
+ * - Can choose MCC or DBS mode depending on the MCC efficiency and hardware
+ *   capability.
+ * - If using MCC, set the MCC duty cycle of the primary connection to be equal
+ *   to the secondary.
+ * - Prefer BSSID candidates which will help provide the best "overall"
+ *   performance for all the STA connections.
+ */
+enum qca_wlan_concurrent_sta_policy_config {
+	QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY = 0,
+	QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_concurrent_sta_policy - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG:
+ * u8 attribute. Configures the concurrent STA policy configuration.
+ * Possible values are defined in enum qca_wlan_concurrent_sta_policy_config.
+ */
+enum qca_wlan_vendor_attr_concurrent_sta_policy {
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_MAX =
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST - 1,
+
+};
+
+/**
+ * enum qca_sta_connect_fail_reason_codes - Defines values carried
+ * by QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE vendor
+ * attribute.
+ * @QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND: No Probe Response frame received
+ *	for unicast Probe Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL: STA failed to send auth request.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED: AP didn't send ACK for
+ *	auth request.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED: Auth response is not
+ *	received from AP.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL: STA failed to send
+ *	Association Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED: AP didn't send ACK for
+ *	Association Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED: Association Response
+ *	frame is not received from AP.
+ */
+enum qca_sta_connect_fail_reason_codes {
+	QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND = 1,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL = 2,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED = 3,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED = 4,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL = 5,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED = 6,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED = 7,
+};
+
+/**
+ * enum qca_wlan_vendor_usable_channels_filter - Bitmask of different
+ * filters defined in this enum are used in attribute
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK.
+ *
+ * @QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX: When this bit is set, the driver
+ * shall filter the channels which are not usable because of coexistence with
+ * cellular radio.
+ * @QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY: When this bit is set, the driver
+ * shall filter the channels which are not usable because of existing active
+ * interfaces in the driver and will result in Multi Channel Concurrency, etc.
+ *
+ */
+enum qca_wlan_vendor_usable_channels_filter {
+	QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX = 0,
+	QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_chan_info - Attributes used inside
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ:
+ * u32 attribute, required. Indicates the center frequency of the primary
+ * channel in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ:
+ * u32 attribute. Indicates the center frequency of the primary segment of the
+ * channel in MHz. This attribute is required when reporting 40 MHz, 80 MHz,
+ * 160 MHz, and 320 MHz channels.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ:
+ * u32 attribute. Indicates the center frequency of the secondary segment of
+ * 80+80 channel in MHz. This attribute is required only when
+ * QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH is set to NL80211_CHAN_WIDTH_80P80.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH:
+ * u32 attribute, required. Indicates the bandwidth of the channel, possible
+ * values are defined in enum nl80211_chan_width.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK:
+ * u32 attribute, required. Indicates all the interface types for which this
+ * channel is usable. This attribute encapsulates bitmasks of interface types
+ * defined in enum nl80211_iftype.
+ *
+ */
+enum qca_wlan_vendor_attr_chan_info {
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ = 1,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH = 4,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_usable_channels - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK:
+ * u32 attribute. Indicates the bands from which the channels should be reported
+ * in response. This attribute encapsulates bit masks of bands defined in enum
+ * nl80211_band. Optional attribute, if not present in the request the driver
+ * shall return channels from all supported bands.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK:
+ * u32 attribute. Indicates all the interface types for which the usable
+ * channels information is requested. This attribute encapsulates bitmasks of
+ * interface types defined in enum nl80211_iftype. Optional attribute, if not
+ * present in the request the driver shall send information of all supported
+ * interface modes.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK:
+ * u32 attribute. This attribute carries information of all filters that shall
+ * be applied while populating usable channels information by the driver. This
+ * attribute carries bit masks of different filters defined in enum
+ * qca_wlan_vendor_usable_channels_filter. Optional attribute, if not present
+ * in the request the driver shall send information of channels without applying
+ * any of the filters that can be configured through this attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * usability information of each channel. The attributes defined in enum
+ * qca_wlan_vendor_attr_chan_info are used inside this attribute.
+ */
+enum qca_wlan_vendor_attr_usable_channels {
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK = 1,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK = 2,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK = 3,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX =
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_radar_history: Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY to get DFS radar history.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES: Nested attribute to carry
+ *	the list of radar history entries.
+ *	Each entry contains freq, timestamp, and radar signal detect flag.
+ *	The driver shall add an entry when CAC has finished, or radar signal
+ *	has been detected post AP beaconing. The driver shall maintain at least
+ *	8 entries in order to save CAC result for a 160 MHz channel.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ: u32 attribute.
+ *	Channel frequency in MHz.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP: u64 nanoseconds.
+ *	CLOCK_BOOTTIME timestamp when this entry is updated due to CAC
+ *	or radar detection.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED: NLA_FLAG attribute.
+ *	This flag indicates radar signal has been detected.
+ */
+enum qca_wlan_vendor_attr_radar_history {
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_INVALID = 0,
+
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES = 1,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP = 3,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX =
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mdns_offload - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE: Required (flag)
+ * Enable mDNS offload. This attribute is mandatory to enable
+ * mDNS offload feature. If this attribute is not present, mDNS offload
+ * is disabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE: Nested attribute containing
+ * one or more %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY attributes. This
+ * attribute is mandatory when enabling the feature, and not required when
+ * disabling the feature.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY: Nested attribute containing
+ * the following attributes:
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN: Required string attribute.
+ * It consists of a hostname and ".local" as the domain name. The character
+ * set is limited to UTF-8 encoding. The maximum allowed size is 63 bytes.
+ * It is used to compare the domain in the "QU" query. Only 1 FQDN is
+ * supported per vdev.
+ * For example: myphone.local
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT: Required
+ * u16 attribute. It specifies the total number of resource records present
+ * in the answer section of the answer payload. This attribute is needed by the
+ * firmware to populate the mDNS response frame for mDNS queries without having
+ * to parse the answer payload.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD: Required binary blob
+ * attribute sent by the mdnsResponder from userspace. It contains resource
+ * records of various types (e.g., A, AAAA, PTR, TXT) and service list. This
+ * payload is passed down to the firmware and is transmitted in response to
+ * mDNS queries.
+ * The maximum supported size of the answer payload is 512 bytes.
+ */
+enum qca_wlan_vendor_attr_mdns_offload {
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE = 1,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE = 2,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY = 3,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN = 4,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT = 5,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD = 6,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_MAX =
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_vendor_monitor_data_frame_type - Represent the various
+ * Data frame types to be sent over the monitor interface.
+ */
+enum qca_wlan_vendor_monitor_data_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17),
+};
+
+/**
+ * qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various
+ * Management frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the Management Frames.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the Management frames
+ * except the Beacon frame.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected
+ * BSSID Beacon frames. Valid only in the connected state.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents
+ * the Beacon frames obtained during the scan (off channel and connected
+ * channel), when in connected state.
+ */
+
+enum qca_wlan_vendor_monitor_mgmt_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_MGMT_NO_BEACON = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3),
+};
+
+/**
+ * qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various
+ * Control frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the Control frames
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger frame
+ */
+enum qca_wlan_vendor_monitor_ctrl_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_set_monitor_mode - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the
+ * monitor mode.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL: u32
+ * attribute.
+ * Represents the interval in milliseconds only for the connected Beacon frames,
+ * expecting the connected BSS's Beacon frames to be sent on the monitor
+ * interface at this specific interval.
+ */
+enum qca_wlan_vendor_attr_set_monitor_mode
+{
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX =
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_roam_scan_state - Roam scan state flags.
+ * Bits will be set to 1 if the corresponding state is enabled.
+ *
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start.
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end.
+ */
+enum qca_wlan_vendor_roam_scan_state {
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_roam_event_type - Roam event type flags.
+ * Bits will be set to 1 if the corresponding event is notified.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event
+ * carries the trigger reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries
+ * the BSSID, RSSI, frequency info of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event
+ * carries the roam fail reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the
+ * BSSID, RSSI, frequency info of the AP to which the roam was attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam
+ * event carries the roam invoke fail reason. When set, it is expected that
+ * the roam event carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event
+ * carries the roam scan state. When set, it is expected that the roam event
+ * carries the respective scan state via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding
+ * frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST.
+ */
+enum qca_wlan_vendor_roam_event_type {
+	QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1),
+	QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2),
+	QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info.
+ * Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address
+ * representing the BSSID of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value
+ * in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is
+ * attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, frequency in MHz
+ * on which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam fail reason for the last failed
+ * roaming attempt by the firmware for the specific BSSID. Different roam
+ * failure reason codes are specified in enum qca_vendor_roam_fail_reasons.
+ */
+enum qca_wlan_vendor_attr_roam_events_candidate_info {
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the
+ * roam events to the driver or notify these events from the driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the
+ * driver/firmware to enable/disable the notification of roam events. It's a
+ * mandatory attribute and used only in the request from the userspace to the
+ * host driver. 1-Enable, 0-Disable.
+ * If the roaming is totally offloaded to the firmware, this request when
+ * enabled shall mandate the firmware to notify all the relevant roam events
+ * represented by the below attributes. If the host is in the suspend mode,
+ * the behavior of the firmware to notify these events is guided by
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get
+ * these events in the suspend state, the firmware is expected to wake up the
+ * host before the respective events are notified. Please note that such a
+ * request to get the events in the suspend state will have a definite power
+ * implication.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents
+ * that the roam events need to be notified in the suspend state too. By
+ * default, these roam events are notified in the resume state. With this flag,
+ * the roam events are notified in both resume and suspend states.
+ * This attribute is used in the request from the userspace to the host driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only.
+ * Represents the different roam event types, signified by the enum
+ * qca_wlan_vendor_roam_event_type.
+ * Each bit of this attribute represents the different roam even types reported
+ * through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. Each bit of this attribute represents the
+ * different roam trigger reason code which are defined in enum
+ * qca_vendor_roam_triggers.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info
+ * for which the roam is attempted. Each entry is a nested attribute defined
+ * by enum qca_wlan_vendor_attr_roam_events_candidate_info.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents
+ * the scan state on which the roam events need to be notified. The values for
+ * this attribute are referred from enum qca_wlan_vendor_roam_scan_state.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of
+ * u32 values. List of frequencies in MHz considered for a roam scan.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ */
+
+enum qca_wlan_vendor_attr_roam_events
+{
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST -1,
+};
+
 #endif /* QCA_VENDOR_H */
diff --git a/qcwcn/wifi_hal/radio_mode.cpp b/legacy/qcwcn/wifi_hal/radio_mode.cpp
similarity index 100%
rename from qcwcn/wifi_hal/radio_mode.cpp
rename to legacy/qcwcn/wifi_hal/radio_mode.cpp
diff --git a/qcwcn/wifi_hal/radio_mode.h b/legacy/qcwcn/wifi_hal/radio_mode.h
similarity index 100%
rename from qcwcn/wifi_hal/radio_mode.h
rename to legacy/qcwcn/wifi_hal/radio_mode.h
diff --git a/qcwcn/wifi_hal/rb_wrapper.cpp b/legacy/qcwcn/wifi_hal/rb_wrapper.cpp
similarity index 99%
rename from qcwcn/wifi_hal/rb_wrapper.cpp
rename to legacy/qcwcn/wifi_hal/rb_wrapper.cpp
index 4c9e475..9017d21 100644
--- a/qcwcn/wifi_hal/rb_wrapper.cpp
+++ b/legacy/qcwcn/wifi_hal/rb_wrapper.cpp
@@ -117,7 +117,7 @@
     wifi_ring_buffer_status rbs;
     wifi_ring_buffer_data_handler handler;
 
-    while (1) {
+    while (info && !info->clean_up) {
         size_t length = 0;
         u8 *buf;
 
diff --git a/qcwcn/wifi_hal/rb_wrapper.h b/legacy/qcwcn/wifi_hal/rb_wrapper.h
similarity index 100%
rename from qcwcn/wifi_hal/rb_wrapper.h
rename to legacy/qcwcn/wifi_hal/rb_wrapper.h
diff --git a/qcwcn/wifi_hal/ring_buffer.cpp b/legacy/qcwcn/wifi_hal/ring_buffer.cpp
similarity index 94%
rename from qcwcn/wifi_hal/ring_buffer.cpp
rename to legacy/qcwcn/wifi_hal/ring_buffer.cpp
index d78bd62..1a65bb6 100644
--- a/qcwcn/wifi_hal/ring_buffer.cpp
+++ b/legacy/qcwcn/wifi_hal/ring_buffer.cpp
@@ -160,7 +160,7 @@
                                      // write in current buffer
     unsigned int total_push_in_rd_ptr = 0; // Total amount of push in read pointer in this write
 
-    if (record_length > rbc->each_buf_size) {
+    if (record_length > rbc->each_buf_size || length > rbc->each_buf_size) {
         return RB_FAILURE;
     }
 
@@ -279,6 +279,17 @@
             }
         }
         rb_unlock(&rbc->rb_rw_lock);
+        if(rbc->bufs[rbc->wr_buf_no].data == NULL || (rbc->bufs[rbc->wr_buf_no].data + rbc->cur_wr_buf_idx) == NULL ||
+                buf == NULL || buf + bytes_written == NULL) {
+            ALOGE("The read or Write buffer is null");
+            return RB_FAILURE;
+        }
+        if (((bytes_written + cur_copy_len) > length
+                || (rbc->cur_wr_buf_idx + cur_copy_len) > rbc->each_buf_size)) {
+            ALOGE("LOG_RB rb_write overflow - cur_copy_len=%d wr_buf[max=%zu no=%d idx=%d] buf[max=%zu accessed=%d]",
+              cur_copy_len, rbc->each_buf_size, rbc->wr_buf_no, rbc->cur_wr_buf_idx, length, bytes_written + cur_copy_len);
+            return RB_FAILURE;
+        }
 
         /* don't use lock while doing memcpy, so that we don't block the read
          * context for too long. There is no harm while writing the memory if
@@ -476,7 +487,12 @@
             cur_read_len = rbc->cur_wr_buf_idx - rbc->cur_rd_buf_idx;
         } else {
             /* write is rolled over and just behind the read */
-            cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+            if (rbc->bufs[rbc->rd_buf_no].last_wr_index >= rbc->cur_rd_buf_idx) {
+                cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+            } else {
+                ALOGE("Alert: cur_read_len=%u invalid, rd_buf[no=%d rd_idx=%d wr_index=%d]",cur_read_len, rbc->rd_buf_no, rbc->cur_rd_buf_idx, rbc->bufs[rbc->rd_buf_no].last_wr_index);
+                return NULL;
+            }
         }
     } else {
         if (rbc->cur_rd_buf_idx == 0) {
diff --git a/qcwcn/wifi_hal/ring_buffer.h b/legacy/qcwcn/wifi_hal/ring_buffer.h
similarity index 100%
rename from qcwcn/wifi_hal/ring_buffer.h
rename to legacy/qcwcn/wifi_hal/ring_buffer.h
diff --git a/qcwcn/wifi_hal/roam.cpp b/legacy/qcwcn/wifi_hal/roam.cpp
similarity index 100%
rename from qcwcn/wifi_hal/roam.cpp
rename to legacy/qcwcn/wifi_hal/roam.cpp
diff --git a/qcwcn/wifi_hal/roamcommand.h b/legacy/qcwcn/wifi_hal/roamcommand.h
similarity index 100%
rename from qcwcn/wifi_hal/roamcommand.h
rename to legacy/qcwcn/wifi_hal/roamcommand.h
diff --git a/qcwcn/wifi_hal/rssi_monitor.cpp b/legacy/qcwcn/wifi_hal/rssi_monitor.cpp
similarity index 100%
rename from qcwcn/wifi_hal/rssi_monitor.cpp
rename to legacy/qcwcn/wifi_hal/rssi_monitor.cpp
diff --git a/qcwcn/wifi_hal/rssi_monitor.h b/legacy/qcwcn/wifi_hal/rssi_monitor.h
similarity index 100%
rename from qcwcn/wifi_hal/rssi_monitor.h
rename to legacy/qcwcn/wifi_hal/rssi_monitor.h
diff --git a/qcwcn/wifi_hal/rtt.cpp b/legacy/qcwcn/wifi_hal/rtt.cpp
similarity index 100%
rename from qcwcn/wifi_hal/rtt.cpp
rename to legacy/qcwcn/wifi_hal/rtt.cpp
diff --git a/qcwcn/wifi_hal/sync.h b/legacy/qcwcn/wifi_hal/sync.h
similarity index 100%
rename from qcwcn/wifi_hal/sync.h
rename to legacy/qcwcn/wifi_hal/sync.h
diff --git a/qcwcn/wifi_hal/tdls.cpp b/legacy/qcwcn/wifi_hal/tdls.cpp
similarity index 100%
rename from qcwcn/wifi_hal/tdls.cpp
rename to legacy/qcwcn/wifi_hal/tdls.cpp
diff --git a/qcwcn/wifi_hal/tdlsCommand.h b/legacy/qcwcn/wifi_hal/tdlsCommand.h
similarity index 100%
rename from qcwcn/wifi_hal/tdlsCommand.h
rename to legacy/qcwcn/wifi_hal/tdlsCommand.h
diff --git a/qcwcn/wifi_hal/vendor_definitions.h b/legacy/qcwcn/wifi_hal/vendor_definitions.h
similarity index 100%
rename from qcwcn/wifi_hal/vendor_definitions.h
rename to legacy/qcwcn/wifi_hal/vendor_definitions.h
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/legacy/qcwcn/wifi_hal/wifi_hal.cpp
similarity index 83%
rename from qcwcn/wifi_hal/wifi_hal.cpp
rename to legacy/qcwcn/wifi_hal/wifi_hal.cpp
index 372d9e1..cb4b8e7 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/legacy/qcwcn/wifi_hal/wifi_hal.cpp
@@ -12,6 +12,40 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <stdint.h>
@@ -106,6 +140,7 @@
                                             u8 enable);
 wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
                              WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
+static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle handle);
 
 /* Initialize/Cleanup */
 
@@ -473,6 +508,226 @@
     return WIFI_SUCCESS;
 }
 
+static uint32_t get_frequency_from_channel(uint32_t channel, wlan_mac_band band)
+{
+  uint32_t freq = 0;
+
+  switch (band)
+  {
+    case WLAN_MAC_2_4_BAND:
+      if (!(channel >= 1 && channel <= 14))
+        goto failure;
+      //special handling for channel 14 by filling freq here
+      if (channel == 14)
+        freq = 2484;
+      else
+        freq = 2407 + (channel * 5);
+      break;
+    case WLAN_MAC_5_0_BAND:
+      if (!((channel >= 34 && channel < 65) ||
+          (channel > 99 && channel <= 196)))
+        goto failure;
+      freq = 5000 + (channel * 5);
+      break;
+    case WLAN_MAC_6_0_BAND:
+      if (!(channel >= 1 && channel <= 233))
+        goto failure;
+      freq = 5950 + (channel * 5);
+      break;
+    default:
+      break;
+  }
+
+failure:
+  return freq;
+}
+
+static u32 get_nl_ifmask_from_coex_restriction_mask(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (!in_mask)
+       return op_mask;
+    if (in_mask & SOFTAP)
+         op_mask |= BIT(NL80211_IFTYPE_AP);
+    if (in_mask & WIFI_DIRECT)
+         op_mask |= BIT(NL80211_IFTYPE_P2P_GO);
+    if (in_mask & WIFI_AWARE)
+         op_mask |= BIT(NL80211_IFTYPE_NAN);
+
+    return op_mask;
+}
+
+wifi_error wifi_set_coex_unsafe_channels(wifi_handle handle, u32 num_channels,
+                                         wifi_coex_unsafe_channel *unsafeChannels,
+                                         u32 restrictions)
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    WifihalGeneric *cmd = NULL;
+    struct nlattr *nl_data = NULL;
+    struct nlattr *nl_attr_unsafe_chan = NULL;
+    struct nlattr *unsafe_channels_attr = NULL;
+    hal_info *info = NULL;
+
+    if (!handle) {
+         ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
+         goto cleanup;
+    }
+
+    info = getHalInfo(handle);
+    if (!info || info->num_interfaces < 1) {
+         ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present",
+               __FUNCTION__);
+         goto cleanup;
+    }
+
+    cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA,
+                             QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT);
+    if (cmd == NULL) {
+         ALOGE("%s: Error, created command NULL", __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    /* Create the NL message. */
+    ret = cmd->create();
+    if (ret < 0) {
+         ALOGE("%s: failed to create NL msg due to error: (%d)",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data) {
+         ALOGE("%s: failed attr_start for NL80211_ATTR_VENDOR_DATA",
+               __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    nl_attr_unsafe_chan = cmd->attr_start(
+        QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE);
+    if (!nl_attr_unsafe_chan) {
+         ALOGE("%s: failed attr_start for"
+               " QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE", __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+    ALOGD("%s: num_channels:%d, restrictions:%x", __FUNCTION__, num_channels,
+          restrictions);
+    if (num_channels == 0) {
+         unsafe_channels_attr = cmd->attr_start(0);
+         if (!unsafe_channels_attr) {
+              ALOGE("%s: failed attr_start for unsafe_channels_attr when"
+                    " trying to clear usafe channels clear", __FUNCTION__);
+              ret = WIFI_ERROR_OUT_OF_MEMORY;
+              goto cleanup;
+         }
+         ret = cmd->put_u32(
+               QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, 0);
+         if (ret != WIFI_SUCCESS) {
+              ALOGE("%s: Failed to put frequency start, ret:%d",
+                    __FUNCTION__, ret);
+              goto cleanup;
+         }
+         ret = cmd->put_u32(
+               QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, 0);
+         if (ret != WIFI_SUCCESS) {
+              ALOGE("%s: Failed to put frequency end, ret:%d",
+                    __FUNCTION__, ret);
+              goto cleanup;
+         }
+         cmd->attr_end(unsafe_channels_attr);
+    }
+    else {
+        if (!unsafeChannels) {
+            ALOGE("%s: unsafe channels buffer should not be NULL when"
+                  " there are unsafe channels", __FUNCTION__);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto cleanup;
+        }
+    }
+    for (int i = 0; i < num_channels; i++) {
+         unsafe_channels_attr = cmd->attr_start(i);
+         if (!unsafe_channels_attr) {
+              ALOGE("%s: failed attr_start for unsafe_channels_attr of"
+                    " index:%d", __FUNCTION__, i);
+              ret = WIFI_ERROR_OUT_OF_MEMORY;
+              goto cleanup;
+         }
+         u32 freq = get_frequency_from_channel(unsafeChannels[i].channel,
+               unsafeChannels[i].band);
+         if (!freq) {
+              ALOGE("%s: Failed to get frequency of band:%d, channel:%d",
+                        __FUNCTION__, (int)unsafeChannels[i].band,
+                        unsafeChannels[i].channel);
+              ret = WIFI_ERROR_INVALID_ARGS;
+              goto cleanup;
+         }
+         ret = cmd->put_u32(
+               QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, freq);
+         if (ret != WIFI_SUCCESS) {
+              ALOGE("%s: Failed to put frequency start, ret:%d",
+                    __FUNCTION__, ret);
+              goto cleanup;
+         }
+         ret = cmd->put_u32(
+               QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, freq);
+         if (ret != WIFI_SUCCESS) {
+              ALOGE("%s: Failed to put frequency end, ret:%d",
+                    __FUNCTION__, ret);
+              goto cleanup;
+         }
+         /**
+          * WIFI_COEX_NO_POWER_CAP (0x7FFFFFF) is specific to android
+          * framework, this value denotes that framework/wifihal is not
+          * providing any power cap and allow driver/firmware to operate on
+          * current power cap dbm. As driver is supposed to work on with
+          * LA/LE etc, we are skipping to send 0x7FFFFFF down to driver,
+          * hence driver will be operating as per current power cap calculated
+          * based on regulatory or other constraints.
+          */
+         if (unsafeChannels[i].power_cap_dbm != WIFI_COEX_NO_POWER_CAP) {
+             ret = cmd->put_s32(
+                   QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM,
+                   unsafeChannels[i].power_cap_dbm);
+             if (ret != WIFI_SUCCESS) {
+                 ALOGE("%s: Failed to put power_cap_dbm, ret:%d",
+                       __FUNCTION__, ret);
+                 goto cleanup;
+             }
+         }
+         cmd->attr_end(unsafe_channels_attr);
+         ALOGD("%s: channel:%d, freq:%d, power_cap_dbm:%d, band:%d",
+               __FUNCTION__, unsafeChannels[i].channel, freq,
+               unsafeChannels[i].power_cap_dbm, unsafeChannels[i].band);
+    }
+    cmd->attr_end(nl_attr_unsafe_chan);
+    if (num_channels > 0) {
+        ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK,
+                       get_nl_ifmask_from_coex_restriction_mask(restrictions));
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: Failed to put restrictions mask, ret:%d",
+                  __FUNCTION__, ret);
+            goto cleanup;
+        }
+    }
+    cmd->attr_end(nl_data);
+
+    /* Send the msg and wait for a response. */
+    ret = cmd->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+cleanup:
+    if (cmd)
+        delete cmd;
+    return ret;
+}
+
 wifi_error wifi_set_dtim_config(wifi_interface_handle handle, u32 multiplier)
 {
     wifi_error ret = WIFI_ERROR_INVALID_ARGS;
@@ -543,6 +798,161 @@
     return ret;
 }
 
+static u32 get_nl_band_mask(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & WLAN_MAC_2_4_BAND)
+         op_mask |= BIT(NL80211_BAND_2GHZ);
+    if (in_mask & WLAN_MAC_5_0_BAND)
+         op_mask |= BIT(NL80211_BAND_5GHZ);
+    if (in_mask & WLAN_MAC_6_0_BAND)
+         op_mask |= BIT(NL80211_BAND_6GHZ);
+    if (in_mask & WLAN_MAC_60_0_BAND)
+         op_mask |= BIT(NL80211_BAND_60GHZ);
+
+    return op_mask;
+}
+
+static u32 get_nl_iftype_mode_masks(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & BIT(WIFI_INTERFACE_STA) ||
+        in_mask & BIT(WIFI_INTERFACE_TDLS))
+         op_mask |= BIT(NL80211_IFTYPE_STATION);
+    if (in_mask & BIT(WIFI_INTERFACE_SOFTAP))
+         op_mask |= BIT(NL80211_IFTYPE_AP);
+    if (in_mask & BIT(WIFI_INTERFACE_P2P_CLIENT))
+         op_mask |= BIT(NL80211_IFTYPE_P2P_CLIENT);
+    if (in_mask & BIT(WIFI_INTERFACE_P2P_GO))
+         op_mask |= BIT(NL80211_IFTYPE_P2P_GO);
+    if (in_mask & BIT(WIFI_INTERFACE_NAN))
+         op_mask |= BIT(NL80211_IFTYPE_NAN);
+
+    return op_mask;
+}
+
+static u32 get_vendor_filter_mask(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE)
+         op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX);
+    if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY)
+         op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY);
+
+    return op_mask;
+}
+
+wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask,
+                                    u32 iface_mode_mask, u32 filter_mask,
+                                    u32 max_size, u32* size,
+                                    wifi_usable_channel* channels)
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    WifihalGeneric *cmd = NULL;
+    struct nlattr *nl_data = NULL;
+    hal_info *info = NULL;
+    u32 band = 0, iface_mask = 0, filter = 0;
+
+    if (!handle) {
+         ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
+         goto cleanup;
+    }
+
+    info = getHalInfo(handle);
+    if (!info || info->num_interfaces < 1) {
+         ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present",
+               __FUNCTION__);
+         goto cleanup;
+    }
+
+    if (!max_size) {
+         ALOGE("%s: max channel size is zero", __FUNCTION__);
+         ret = WIFI_ERROR_INVALID_ARGS;
+         goto cleanup;
+    }
+
+    if (!channels) {
+         ALOGE("%s: user input channel buffer NULL", __FUNCTION__);
+         ret = WIFI_ERROR_INVALID_ARGS;
+         goto cleanup;
+    }
+
+    cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA,
+                             QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS);
+    if (cmd == NULL) {
+         ALOGE("%s: Error, created command NULL", __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    /* Create the NL message. */
+    ret = cmd->create();
+    if (ret < 0) {
+         ALOGE("%s: failed to create NL msg due to error: (%d)",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data) {
+         ALOGE("%s: failed attr_start for VENDOR_DATA due to error: (%d)",
+               __FUNCTION__, ret);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    band = get_nl_band_mask(band_mask);
+    ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK,
+                       band);
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: failed to put vendor data due to error:%d",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    iface_mask = get_nl_iftype_mode_masks(iface_mode_mask);
+    ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK,
+                       iface_mask);
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: failed to put vendor data due to error:%d",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    filter = get_vendor_filter_mask(filter_mask);
+    ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK,
+                       filter);
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: failed to put vendor data due to error:%d",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    cmd->attr_end(nl_data);
+
+    /* Populate the input received from caller/framework. */
+    cmd->setMaxSetSize(max_size);
+    cmd->set_channels_buff(channels);
+
+    /* Send the msg and wait for a response. */
+    ret = cmd->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    *size = cmd->get_results_size();
+
+cleanup:
+    if (cmd)
+        delete cmd;
+    return ret;
+}
+
 /*initialize function pointer table with Qualcomm HAL API*/
 wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
     if (fn == NULL) {
@@ -644,7 +1054,9 @@
     fn->wifi_virtual_interface_delete = wifi_virtual_interface_delete;
     fn->wifi_set_latency_mode = wifi_set_latency_mode;
     fn->wifi_set_thermal_mitigation_mode = wifi_set_thermal_mitigation_mode;
+    fn->wifi_set_coex_unsafe_channels = wifi_set_coex_unsafe_channels;
     fn->wifi_set_dtim_config = wifi_set_dtim_config;
+    fn->wifi_get_usable_channels = wifi_get_usable_channels;
 
     return WIFI_SUCCESS;
 }
@@ -955,6 +1367,14 @@
     ALOGV("Initialized Wifi HAL Successfully; vendor cmd = %d Supported"
             " features : 0x%" PRIx64, NL80211_CMD_VENDOR, info->supported_feature_set);
 
+    if (wifi_is_nan_ext_cmd_supported(iface_handle))
+        info->support_nan_ext_cmd = true;
+    else
+        info->support_nan_ext_cmd = false;
+
+    ALOGV("support_nan_ext_cmd is %d",
+          info->support_nan_ext_cmd);
+
 cld80211_cleanup:
     if (status != 0 || ret != WIFI_SUCCESS) {
         ret = WIFI_ERROR_UNKNOWN;
@@ -2711,3 +3131,99 @@
     delete vCommand;
     return ret;
 }
+
+class GetSupportedVendorCmd : public WifiCommand
+{
+private:
+    u32 mVendorCmds[256];
+    int mNumOfVendorCmds;
+
+public:
+    GetSupportedVendorCmd(wifi_handle handle) : WifiCommand(handle, 0)
+    {
+        mNumOfVendorCmds = 0;
+        memset(mVendorCmds, 0, 256);
+    }
+
+    virtual wifi_error create() {
+        int nl80211_id = genl_ctrl_resolve(mInfo->cmd_sock, "nl80211");
+        wifi_error ret = mMsg.create(nl80211_id, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, 0);
+        mMsg.put_flag(NL80211_ATTR_SPLIT_WIPHY_DUMP);
+
+        return ret;
+    }
+
+    virtual wifi_error requestResponse() {
+        return WifiCommand::requestResponse(mMsg);
+    }
+    virtual wifi_error set_iface_id(const char* name) {
+        unsigned ifindex = if_nametoindex(name);
+        return mMsg.set_iface_id(ifindex);
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        struct nlattr **tb = reply.attributes();
+
+        if (tb[NL80211_ATTR_VENDOR_DATA]) {
+            struct nlattr *nl;
+            int rem, i = 0;
+
+            for_each_attr(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
+                struct nl80211_vendor_cmd_info *vinfo;
+                if (nla_len(nl) != sizeof(*vinfo)) {
+                    ALOGE("Unexpected vendor data info found in attribute");
+                    continue;
+                }
+                vinfo = (struct nl80211_vendor_cmd_info *)nla_data(nl);
+                if (vinfo->vendor_id == OUI_QCA) {
+                    mVendorCmds[i] = vinfo->subcmd;
+                    i++;
+                }
+            }
+            mNumOfVendorCmds = i;
+        }
+        return NL_SKIP;
+    }
+
+    int isVendorCmdSupported(u32 cmdId) {
+        int i, ret;
+
+        ret = 0;
+        for (i = 0; i < mNumOfVendorCmds; i++) {
+            if (cmdId == mVendorCmds[i]) {
+                ret = 1;
+                break;
+            }
+        }
+
+        return ret;
+    }
+};
+
+static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle iface_handle)
+{
+    wifi_error ret;
+    wifi_handle handle = getWifiHandle(iface_handle);
+    interface_info *info = getIfaceInfo(iface_handle);
+    GetSupportedVendorCmd cmd(handle);
+
+    ret = cmd.create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: create command failed", __func__);
+        return 0;
+    }
+
+    ret = cmd.set_iface_id(info->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: set iface id failed", __func__);
+        return 0;
+    }
+
+    ret = cmd.requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to query nan_ext command support, ret=%d", ret);
+        return 0;
+    } else {
+        return cmd.isVendorCmdSupported(QCA_NL80211_VENDOR_SUBCMD_NAN_EXT);
+    }
+}
diff --git a/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c b/legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
similarity index 100%
rename from qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
rename to legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
diff --git a/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h b/legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h
similarity index 100%
rename from qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h
rename to legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h
diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/legacy/qcwcn/wifi_hal/wificonfig.cpp
similarity index 100%
rename from qcwcn/wifi_hal/wificonfig.cpp
rename to legacy/qcwcn/wifi_hal/wificonfig.cpp
diff --git a/qcwcn/wifi_hal/wificonfigcommand.h b/legacy/qcwcn/wifi_hal/wificonfigcommand.h
similarity index 100%
rename from qcwcn/wifi_hal/wificonfigcommand.h
rename to legacy/qcwcn/wifi_hal/wificonfigcommand.h
diff --git a/qcwcn/wifi_hal/wifihal_internal.h b/legacy/qcwcn/wifi_hal/wifihal_internal.h
similarity index 100%
rename from qcwcn/wifi_hal/wifihal_internal.h
rename to legacy/qcwcn/wifi_hal/wifihal_internal.h
diff --git a/qcwcn/wifi_hal/wifihal_vendor.cpp b/legacy/qcwcn/wifi_hal/wifihal_vendor.cpp
similarity index 100%
rename from qcwcn/wifi_hal/wifihal_vendor.cpp
rename to legacy/qcwcn/wifi_hal/wifihal_vendor.cpp
diff --git a/qcwcn/wifi_hal/wifihal_vendorcommand.h b/legacy/qcwcn/wifi_hal/wifihal_vendorcommand.h
similarity index 100%
rename from qcwcn/wifi_hal/wifihal_vendorcommand.h
rename to legacy/qcwcn/wifi_hal/wifihal_vendorcommand.h
diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/legacy/qcwcn/wifi_hal/wifilogger.cpp
similarity index 100%
rename from qcwcn/wifi_hal/wifilogger.cpp
rename to legacy/qcwcn/wifi_hal/wifilogger.cpp
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/legacy/qcwcn/wifi_hal/wifilogger_diag.cpp
similarity index 95%
rename from qcwcn/wifi_hal/wifilogger_diag.cpp
rename to legacy/qcwcn/wifi_hal/wifilogger_diag.cpp
index bdc9c7f..09ac928 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/legacy/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -24,6 +24,40 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 /* Suppress -Waddress-of-packed-member for new toolchain update.
@@ -862,8 +896,23 @@
     buf += 4;
     length -= 4;
 
-    while (length > (count + sizeof(fw_diag_msg_fixed_hdr_t))) {
+    while ((info && !info->clean_up)
+          && (length > (count + sizeof(fw_diag_msg_fixed_hdr_t)))) {
         diag_msg_fixed_hdr = (fw_diag_msg_fixed_hdr_t *)(buf + count);
+
+        if (diag_msg_fixed_hdr->diag_event_type > WLAN_DIAG_TYPE_LEGACY_MSG) {
+            hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
+        } else {
+            hdr_size = sizeof(fw_diag_msg_hdr_t);
+        }
+
+        if ((count + hdr_size) > length)
+        {
+            ALOGE("process_fw_diag_msg (%d) - possible buffer over access, length=%d count=%d hdr_size=%d",
+                  diag_msg_fixed_hdr->diag_event_type, length, count, hdr_size);
+            return WIFI_ERROR_UNKNOWN;
+        }
+
         switch (diag_msg_fixed_hdr->diag_event_type) {
             case WLAN_DIAG_TYPE_EVENT:
             case WLAN_DIAG_TYPE_EVENT_V2:
@@ -883,6 +932,12 @@
                     hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
                     payload = diag_msg_hdr_v2->payload;
                 }
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_EVENT - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
+
                 switch (id) {
                     case EVENT_WLAN_BT_COEX_BT_SCO_START:
                     case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
@@ -980,6 +1035,12 @@
                     hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
                     payload = diag_msg_hdr_v2->payload;
                 }
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_LOG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
+
                 switch (id) {
                 case LOG_WLAN_EXTSCAN_CAPABILITIES:
                     status = process_log_extscan_capabilities(info,
@@ -1002,6 +1063,11 @@
                 payloadlen = diag_msg_hdr->u.msg_hdr.payload_len;
                 hdr_size = sizeof(fw_diag_msg_hdr_t);
                 payload = diag_msg_hdr->payload;
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_MSG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
                 process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
                                        payloadlen + hdr_size);
                 break;
@@ -1012,6 +1078,11 @@
                 payloadlen = diag_msg_hdr_v2->u.msg_hdr.payload_len;
                 hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
                 payload = diag_msg_hdr_v2->payload;
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_MSG_V2 - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
                 process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
                                        payloadlen + hdr_size);
                 break;
@@ -1023,6 +1094,11 @@
                 payload = diag_msg_hdr->payload;
                 payloadlen = diag_msg_hdr->u.payload_len;
                 hdr_size = sizeof(fw_diag_msg_hdr_t);
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_CONFIG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
                 process_firmware_prints(info, (u8 *)diag_msg_hdr,
                                         payloadlen + hdr_size);
             }
@@ -1510,7 +1586,7 @@
     wifi_ring_per_packet_status_entry *pps_entry;
     u32 index = 0;
 
-    while (index < info->rx_buf_size_occupied) {
+    while ((info && !info->clean_up) && (index < info->rx_buf_size_occupied)) {
         pps_entry = (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
 
         pps_entry->MCS = info->aggr_stats.RxMCS.mcs;
@@ -2347,6 +2423,9 @@
                        rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
                       }
                  break;
+                 default:
+                 // TODO: Unexpected PKTLOG types
+                 break;
               }
               if (info->pkt_stats->tx_stats_events &  BIT(PKTLOG_TYPE_TX_STAT)) {
                  /* if bmap_enqueued is 1 ,Handle non aggregated cases */
@@ -2385,7 +2464,7 @@
            data = (u8*) (data + sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len);
            info->pkt_stats->tx_stats_events = 0;
         }
-    } while (pkt_stats_len > 0);
+    } while ((info && !info->clean_up) && (pkt_stats_len > 0));
     return status;
 }
 
@@ -2522,7 +2601,7 @@
         data += record_len;
         buflen -= record_len;
 
-    } while (buflen > 0);
+    } while ((info && !info->clean_up) && (buflen > 0));
 
     return status;
 }
@@ -2597,14 +2676,14 @@
                     clh = (tAniCLDHdr *)nla_data(tb_vendor[CLD80211_ATTR_DATA]);
                 }
             }
-            if (!clh) {
-                ALOGE("Invalid data received from driver");
-                return WIFI_SUCCESS;
-            }
             if((info->wifihal_ctrl_sock.s > 0) && (genlh->cmd == WLAN_NL_MSG_OEM)) {
                wifihal_ctrl_event_t *ctrl_evt;
                wifihal_mon_sock_t *reg;
 
+               if (!(tb_vendor[CLD80211_ATTR_DATA] || tb_vendor[CLD80211_ATTR_CMD])) {
+                   ALOGE("Invalid oem data received from driver");
+                   return WIFI_ERROR_UNKNOWN;
+               }
                ctrl_evt = (wifihal_ctrl_event_t *)malloc(sizeof(*ctrl_evt) + nlh->nlmsg_len);
 
                if(ctrl_evt == NULL)
@@ -2653,6 +2732,7 @@
                    }
                }
                free(ctrl_evt);
+               return WIFI_SUCCESS;
             }
         }
     } else {
@@ -2660,6 +2740,10 @@
         cmd = wnl->nlh.nlmsg_type;
     }
 
+    if (!clh) {
+         ALOGE("Invalid data received from driver");
+         return WIFI_ERROR_UNKNOWN;
+    }
     /* Check nlmsg_type also to avoid processing unintended msgs */
     if (cmd == ANI_NL_MSG_PUMAC) {
         if (!info->cldctx) {
diff --git a/qcwcn/wifi_hal/wifilogger_diag.h b/legacy/qcwcn/wifi_hal/wifilogger_diag.h
similarity index 100%
rename from qcwcn/wifi_hal/wifilogger_diag.h
rename to legacy/qcwcn/wifi_hal/wifilogger_diag.h
diff --git a/qcwcn/wifi_hal/wifilogger_event_defs.h b/legacy/qcwcn/wifi_hal/wifilogger_event_defs.h
similarity index 100%
rename from qcwcn/wifi_hal/wifilogger_event_defs.h
rename to legacy/qcwcn/wifi_hal/wifilogger_event_defs.h
diff --git a/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h b/legacy/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
similarity index 100%
rename from qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
rename to legacy/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
diff --git a/qcwcn/wifi_hal/wifiloggercmd.h b/legacy/qcwcn/wifi_hal/wifiloggercmd.h
similarity index 100%
rename from qcwcn/wifi_hal/wifiloggercmd.h
rename to legacy/qcwcn/wifi_hal/wifiloggercmd.h
diff --git a/qcwcn/wpa_supplicant_8_lib/Android.mk b/legacy/qcwcn/wpa_supplicant_8_lib/Android.mk
similarity index 100%
rename from qcwcn/wpa_supplicant_8_lib/Android.mk
rename to legacy/qcwcn/wpa_supplicant_8_lib/Android.mk
diff --git a/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD b/legacy/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD
similarity index 100%
rename from qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD
rename to legacy/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD
diff --git a/qcwcn/wpa_supplicant_8_lib/NOTICE b/legacy/qcwcn/wpa_supplicant_8_lib/NOTICE
similarity index 100%
rename from qcwcn/wpa_supplicant_8_lib/NOTICE
rename to legacy/qcwcn/wpa_supplicant_8_lib/NOTICE
diff --git a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/legacy/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
similarity index 100%
rename from qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
rename to legacy/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
diff --git a/wcn6740/Android.mk b/wcn6740/Android.mk
new file mode 100644
index 0000000..6695cef
--- /dev/null
+++ b/wcn6740/Android.mk
@@ -0,0 +1,6 @@
+# TODO:  Find a better way to separate build configs for ADP vs non-ADP devices
+QCOM_WLAN_ROOT := $(call my-dir)
+
+ifneq ($(BOARD_IS_AUTOMOTIVE),true)
+include $(call all-subdir-makefiles)
+endif
diff --git a/wcn6740/cld80211-lib/Android.mk b/wcn6740/cld80211-lib/Android.mk
new file mode 100644
index 0000000..7b40fe1
--- /dev/null
+++ b/wcn6740/cld80211-lib/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH := $(call my-dir)
+
+# =================================
+# copy header
+# =================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libcld80211_headers
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_VENDOR_MODULE := true
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
+include $(BUILD_HEADER_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcld80211
+LOCAL_CLANG := true
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES += $(LOCAL_PATH) \
+	external/libnl/include
+LOCAL_SHARED_LIBRARIES := libcutils libnl liblog
+LOCAL_SRC_FILES := cld80211_lib.c
+LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
+LOCAL_HEADER_LIBRARIES := libcld80211_headers
+LOCAL_VENDOR_MODULE := true
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
+include $(BUILD_SHARED_LIBRARY)
diff --git a/wcn6740/cld80211-lib/Makefile.am b/wcn6740/cld80211-lib/Makefile.am
new file mode 100644
index 0000000..19cdc49
--- /dev/null
+++ b/wcn6740/cld80211-lib/Makefile.am
@@ -0,0 +1,27 @@
+# Makefile.am - Automake script for cld80211-lib
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CFLAGS = -Wall
+
+if DEBUG
+AM_CFLAGS += -g
+else
+AM_CFLAGS += -O2
+endif
+
+AM_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast \
+             -Wno-maybe-uninitialized -Wno-parentheses -DLE_BUILD \
+             -D_GNU_SOURCE=1
+
+h_sources = cld80211_lib.h
+library_includedir = $(pkgincludedir)
+library_include_HEADERS = $(h_sources)
+
+libcld80211_la_SOURCES = cld80211_lib.c
+libcld80211_la_CFLAGS = ${AM_CFLAGS} ${LIBNL_CFLAGS}
+libcld80211_la_LIBADD = ${LIBNL_LIBS}
+lib_LTLIBRARIES = libcld80211.la
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = cld80211-lib.pc
+EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/wcn6740/cld80211-lib/cld80211-lib.pc.in b/wcn6740/cld80211-lib/cld80211-lib.pc.in
new file mode 100644
index 0000000..c611c64
--- /dev/null
+++ b/wcn6740/cld80211-lib/cld80211-lib.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: cld80211-lib
+Description: "cld80211 Library"
+Version: @VERSION@
+Libs: -L${libdir} -lcld80211
+Cflags: -I${includedir}/@PACKAGE@
diff --git a/cld80211-lib/cld80211_lib.c b/wcn6740/cld80211-lib/cld80211_lib.c
similarity index 93%
copy from cld80211-lib/cld80211_lib.c
copy to wcn6740/cld80211-lib/cld80211_lib.c
index 5c8255b..bc082a9 100644
--- a/cld80211-lib/cld80211_lib.c
+++ b/wcn6740/cld80211-lib/cld80211_lib.c
@@ -5,7 +5,7 @@
  * Copyright (c) 2005-2006, Devicescape Software, Inc.
  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
  * Copyright (c) 2009-2010, Atheros Communications
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -38,11 +38,22 @@
 #include <netlink/genl/ctrl.h>
 #include <linux/pkt_sched.h>
 #include <unistd.h>
-#include <log/log.h>
 #include "cld80211_lib.h"
 
-#undef LOG_TAG
-#define LOG_TAG "CLD80211"
+#ifndef LE_BUILD
+ #include <log/log.h>
+ #undef LOG_TAG
+ #define LOG_TAG "CLD80211"
+#else
+ #include <stdlib.h>
+ #include <syslog.h>
+ #include <unistd.h>
+ #define ALOGI(fmt, args...) syslog(LOG_INFO, fmt, ## args)
+ #define ALOGE(fmt, args...) syslog(LOG_ERR, fmt, ## args)
+ extern const char *__progname;
+ const char *getprogname() { return (__progname); }
+#endif
+
 #define SOCK_BUF_SIZE (256*1024)
 
 struct family_data {
@@ -225,7 +236,7 @@
 }
 
 
-static int get_multicast_id(struct cld80211_ctx *ctx, const char *group, bool sync_driver)
+static int get_multicast_id(struct cld80211_ctx *ctx, const char *group)
 {
 	struct family_data res = { group, -ENOENT };
 	struct nl_msg *nlmsg = nlmsg_alloc();
@@ -238,11 +249,9 @@
 	            CTRL_CMD_GETFAMILY, 0);
 	nla_put_string(nlmsg, CTRL_ATTR_FAMILY_NAME, "cld80211");
 
-	if (sync_driver == true) {
-		cld80211_send_recv_msg(ctx, nlmsg, family_handler, &res);
-		ALOGI("%s: nlctrl family id: %d group: %s mcast_id: %d", getprogname(),
-				ctx->nlctrl_familyid, group, res.id);
-	}
+	cld80211_send_recv_msg(ctx, nlmsg, family_handler, &res);
+	ALOGI("%s: nlctrl family id: %d group: %s mcast_id: %d", getprogname(),
+				   ctx->nlctrl_familyid, group, res.id);
 	nlmsg_free(nlmsg);
 	return res.id;
 }
@@ -254,7 +263,7 @@
 		ALOGE("%s: ctx/mcgroup is NULL: %s", getprogname(), __func__);
 		return 0;
 	}
-	int id = get_multicast_id(ctx, mcgroup, true);
+	int id = get_multicast_id(ctx, mcgroup);
 	if (id < 0) {
 		ALOGE("%s: Could not find group %s, errno: %d id: %d",
 		      getprogname(), mcgroup, errno, id);
@@ -273,11 +282,13 @@
 
 int cld80211_remove_mcast_group(struct cld80211_ctx *ctx, const char* mcgroup)
 {
+	// Drop membership is not a necessary cleanup action so comment it out.
+#if 0
 	if (!ctx || !mcgroup) {
 		ALOGE("%s: ctx/mcgroup is NULL: %s", getprogname(), __func__);
 		return 0;
 	}
-	int id = get_multicast_id(ctx, mcgroup, false);
+	int id = get_multicast_id(ctx, mcgroup);
 	if (id < 0) {
 		ALOGE("%s: Could not find group %s, errno: %d id: %d",
 		      getprogname(), mcgroup, errno, id);
@@ -290,7 +301,7 @@
 		      " ret: %d", getprogname(), mcgroup, errno, ret);
 		return ret;
 	}
-
+#endif
 	return 0;
 }
 
@@ -315,7 +326,7 @@
 			0, 0, cmd, /* version = */ 0);
 
 	*nla_data = nla_nest_start(nlmsg, CLD80211_ATTR_VENDOR_DATA);
-	if (!nla_data)
+	if (!*nla_data)
 		goto cleanup;
 
 	return nlmsg;
@@ -446,7 +457,7 @@
 }
 
 
-struct cld80211_ctx * cld80211_init()
+struct cld80211_ctx * cld80211_init(void)
 {
 	struct cld80211_ctx *ctx;
 
diff --git a/cld80211-lib/cld80211_lib.h b/wcn6740/cld80211-lib/cld80211_lib.h
similarity index 93%
copy from cld80211-lib/cld80211_lib.h
copy to wcn6740/cld80211-lib/cld80211_lib.h
index 3dd53bb..2503f2a 100644
--- a/cld80211-lib/cld80211_lib.h
+++ b/wcn6740/cld80211-lib/cld80211_lib.h
@@ -58,6 +58,10 @@
  * CLD80211_ATTR_META_DATA: Embed meta data for above data. This will  help
  * wlan driver to peek into request message packet without opening up definition
  * of complete request message.
+ * @CLD80211_ATTR_CMD: cld80211 vendor subcommand in this attribute
+ * @CLD80211_ATTR_CMD_TAG_DATA: cld80211 vendor subcommand data is present in
+ * this attribute. It is a nested attribute with sub attributes of specified
+ * vendor sub command.
  *
  * Any new message in future can be added as another attribute
  */
@@ -65,6 +69,8 @@
 	CLD80211_ATTR_VENDOR_DATA = 1,
 	CLD80211_ATTR_DATA,
 	CLD80211_ATTR_META_DATA,
+	CLD80211_ATTR_CMD,
+	CLD80211_ATTR_CMD_TAG_DATA,
 
 	__CLD80211_ATTR_AFTER_LAST,
 	CLD80211_ATTR_MAX = __CLD80211_ATTR_AFTER_LAST - 1
@@ -75,7 +81,7 @@
  * Retuns valid sock only if socket creation is succesful and cld80211
  * family is present, returns NULL otherwise
  */
-struct cld80211_ctx *cld80211_init();
+struct cld80211_ctx *cld80211_init(void);
 
 /**
  * free the socket created in cld80211_init()
diff --git a/wcn6740/cld80211-lib/configure.ac b/wcn6740/cld80211-lib/configure.ac
new file mode 100644
index 0000000..7996d3f
--- /dev/null
+++ b/wcn6740/cld80211-lib/configure.ac
@@ -0,0 +1,77 @@
+# -*- Autoconf -*-
+# configure.ac -- Autoconf script for qcacld-tools
+#
+
+AC_PREREQ(2.61)
+AC_INIT([cld80211-lib], 1.0.0)
+AM_INIT_AUTOMAKE([foreign])
+AM_MAINTAINER_MODE
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+LT_INIT
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_LIBTOOL
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+
+AC_ARG_ENABLE([debug],
+        [  --enable-debug    Turn on debugging],
+        [case "${enableval}" in
+            yes) debug=true ;;
+            no)  debug=false ;;
+            *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
+        esac],[debug=false])
+AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])
+
+has_libnl_ver=0
+# libnl-2 provides only libnl-2.0.pc file, so we check for separate libnl-genl-3.0.pc
+# pkg-config file just for libnl-3.0 case.
+#
+PKG_CHECK_MODULES([LIBNL], [libnl-3.0 >= 3.0 libnl-genl-3.0 >= 3.0], [has_libnl_ver=3], [
+   PKG_CHECK_MODULES([LIBNL], [libnl-2.0 >= 2.0], [has_libnl_ver=2], [
+           PKG_CHECK_MODULES([LIBNL], [libnl-1], [has_libnl_ver=1], [has_libnl_ver=0])])])
+
+if (test "$has_libnl_ver" -eq 0); then
+        AC_MSG_ERROR(libnl and libnl-genl are required but were not found)
+fi
+
+if (test "$has_libnl_ver" -gt 1); then
+        AC_DEFINE([HAVE_LIBNL20], [1], [Define if you have libnl-2.0 or higher])
+fi
+
+if (test "$has_libnl_ver" -gt 2); then
+        AC_DEFINE([HAVE_LIBNL30], [1], [Define if you have libnl-3.0 or higher])
+fi
+
+AC_SUBST([LIBNL_CFLAGS])
+AC_SUBST([LIBNL_LIBS])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_HEADER_STDC
+AC_C_INLINE
+AC_TYPE_INT64_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT8_T
+
+# Checks for library functions.
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FORK
+AC_FUNC_MALLOC
+
+AC_CONFIG_FILES([ \
+    Makefile \
+    cld80211-lib.pc
+])
+AC_OUTPUT
diff --git a/qcwcn/Android.mk b/wcn6740/qcwcn/Android.mk
similarity index 100%
copy from qcwcn/Android.mk
copy to wcn6740/qcwcn/Android.mk
diff --git a/qcwcn/config/Android.mk b/wcn6740/qcwcn/config/Android.mk
similarity index 100%
copy from qcwcn/config/Android.mk
copy to wcn6740/qcwcn/config/Android.mk
diff --git a/wcn6740/qcwcn/wifi_hal/Android.mk b/wcn6740/qcwcn/wifi_hal/Android.mk
new file mode 100644
index 0000000..7cb6611
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/Android.mk
@@ -0,0 +1,203 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Control APIs used by clients to communicate with HAL.
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -Wno-unused-parameter
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_MODULE := libwifi-hal-ctrl
+LOCAL_VENDOR_MODULE := true
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/wifi_hal_ctrl
+LOCAL_SRC_FILES := wifi_hal_ctrl/wifi_hal_ctrl.c
+LOCAL_HEADER_LIBRARIES := libcutils_headers
+LOCAL_LICENSE_KINDS := legacy_not_a_contribution SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-hal-ctrl_headers
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/wifi_hal_ctrl
+LOCAL_HEADER_LIBRARIES := libcutils_headers
+LOCAL_LICENSE_KINDS := legacy_not_a_contribution SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
+include $(BUILD_HEADER_LIBRARY)
+
+# Make the HAL library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -Wno-unused-parameter
+ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+LOCAL_CFLAGS += "-DLOG_NDEBUG=0"
+endif
+
+ifneq ($(TARGET_USES_AOSP_FOR_WLAN), true)
+LOCAL_CFLAGS += -DWCNSS_QTI_AOSP
+endif
+
+# gscan.cpp: address of array 'cached_results[i].results' will always evaluate to 'true'
+LOCAL_CLANG_CFLAGS := -Wno-pointer-bool-conversion
+
+LOCAL_CFLAGS += -Wall -Werror
+
+ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_CTRL_PARAM=\"$(WIFI_DRIVER_STATE_CTRL_PARAM)\"
+ifdef WIFI_DRIVER_STATE_ON
+LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_ON=\"$(WIFI_DRIVER_STATE_ON)\"
+endif
+endif
+
+LOCAL_C_INCLUDES += \
+	$(LOCAL_PATH) \
+	external/libnl/include \
+	$(call include-path-for, libhardware_legacy)/hardware_legacy \
+	external/wpa_supplicant_8/src/drivers \
+	$(TARGET_OUT_HEADERS)/cld80211-lib
+
+LOCAL_C_INCLUDES += \
+	external/boringssl/include \
+	external/boringssl/src/crypto/digest \
+	external/boringssl/src/crypto/evp/
+
+LOCAL_SRC_FILES := \
+	list.cpp \
+	wifi_hal.cpp \
+	common.cpp \
+	cpp_bindings.cpp \
+	llstats.cpp \
+	gscan.cpp \
+	gscan_event_handler.cpp \
+	rtt.cpp \
+	ifaceeventhandler.cpp \
+	tdls.cpp \
+	nan.cpp \
+	nan_ind.cpp \
+	nan_req.cpp \
+	nan_rsp.cpp \
+	wificonfig.cpp \
+	wifilogger.cpp \
+	wifilogger_diag.cpp \
+	ring_buffer.cpp \
+	rb_wrapper.cpp \
+	rssi_monitor.cpp \
+	roam.cpp \
+	radio_mode.cpp \
+	tcp_params_update.cpp \
+	wifihal_vendor.cpp
+
+LOCAL_MODULE := libwifi-hal-qcom
+LOCAL_VENDOR_MODULE := true
+LOCAL_CLANG := true
+LOCAL_SHARED_LIBRARIES += libnetutils liblog libcld80211
+LOCAL_SHARED_LIBRARIES += libcrypto
+
+ifneq ($(wildcard external/libnl),)
+LOCAL_SHARED_LIBRARIES += libnl
+LOCAL_C_INCLUDES += external/libnl/include
+else
+LOCAL_SHARED_LIBRARIES += libnl_2
+LOCAL_C_INCLUDES += external/libnl-headers
+endif
+
+LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers libcld80211_headers
+LOCAL_SANITIZE := cfi
+
+LOCAL_LICENSE_KINDS := legacy_not_a_contribution SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_REQUIRED_MODULES :=
+
+LOCAL_CFLAGS += -Wno-unused-parameter -Wall -Werror
+LOCAL_CPPFLAGS += -Wno-conversion-null
+ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+LOCAL_CFLAGS += "-DLOG_NDEBUG=0"
+endif
+
+# gscan.cpp: address of array 'cached_results[i].results' will always evaluate to 'true'
+LOCAL_CLANG_CFLAGS := -Wno-pointer-bool-conversion
+
+ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_CTRL_PARAM=\"$(WIFI_DRIVER_STATE_CTRL_PARAM)\"
+ifdef WIFI_DRIVER_STATE_ON
+LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_ON=\"$(WIFI_DRIVER_STATE_ON)\"
+endif
+endif
+
+LOCAL_C_INCLUDES += \
+	$(LOCAL_PATH) \
+	external/libnl/include \
+	$(call include-path-for, libhardware_legacy)/hardware_legacy \
+	external/wpa_supplicant_8/src/drivers \
+	$(TARGET_OUT_HEADERS)/cld80211-lib
+
+LOCAL_C_INCLUDES += \
+	external/boringssl/include \
+	external/boringssl/src/crypto/digest \
+	external/boringssl/src/crypto/evp/
+
+LOCAL_SRC_FILES := \
+	list.cpp \
+	wifi_hal.cpp \
+	common.cpp \
+	cpp_bindings.cpp \
+	llstats.cpp \
+	gscan.cpp \
+	gscan_event_handler.cpp \
+	rtt.cpp \
+	ifaceeventhandler.cpp \
+	tdls.cpp \
+	nan.cpp \
+	nan_ind.cpp \
+	nan_req.cpp \
+	nan_rsp.cpp \
+	wificonfig.cpp \
+	wifilogger.cpp \
+	wifilogger_diag.cpp \
+	ring_buffer.cpp \
+	rb_wrapper.cpp \
+	rssi_monitor.cpp \
+	roam.cpp \
+	radio_mode.cpp \
+	tcp_params_update.cpp \
+	wifihal_vendor.cpp
+
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_MODULE := libwifi-hal-qcom
+LOCAL_VENDOR_MODULE := true
+LOCAL_CLANG := true
+LOCAL_SHARED_LIBRARIES += libnetutils liblog
+LOCAL_SHARED_LIBRARIES += libdl libcld80211
+LOCAL_SHARED_LIBRARIES += libwifi-hal-ctrl
+LOCAL_SHARED_LIBRARIES += libcrypto
+
+ifneq ($(wildcard external/libnl),)
+LOCAL_SHARED_LIBRARIES += libnl
+LOCAL_C_INCLUDES += external/libnl/include
+else
+LOCAL_SHARED_LIBRARIES += libnl_2
+LOCAL_C_INCLUDES += external/libnl-headers
+endif
+
+LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers libcld80211_headers
+LOCAL_SANITIZE := cfi integer_overflow
+LOCAL_LICENSE_KINDS := legacy_not_a_contribution SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
+include $(BUILD_SHARED_LIBRARY)
diff --git a/wcn6740/qcwcn/wifi_hal/common.cpp b/wcn6740/qcwcn/wifi_hal/common.cpp
new file mode 100644
index 0000000..263043b
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/common.cpp
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <linux/pkt_sched.h>
+#include <linux-private/linux/fib_rules.h>
+#include <netlink/object-api.h>
+#include <netlink-private/object-api.h>
+#include <netlink-private/types.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include "wifi_hal.h"
+#include "common.h"
+#include <errno.h>
+
+interface_info *getIfaceInfo(wifi_interface_handle handle)
+{
+    return (interface_info *)handle;
+}
+
+wifi_handle getWifiHandle(wifi_interface_handle handle)
+{
+    return getIfaceInfo(handle)->handle;
+}
+
+hal_info *getHalInfo(wifi_handle handle)
+{
+    return (hal_info *)handle;
+}
+
+hal_info *getHalInfo(wifi_interface_handle handle)
+{
+    return getHalInfo(getWifiHandle(handle));
+}
+
+wifi_handle getWifiHandle(hal_info *info)
+{
+    return (wifi_handle)info;
+}
+
+wifi_interface_handle getIfaceHandle(interface_info *info)
+{
+    return (wifi_interface_handle)info;
+}
+
+wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
+{
+    hal_info *info = (hal_info *)handle;
+
+    pthread_mutex_lock(&info->cb_lock);
+
+    wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+        if(info->event_cb[i].nl_cmd == cmd &&
+           info->event_cb[i].cb_arg == arg) {
+            info->event_cb[i].cb_func = func;
+            ALOGV("Updated event handler %p for nl_cmd 0x%0x"
+                    " and arg %p", func, cmd, arg);
+            pthread_mutex_unlock(&info->cb_lock);
+            return WIFI_SUCCESS;
+        }
+    }
+
+    if (info->num_event_cb < info->alloc_event_cb) {
+        info->event_cb[info->num_event_cb].nl_cmd  = cmd;
+        info->event_cb[info->num_event_cb].vendor_id  = 0;
+        info->event_cb[info->num_event_cb].vendor_subcmd  = 0;
+        info->event_cb[info->num_event_cb].cb_func = func;
+        info->event_cb[info->num_event_cb].cb_arg  = arg;
+        info->num_event_cb++;
+        ALOGV("Successfully added event handler %p for command %d", func, cmd);
+        result = WIFI_SUCCESS;
+    } else {
+        result = WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+    return result;
+}
+
+wifi_error wifi_register_vendor_handler(wifi_handle handle,
+        uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
+{
+    hal_info *info = (hal_info *)handle;
+
+    pthread_mutex_lock(&info->cb_lock);
+
+    wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+        if(info->event_cb[i].vendor_id  == id &&
+           info->event_cb[i].vendor_subcmd == subcmd)
+        {
+            info->event_cb[i].cb_func = func;
+            info->event_cb[i].cb_arg  = arg;
+            ALOGV("Updated event handler %p for vendor 0x%0x, subcmd 0x%0x"
+                " and arg %p", func, id, subcmd, arg);
+            pthread_mutex_unlock(&info->cb_lock);
+            return WIFI_SUCCESS;
+        }
+    }
+
+    if (info->num_event_cb < info->alloc_event_cb) {
+        info->event_cb[info->num_event_cb].nl_cmd  = NL80211_CMD_VENDOR;
+        info->event_cb[info->num_event_cb].vendor_id  = id;
+        info->event_cb[info->num_event_cb].vendor_subcmd  = subcmd;
+        info->event_cb[info->num_event_cb].cb_func = func;
+        info->event_cb[info->num_event_cb].cb_arg  = arg;
+        info->num_event_cb++;
+        ALOGV("Added event handler %p for vendor 0x%0x, subcmd 0x%0x and arg"
+            " %p", func, id, subcmd, arg);
+        result = WIFI_SUCCESS;
+    } else {
+        result = WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+    return result;
+}
+
+void wifi_unregister_handler(wifi_handle handle, int cmd)
+{
+    hal_info *info = (hal_info *)handle;
+
+    if (cmd == NL80211_CMD_VENDOR) {
+        ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
+        return;
+    }
+
+    pthread_mutex_lock(&info->cb_lock);
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+        if (info->event_cb[i].nl_cmd == cmd) {
+            if(i < info->num_event_cb-1) {
+                /* No need to memmove if only one entry exist and deleting
+                 * the same, as the num_event_cb will become 0 in this case.
+                 */
+                memmove(&info->event_cb[i], &info->event_cb[i+1],
+                        (info->num_event_cb - i) * sizeof(cb_info));
+            }
+            info->num_event_cb--;
+            ALOGV("Successfully removed event handler for command %d", cmd);
+            break;
+        }
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+}
+
+void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
+{
+    hal_info *info = (hal_info *)handle;
+
+    pthread_mutex_lock(&info->cb_lock);
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+
+        if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
+                && info->event_cb[i].vendor_id == id
+                && info->event_cb[i].vendor_subcmd == subcmd) {
+            if(i < info->num_event_cb-1) {
+                /* No need to memmove if only one entry exist and deleting
+                 * the same, as the num_event_cb will become 0 in this case.
+                 */
+                memmove(&info->event_cb[i], &info->event_cb[i+1],
+                        (info->num_event_cb - i) * sizeof(cb_info));
+            }
+            info->num_event_cb--;
+            ALOGV("Successfully removed event handler for vendor 0x%0x", id);
+            break;
+        }
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+}
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+void hexdump(void *buf, u16 len)
+{
+    int i=0;
+    char *bytes = (char *)buf;
+
+    if (len) {
+        ALOGV("******HexDump len:%d*********", len);
+        for (i = 0; ((i + 7) < len); i+=8) {
+            ALOGV("%02x %02x %02x %02x   %02x %02x %02x %02x",
+                bytes[i], bytes[i+1],
+                bytes[i+2], bytes[i+3],
+                bytes[i+4], bytes[i+5],
+                bytes[i+6], bytes[i+7]);
+        }
+        if ((len - i) >= 4) {
+            ALOGV("%02x %02x %02x %02x",
+                bytes[i], bytes[i+1],
+                bytes[i+2], bytes[i+3]);
+            i+=4;
+        }
+        for (;i < len;i++) {
+            ALOGV("%02x", bytes[i]);
+        }
+        ALOGV("******HexDump End***********");
+    } else {
+        return;
+    }
+}
+
+/* Firmware sends RSSI value without noise floor.
+ * Add noise floor to the same and return absolute values.
+ */
+u8 get_rssi(u8 rssi_wo_noise_floor)
+{
+    return abs((int)rssi_wo_noise_floor - 96);
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* Pointer to the table of LOWI callback funcs */
+lowi_cb_table_t *LowiWifiHalApi = NULL;
+/* LowiSupportedCapabilities read */
+u32 lowiSupportedCapabilities = 0;
+
+int compareLowiVersion(u16 major, u16 minor, u16 micro)
+{
+    u32 currVersion = 0x10000*(WIFIHAL_LOWI_MAJOR_VERSION) + \
+                      0x100*(WIFIHAL_LOWI_MINOR_VERSION) + \
+                      WIFIHAL_LOWI_MICRO_VERSION;
+
+    u32 lowiVersion = 0x10000*(major) + \
+                      0x100*(minor) + \
+                      micro;
+
+    return (memcmp(&currVersion, &lowiVersion, sizeof(u32)));
+}
+
+/*
+ * This function will open the lowi shared library and obtain the
+ * Lowi Callback table and the capabilities supported.
+ * A version check is also performed in this function and if the version
+ * check fails then the callback table returned will be NULL.
+ */
+wifi_error fetchLowiCbTableAndCapabilities(lowi_cb_table_t **lowi_wifihal_api,
+                                           bool *lowi_get_capa_supported)
+{
+    getCbTable_t* lowiCbTable = NULL;
+    int ret = 0;
+    wifi_error retVal = WIFI_SUCCESS;
+
+    *lowi_wifihal_api = NULL;
+    *lowi_get_capa_supported = false;
+
+#if __WORDSIZE == 64
+    void* lowi_handle = dlopen("/vendor/lib64/liblowi_wifihal.so", RTLD_NOW);
+#else
+    void* lowi_handle = dlopen("/vendor/lib/liblowi_wifihal.so", RTLD_NOW);
+#endif
+    if (!lowi_handle) {
+        ALOGE("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror());
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    lowiCbTable = (getCbTable_t*)dlsym(lowi_handle,
+                                       "lowi_wifihal_get_cb_table");
+    if (!lowiCbTable) {
+        ALOGE("%s: NULL lowi callback table", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    *lowi_wifihal_api = lowiCbTable();
+
+    /* First check whether lowi module implements the get_lowi_version
+     * function. All the functions in lowi module starts with
+     * "lowi_wifihal_" prefix thus the below function name.
+     */
+    if ((dlsym(lowi_handle, "lowi_wifihal_get_lowi_version") != NULL) &&
+        ((*lowi_wifihal_api)->get_lowi_version != NULL)) {
+        u16 lowiMajorVersion = WIFIHAL_LOWI_MAJOR_VERSION;
+        u16 lowiMinorVersion = WIFIHAL_LOWI_MINOR_VERSION;
+        u16 lowiMicroVersion = WIFIHAL_LOWI_MICRO_VERSION;
+        int versionCheck = -1;
+
+        ret = (*lowi_wifihal_api)->get_lowi_version(&lowiMajorVersion,
+                                                    &lowiMinorVersion,
+                                                    &lowiMicroVersion);
+        if (ret) {
+            ALOGE("%s: get_lowi_version returned error:%d",
+                  __FUNCTION__, ret);
+            retVal = WIFI_ERROR_NOT_SUPPORTED;
+            goto cleanup;
+        }
+        ALOGV("%s: Lowi version:%d.%d.%d", __FUNCTION__,
+              lowiMajorVersion, lowiMinorVersion,
+              lowiMicroVersion);
+
+        /* Compare the version with version in wifihal_internal.h */
+        versionCheck = compareLowiVersion(lowiMajorVersion,
+                                          lowiMinorVersion,
+                                          lowiMicroVersion);
+        if (versionCheck < 0) {
+            ALOGE("%s: Version Check failed:%d", __FUNCTION__,
+                  versionCheck);
+            retVal = WIFI_ERROR_NOT_SUPPORTED;
+            goto cleanup;
+        }
+    }
+    else {
+        ALOGV("%s: lowi_wifihal_get_lowi_version not present",
+              __FUNCTION__);
+    }
+
+
+    /* Check if get_lowi_capabilities func pointer exists in
+     * the lowi lib and populate lowi_get_capa_supported
+     * All the functions in lowi modules starts with
+     * "lowi_wifihal_ prefix" thus the below function name.
+     */
+    if (dlsym(lowi_handle, "lowi_wifihal_get_lowi_capabilities") != NULL) {
+        *lowi_get_capa_supported = true;
+    }
+    else {
+        ALOGV("lowi_wifihal_get_lowi_capabilities() is not supported.");
+        *lowi_get_capa_supported = false;
+    }
+cleanup:
+    if (retVal) {
+        *lowi_wifihal_api = NULL;
+    }
+    return retVal;
+}
+
+lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities)
+{
+    int ret = WIFI_SUCCESS;
+    bool lowi_get_capabilities_support = false;
+
+    if (LowiWifiHalApi == NULL) {
+        ALOGV("%s: LowiWifiHalApi Null, Initialize Lowi",
+              __FUNCTION__);
+        ret = fetchLowiCbTableAndCapabilities(&LowiWifiHalApi,
+                                              &lowi_get_capabilities_support);
+        if (ret != WIFI_SUCCESS || LowiWifiHalApi == NULL ||
+            LowiWifiHalApi->init == NULL) {
+            ALOGE("%s: LOWI is not supported.", __FUNCTION__);
+            goto cleanup;
+        }
+        /* Initialize LOWI if it isn't up already. */
+        ret = LowiWifiHalApi->init();
+        if (ret) {
+            ALOGE("%s: failed lowi initialization. "
+                "Returned error:%d. Exit.", __FUNCTION__, ret);
+            goto cleanup;
+        }
+        if (!lowi_get_capabilities_support ||
+            LowiWifiHalApi->get_lowi_capabilities == NULL) {
+                ALOGV("%s: Allow rtt APIs thru LOWI to proceed even though "
+                      "get_lowi_capabilities() is not supported. Returning",
+                      __FUNCTION__);
+                lowiSupportedCapabilities |=
+                    (ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+                return LowiWifiHalApi;
+        }
+        ret =
+            LowiWifiHalApi->get_lowi_capabilities(&lowiSupportedCapabilities);
+        if (ret) {
+            ALOGV("%s: failed to get lowi supported capabilities."
+                "Returned error:%d. Exit.", __FUNCTION__, ret);
+            goto cleanup;
+        }
+    } else if (lowiSupportedCapabilities == 0 &&
+               LowiWifiHalApi->get_lowi_capabilities) {
+            LowiWifiHalApi->get_lowi_capabilities(&lowiSupportedCapabilities);
+    }
+
+    if ((lowiSupportedCapabilities & requested_lowi_capabilities) == 0) {
+        return NULL;
+    }
+    return LowiWifiHalApi;
+
+cleanup:
+    if (LowiWifiHalApi && LowiWifiHalApi->destroy) {
+        ret = LowiWifiHalApi->destroy();
+    }
+    LowiWifiHalApi = NULL;
+    lowiSupportedCapabilities = 0;
+    return LowiWifiHalApi;
+}
+
+wifi_error mapKernelErrortoWifiHalError(int kern_err)
+{
+    if (kern_err >= 0)
+        return WIFI_SUCCESS;
+
+    switch (kern_err) {
+        case -EOPNOTSUPP:
+            return WIFI_ERROR_NOT_SUPPORTED;
+        case -EAGAIN:
+            return WIFI_ERROR_NOT_AVAILABLE;
+        case -EINVAL:
+            return WIFI_ERROR_INVALID_ARGS;
+        case -ETIMEDOUT:
+            return WIFI_ERROR_TIMED_OUT;
+        case -ENOMEM:
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        case -EBUSY:
+            return WIFI_ERROR_BUSY;
+        case -ENOBUFS:
+            return WIFI_ERROR_TOO_MANY_REQUESTS;
+    }
+    return WIFI_ERROR_UNKNOWN;
+}
diff --git a/qcwcn/wifi_hal/common.h b/wcn6740/qcwcn/wifi_hal/common.h
similarity index 75%
copy from qcwcn/wifi_hal/common.h
copy to wcn6740/qcwcn/wifi_hal/common.h
index b0aca97..8816f5f 100644
--- a/qcwcn/wifi_hal/common.h
+++ b/wcn6740/qcwcn/wifi_hal/common.h
@@ -12,6 +12,40 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "wifi_hal.h"
@@ -53,6 +87,7 @@
 #define RECV_BUF_SIZE           (4096)
 #define DEFAULT_EVENT_CB_SIZE   (64)
 #define NUM_RING_BUFS           5
+#define MAX_NUM_RADAR_HISTORY   64
 
 #define WIFI_HAL_CTRL_IFACE     "/dev/socket/wifihal/wifihal_ctrlsock"
 
@@ -161,6 +196,7 @@
     u32 prev_seq_no;
     // pointer to structure having various gscan_event_handlers
     struct gscan_event_handlers_s *gscan_handlers;
+    struct tcp_param_cmd_handler_s *tcp_param_handler;
     /* mutex for the log_handler access*/
     pthread_mutex_t lh_lock;
     /* mutex for the alert_handler access*/
@@ -171,12 +207,26 @@
     /* mutex for the packet fate stats shared resource protection */
     pthread_mutex_t pkt_fate_stats_lock;
     struct rssi_monitor_event_handler_s *rssi_handlers;
+    struct radio_event_handler_s *radio_handlers;
     wifi_capa capa;
     struct cld80211_ctx *cldctx;
     bool apf_enabled;
+    bool support_nan_ext_cmd;
     pkt_log_version  pkt_log_ver;
+    qca_wlan_vendor_sar_version sar_version;
 } hal_info;
 
+typedef struct {
+    bool radar_detected;
+    u32 freq;
+    u64 clock_boottime;
+} radar_history_result;
+
+static inline void wifi_put_le16(u8 *a, u16 val) {
+    a[1] = val >> 8;
+    a[0] = val & 0xff;
+}
+
 wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg);
 wifi_error wifi_register_vendor_handler(wifi_handle handle,
             uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg);
@@ -194,12 +244,14 @@
 wifi_error cleanupGscanHandlers(hal_info *info);
 wifi_error initializeRSSIMonitorHandler(hal_info *info);
 wifi_error cleanupRSSIMonitorHandler(hal_info *info);
+wifi_error initializeRadioHandler(hal_info *info);
+wifi_error cleanupRadioHandler(hal_info *info);
 
 lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities);
 
 wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id,
-        wifi_interface_handle iface, u16 ether_type, u8 *ip_packet,
-        u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec);
+        wifi_interface_handle iface, u8 *ip_packet, u16 ip_packet_len,
+        u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec);
 wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id,
         wifi_interface_handle iface);
 wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
@@ -212,6 +264,9 @@
 wifi_error wifi_virtual_interface_create(wifi_handle handle, const char* ifname,
                                          wifi_interface_type iface_type);
 wifi_error wifi_virtual_interface_delete(wifi_handle handle, const char* ifname);
+wifi_error wifi_get_radar_history(wifi_interface_handle handle,
+        radar_history_result *resultBuf, int resultBufSize, int *numResults);
+wifi_error wifi_disable_next_cac(wifi_interface_handle handle);
 // some common macros
 
 #define min(x, y)       ((x) < (y) ? (x) : (y))
diff --git a/wcn6740/qcwcn/wifi_hal/cpp_bindings.cpp b/wcn6740/qcwcn/wifi_hal/cpp_bindings.cpp
new file mode 100644
index 0000000..4ac01b7
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/cpp_bindings.cpp
@@ -0,0 +1,1029 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution
+ */
+
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <net/if.h>
+
+#include "nl80211_copy.h"
+#include <ctype.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "vendor_definitions.h"
+
+void appendFmt(char *buf, size_t buf_len, int &offset, const char *fmt, ...)
+{
+    va_list params;
+    va_start(params, fmt);
+    offset += vsnprintf(buf + offset, buf_len - offset, fmt, params);
+    va_end(params);
+}
+
+#define C2S(x)  case x: return #x;
+
+static const char *cmdToString(int cmd)
+{
+    switch (cmd) {
+    C2S(NL80211_CMD_UNSPEC)
+    C2S(NL80211_CMD_GET_WIPHY)
+    C2S(NL80211_CMD_SET_WIPHY)
+    C2S(NL80211_CMD_NEW_WIPHY)
+    C2S(NL80211_CMD_DEL_WIPHY)
+    C2S(NL80211_CMD_GET_INTERFACE)
+    C2S(NL80211_CMD_SET_INTERFACE)
+    C2S(NL80211_CMD_NEW_INTERFACE)
+    C2S(NL80211_CMD_DEL_INTERFACE)
+    C2S(NL80211_CMD_GET_KEY)
+    C2S(NL80211_CMD_SET_KEY)
+    C2S(NL80211_CMD_NEW_KEY)
+    C2S(NL80211_CMD_DEL_KEY)
+    C2S(NL80211_CMD_GET_BEACON)
+    C2S(NL80211_CMD_SET_BEACON)
+    C2S(NL80211_CMD_START_AP)
+    C2S(NL80211_CMD_STOP_AP)
+    C2S(NL80211_CMD_GET_STATION)
+    C2S(NL80211_CMD_SET_STATION)
+    C2S(NL80211_CMD_NEW_STATION)
+    C2S(NL80211_CMD_DEL_STATION)
+    C2S(NL80211_CMD_GET_MPATH)
+    C2S(NL80211_CMD_SET_MPATH)
+    C2S(NL80211_CMD_NEW_MPATH)
+    C2S(NL80211_CMD_DEL_MPATH)
+    C2S(NL80211_CMD_SET_BSS)
+    C2S(NL80211_CMD_SET_REG)
+    C2S(NL80211_CMD_REQ_SET_REG)
+    C2S(NL80211_CMD_GET_MESH_CONFIG)
+    C2S(NL80211_CMD_SET_MESH_CONFIG)
+    C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
+    C2S(NL80211_CMD_GET_REG)
+    C2S(NL80211_CMD_GET_SCAN)
+    C2S(NL80211_CMD_TRIGGER_SCAN)
+    C2S(NL80211_CMD_NEW_SCAN_RESULTS)
+    C2S(NL80211_CMD_SCAN_ABORTED)
+    C2S(NL80211_CMD_REG_CHANGE)
+    C2S(NL80211_CMD_AUTHENTICATE)
+    C2S(NL80211_CMD_ASSOCIATE)
+    C2S(NL80211_CMD_DEAUTHENTICATE)
+    C2S(NL80211_CMD_DISASSOCIATE)
+    C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
+    C2S(NL80211_CMD_REG_BEACON_HINT)
+    C2S(NL80211_CMD_JOIN_IBSS)
+    C2S(NL80211_CMD_LEAVE_IBSS)
+    C2S(NL80211_CMD_TESTMODE)
+    C2S(NL80211_CMD_CONNECT)
+    C2S(NL80211_CMD_ROAM)
+    C2S(NL80211_CMD_DISCONNECT)
+    C2S(NL80211_CMD_SET_WIPHY_NETNS)
+    C2S(NL80211_CMD_GET_SURVEY)
+    C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
+    C2S(NL80211_CMD_SET_PMKSA)
+    C2S(NL80211_CMD_DEL_PMKSA)
+    C2S(NL80211_CMD_FLUSH_PMKSA)
+    C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
+    C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
+    C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
+    C2S(NL80211_CMD_REGISTER_FRAME)
+    C2S(NL80211_CMD_FRAME)
+    C2S(NL80211_CMD_FRAME_TX_STATUS)
+    C2S(NL80211_CMD_SET_POWER_SAVE)
+    C2S(NL80211_CMD_GET_POWER_SAVE)
+    C2S(NL80211_CMD_SET_CQM)
+    C2S(NL80211_CMD_NOTIFY_CQM)
+    C2S(NL80211_CMD_SET_CHANNEL)
+    C2S(NL80211_CMD_SET_WDS_PEER)
+    C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
+    C2S(NL80211_CMD_JOIN_MESH)
+    C2S(NL80211_CMD_LEAVE_MESH)
+    C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
+    C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
+    C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
+    C2S(NL80211_CMD_GET_WOWLAN)
+    C2S(NL80211_CMD_SET_WOWLAN)
+    C2S(NL80211_CMD_START_SCHED_SCAN)
+    C2S(NL80211_CMD_STOP_SCHED_SCAN)
+    C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
+    C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
+    C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
+    C2S(NL80211_CMD_PMKSA_CANDIDATE)
+    C2S(NL80211_CMD_TDLS_OPER)
+    C2S(NL80211_CMD_TDLS_MGMT)
+    C2S(NL80211_CMD_UNEXPECTED_FRAME)
+    C2S(NL80211_CMD_PROBE_CLIENT)
+    C2S(NL80211_CMD_REGISTER_BEACONS)
+    C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
+    C2S(NL80211_CMD_SET_NOACK_MAP)
+    C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
+    C2S(NL80211_CMD_START_P2P_DEVICE)
+    C2S(NL80211_CMD_STOP_P2P_DEVICE)
+    C2S(NL80211_CMD_CONN_FAILED)
+    C2S(NL80211_CMD_SET_MCAST_RATE)
+    C2S(NL80211_CMD_SET_MAC_ACL)
+    C2S(NL80211_CMD_RADAR_DETECT)
+    C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
+    C2S(NL80211_CMD_UPDATE_FT_IES)
+    C2S(NL80211_CMD_FT_EVENT)
+    C2S(NL80211_CMD_CRIT_PROTOCOL_START)
+    C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
+    C2S(NL80211_CMD_GET_COALESCE)
+    C2S(NL80211_CMD_SET_COALESCE)
+    C2S(NL80211_CMD_CHANNEL_SWITCH)
+    C2S(NL80211_CMD_VENDOR)
+    C2S(NL80211_CMD_SET_QOS_MAP)
+    default:
+        return "NL80211_CMD_UNKNOWN";
+    }
+}
+
+const char *attributeToString(int attribute)
+{
+    switch (attribute) {
+    C2S(NL80211_ATTR_UNSPEC)
+
+    C2S(NL80211_ATTR_WIPHY)
+    C2S(NL80211_ATTR_WIPHY_NAME)
+
+    C2S(NL80211_ATTR_IFINDEX)
+    C2S(NL80211_ATTR_IFNAME)
+    C2S(NL80211_ATTR_IFTYPE)
+
+    C2S(NL80211_ATTR_MAC)
+
+    C2S(NL80211_ATTR_KEY_DATA)
+    C2S(NL80211_ATTR_KEY_IDX)
+    C2S(NL80211_ATTR_KEY_CIPHER)
+    C2S(NL80211_ATTR_KEY_SEQ)
+    C2S(NL80211_ATTR_KEY_DEFAULT)
+
+    C2S(NL80211_ATTR_BEACON_INTERVAL)
+    C2S(NL80211_ATTR_DTIM_PERIOD)
+    C2S(NL80211_ATTR_BEACON_HEAD)
+    C2S(NL80211_ATTR_BEACON_TAIL)
+
+    C2S(NL80211_ATTR_STA_AID)
+    C2S(NL80211_ATTR_STA_FLAGS)
+    C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
+    C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
+    C2S(NL80211_ATTR_STA_VLAN)
+    C2S(NL80211_ATTR_STA_INFO)
+
+    C2S(NL80211_ATTR_WIPHY_BANDS)
+
+    C2S(NL80211_ATTR_MNTR_FLAGS)
+
+    C2S(NL80211_ATTR_MESH_ID)
+    C2S(NL80211_ATTR_STA_PLINK_ACTION)
+    C2S(NL80211_ATTR_MPATH_NEXT_HOP)
+    C2S(NL80211_ATTR_MPATH_INFO)
+
+    C2S(NL80211_ATTR_BSS_CTS_PROT)
+    C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
+    C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
+
+    C2S(NL80211_ATTR_HT_CAPABILITY)
+
+    C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
+
+    C2S(NL80211_ATTR_REG_ALPHA2)
+    C2S(NL80211_ATTR_REG_RULES)
+
+    C2S(NL80211_ATTR_MESH_CONFIG)
+
+    C2S(NL80211_ATTR_BSS_BASIC_RATES)
+
+    C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
+    C2S(NL80211_ATTR_WIPHY_FREQ)
+    C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
+
+    C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
+
+    C2S(NL80211_ATTR_MGMT_SUBTYPE)
+    C2S(NL80211_ATTR_IE)
+
+    C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
+
+    C2S(NL80211_ATTR_SCAN_FREQUENCIES)
+    C2S(NL80211_ATTR_SCAN_SSIDS)
+    C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
+    C2S(NL80211_ATTR_BSS)
+
+    C2S(NL80211_ATTR_REG_INITIATOR)
+    C2S(NL80211_ATTR_REG_TYPE)
+
+    C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
+
+    C2S(NL80211_ATTR_FRAME)
+    C2S(NL80211_ATTR_SSID)
+    C2S(NL80211_ATTR_AUTH_TYPE)
+    C2S(NL80211_ATTR_REASON_CODE)
+
+    C2S(NL80211_ATTR_KEY_TYPE)
+
+    C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
+    C2S(NL80211_ATTR_CIPHER_SUITES)
+
+    C2S(NL80211_ATTR_FREQ_BEFORE)
+    C2S(NL80211_ATTR_FREQ_AFTER)
+
+    C2S(NL80211_ATTR_FREQ_FIXED)
+
+
+    C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
+    C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
+    C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
+    C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
+
+    C2S(NL80211_ATTR_TIMED_OUT)
+
+    C2S(NL80211_ATTR_USE_MFP)
+
+    C2S(NL80211_ATTR_STA_FLAGS2)
+
+    C2S(NL80211_ATTR_CONTROL_PORT)
+
+    C2S(NL80211_ATTR_TESTDATA)
+
+    C2S(NL80211_ATTR_PRIVACY)
+
+    C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
+    C2S(NL80211_ATTR_STATUS_CODE)
+
+    C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
+    C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
+    C2S(NL80211_ATTR_WPA_VERSIONS)
+    C2S(NL80211_ATTR_AKM_SUITES)
+
+    C2S(NL80211_ATTR_REQ_IE)
+    C2S(NL80211_ATTR_RESP_IE)
+
+    C2S(NL80211_ATTR_PREV_BSSID)
+
+    C2S(NL80211_ATTR_KEY)
+    C2S(NL80211_ATTR_KEYS)
+
+    C2S(NL80211_ATTR_PID)
+
+    C2S(NL80211_ATTR_4ADDR)
+
+    C2S(NL80211_ATTR_SURVEY_INFO)
+
+    C2S(NL80211_ATTR_PMKID)
+    C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
+
+    C2S(NL80211_ATTR_DURATION)
+
+    C2S(NL80211_ATTR_COOKIE)
+
+    C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
+
+    C2S(NL80211_ATTR_TX_RATES)
+
+    C2S(NL80211_ATTR_FRAME_MATCH)
+
+    C2S(NL80211_ATTR_ACK)
+
+    C2S(NL80211_ATTR_PS_STATE)
+
+    C2S(NL80211_ATTR_CQM)
+
+    C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
+
+    C2S(NL80211_ATTR_AP_ISOLATE)
+
+    C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
+    C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
+
+    C2S(NL80211_ATTR_TX_FRAME_TYPES)
+    C2S(NL80211_ATTR_RX_FRAME_TYPES)
+    C2S(NL80211_ATTR_FRAME_TYPE)
+
+    C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
+    C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
+
+    C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
+
+    C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
+    C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
+
+    C2S(NL80211_ATTR_MCAST_RATE)
+
+    C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
+
+    C2S(NL80211_ATTR_BSS_HT_OPMODE)
+
+    C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
+
+    C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
+
+    C2S(NL80211_ATTR_MESH_SETUP)
+
+    C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
+    C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
+
+    C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
+    C2S(NL80211_ATTR_STA_PLINK_STATE)
+
+    C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
+    C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
+
+    C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
+
+    C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
+    C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
+
+    C2S(NL80211_ATTR_REKEY_DATA)
+
+    C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
+    C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
+
+    C2S(NL80211_ATTR_SCAN_SUPP_RATES)
+
+    C2S(NL80211_ATTR_HIDDEN_SSID)
+
+    C2S(NL80211_ATTR_IE_PROBE_RESP)
+    C2S(NL80211_ATTR_IE_ASSOC_RESP)
+
+    C2S(NL80211_ATTR_STA_WME)
+    C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
+
+    C2S(NL80211_ATTR_ROAM_SUPPORT)
+
+    C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
+    C2S(NL80211_ATTR_MAX_MATCH_SETS)
+
+    C2S(NL80211_ATTR_PMKSA_CANDIDATE)
+
+    C2S(NL80211_ATTR_TX_NO_CCK_RATE)
+
+    C2S(NL80211_ATTR_TDLS_ACTION)
+    C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
+    C2S(NL80211_ATTR_TDLS_OPERATION)
+    C2S(NL80211_ATTR_TDLS_SUPPORT)
+    C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
+
+    C2S(NL80211_ATTR_DEVICE_AP_SME)
+
+    C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
+
+    C2S(NL80211_ATTR_FEATURE_FLAGS)
+
+    C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
+
+    C2S(NL80211_ATTR_PROBE_RESP)
+
+    C2S(NL80211_ATTR_DFS_REGION)
+
+    C2S(NL80211_ATTR_DISABLE_HT)
+    C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
+
+    C2S(NL80211_ATTR_NOACK_MAP)
+
+    C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
+
+    C2S(NL80211_ATTR_RX_SIGNAL_DBM)
+
+    C2S(NL80211_ATTR_BG_SCAN_PERIOD)
+
+    C2S(NL80211_ATTR_WDEV)
+
+    C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
+
+    C2S(NL80211_ATTR_CONN_FAILED_REASON)
+
+    C2S(NL80211_ATTR_SAE_DATA)
+
+    C2S(NL80211_ATTR_VHT_CAPABILITY)
+
+    C2S(NL80211_ATTR_SCAN_FLAGS)
+
+    C2S(NL80211_ATTR_CHANNEL_WIDTH)
+    C2S(NL80211_ATTR_CENTER_FREQ1)
+    C2S(NL80211_ATTR_CENTER_FREQ2)
+
+    C2S(NL80211_ATTR_P2P_CTWINDOW)
+    C2S(NL80211_ATTR_P2P_OPPPS)
+
+    C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
+
+    C2S(NL80211_ATTR_ACL_POLICY)
+
+    C2S(NL80211_ATTR_MAC_ADDRS)
+
+    C2S(NL80211_ATTR_MAC_ACL_MAX)
+
+    C2S(NL80211_ATTR_RADAR_EVENT)
+
+    C2S(NL80211_ATTR_EXT_CAPA)
+    C2S(NL80211_ATTR_EXT_CAPA_MASK)
+
+    C2S(NL80211_ATTR_STA_CAPABILITY)
+    C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
+
+    C2S(NL80211_ATTR_PROTOCOL_FEATURES)
+    C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
+
+    C2S(NL80211_ATTR_DISABLE_VHT)
+    C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
+
+    C2S(NL80211_ATTR_MDID)
+    C2S(NL80211_ATTR_IE_RIC)
+
+    C2S(NL80211_ATTR_CRIT_PROT_ID)
+    C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
+
+    C2S(NL80211_ATTR_PEER_AID)
+
+    C2S(NL80211_ATTR_COALESCE_RULE)
+
+    C2S(NL80211_ATTR_CH_SWITCH_COUNT)
+    C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX)
+    C2S(NL80211_ATTR_CSA_IES)
+    C2S(NL80211_ATTR_CSA_C_OFF_BEACON)
+    C2S(NL80211_ATTR_CSA_C_OFF_PRESP)
+
+    C2S(NL80211_ATTR_RXMGMT_FLAGS)
+
+    C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS)
+
+    C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES)
+
+    C2S(NL80211_ATTR_HANDLE_DFS)
+
+    C2S(NL80211_ATTR_SUPPORT_5_MHZ)
+    C2S(NL80211_ATTR_SUPPORT_10_MHZ)
+
+    C2S(NL80211_ATTR_OPMODE_NOTIF)
+
+    C2S(NL80211_ATTR_VENDOR_ID)
+    C2S(NL80211_ATTR_VENDOR_SUBCMD)
+    C2S(NL80211_ATTR_VENDOR_DATA)
+    C2S(NL80211_ATTR_VENDOR_EVENTS)
+
+    C2S(NL80211_ATTR_QOS_MAP)
+    default:
+        return "NL80211_ATTR_UNKNOWN";
+    }
+}
+
+void WifiEvent::log() {
+    parse();
+
+    byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
+    int len = genlmsg_attrlen(mHeader, 0);
+
+    for (int i = 0; i < len; i += 16) {
+        char line[81];
+        int linelen = min(16, len - i);
+        int offset = 0;
+        appendFmt(line, sizeof(line), offset, "%02x", data[i]);
+        for (int j = 1; j < linelen; j++) {
+            appendFmt(line, sizeof(line), offset, " %02x", data[i+j]);
+        }
+
+        for (int j = linelen; j < 16; j++) {
+            appendFmt(line, sizeof(line), offset, "   ");
+        }
+
+        line[23] = '-';
+
+        appendFmt(line, sizeof(line), offset, "  ");
+
+        for (int j = 0; j < linelen; j++) {
+            if (isprint(data[i+j])) {
+                appendFmt(line, sizeof(line), offset, "%c", data[i+j]);
+            } else {
+                appendFmt(line, sizeof(line), offset, "-");
+            }
+        }
+
+    }
+
+}
+
+const char *WifiEvent::get_cmdString() {
+    return cmdToString(get_cmd());
+}
+
+
+int WifiEvent::parse() {
+    if (mHeader != NULL) {
+        return WIFI_SUCCESS;
+    }
+    mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
+    int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
+          genlmsg_attrlen(mHeader, 0), NULL);
+
+    return result;
+}
+
+wifi_error WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
+
+    destroy();
+
+    mMsg = nlmsg_alloc();
+    if (mMsg != NULL) {
+        genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
+                hdrlen, flags, cmd, /* version = */ 0);
+        return WIFI_SUCCESS;
+    } else {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+}
+
+wifi_error WifiRequest::create(uint32_t id, int subcmd) {
+    wifi_error res = create(NL80211_CMD_VENDOR);
+    if (res != WIFI_SUCCESS)
+        return res;
+
+    res = put_u32(NL80211_ATTR_VENDOR_ID, id);
+    if (res != WIFI_SUCCESS)
+        return res;
+
+    res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
+    if (res != WIFI_SUCCESS)
+        return res;
+
+    if (mIface != -1)
+        res = set_iface_id(mIface);
+
+    return res;
+}
+
+
+static int no_seq_check(struct nl_msg *msg, void *arg)
+{
+    return NL_OK;
+}
+
+wifi_error WifiCommand::requestResponse()
+{
+    wifi_error err = create();                 /* create the message */
+    if (err != WIFI_SUCCESS)
+        return err;
+
+    return requestResponse(mMsg);
+}
+
+wifi_error WifiCommand::requestResponse(WifiRequest& request)
+{
+    int err = 0;
+
+    struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
+    if (!cb)
+        goto out;
+
+    err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
+    if (err < 0)
+        goto out;
+
+    err = 1;
+
+    nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
+    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
+    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
+
+    while (err > 0) {                   /* wait for reply */
+        int res = nl_recvmsgs(mInfo->cmd_sock, cb);
+        if (res) {
+            ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __FUNCTION__, res);
+        }
+    }
+out:
+    nl_cb_put(cb);
+    mMsg.destroy();
+    return mapKernelErrortoWifiHalError(err);
+}
+
+wifi_error WifiCommand::requestEvent(int cmd)
+{
+
+    int status;
+    wifi_error res = wifi_register_handler(wifiHandle(), cmd, event_handler,
+                                           this);
+    if (res != WIFI_SUCCESS)
+        return res;
+
+    res = create();                                                 /* create the message */
+    if (res != WIFI_SUCCESS)
+        goto out;
+
+    status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
+        goto out;
+    }
+
+    res = mCondition.wait();
+    if (res != WIFI_SUCCESS)
+        goto out;
+
+out:
+    wifi_unregister_handler(wifiHandle(), cmd);
+    return res;
+}
+
+wifi_error WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
+    int status;
+    wifi_error res = wifi_register_vendor_handler(wifiHandle(), id, subcmd,
+                                                  event_handler, this);
+    if (res != WIFI_SUCCESS)
+        return res;
+
+    res = create();                                                 /* create the message */
+    if (res != WIFI_SUCCESS)
+        goto out;
+
+    status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
+        goto out;
+    }
+
+    res = mCondition.wait();
+    if (res != WIFI_SUCCESS)
+        goto out;
+
+out:
+    wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
+    return res;
+}
+
+/* Event handlers */
+int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
+    WifiCommand *cmd = (WifiCommand *)arg;
+    WifiEvent reply(msg);
+    int res = reply.parse();
+    if (res < 0) {
+        ALOGE("Failed to parse reply message = %d", res);
+        return NL_SKIP;
+    } else {
+        // reply.log(); /* Don't call log() to avoid excess WiFi HAL logging */
+        return cmd->handleResponse(reply);
+    }
+}
+
+int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
+    WifiCommand *cmd = (WifiCommand *)arg;
+    WifiEvent event(msg);
+    int res = event.parse();
+    if (res < 0) {
+        ALOGE("Failed to parse event = %d", res);
+        res = NL_SKIP;
+    } else {
+        res = cmd->handleEvent(event);
+    }
+
+    cmd->mCondition.signal();
+    return res;
+}
+
+/* Other event handlers */
+int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
+     int *err = (int *)arg;
+    *err = 0;
+    return NL_SKIP;
+}
+
+int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
+    int *err = (int *)arg;
+    *err = 0;
+    return NL_STOP;
+}
+
+int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
+    int *ret = (int *)arg;
+    *ret = 0;
+    return NL_SKIP;
+}
+
+int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
+    int *ret = (int *)arg;
+    *ret = err->error;
+
+    return NL_SKIP;
+}
+
+
+WifiVendorCommand::WifiVendorCommand(wifi_handle handle,
+                                     wifi_request_id id,
+                                     u32 vendor_id,
+                                     u32 subcmd)
+        : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd),
+        mVendorData(NULL), mDataLen(0)
+{
+    ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u",
+          this, mVendor_id, mSubcmd);
+}
+
+WifiVendorCommand::~WifiVendorCommand()
+{
+    //ALOGV("~WifiVendorCommand %p destroyed", this);
+    //mVendorData is not destroyed here. Assumption
+    //is that VendorData is specific to each Vendor and they
+    //are responsible for owning the same.
+}
+
+// Override this method to parse reply and dig out data; save it
+// in the corresponding object
+int WifiVendorCommand::handleResponse(WifiEvent &reply)
+{
+    struct nlattr **tb = reply.attributes();
+    struct genlmsghdr *gnlh = reply.header();
+
+    if (gnlh->cmd == NL80211_CMD_VENDOR) {
+        if (tb[NL80211_ATTR_VENDOR_DATA]) {
+            mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
+            mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
+        }
+    }
+    return NL_SKIP;
+}
+
+// Override this method to parse event and dig out data;
+// save it in the object
+int WifiVendorCommand::handleEvent(WifiEvent &event)
+{
+    struct nlattr **tb = event.attributes();
+    struct genlmsghdr *gnlh = event.header();
+
+    if (gnlh->cmd == NL80211_CMD_VENDOR) {
+        /* Vendor Event */
+        if (!tb[NL80211_ATTR_VENDOR_ID] ||
+            !tb[NL80211_ATTR_VENDOR_SUBCMD])
+            return NL_SKIP;
+
+        mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
+        mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
+
+        ALOGV("%s: Vendor event: vendor_id=0x%x subcmd=%u",
+              __FUNCTION__, mVendor_id, mSubcmd);
+
+        if (tb[NL80211_ATTR_VENDOR_DATA]) {
+            mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
+            mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
+            ALOGV("%s: Vendor data len received:%d", __FUNCTION__, mDataLen);
+            hexdump(mVendorData, mDataLen);
+        }
+    }
+    return NL_SKIP;
+}
+
+wifi_error WifiVendorCommand::create() {
+    int ifindex;
+    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    // insert the oui in the msg
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+
+    // insert the subcmd in the msg
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+
+    //Insert the vendor specific data
+    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+    hexdump(mVendorData, mDataLen);
+
+    //insert the iface id to be "wlan0"
+    ifindex = if_nametoindex("wlan0");
+    ret = mMsg.set_iface_id(ifindex);
+out:
+    return ret;
+}
+
+wifi_error WifiVendorCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+wifi_error WifiVendorCommand::requestEvent()
+{
+    wifi_error res = requestVendorEvent(mVendor_id, mSubcmd);
+    return res;
+}
+
+wifi_error WifiVendorCommand::put_u8(int attribute, uint8_t value)
+{
+    return mMsg.put_u8(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_u16(int attribute, uint16_t value)
+{
+    return mMsg.put_u16(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_u32(int attribute, uint32_t value)
+{
+    return mMsg.put_u32(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_u64(int attribute, uint64_t value)
+{
+    return mMsg.put_u64(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_s8(int attribute, s8 value)
+{
+    return mMsg.put_s8(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_s16(int attribute, s16 value)
+{
+    return mMsg.put_s16(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_s32(int attribute, s32 value)
+{
+    return mMsg.put_s32(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_s64(int attribute, s64 value)
+{
+    return mMsg.put_s64(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_flag(int attribute)
+{
+    return mMsg.put_flag(attribute);
+}
+
+u8 WifiVendorCommand::get_u8(const struct nlattr *nla)
+{
+    return mMsg.get_u8(nla);
+}
+
+u16 WifiVendorCommand::get_u16(const struct nlattr *nla)
+{
+    return mMsg.get_u16(nla);
+}
+
+u32 WifiVendorCommand::get_u32(const struct nlattr *nla)
+{
+    return mMsg.get_u32(nla);
+}
+
+u64 WifiVendorCommand::get_u64(const struct nlattr *nla)
+{
+    return mMsg.get_u64(nla);
+}
+
+s8 WifiVendorCommand::get_s8(const struct nlattr *nla)
+{
+    return mMsg.get_s8(nla);
+}
+
+s16 WifiVendorCommand::get_s16(const struct nlattr *nla)
+{
+    return mMsg.get_s16(nla);
+}
+
+s32 WifiVendorCommand::get_s32(const struct nlattr *nla)
+{
+    return mMsg.get_s32(nla);
+}
+
+s64 WifiVendorCommand::get_s64(const struct nlattr *nla)
+{
+    return mMsg.get_s64(nla);
+}
+
+wifi_error WifiVendorCommand::put_ipv6_addr(int attribute, uint8_t value[16])
+{
+    return mMsg.put_ipv6_addr(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_string(int attribute, const char *value)
+{
+    return mMsg.put_string(attribute, value);
+}
+
+wifi_error WifiVendorCommand::put_addr(int attribute, mac_addr value)
+{
+    return mMsg.put_addr(attribute, value);
+}
+
+struct nlattr * WifiVendorCommand::attr_start(int attribute)
+{
+    return mMsg.attr_start(attribute);
+}
+
+void WifiVendorCommand::attr_end(struct nlattr *attribute)
+{
+    return mMsg.attr_end(attribute);
+}
+
+wifi_error WifiVendorCommand::set_iface_id(const char* name)
+{
+    unsigned ifindex = if_nametoindex(name);
+    return mMsg.set_iface_id(ifindex);
+}
+
+wifi_error WifiVendorCommand::put_bytes(int attribute,
+                                        const char *data,
+                                        int len)
+{
+    return mMsg.put_bytes(attribute, data, len);
+}
+
+wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor,
+                                       int attribute,
+                                       mac_addr addr)
+{
+    if (!tb_vendor[attribute]) {
+        ALOGE("Failed to get attribute : %d", attribute);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    if (!addr) {
+        ALOGE("addr is NULL");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (nla_len(tb_vendor[attribute]) != sizeof(mac_addr)) {
+        ALOGE("Invalid mac addr lenght\n");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    memcpy(addr, (u8 *)nla_data(tb_vendor[attribute]),
+                 nla_len(tb_vendor[attribute]));
+
+    return WIFI_SUCCESS;
+}
+
+wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
+                                 wifi_request_id id,
+                                 u32 subcmd,
+                                 WifiVendorCommand **vCommand)
+{
+    wifi_error ret;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    if (vCommand == NULL) {
+        ALOGE("%s: Error vCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    *vCommand = new WifiVendorCommand(wifiHandle, id,
+                                      OUI_QCA,
+                                      subcmd);
+    if (*vCommand == NULL) {
+        ALOGE("%s: Object creation failed", __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    /* Create the message */
+    ret = (*vCommand)->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = (*vCommand)->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    return WIFI_SUCCESS;
+
+cleanup:
+    delete *vCommand;
+    return ret;
+}
diff --git a/wcn6740/qcwcn/wifi_hal/cpp_bindings.h b/wcn6740/qcwcn/wifi_hal/cpp_bindings.h
new file mode 100644
index 0000000..4ddb93e
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/cpp_bindings.h
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution
+ */
+
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __WIFI_HAL_CPP_BINDINGS_H__
+#define __WIFI_HAL_CPP_BINDINGS_H__
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "sync.h"
+
+class WifiEvent
+{
+    /* TODO: remove this when nl headers are updated */
+    static const unsigned NL80211_ATTR_MAX_INTERNAL = 256;
+private:
+    struct nl_msg *mMsg;
+    struct genlmsghdr *mHeader;
+    struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1];
+
+public:
+    WifiEvent(nl_msg *msg) {
+        mMsg = msg;
+        mHeader = NULL;
+        memset(mAttributes, 0, sizeof(mAttributes));
+    }
+    ~WifiEvent() {
+        /* don't destroy mMsg; it doesn't belong to us */
+    }
+
+    void log();
+
+    int parse();
+
+    genlmsghdr *header() {
+        return mHeader;
+    }
+
+    int get_cmd() {
+        return mHeader->cmd;
+    }
+
+    int get_vendor_id() {
+        return get_u32(NL80211_ATTR_VENDOR_ID);
+    }
+
+    int get_vendor_subcmd() {
+        return get_u32(NL80211_ATTR_VENDOR_SUBCMD);
+    }
+
+    void *get_vendor_data() {
+        return get_data(NL80211_ATTR_VENDOR_DATA);
+    }
+
+    int get_vendor_data_len() {
+        return get_len(NL80211_ATTR_VENDOR_DATA);
+    }
+
+    const char *get_cmdString();
+
+    nlattr ** attributes() {
+        return mAttributes;
+    }
+
+    nlattr *get_attribute(int attribute) {
+        return mAttributes[attribute];
+    }
+
+    uint8_t get_u8(int attribute) {
+        return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0;
+    }
+
+    uint16_t get_u16(int attribute) {
+        return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0;
+    }
+
+    uint32_t get_u32(int attribute) {
+        return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0;
+    }
+
+    uint64_t get_u64(int attribute) {
+        return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0;
+    }
+
+    int get_len(int attribute) {
+        return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0;
+    }
+
+    void *get_data(int attribute) {
+        return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL;
+    }
+
+private:
+    WifiEvent(const WifiEvent&);        // hide copy constructor to prevent copies
+};
+
+class nl_iterator {
+    struct nlattr *pos;
+    int rem;
+public:
+    nl_iterator(struct nlattr *attr) {
+        pos = (struct nlattr *)nla_data(attr);
+        rem = nla_len(attr);
+    }
+    bool has_next() {
+        return nla_ok(pos, rem);
+    }
+    void next() {
+        pos = (struct nlattr *)nla_next(pos, &(rem));
+    }
+    struct nlattr *get() {
+        return pos;
+    }
+    uint16_t get_type() {
+        return pos->nla_type;
+    }
+    uint8_t get_u8() {
+        return nla_get_u8(pos);
+    }
+    uint16_t get_u16() {
+        return nla_get_u16(pos);
+    }
+    uint32_t get_u32() {
+        return nla_get_u32(pos);
+    }
+    uint64_t get_u64() {
+        return nla_get_u64(pos);
+    }
+    void* get_data() {
+        return nla_data(pos);
+    }
+    int get_len() {
+        return nla_len(pos);
+    }
+private:
+    nl_iterator(const nl_iterator&);    // hide copy constructor to prevent copies
+};
+
+class WifiRequest
+{
+private:
+    int mFamily;
+    int mIface;
+    struct nl_msg *mMsg;
+
+public:
+    WifiRequest(int family) {
+        mMsg = NULL;
+        mFamily = family;
+        mIface = -1;
+    }
+
+    WifiRequest(int family, int iface) {
+        mMsg = NULL;
+        mFamily = family;
+        mIface = iface;
+    }
+
+    ~WifiRequest() {
+        destroy();
+    }
+
+    void destroy() {
+        if (mMsg) {
+            nlmsg_free(mMsg);
+            mMsg = NULL;
+        }
+    }
+
+    nl_msg *getMessage() {
+        return mMsg;
+    }
+
+    /* Command assembly helpers */
+    wifi_error create(int family, uint8_t cmd, int flags, int hdrlen);
+    wifi_error create(uint8_t cmd, int flags, int hdrlen) {
+        return create(mFamily, cmd, flags, hdrlen);
+    }
+    wifi_error create(uint8_t cmd) {
+        return create(mFamily, cmd, 0, 0);
+    }
+
+    wifi_error create(uint32_t id, int subcmd);
+
+    wifi_error wifi_nla_put(struct nl_msg *msg, int attr,
+                            int attrlen, const void *data)
+    {
+        int status;
+
+        status = nla_put(msg, attr, attrlen, data);
+	if (status < 0)
+            ALOGE("Failed to put attr with size = %d, type = %d, error = %d",
+                  attrlen, attr, status);
+        return mapKernelErrortoWifiHalError(status);
+    }
+    wifi_error put_u8(int attribute, uint8_t value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+    wifi_error put_u16(int attribute, uint16_t value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+    wifi_error put_u32(int attribute, uint32_t value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+
+    wifi_error put_u64(int attribute, uint64_t value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+
+    wifi_error put_s8(int attribute, s8 value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(int8_t), &value);
+    }
+    wifi_error put_s16(int attribute, s16 value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(int16_t), &value);
+    }
+    wifi_error put_s32(int attribute, s32 value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(int32_t), &value);
+    }
+    wifi_error put_s64(int attribute, s64 value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(int64_t), &value);
+    }
+    wifi_error put_flag(int attribute) {
+        int status;
+
+        status =  nla_put_flag(mMsg, attribute);
+        if(status < 0)
+           ALOGE("Failed to put flag attr of type = %d, error = %d",
+                  attribute, status);
+        return mapKernelErrortoWifiHalError(status);
+    }
+
+    u8 get_u8(const struct nlattr *nla)
+    {
+        return *(u8 *) nla_data(nla);
+    }
+    u16 get_u16(const struct nlattr *nla)
+    {
+        return *(u16 *) nla_data(nla);
+    }
+    u32 get_u32(const struct nlattr *nla)
+    {
+        return *(u32 *) nla_data(nla);
+    }
+    u64 get_u64(const struct nlattr *nla)
+    {
+        return *(u64 *) nla_data(nla);
+    }
+
+    s8 get_s8(const struct nlattr *nla)
+    {
+        return *(s8 *) nla_data(nla);
+    }
+
+    s16 get_s16(const struct nlattr *nla)
+    {
+        return *(s16 *) nla_data(nla);
+    }
+    s32 get_s32(const struct nlattr *nla)
+    {
+        return *(s32 *) nla_data(nla);
+    }
+    s64 get_s64(const struct nlattr *nla)
+    {
+        return *(s64 *) nla_data(nla);
+    }
+
+    wifi_error put_ipv6_addr(int attribute, uint8_t *value) {
+        return wifi_nla_put(mMsg, attribute, 16, value);
+    }
+
+    wifi_error put_string(int attribute, const char *value) {
+        return wifi_nla_put(mMsg, attribute, strlen(value) + 1, value);
+    }
+    wifi_error put_addr(int attribute, mac_addr value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(mac_addr), value);
+    }
+
+    struct nlattr * attr_start(int attribute) {
+        return nla_nest_start(mMsg, attribute);
+    }
+    void attr_end(struct nlattr *attr) {
+        nla_nest_end(mMsg, attr);
+    }
+
+    wifi_error set_iface_id(int ifindex) {
+        return put_u32(NL80211_ATTR_IFINDEX, ifindex);
+    }
+
+    wifi_error put_bytes(int attribute, const char *data, int len) {
+        return wifi_nla_put(mMsg, attribute, len, data);
+    }
+
+private:
+    WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
+
+};
+
+class WifiCommand
+{
+protected:
+    hal_info *mInfo;
+    WifiRequest mMsg;
+    Condition mCondition;
+    wifi_request_id mId;
+    interface_info *mIfaceInfo;
+public:
+    WifiCommand(wifi_handle handle, wifi_request_id id)
+            : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id)
+    {
+        mIfaceInfo = NULL;
+        mInfo = getHalInfo(handle);
+    }
+
+    WifiCommand(wifi_interface_handle iface, wifi_request_id id)
+            : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id)
+    {
+        mIfaceInfo = getIfaceInfo(iface);
+        mInfo = getHalInfo(iface);
+    }
+
+    virtual ~WifiCommand() {
+    }
+
+    wifi_request_id id() {
+        return mId;
+    }
+
+    virtual wifi_error create() {
+        /* by default there is no way to cancel */
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    virtual wifi_error cancel() {
+        /* by default there is no way to cancel */
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    wifi_error requestResponse();
+    wifi_error requestEvent(int cmd);
+    wifi_error requestVendorEvent(uint32_t id, int subcmd);
+    wifi_error requestResponse(WifiRequest& request);
+
+protected:
+    wifi_handle wifiHandle() {
+        return getWifiHandle(mInfo);
+    }
+
+    wifi_interface_handle ifaceHandle() {
+        return getIfaceHandle(mIfaceInfo);
+    }
+
+    int familyId() {
+        return mInfo->nl80211_family_id;
+    }
+
+    int ifaceId() {
+        return mIfaceInfo->id;
+    }
+
+    /* Override this method to parse reply and dig out data; save it in the object */
+    virtual int handleResponse(WifiEvent& reply) {
+        UNUSED(reply);
+        return NL_SKIP;
+    }
+
+    /* Override this method to parse event and dig out data; save it in the object */
+    virtual int handleEvent(WifiEvent& event) {
+        UNUSED(event);
+        return NL_SKIP;
+    }
+
+    int registerHandler(int cmd) {
+        return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
+    }
+
+    void unregisterHandler(int cmd) {
+        wifi_unregister_handler(wifiHandle(), cmd);
+    }
+
+    wifi_error registerVendorHandler(uint32_t id, int subcmd) {
+        return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
+    }
+
+    void unregisterVendorHandler(uint32_t id, int subcmd) {
+        wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
+    }
+
+private:
+    WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
+
+    /* Event handling */
+    static int response_handler(struct nl_msg *msg, void *arg);
+
+    static int event_handler(struct nl_msg *msg, void *arg);
+
+    /* Other event handlers */
+    static int valid_handler(struct nl_msg *msg, void *arg);
+
+    static int ack_handler(struct nl_msg *msg, void *arg);
+
+    static int finish_handler(struct nl_msg *msg, void *arg);
+
+    static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
+};
+
+//WifiVendorCommand class
+class WifiVendorCommand: public WifiCommand
+{
+protected:
+    u32 mVendor_id;
+    u32 mSubcmd;
+    char *mVendorData;
+    u32 mDataLen;
+
+
+public:
+    WifiVendorCommand(wifi_handle handle, wifi_request_id id, u32 vendor_id, u32 subcmd);
+
+    virtual ~WifiVendorCommand();
+
+    virtual wifi_error create();
+
+    virtual wifi_error requestResponse();
+
+    virtual wifi_error requestEvent();
+
+    virtual wifi_error put_u8(int attribute, uint8_t value);
+
+    virtual wifi_error put_u16(int attribute, uint16_t value);
+
+    virtual wifi_error put_u32(int attribute, uint32_t value);
+
+    virtual wifi_error put_u64(int attribute, uint64_t value);
+
+    virtual wifi_error put_s8(int attribute, s8 value);
+
+    virtual wifi_error put_s16(int attribute, s16 value);
+
+    virtual wifi_error put_s32(int attribute, s32 value);
+
+    virtual wifi_error put_s64(int attribute, s64 value);
+
+    wifi_error put_flag(int attribute);
+
+    virtual u8 get_u8(const struct nlattr *nla);
+    virtual u16 get_u16(const struct nlattr *nla);
+    virtual u32 get_u32(const struct nlattr *nla);
+    virtual u64 get_u64(const struct nlattr *nla);
+
+    virtual s8 get_s8(const struct nlattr *nla);
+    virtual s16 get_s16(const struct nlattr *nla);
+    virtual s32 get_s32(const struct nlattr *nla);
+    virtual s64 get_s64(const struct nlattr *nla);
+
+    virtual wifi_error put_ipv6_addr(int attribute, uint8_t value[16]);
+
+    virtual wifi_error put_string(int attribute, const char *value);
+
+    virtual wifi_error put_addr(int attribute, mac_addr value);
+
+    virtual struct nlattr * attr_start(int attribute);
+
+    virtual void attr_end(struct nlattr *attribute);
+
+    virtual wifi_error set_iface_id(const char* name);
+
+    virtual wifi_error put_bytes(int attribute, const char *data, int len);
+
+    virtual wifi_error get_mac_addr(struct nlattr **tb_vendor,
+                                int attribute,
+                                mac_addr addr);
+
+protected:
+
+    /* Override this method to parse reply and dig out data; save it in the corresponding
+       object */
+    virtual int handleResponse(WifiEvent &reply);
+
+    /* Override this method to parse event and dig out data; save it in the object */
+    virtual int handleEvent(WifiEvent &event);
+};
+
+/* nl message processing macros (required to pass C++ type checks) */
+
+#define for_each_attr(pos, nla, rem) \
+    for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
+        nla_ok(pos, rem); \
+        pos = (nlattr *)nla_next(pos, &(rem)))
+
+wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
+                                 wifi_request_id id,
+                                 u32 subcmd,
+                                 WifiVendorCommand **vCommand);
+#endif
diff --git a/wcn6740/qcwcn/wifi_hal/gscan.cpp b/wcn6740/qcwcn/wifi_hal/gscan.cpp
new file mode 100644
index 0000000..fc76219
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/gscan.cpp
@@ -0,0 +1,2344 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+#define LOG_TAG  "WifiHAL"
+#include <utils/Log.h>
+#include <time.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "common.h"
+#include "cpp_bindings.h"
+#include "gscancommand.h"
+#include "gscan_event_handler.h"
+#include "vendor_definitions.h"
+
+#define GSCAN_EVENT_WAIT_TIME_SECONDS 4
+#define WIFI_SCANNING_MAC_OUI_LENGTH 3
+#define EPNO_NO_NETWORKS 0
+
+/* BSSID blacklist */
+typedef struct {
+    int num_bssid;                           // number of blacklisted BSSIDs
+    mac_addr bssids[MAX_BLACKLIST_BSSID];    // blacklisted BSSIDs
+} wifi_bssid_params;
+
+/* Used to handle gscan command events from driver/firmware.*/
+typedef struct gscan_event_handlers_s {
+    GScanCommandEventHandler *gscanStartCmdEventHandler;
+    GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler;
+    GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler;
+    GScanCommandEventHandler *gScanSetSsidHotlistCmdEventHandler;
+    GScanCommandEventHandler *gScanSetPnoListCmdEventHandler;
+    GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler;
+} gscan_event_handlers;
+
+wifi_error initializeGscanHandlers(hal_info *info)
+{
+    info->gscan_handlers = (gscan_event_handlers *)malloc(sizeof(gscan_event_handlers));
+    if (info->gscan_handlers) {
+        memset(info->gscan_handlers, 0, sizeof(gscan_event_handlers));
+    }
+    else {
+        ALOGE("%s: Allocation of gscan event handlers failed",
+              __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return WIFI_SUCCESS;
+}
+
+wifi_error cleanupGscanHandlers(hal_info *info)
+{
+    gscan_event_handlers* event_handlers;
+    if (info && info->gscan_handlers) {
+        event_handlers = (gscan_event_handlers*) info->gscan_handlers;
+        if (event_handlers->gscanStartCmdEventHandler) {
+            delete event_handlers->gscanStartCmdEventHandler;
+        }
+        if (event_handlers->gScanSetBssidHotlistCmdEventHandler) {
+            delete event_handlers->gScanSetBssidHotlistCmdEventHandler;
+        }
+        if (event_handlers->gScanSetSignificantChangeCmdEventHandler) {
+            delete event_handlers->gScanSetSignificantChangeCmdEventHandler;
+        }
+        if (event_handlers->gScanSetSsidHotlistCmdEventHandler) {
+            delete event_handlers->gScanSetSsidHotlistCmdEventHandler;
+        }
+        if (event_handlers->gScanSetPnoListCmdEventHandler) {
+            delete event_handlers->gScanSetPnoListCmdEventHandler;
+        }
+        if (event_handlers->gScanPnoSetPasspointListCmdEventHandler) {
+            delete event_handlers->gScanPnoSetPasspointListCmdEventHandler;
+        }
+        memset(event_handlers, 0, sizeof(gscan_event_handlers));
+        free(info->gscan_handlers);
+        info->gscan_handlers = NULL;
+        return WIFI_SUCCESS;
+    }
+    ALOGE ("%s: info or info->gscan_handlers NULL", __FUNCTION__);
+    return WIFI_ERROR_UNKNOWN;
+}
+
+/* Implementation of the API functions exposed in gscan.h */
+wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
+       int band, int max_channels, wifi_channel *channels, int *num_channels)
+{
+    int requestId;
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(handle);
+    wifi_handle wifiHandle = getWifiHandle(handle);
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate one randomly.
+     */
+    requestId = get_requestid();
+    ALOGV("%s: RequestId:%d band:%d max_channels:%d", __FUNCTION__,
+          requestId, band, max_channels);
+
+    if (channels == NULL) {
+        ALOGE("%s: NULL channels pointer provided. Exit.",
+            __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    gScanCommand = new GScanCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData)
+        goto cleanup;
+
+    if (gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            requestId) ||
+        gScanCommand->put_u32(
+        QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND,
+            band) ||
+        gScanCommand->put_u32(
+        QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS,
+            max_channels) )
+    {
+        goto cleanup;
+    }
+    gScanCommand->attr_end(nlData);
+    /* Populate the input received from caller/framework. */
+    gScanCommand->setMaxChannels(max_channels);
+    gScanCommand->setChannels(channels);
+    gScanCommand->setNumChannelsPtr(num_channels);
+
+    /* Send the msg and wait for a response. */
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+cleanup:
+    delete gScanCommand;
+    return ret;
+}
+
+wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
+                                 wifi_gscan_capabilities *capabilities)
+{
+    wifi_handle wifiHandle = getWifiHandle(handle);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if (capabilities == NULL) {
+        ALOGE("%s: NULL capabilities pointer provided. Exit.", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    memcpy(capabilities, &info->capa.gscan_capa, sizeof(wifi_gscan_capabilities));
+
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_start_gscan(wifi_request_id id,
+                            wifi_interface_handle iface,
+                            wifi_scan_cmd_params params,
+                            wifi_scan_result_handler handler)
+{
+    wifi_error ret;
+    u32 i, j;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    u32 num_scan_buckets, numChannelSpecs;
+    wifi_scan_bucket_spec bucketSpec;
+    struct nlattr *nlBuckectSpecList;
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanStartCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ALOGV("%s: RequestId:%d ", __FUNCTION__, id);
+    /* Wi-Fi HAL doesn't need to check if a similar request to start gscan was
+     *  made earlier. If start_gscan() is called while another gscan is already
+     *  running, the request will be sent down to driver and firmware. If new
+     * request is successfully honored, then Wi-Fi HAL will use the new request
+     * id for the gScanStartCmdEventHandler object.
+     */
+    gScanCommand = new GScanCommand(
+                                wifiHandle,
+                                id,
+                                OUI_QCA,
+                                QCA_NL80211_VENDOR_SUBCMD_GSCAN_START);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    num_scan_buckets = (unsigned int)params.num_buckets > MAX_BUCKETS ?
+                            MAX_BUCKETS : params.num_buckets;
+
+    ALOGV("%s: Base Period:%d Max_ap_per_scan:%d "
+          "Threshold_percent:%d Threshold_num_scans:%d "
+          "num_buckets:%d", __FUNCTION__, params.base_period,
+          params.max_ap_per_scan, params.report_threshold_percent,
+          params.report_threshold_num_scans, num_scan_buckets);
+    if (gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            id) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_BASE_PERIOD,
+            params.base_period) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN,
+            params.max_ap_per_scan) ||
+        gScanCommand->put_u8(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT,
+            params.report_threshold_percent) ||
+        gScanCommand->put_u8(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS,
+            params.report_threshold_num_scans) ||
+        gScanCommand->put_u8(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS,
+            num_scan_buckets))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    nlBuckectSpecList =
+        gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC);
+    /* Add NL attributes for scan bucket specs . */
+    for (i = 0; i < num_scan_buckets; i++) {
+        bucketSpec = params.buckets[i];
+        numChannelSpecs = (unsigned int)bucketSpec.num_channels > MAX_CHANNELS ?
+                                MAX_CHANNELS : bucketSpec.num_channels;
+
+        ALOGV("%s: Index: %d Bucket Id:%d Band:%d Period:%d ReportEvent:%d "
+              "numChannelSpecs:%d max_period:%d base:%d step_count:%d",
+              __FUNCTION__, i, bucketSpec.bucket, bucketSpec.band,
+              bucketSpec.period, bucketSpec.report_events,
+              numChannelSpecs, bucketSpec.max_period,
+              bucketSpec.base, bucketSpec.step_count);
+
+        struct nlattr *nlBucketSpec = gScanCommand->attr_start(i);
+        if (gScanCommand->put_u8(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_INDEX,
+                bucketSpec.bucket) ||
+            gScanCommand->put_u8(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BAND,
+                bucketSpec.band) ||
+            gScanCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_PERIOD,
+                bucketSpec.period) ||
+            gScanCommand->put_u8(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_REPORT_EVENTS,
+                bucketSpec.report_events) ||
+            gScanCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS,
+                numChannelSpecs) ||
+            gScanCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_MAX_PERIOD,
+                bucketSpec.max_period) ||
+            gScanCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BASE,
+                bucketSpec.base) ||
+            gScanCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_STEP_COUNT,
+                bucketSpec.step_count))
+        {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+
+        struct nlattr *nl_channelSpecList =
+            gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC);
+
+        /* Add NL attributes for scan channel specs . */
+        for (j = 0; j < numChannelSpecs; j++) {
+            struct nlattr *nl_channelSpec = gScanCommand->attr_start(j);
+            wifi_scan_channel_spec channel_spec = bucketSpec.channels[j];
+
+            ALOGV("%s: Channel Spec Index:%d Channel:%d Dwell Time:%d "
+                  "passive:%d", __FUNCTION__, j, channel_spec.channel,
+                  channel_spec.dwellTimeMs, channel_spec.passive);
+
+            if ( gScanCommand->put_u32(
+                    QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CHANNEL,
+                    channel_spec.channel) ||
+                gScanCommand->put_u32(
+                    QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_DWELL_TIME,
+                    channel_spec.dwellTimeMs) ||
+                gScanCommand->put_u8(
+                    QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_PASSIVE,
+                    channel_spec.passive) )
+            {
+                ret = WIFI_ERROR_UNKNOWN;
+                goto cleanup;
+            }
+
+            gScanCommand->attr_end(nl_channelSpec);
+        }
+        gScanCommand->attr_end(nl_channelSpecList);
+        gScanCommand->attr_end(nlBucketSpec);
+    }
+    gScanCommand->attr_end(nlBuckectSpecList);
+
+    gScanCommand->attr_end(nlData);
+
+    /* Set the callback handler functions for related events. */
+    GScanCallbackHandler callbackHandler;
+    memset(&callbackHandler, 0, sizeof(callbackHandler));
+    callbackHandler.on_full_scan_result = handler.on_full_scan_result;
+    callbackHandler.on_scan_event = handler.on_scan_event;
+
+    /* Create an object to handle the related events from firmware/driver. */
+    if (gScanStartCmdEventHandler == NULL) {
+        gScanStartCmdEventHandler = new GScanCommandEventHandler(
+                                    wifiHandle,
+                                    id,
+                                    OUI_QCA,
+                                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_START,
+                                    callbackHandler);
+        if (gScanStartCmdEventHandler == NULL) {
+            ALOGE("%s: Error gScanStartCmdEventHandler NULL", __FUNCTION__);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        event_handlers->gscanStartCmdEventHandler = gScanStartCmdEventHandler;
+    } else {
+        gScanStartCmdEventHandler->setCallbackHandler(callbackHandler);
+    }
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s : requestResponse Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (gScanStartCmdEventHandler != NULL) {
+        gScanStartCmdEventHandler->set_request_id(id);
+        gScanStartCmdEventHandler->enableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    /* Disable Event Handling if ret != 0 */
+    if ((ret != WIFI_SUCCESS) && gScanStartCmdEventHandler) {
+        ALOGI("%s: Error ret:%d, disable event handling",
+            __FUNCTION__, ret);
+        gScanStartCmdEventHandler->disableEventHandling();
+    }
+    return ret;
+
+}
+
+wifi_error wifi_stop_gscan(wifi_request_id id,
+                            wifi_interface_handle iface)
+{
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanStartCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if (gScanStartCmdEventHandler == NULL ||
+        gScanStartCmdEventHandler->isEventHandlingEnabled() == false) {
+        ALOGE("%s: GSCAN isn't running or already stopped. "
+            "Nothing to do. Exit", __FUNCTION__);
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    gScanCommand = new GScanCommand(
+                                wifiHandle,
+                                id,
+                                OUI_QCA,
+                                QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    gScanCommand->attr_end(nlData);
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+    /* Disable Event Handling. */
+    if (gScanStartCmdEventHandler) {
+        gScanStartCmdEventHandler->disableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    return ret;
+}
+
+/* Set the GSCAN BSSID Hotlist. */
+wifi_error wifi_set_bssid_hotlist(wifi_request_id id,
+                                    wifi_interface_handle iface,
+                                    wifi_bssid_hotlist_params params,
+                                    wifi_hotlist_ap_found_handler handler)
+{
+    int i, numAp;
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData, *nlApThresholdParamList;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanSetBssidHotlistCmdEventHandler =
+        event_handlers->gScanSetBssidHotlistCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    /* Wi-Fi HAL doesn't need to check if a similar request to set bssid
+     * hotlist was made earlier. If set_bssid_hotlist() is called while
+     * another one is running, the request will be sent down to driver and
+     * firmware. If the new request is successfully honored, then Wi-Fi HAL
+     * will use the new request id for the gScanSetBssidHotlistCmdEventHandler
+     * object.
+     */
+
+    gScanCommand =
+        new GScanCommand(
+                    wifiHandle,
+                    id,
+                    OUI_QCA,
+                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    numAp = (unsigned int)params.num_bssid > MAX_HOTLIST_APS ?
+        MAX_HOTLIST_APS : params.num_bssid;
+    if (gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            id) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE,
+            params.lost_ap_sample_size) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_NUM_AP,
+            numAp))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ALOGV("%s: lost_ap_sample_size:%d numAp:%d", __FUNCTION__,
+          params.lost_ap_sample_size, numAp);
+    /* Add the vendor specific attributes for the NL command. */
+    nlApThresholdParamList =
+        gScanCommand->attr_start(
+                                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM);
+    if (!nlApThresholdParamList){
+        ret = WIFI_ERROR_UNINITIALIZED;
+        goto cleanup;
+    }
+
+    /* Add nested NL attributes for AP Threshold Param. */
+    for (i = 0; i < numAp; i++) {
+        ap_threshold_param apThreshold = params.ap[i];
+        struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i);
+        if (!nlApThresholdParam){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        if (gScanCommand->put_addr(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID,
+                apThreshold.bssid) ||
+            gScanCommand->put_s32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW,
+                apThreshold.low) ||
+            gScanCommand->put_s32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH,
+                apThreshold.high))
+        {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        ALOGV("%s: Index:%d BssId: %hhx:%hhx:%hhx:%hhx:%hhx:%hhx "
+              "Threshold low:%d high:%d", __FUNCTION__, i,
+              apThreshold.bssid[0], apThreshold.bssid[1],
+              apThreshold.bssid[2], apThreshold.bssid[3],
+              apThreshold.bssid[4], apThreshold.bssid[5],
+              apThreshold.low, apThreshold.high);
+        gScanCommand->attr_end(nlApThresholdParam);
+    }
+
+    gScanCommand->attr_end(nlApThresholdParamList);
+
+    gScanCommand->attr_end(nlData);
+
+    GScanCallbackHandler callbackHandler;
+    memset(&callbackHandler, 0, sizeof(callbackHandler));
+    callbackHandler.on_hotlist_ap_found = handler.on_hotlist_ap_found;
+    callbackHandler.on_hotlist_ap_lost = handler.on_hotlist_ap_lost;
+
+    /* Create an object of the event handler class to take care of the
+      * asychronous events on the north-bound.
+      */
+    if (gScanSetBssidHotlistCmdEventHandler == NULL) {
+        gScanSetBssidHotlistCmdEventHandler = new GScanCommandEventHandler(
+                            wifiHandle,
+                            id,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST,
+                            callbackHandler);
+        if (gScanSetBssidHotlistCmdEventHandler == NULL) {
+            ALOGE("%s: Error instantiating "
+                "gScanSetBssidHotlistCmdEventHandler.", __FUNCTION__);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        event_handlers->gScanSetBssidHotlistCmdEventHandler =
+            gScanSetBssidHotlistCmdEventHandler;
+    } else {
+        gScanSetBssidHotlistCmdEventHandler->setCallbackHandler(callbackHandler);
+    }
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (gScanSetBssidHotlistCmdEventHandler != NULL) {
+        gScanSetBssidHotlistCmdEventHandler->set_request_id(id);
+        gScanSetBssidHotlistCmdEventHandler->enableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    /* Disable Event Handling if ret != 0 */
+    if ((ret != WIFI_SUCCESS) && gScanSetBssidHotlistCmdEventHandler) {
+        ALOGI("%s: Error ret:%d, disable event handling",
+            __FUNCTION__, ret);
+        gScanSetBssidHotlistCmdEventHandler->disableEventHandling();
+    }
+    return ret;
+}
+
+wifi_error wifi_reset_bssid_hotlist(wifi_request_id id,
+                            wifi_interface_handle iface)
+{
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanSetBssidHotlistCmdEventHandler =
+        event_handlers->gScanSetBssidHotlistCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if (gScanSetBssidHotlistCmdEventHandler == NULL ||
+        (gScanSetBssidHotlistCmdEventHandler->isEventHandlingEnabled() ==
+         false)) {
+        ALOGE("wifi_reset_bssid_hotlist: GSCAN bssid_hotlist isn't set. "
+            "Nothing to do. Exit");
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    gScanCommand = new GScanCommand(
+                        wifiHandle,
+                        id,
+                        OUI_QCA,
+                        QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST);
+
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    gScanCommand->attr_end(nlData);
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+    /* Disable Event Handling. */
+    if (gScanSetBssidHotlistCmdEventHandler) {
+        gScanSetBssidHotlistCmdEventHandler->disableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    return ret;
+}
+
+/* Set the GSCAN Significant AP Change list. */
+wifi_error wifi_set_significant_change_handler(wifi_request_id id,
+                                            wifi_interface_handle iface,
+                                    wifi_significant_change_params params,
+                                    wifi_significant_change_handler handler)
+{
+    int i, numAp;
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData, *nlApThresholdParamList;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanSetSignificantChangeCmdEventHandler =
+        event_handlers->gScanSetSignificantChangeCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    /* Wi-Fi HAL doesn't need to check if a similar request to set significant
+     * change list was made earlier. If set_significant_change() is called while
+     * another one is running, the request will be sent down to driver and
+     * firmware. If the new request is successfully honored, then Wi-Fi HAL
+     * will use the new request id for the gScanSetSignificantChangeCmdEventHandler
+     * object.
+     */
+
+    gScanCommand = new GScanCommand(
+                    wifiHandle,
+                    id,
+                    OUI_QCA,
+                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    numAp = (unsigned int)params.num_bssid > MAX_SIGNIFICANT_CHANGE_APS ?
+        MAX_SIGNIFICANT_CHANGE_APS : params.num_bssid;
+
+    if (gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            id) ||
+        gScanCommand->put_u32(
+        QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE,
+            params.rssi_sample_size) ||
+        gScanCommand->put_u32(
+        QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE,
+            params.lost_ap_sample_size) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING,
+            params.min_breaching) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP,
+            numAp))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ALOGV("%s: Number of AP params:%d Rssi_sample_size:%d "
+          "lost_ap_sample_size:%d min_breaching:%d", __FUNCTION__,
+          numAp, params.rssi_sample_size, params.lost_ap_sample_size,
+          params.min_breaching);
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlApThresholdParamList =
+        gScanCommand->attr_start(
+                                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM);
+    if (!nlApThresholdParamList){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    /* Add nested NL attributes for AP Threshold Param list. */
+    for (i = 0; i < numAp; i++) {
+        ap_threshold_param apThreshold = params.ap[i];
+        struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i);
+        if (!nlApThresholdParam){
+            ret = WIFI_ERROR_UNINITIALIZED;
+            goto cleanup;
+        }
+        if ( gScanCommand->put_addr(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID,
+                apThreshold.bssid) ||
+            gScanCommand->put_s32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW,
+                apThreshold.low) ||
+            gScanCommand->put_s32(
+                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH,
+                apThreshold.high))
+        {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        ALOGV("%s: ap[%d].bssid:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx "
+              "ap[%d].low:%d  ap[%d].high:%d", __FUNCTION__,
+              i,
+              apThreshold.bssid[0], apThreshold.bssid[1],
+              apThreshold.bssid[2], apThreshold.bssid[3],
+              apThreshold.bssid[4], apThreshold.bssid[5],
+              i, apThreshold.low, i, apThreshold.high);
+        gScanCommand->attr_end(nlApThresholdParam);
+    }
+
+    gScanCommand->attr_end(nlApThresholdParamList);
+
+    gScanCommand->attr_end(nlData);
+
+    GScanCallbackHandler callbackHandler;
+    memset(&callbackHandler, 0, sizeof(callbackHandler));
+    callbackHandler.on_significant_change = handler.on_significant_change;
+
+    /* Create an object of the event handler class to take care of the
+      * asychronous events on the north-bound.
+      */
+    if (gScanSetSignificantChangeCmdEventHandler == NULL) {
+        gScanSetSignificantChangeCmdEventHandler =
+            new GScanCommandEventHandler(
+                     wifiHandle,
+                     id,
+                     OUI_QCA,
+                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE,
+                     callbackHandler);
+        if (gScanSetSignificantChangeCmdEventHandler == NULL) {
+            ALOGE("%s: Error in instantiating, "
+                "gScanSetSignificantChangeCmdEventHandler.",
+                __FUNCTION__);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        event_handlers->gScanSetSignificantChangeCmdEventHandler =
+            gScanSetSignificantChangeCmdEventHandler;
+    } else {
+        gScanSetSignificantChangeCmdEventHandler->setCallbackHandler(callbackHandler);
+    }
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (gScanSetSignificantChangeCmdEventHandler != NULL) {
+        gScanSetSignificantChangeCmdEventHandler->set_request_id(id);
+        gScanSetSignificantChangeCmdEventHandler->enableEventHandling();
+    }
+
+cleanup:
+    /* Disable Event Handling if ret != 0 */
+    if ((ret != WIFI_SUCCESS) && gScanSetSignificantChangeCmdEventHandler) {
+        ALOGI("%s: Error ret:%d, disable event handling",
+            __FUNCTION__, ret);
+        gScanSetSignificantChangeCmdEventHandler->disableEventHandling();
+    }
+    delete gScanCommand;
+    return ret;
+}
+
+/* Clear the GSCAN Significant AP change list. */
+wifi_error wifi_reset_significant_change_handler(wifi_request_id id,
+                                            wifi_interface_handle iface)
+{
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanSetSignificantChangeCmdEventHandler =
+        event_handlers->gScanSetSignificantChangeCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if (gScanSetSignificantChangeCmdEventHandler == NULL ||
+        (gScanSetSignificantChangeCmdEventHandler->isEventHandlingEnabled() ==
+        false)) {
+        ALOGE("wifi_reset_significant_change_handler: GSCAN significant_change"
+            " isn't set. Nothing to do. Exit");
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    gScanCommand =
+        new GScanCommand
+                    (
+                    wifiHandle,
+                    id,
+                    OUI_QCA,
+                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = gScanCommand->put_u32(
+                    QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+                    id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    gScanCommand->attr_end(nlData);
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+    /* Disable Event Handling. */
+    if (gScanSetSignificantChangeCmdEventHandler) {
+        gScanSetSignificantChangeCmdEventHandler->disableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    return ret;
+}
+
+/* Get the GSCAN cached scan results. */
+wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface,
+                                            byte flush, int max,
+                                            wifi_cached_scan_results *results,
+                                            int *num)
+{
+    int requestId, retRequestRsp = 0;
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        ALOGE("%s: GSCAN is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    /* No request id from caller, so generate one and pass it on to the driver. */
+    /* Generate it randomly */
+    requestId = get_requestid();
+
+    if (results == NULL || num == NULL) {
+        ALOGE("%s: NULL pointer provided. Exit.",
+            __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    gScanCommand = new GScanCommand(
+                        wifiHandle,
+                        requestId,
+                        OUI_QCA,
+                        QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = gScanCommand->allocRspParams(eGScanGetCachedResultsRspParams);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to allocate memory for response struct. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = gScanCommand->allocCachedResultsTemp(max, results);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to allocate memory for temp gscan cached list. "
+            "Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Clear the destination cached results list before copying results. */
+    memset(results, 0, max * sizeof(wifi_cached_scan_results));
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (gScanCommand->put_u32(
+         QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            requestId) ||
+        gScanCommand->put_u8(
+         QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH,
+            flush) ||
+        gScanCommand->put_u32(
+         QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX,
+            max))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ALOGV("%s: flush:%d max:%d", __FUNCTION__, flush, max);
+    gScanCommand->attr_end(nlData);
+
+    retRequestRsp = gScanCommand->requestResponse();
+    if (retRequestRsp != 0) {
+        ALOGE("%s: requestResponse Error:%d",
+            __FUNCTION__, retRequestRsp);
+        /* It's possible to get ETIMEDOUT after receiving few results from
+         * driver. Copy and forward them to framework.
+         */
+        if (retRequestRsp != -ETIMEDOUT) {
+            /* Proceed to cleanup & return no results */
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+
+    /* No more data, copy the parsed results into the caller's results array */
+    ret = gScanCommand->copyCachedScanResults(num, results);
+    ALOGV("%s: max: %d, num:%d", __FUNCTION__, max, *num);
+
+    if (!ret) {
+        /* If requestResponse returned a TIMEOUT */
+        if (retRequestRsp == -ETIMEDOUT) {
+            if (*num > 0) {
+                /* Mark scan results as incomplete for the last scan_id */
+                results[(*num)-1].flags = WIFI_SCAN_FLAG_INTERRUPTED;
+                ALOGV("%s: Timeout happened. Mark scan results as incomplete "
+                    "for scan_id:%d", __FUNCTION__, results[(*num)-1].scan_id);
+                ret = WIFI_SUCCESS;
+            } else
+                ret = WIFI_ERROR_TIMED_OUT;
+        }
+    }
+cleanup:
+    gScanCommand->freeRspParams(eGScanGetCachedResultsRspParams);
+    delete gScanCommand;
+    return ret;
+}
+
+/* Random MAC OUI for PNO */
+wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
+{
+    wifi_error ret;
+    struct nlattr *nlData;
+    WifiVendorCommand *vCommand = NULL;
+    interface_info *iinfo = getIfaceInfo(handle);
+    wifi_handle wifiHandle = getWifiHandle(handle);
+
+    vCommand = new WifiVendorCommand(wifiHandle, 0,
+            OUI_QCA,
+            QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI);
+    if (vCommand == NULL) {
+        ALOGE("%s: Error vCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    /* create the message */
+    ret = vCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = vCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ALOGV("%s: MAC_OUI - %02x:%02x:%02x", __FUNCTION__,
+          scan_oui[0], scan_oui[1], scan_oui[2]);
+
+    /* Add the fixed part of the mac_oui to the nl command */
+    ret = vCommand->put_bytes(
+            QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI,
+            (char *)scan_oui,
+            WIFI_SCANNING_MAC_OUI_LENGTH);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    vCommand->attr_end(nlData);
+
+    ret = vCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete vCommand;
+    return ret;
+}
+
+
+GScanCommand::GScanCommand(wifi_handle handle, int id, u32 vendor_id,
+                                  u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    /* Initialize the member data variables here */
+    mGetCachedResultsRspParams = NULL;
+    mChannels = NULL;
+    mMaxChannels = 0;
+    mNumChannelsPtr = NULL;
+
+    mRequestId = id;
+    memset(&mHandler, 0,sizeof(mHandler));
+}
+
+GScanCommand::~GScanCommand()
+{
+    unregisterVendorHandler(mVendor_id, mSubcmd);
+}
+
+
+/* This function implements creation of Vendor command */
+wifi_error GScanCommand::create() {
+    wifi_error ret;
+
+    ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    /* Insert the oui in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    /* Insert the subcmd in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+     ALOGV("%s: mVendor_id = %d, Subcmd = %d.",
+        __FUNCTION__, mVendor_id, mSubcmd);
+
+    return ret;
+}
+
+wifi_error GScanCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+int GScanCommand::handleResponse(WifiEvent &reply)
+{
+    int i = 0;
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    u32 val;
+
+    WifiVendorCommand::handleResponse(reply);
+
+    struct nlattr *tbVendor[
+        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
+    nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
+                (struct nlattr *)mVendorData,mDataLen, NULL);
+
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS:
+        {
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]) {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS"
+                    " not found", __FUNCTION__);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                break;
+            }
+            val = nla_get_u32(tbVendor[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]);
+
+            val = val > (unsigned int)mMaxChannels ?
+                    (unsigned int)mMaxChannels : val;
+            *mNumChannelsPtr = val;
+
+            /* Extract the list of channels. */
+            if (*mNumChannelsPtr > 0 ) {
+                if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS]) {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS"
+                        " not found", __FUNCTION__);
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    break;
+                }
+                nla_memcpy(mChannels,
+                    tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS],
+                    sizeof(wifi_channel) * (*mNumChannelsPtr));
+            }
+            char buf[256];
+            size_t len = 0;
+            for (i = 0; i < *mNumChannelsPtr && len < sizeof(buf); i++) {
+                 len +=  snprintf(buf + len, sizeof(buf) - len, "%u ",
+                                  *(mChannels + i));
+            }
+            ALOGV("%s: Num Channels %d: List of valid channels are: %s",
+                  __FUNCTION__, *mNumChannelsPtr, buf);
+
+        }
+        break;
+        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS:
+        {
+            wifi_request_id id;
+            u32 numResults = 0;
+            int firstScanIdInPatch = -1;
+
+            if (!tbVendor[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
+                ALOGE("%s: GSCAN_RESULTS_REQUEST_ID not"
+                    "found", __FUNCTION__);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                break;
+            }
+            id = nla_get_u32(
+                    tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
+                    );
+            /* If this is not for us, just ignore it. */
+            if (id != mRequestId) {
+                ALOGV("%s: Event has Req. ID:%d <> ours:%d",
+                    __FUNCTION__, id, mRequestId);
+                break;
+            }
+            if (!tbVendor[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
+                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not"
+                    "found", __FUNCTION__);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                break;
+            }
+            /* Read num of cached scan results in this data chunk. Note that
+             * this value doesn't represent the number of unique gscan scan Ids
+             * since the first scan id in this new chunk could be similar to
+             * the last scan id in the previous chunk.
+             */
+            numResults = nla_get_u32(tbVendor[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
+            ALOGV("%s: num Cached results in this fragment:%d",
+                       __FUNCTION__, numResults);
+
+            if (!mGetCachedResultsRspParams) {
+                ALOGE("%s: mGetCachedResultsRspParams is NULL, exit.",
+                    __FUNCTION__);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                break;
+            }
+
+            /* To support fragmentation from firmware, monitor the
+             * MORE_DATA flag and cache results until MORE_DATA = 0.
+             */
+            if (!tbVendor[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
+                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA "
+                    "not found", __FUNCTION__);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                break;
+            } else {
+                mGetCachedResultsRspParams->more_data = nla_get_u8(
+                    tbVendor[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
+            }
+
+            /* No data in this chunk so skip this chunk */
+            if (numResults == 0) {
+                return NL_SKIP;
+            }
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID]) {
+                ALOGE("GSCAN_CACHED_RESULTS_SCAN_ID not found");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                break;
+            }
+
+            /* Get the first Scan-Id in this chuck of cached results. */
+            firstScanIdInPatch = nla_get_u32(tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID]);
+
+            ALOGV("More data: %d, firstScanIdInPatch: %d, lastProcessedScanId: %d",
+                mGetCachedResultsRspParams->more_data, firstScanIdInPatch,
+                mGetCachedResultsRspParams->lastProcessedScanId);
+
+            if (numResults) {
+                if (firstScanIdInPatch !=
+                    mGetCachedResultsRspParams->lastProcessedScanId) {
+                    /* New result scan Id block, update the starting index. */
+                    mGetCachedResultsRspParams->cachedResultsStartingIndex++;
+                }
+
+                ret = gscan_get_cached_results(
+                                    mGetCachedResultsRspParams->cached_results,
+                                    tbVendor);
+                /* If a parsing error occurred, exit and proceed for cleanup. */
+                if (ret)
+                    break;
+            }
+        }
+        break;
+        default:
+            /* Error case should not happen print log */
+            ALOGE("%s: Wrong GScan subcmd response received %d",
+                __FUNCTION__, mSubcmd);
+    }
+
+    /* A parsing error occurred, do the cleanup of gscan result lists. */
+    if (ret) {
+        switch(mSubcmd)
+        {
+            case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS:
+            {
+                ALOGE("%s: Parsing error, free CachedResultsRspParams",
+                    __FUNCTION__);
+                freeRspParams(eGScanGetCachedResultsRspParams);
+            }
+            break;
+            default:
+                ALOGE("%s: Wrong GScan subcmd received %d", __FUNCTION__, mSubcmd);
+        }
+    }
+    return NL_SKIP;
+}
+
+/* Called to parse and extract cached results. */
+wifi_error GScanCommand:: gscan_get_cached_results(
+                                      wifi_cached_scan_results *cached_results,
+                                      struct nlattr **tb_vendor)
+{
+    int j = 0;
+    struct nlattr *scanResultsInfo, *wifiScanResultsInfo;
+    int rem = 0, remResults = 0;
+    u32 len = 0, numScanResults = 0;
+    int i = mGetCachedResultsRspParams->cachedResultsStartingIndex;
+    ALOGV("%s: starting counter: %d", __FUNCTION__, i);
+
+    for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
+               QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST]),
+               rem = nla_len(tb_vendor[
+               QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST]);
+           nla_ok(scanResultsInfo, rem) && i < mGetCachedResultsRspParams->max;
+           scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
+       {
+           struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
+           nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
+           (struct nlattr *) nla_data(scanResultsInfo),
+                   nla_len(scanResultsInfo), NULL);
+
+           if (!
+               tb2[
+                   QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID
+                   ])
+           {
+               ALOGE("%s: GSCAN_CACHED_RESULTS_SCAN_ID"
+                   " not found", __FUNCTION__);
+               return WIFI_ERROR_INVALID_ARGS;
+           }
+           cached_results[i].scan_id =
+               nla_get_u32(
+               tb2[
+                   QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID
+                   ]);
+
+           if (!
+               tb2[
+                   QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS
+                   ])
+           {
+               ALOGE("%s: GSCAN_CACHED_RESULTS_FLAGS "
+                   "not found", __FUNCTION__);
+               return WIFI_ERROR_INVALID_ARGS;
+           }
+           cached_results[i].flags =
+               nla_get_u32(
+               tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS]);
+
+           if (!tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED])
+           {
+               ALOGI("%s: GSCAN_RESULTS_BUCKETS_SCANNED"
+                   "not found", __FUNCTION__);
+           } else {
+               cached_results[i].buckets_scanned = nla_get_u32(
+                       tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED]);
+           }
+
+           if (!
+               tb2[
+                   QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE
+                   ])
+           {
+               ALOGE("%s: RESULTS_NUM_RESULTS_AVAILABLE "
+                   "not found", __FUNCTION__);
+               return WIFI_ERROR_INVALID_ARGS;
+           }
+           numScanResults =
+               nla_get_u32(
+               tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
+
+           if (mGetCachedResultsRspParams->lastProcessedScanId !=
+                                        cached_results[i].scan_id) {
+               j = 0; /* reset wifi_scan_result counter */
+               cached_results[i].num_results = 0;
+               ALOGV("parsing: *lastProcessedScanId [%d] !="
+                     " cached_results[%d].scan_id:%d, j:%d "
+                     "numScanResults: %d",
+                     mGetCachedResultsRspParams->lastProcessedScanId, i,
+                     cached_results[i].scan_id, j, numScanResults);
+               mGetCachedResultsRspParams->lastProcessedScanId =
+                   cached_results[i].scan_id;
+               mGetCachedResultsRspParams->wifiScanResultsStartingIndex = 0;
+               /* Increment the number of cached scan results received */
+               mGetCachedResultsRspParams->num_cached_results++;
+           } else {
+               j = mGetCachedResultsRspParams->wifiScanResultsStartingIndex;
+               ALOGV("parsing: *lastProcessedScanId [%d] == "
+                     "cached_results[%d].scan_id:%d, j:%d "
+                     "numScanResults:%d",
+                     mGetCachedResultsRspParams->lastProcessedScanId, i,
+                     cached_results[i].scan_id, j, numScanResults);
+           }
+
+           ALOGV("%s: scan_id %d ", __FUNCTION__,
+            cached_results[i].scan_id);
+           ALOGV("%s: flags  %u ", __FUNCTION__,
+            cached_results[i].flags);
+
+           for (wifiScanResultsInfo = (struct nlattr *) nla_data(tb2[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
+                remResults = nla_len(tb2[
+                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
+                nla_ok(wifiScanResultsInfo, remResults);
+                wifiScanResultsInfo = nla_next(wifiScanResultsInfo, &(remResults)))
+           {
+                struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
+                nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
+                        (struct nlattr *) nla_data(wifiScanResultsInfo),
+                        nla_len(wifiScanResultsInfo), NULL);
+                if (j < MAX_AP_CACHE_PER_SCAN) {
+                    if (!
+                        tb3[
+                           QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
+                           ])
+                    {
+                        ALOGE("%s: "
+                            "RESULTS_SCAN_RESULT_TIME_STAMP not found",
+                            __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    cached_results[i].results[j].ts =
+                        nla_get_u64(
+                        tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
+                            ]);
+                    if (!
+                        tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
+                            ])
+                    {
+                        ALOGE("%s: "
+                            "RESULTS_SCAN_RESULT_SSID not found",
+                            __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    len = nla_len(tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
+                    len =
+                        sizeof(cached_results[i].results[j].ssid) <= len ?
+                        sizeof(cached_results[i].results[j].ssid) : len;
+                    memcpy((void *)&cached_results[i].results[j].ssid,
+                        nla_data(
+                        tb3[
+                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]),
+                        len);
+                    if (!
+                        tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
+                            ])
+                    {
+                        ALOGE("%s: "
+                            "RESULTS_SCAN_RESULT_BSSID not found",
+                            __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    len = nla_len(
+                        tb3[
+                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
+                    len =
+                        sizeof(cached_results[i].results[j].bssid) <= len ?
+                        sizeof(cached_results[i].results[j].bssid) : len;
+                    memcpy(&cached_results[i].results[j].bssid,
+                        nla_data(
+                        tb3[
+                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]),
+                        len);
+                    if (!
+                        tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
+                            ])
+                    {
+                        ALOGE("%s: "
+                            "RESULTS_SCAN_RESULT_CHANNEL not found",
+                            __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    cached_results[i].results[j].channel =
+                        nla_get_u32(
+                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
+                    if (!
+                        tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
+                            ])
+                    {
+                        ALOGE("%s: "
+                            "RESULTS_SCAN_RESULT_RSSI not found",
+                            __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    cached_results[i].results[j].rssi =
+                        get_s32(
+                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
+                    if (!
+                        tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
+                            ])
+                    {
+                        ALOGE("%s: "
+                            "RESULTS_SCAN_RESULT_RTT not found",
+                            __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    cached_results[i].results[j].rtt =
+                        nla_get_u32(
+                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
+                    if (!
+                        tb3[
+                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
+                        ])
+                    {
+                        ALOGE("%s: "
+                            "RESULTS_SCAN_RESULT_RTT_SD not found",
+                            __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    cached_results[i].results[j].rtt_sd =
+                        nla_get_u32(
+                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
+#ifdef QC_HAL_DEBUG
+                    /* Enable these prints for debugging if needed. */
+                    ALOGD("%s: ts  %" PRId64, __FUNCTION__,
+                        cached_results[i].results[j].ts);
+                    ALOGD("%s: SSID  %s ", __FUNCTION__,
+                        cached_results[i].results[j].ssid);
+                    ALOGD("%s: BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
+                        __FUNCTION__, cached_results[i].results[j].bssid[0],
+                        cached_results[i].results[j].bssid[1],
+                        cached_results[i].results[j].bssid[2],
+                        cached_results[i].results[j].bssid[3],
+                        cached_results[i].results[j].bssid[4],
+                        cached_results[i].results[j].bssid[5]);
+                    ALOGD("%s: channel %d ", __FUNCTION__,
+                        cached_results[i].results[j].channel);
+                    ALOGD("%s: rssi  %d ", __FUNCTION__,
+                        cached_results[i].results[j].rssi);
+                    ALOGD("%s: rtt  %" PRId64, __FUNCTION__,
+                        cached_results[i].results[j].rtt);
+                    ALOGD("%s: rtt_sd  %" PRId64, __FUNCTION__,
+                        cached_results[i].results[j].rtt_sd);
+#endif
+                    /* Increment loop index for next record */
+                    j++;
+                    /* For this scan id, update the wifiScanResultsStartingIndex
+                    * and number of cached results parsed so far.
+                    */
+                    mGetCachedResultsRspParams->wifiScanResultsStartingIndex = j;
+                    cached_results[i].num_results++;
+                } else {
+                    /* We already parsed and stored up to max wifi_scan_results
+                     * specified by the caller. Now, continue to loop over NL
+                     * entries in order to properly update NL parsing pointer
+                     * so it points to the next scan_id results.
+                     */
+                    ALOGD("%s: loop index:%d > max num"
+                        " of wifi_scan_results:%d for gscan cached results"
+                        " bucket:%d. Dummy loop", __FUNCTION__,
+                        j, MAX_AP_CACHE_PER_SCAN, i);
+                }
+           }
+           ALOGV("%s: cached_results[%d].num_results: %d ", __FUNCTION__,
+            i, cached_results[i].num_results);
+           /* Increment loop index for next cached scan result record */
+           i++;
+       }
+       /* Increment starting index of filling cached results received */
+       if (mGetCachedResultsRspParams->num_cached_results <= 1024)
+           mGetCachedResultsRspParams->cachedResultsStartingIndex =
+               mGetCachedResultsRspParams->num_cached_results - 1;
+    return WIFI_SUCCESS;
+}
+
+/* Set the GSCAN BSSID Hotlist. */
+wifi_error wifi_set_epno_list(wifi_request_id id,
+                                wifi_interface_handle iface,
+                                const wifi_epno_params *epno_params,
+                                wifi_epno_handler handler)
+{
+    int i, num_networks;
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData, *nlPnoParamList;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanSetPnoListCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanSetPnoListCmdEventHandler =
+        event_handlers->gScanSetPnoListCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
+        ALOGE("%s: Enhanced PNO is not supported by the driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO
+     * list was made earlier. If wifi_set_epno_list() is called while
+     * another one is running, the request will be sent down to driver and
+     * firmware. If the new request is successfully honored, then Wi-Fi HAL
+     * will use the new request id for the gScanSetPnoListCmdEventHandler
+     * object.
+     */
+
+    gScanCommand =
+        new GScanCommand(
+                    wifiHandle,
+                    id,
+                    OUI_QCA,
+                    QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    num_networks = (unsigned int)epno_params->num_networks > MAX_EPNO_NETWORKS ?
+                   MAX_EPNO_NETWORKS : epno_params->num_networks;
+    if (gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            id) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI,
+            epno_params->min5GHz_rssi) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI,
+            epno_params->min24GHz_rssi) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX,
+            epno_params->initial_score_max) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS,
+            epno_params->current_connection_bonus) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS,
+            epno_params->same_network_bonus) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS,
+            epno_params->secure_bonus) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS,
+            epno_params->band5GHz_bonus) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS,
+            num_networks))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add vendor atributes. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlPnoParamList =
+        gScanCommand->attr_start(
+                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST);
+    if (!nlPnoParamList) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add attr. PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST. "
+            "Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add nested NL attributes for ePno List. */
+    for (i = 0; i < num_networks; i++) {
+        wifi_epno_network pnoNetwork = epno_params->networks[i];
+        struct nlattr *nlPnoNetwork = gScanCommand->attr_start(i);
+        if (!nlPnoNetwork) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Failed attr_start for nlPnoNetwork. Error:%d",
+                __FUNCTION__, ret);
+            goto cleanup;
+        }
+        if (gScanCommand->put_string(
+                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID,
+                pnoNetwork.ssid) ||
+            gScanCommand->put_u8(
+                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS,
+                pnoNetwork.flags) ||
+            gScanCommand->put_u8(
+                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT,
+                pnoNetwork.auth_bit_field))
+        {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Failed to add PNO_SET_LIST_PARAM_EPNO_NETWORK_*. "
+                "Error:%d", __FUNCTION__, ret);
+            goto cleanup;
+        }
+        gScanCommand->attr_end(nlPnoNetwork);
+    }
+
+    gScanCommand->attr_end(nlPnoParamList);
+
+    gScanCommand->attr_end(nlData);
+
+    GScanCallbackHandler callbackHandler;
+    memset(&callbackHandler, 0, sizeof(callbackHandler));
+    callbackHandler.on_pno_network_found = handler.on_network_found;
+
+    /* Create an object of the event handler class to take care of the
+      * asychronous events on the north-bound.
+      */
+    if (gScanSetPnoListCmdEventHandler == NULL) {
+        gScanSetPnoListCmdEventHandler = new GScanCommandEventHandler(
+                            wifiHandle,
+                            id,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST,
+                            callbackHandler);
+        if (gScanSetPnoListCmdEventHandler == NULL) {
+            ALOGE("%s: Error instantiating "
+                "gScanSetPnoListCmdEventHandler.", __FUNCTION__);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        event_handlers->gScanSetPnoListCmdEventHandler =
+            gScanSetPnoListCmdEventHandler;
+    } else {
+        gScanSetPnoListCmdEventHandler->setCallbackHandler(callbackHandler);
+    }
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (gScanSetPnoListCmdEventHandler != NULL) {
+        gScanSetPnoListCmdEventHandler->set_request_id(id);
+        gScanSetPnoListCmdEventHandler->enableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    /* Disable Event Handling if ret != 0 */
+    if ((ret != WIFI_SUCCESS) && gScanSetPnoListCmdEventHandler) {
+        ALOGI("%s: Error ret:%d, disable event handling",
+            __FUNCTION__, ret);
+        gScanSetPnoListCmdEventHandler->disableEventHandling();
+    }
+    return ret;
+}
+
+/* Reset the ePNO list - no ePNO networks should be matched after this */
+wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
+        ALOGE("%s: Enhanced PNO is not supported by the driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    gScanCommand = new GScanCommand(wifiHandle,
+                                    id,
+                                    OUI_QCA,
+                                    QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            id) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS,
+            EPNO_NO_NETWORKS))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add vendor atributes Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    gScanCommand->attr_end(nlData);
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    delete gScanCommand;
+    return ret;
+}
+
+/* Set the ePNO Passpoint List. */
+wifi_error wifi_set_passpoint_list(wifi_request_id id,
+                                   wifi_interface_handle iface, int num,
+                                   wifi_passpoint_network *networks,
+                                   wifi_passpoint_event_handler handler)
+{
+    int i;
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData, *nlPasspointNetworksParamList;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanPnoSetPasspointListCmdEventHandler =
+        event_handlers->gScanPnoSetPasspointListCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
+        ALOGE("%s: Enhanced PNO is not supported by the driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO
+     * passpoint list was made earlier. If wifi_set_passpoint_list() is called
+     * while another one is running, the request will be sent down to driver and
+     * firmware. If the new request is successfully honored, then Wi-Fi HAL
+     * will use the new request id for the
+     * gScanPnoSetPasspointListCmdEventHandler object.
+     */
+    gScanCommand =
+        new GScanCommand(
+                    wifiHandle,
+                    id,
+                    OUI_QCA,
+                    QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST);
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
+            id) ||
+        gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM,
+            num))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add vendor atributes. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlPasspointNetworksParamList =
+        gScanCommand->attr_start(
+            QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY);
+    if (!nlPasspointNetworksParamList) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed attr_start for PASSPOINT_LIST_PARAM_NETWORK_ARRAY. "
+            "Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add nested NL attributes for Passpoint List param. */
+    for (i = 0; i < num; i++) {
+        wifi_passpoint_network passpointNetwork = networks[i];
+        struct nlattr *nlPasspointNetworkParam = gScanCommand->attr_start(i);
+        if (!nlPasspointNetworkParam) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Failed attr_start for nlPasspointNetworkParam. "
+                "Error:%d", __FUNCTION__, ret);
+            goto cleanup;
+        }
+        if (gScanCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID,
+                passpointNetwork.id) ||
+            gScanCommand->put_string(
+                QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM,
+                passpointNetwork.realm) ||
+            gScanCommand->put_bytes(
+         QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID,
+                (char*)passpointNetwork.roamingConsortiumIds,
+                16 * sizeof(int64_t)) ||
+            gScanCommand->put_bytes(
+            QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN,
+                (char*)passpointNetwork.plmn, 3 * sizeof(u8)))
+        {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Failed to add PNO_PASSPOINT_NETWORK_PARAM_ROAM_* attr. "
+                "Error:%d", __FUNCTION__, ret);
+            goto cleanup;
+        }
+        gScanCommand->attr_end(nlPasspointNetworkParam);
+    }
+
+    gScanCommand->attr_end(nlPasspointNetworksParamList);
+
+    gScanCommand->attr_end(nlData);
+
+    GScanCallbackHandler callbackHandler;
+    memset(&callbackHandler, 0, sizeof(callbackHandler));
+    callbackHandler.on_passpoint_network_found =
+                        handler.on_passpoint_network_found;
+
+    /* Create an object of the event handler class to take care of the
+      * asychronous events on the north-bound.
+      */
+    if (gScanPnoSetPasspointListCmdEventHandler == NULL) {
+        gScanPnoSetPasspointListCmdEventHandler = new GScanCommandEventHandler(
+                        wifiHandle,
+                        id,
+                        OUI_QCA,
+                        QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST,
+                        callbackHandler);
+        if (gScanPnoSetPasspointListCmdEventHandler == NULL) {
+            ALOGE("%s: Error instantiating "
+                "gScanPnoSetPasspointListCmdEventHandler.", __FUNCTION__);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        event_handlers->gScanPnoSetPasspointListCmdEventHandler =
+            gScanPnoSetPasspointListCmdEventHandler;
+    } else {
+        gScanPnoSetPasspointListCmdEventHandler->setCallbackHandler(callbackHandler);
+    }
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (gScanPnoSetPasspointListCmdEventHandler != NULL) {
+        gScanPnoSetPasspointListCmdEventHandler->set_request_id(id);
+        gScanPnoSetPasspointListCmdEventHandler->enableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    /* Disable Event Handling if ret != 0 */
+    if ((ret != WIFI_SUCCESS) && gScanPnoSetPasspointListCmdEventHandler) {
+        ALOGI("%s: Error ret:%d, disable event handling",
+            __FUNCTION__, ret);
+        gScanPnoSetPasspointListCmdEventHandler->disableEventHandling();
+    }
+    return ret;
+}
+
+wifi_error wifi_reset_passpoint_list(wifi_request_id id,
+                            wifi_interface_handle iface)
+{
+    wifi_error ret;
+    GScanCommand *gScanCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    gscan_event_handlers* event_handlers;
+    GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler;
+
+    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
+    gScanPnoSetPasspointListCmdEventHandler =
+        event_handlers->gScanPnoSetPasspointListCmdEventHandler;
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
+        ALOGE("%s: Enhanced PNO is not supported by the driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if (gScanPnoSetPasspointListCmdEventHandler == NULL ||
+        (gScanPnoSetPasspointListCmdEventHandler->isEventHandlingEnabled() ==
+         false)) {
+        ALOGE("wifi_reset_passpoint_list: ePNO passpoint_list isn't set. "
+            "Nothing to do. Exit.");
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    gScanCommand = new GScanCommand(
+                    wifiHandle,
+                    id,
+                    OUI_QCA,
+                    QCA_NL80211_VENDOR_SUBCMD_PNO_RESET_PASSPOINT_LIST);
+
+    if (gScanCommand == NULL) {
+        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = gScanCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = gScanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = gScanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id);
+    if (ret != WIFI_SUCCESS) {
+        ret = WIFI_ERROR_OUT_OF_MEMORY;
+        ALOGE("%s: Failed to add vendor data attributes. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    gScanCommand->attr_end(nlData);
+
+    ret = gScanCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+    /* Disable Event Handling. */
+    if (gScanPnoSetPasspointListCmdEventHandler) {
+        gScanPnoSetPasspointListCmdEventHandler->disableEventHandling();
+    }
+
+cleanup:
+    delete gScanCommand;
+    return ret;
+}
+
+wifi_error GScanCommand::allocCachedResultsTemp(int max,
+                                     wifi_cached_scan_results *cached_results)
+{
+    /* Alloc memory for "max" number of cached results. */
+    mGetCachedResultsRspParams->cached_results =
+        (wifi_cached_scan_results*)
+        malloc(max * sizeof(wifi_cached_scan_results));
+    if (!mGetCachedResultsRspParams->cached_results) {
+        ALOGE("%s: Failed to allocate memory for "
+              "mGetCachedResultsRspParams->cached_results.",
+              __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    memset(mGetCachedResultsRspParams->cached_results, 0,
+           max * sizeof(wifi_cached_scan_results));
+
+    mGetCachedResultsRspParams->max = max;
+
+    return WIFI_SUCCESS;
+}
+
+/*
+ * Allocates memory for the subCmd response struct and initializes status = -1
+ */
+wifi_error GScanCommand::allocRspParams(eGScanRspRarams cmd)
+{
+    switch(cmd)
+    {
+        case eGScanGetCachedResultsRspParams:
+            mGetCachedResultsRspParams = (GScanGetCachedResultsRspParams *)
+                malloc(sizeof(GScanGetCachedResultsRspParams));
+            if (!mGetCachedResultsRspParams)
+                return WIFI_ERROR_OUT_OF_MEMORY;
+
+            mGetCachedResultsRspParams->num_cached_results = 0;
+            mGetCachedResultsRspParams->more_data = false;
+            mGetCachedResultsRspParams->cachedResultsStartingIndex = -1;
+            mGetCachedResultsRspParams->lastProcessedScanId = -1;
+            mGetCachedResultsRspParams->wifiScanResultsStartingIndex = -1;
+            mGetCachedResultsRspParams->max = 0;
+            mGetCachedResultsRspParams->cached_results = NULL;
+        break;
+        default:
+            ALOGD("%s: Wrong request for alloc.", __FUNCTION__);
+            return WIFI_ERROR_NOT_SUPPORTED;
+    }
+    return WIFI_SUCCESS;
+}
+
+void GScanCommand::freeRspParams(eGScanRspRarams cmd)
+{
+    switch(cmd)
+    {
+        case eGScanGetCachedResultsRspParams:
+            if (mGetCachedResultsRspParams) {
+                if (mGetCachedResultsRspParams->cached_results) {
+                    free(mGetCachedResultsRspParams->cached_results);
+                    mGetCachedResultsRspParams->cached_results = NULL;
+                }
+                free(mGetCachedResultsRspParams);
+                mGetCachedResultsRspParams = NULL;
+            }
+        break;
+        default:
+            ALOGD("%s: Wrong request for free.", __FUNCTION__);
+    }
+}
+
+wifi_error GScanCommand::copyCachedScanResults(
+                                      int *numResults,
+                                      wifi_cached_scan_results *cached_results)
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    int i;
+    wifi_cached_scan_results *cachedResultRsp;
+
+    if (mGetCachedResultsRspParams && cached_results)
+    {
+        /* Populate the number of parsed cached results. */
+        *numResults = mGetCachedResultsRspParams->num_cached_results;
+
+        for (i = 0; i < *numResults; i++) {
+            cachedResultRsp = &mGetCachedResultsRspParams->cached_results[i];
+            cached_results[i].scan_id = cachedResultRsp->scan_id;
+            cached_results[i].flags = cachedResultRsp->flags;
+            cached_results[i].num_results = cachedResultRsp->num_results;
+            cached_results[i].buckets_scanned = cachedResultRsp->buckets_scanned;
+
+            if (!cached_results[i].num_results) {
+                ALOGI("Error: cached_results[%d].num_results=0", i);
+                continue;
+            }
+
+            ALOGV("copyCachedScanResults: "
+                "cached_results[%d].num_results : %d",
+                i, cached_results[i].num_results);
+
+            memcpy(cached_results[i].results,
+                cachedResultRsp->results,
+                cached_results[i].num_results * sizeof(wifi_scan_result));
+            ret = WIFI_SUCCESS;
+        }
+    } else {
+        ALOGE("%s: mGetCachedResultsRspParams is NULL", __FUNCTION__);
+        *numResults = 0;
+        ret = WIFI_ERROR_INVALID_ARGS;
+    }
+    return ret;
+}
+
+void GScanCommand::setMaxChannels(int max_channels) {
+    mMaxChannels = max_channels;
+}
+
+void GScanCommand::setChannels(int *channels) {
+    mChannels = channels;
+}
+
+void GScanCommand::setNumChannelsPtr(int *num_channels) {
+    mNumChannelsPtr = num_channels;
+}
diff --git a/qcwcn/wifi_hal/gscan_event_handler.cpp b/wcn6740/qcwcn/wifi_hal/gscan_event_handler.cpp
similarity index 100%
copy from qcwcn/wifi_hal/gscan_event_handler.cpp
copy to wcn6740/qcwcn/wifi_hal/gscan_event_handler.cpp
diff --git a/qcwcn/wifi_hal/gscan_event_handler.h b/wcn6740/qcwcn/wifi_hal/gscan_event_handler.h
similarity index 100%
copy from qcwcn/wifi_hal/gscan_event_handler.h
copy to wcn6740/qcwcn/wifi_hal/gscan_event_handler.h
diff --git a/wcn6740/qcwcn/wifi_hal/gscancommand.h b/wcn6740/qcwcn/wifi_hal/gscancommand.h
new file mode 100644
index 0000000..6fbc90b
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/gscancommand.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_GSCAN_COMMAND_H__
+#define __WIFI_HAL_GSCAN_COMMAND_H__
+
+#include "common.h"
+#include "cpp_bindings.h"
+#ifdef __GNUC__
+#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
+#define STRUCT_PACKED __attribute__ ((packed))
+#else
+#define PRINTF_FORMAT(a,b)
+#define STRUCT_PACKED
+#endif
+#include "gscan.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+typedef struct{
+    u32 status;
+    u32 num_channels;
+    wifi_channel channels[];
+} GScanGetValidChannelsRspParams;
+
+typedef struct{
+    wifi_gscan_capabilities capabilities;
+} GScanGetCapabilitiesRspParams;
+
+typedef struct{
+    u8  more_data;
+    u32 num_cached_results;
+    int cachedResultsStartingIndex; /* Used in filling cached scan results */
+    int lastProcessedScanId; /* Last scan id in gscan cached results block */
+    int wifiScanResultsStartingIndex; /* For the lastProcessedScanId */
+    int max;                /* max num of cached results specified by caller */
+    wifi_cached_scan_results *cached_results;
+} GScanGetCachedResultsRspParams;
+
+typedef struct {
+    int max_channels;
+    wifi_channel *channels;
+    int *number_channels;
+} GScan_get_valid_channels_cb_data;
+
+typedef enum{
+    eGScanRspParamsInvalid = 0,
+    eGScanGetValidChannelsRspParams,
+    eGScanGetCapabilitiesRspParams,
+    eGScanGetCachedResultsRspParams,
+} eGScanRspRarams;
+
+/* Response and Event Callbacks */
+typedef struct {
+    /* Various Events Callback */
+    void (*on_hotlist_ap_found)(wifi_request_id id,
+        unsigned num_results, wifi_scan_result *results);
+    void (*on_hotlist_ap_lost)(wifi_request_id id,
+        unsigned num_results, wifi_scan_result *results);
+    void (*on_significant_change)(wifi_request_id id,
+                unsigned num_results,
+                wifi_significant_change_result **results);
+    /* Reported when each probe response is received, if report_events
+     * enabled in wifi_scan_cmd_params
+     */
+    void (*on_full_scan_result) (wifi_request_id id, wifi_scan_result *result,
+                                                   unsigned buckets_scanned);
+    /* Optional event - indicates progress of scanning statemachine */
+    void (*on_scan_event) (wifi_request_id id, wifi_scan_event event);
+    void (*on_hotlist_ssid_found)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+    void (*on_hotlist_ssid_lost)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+    void (*on_pno_network_found)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+    void (*on_passpoint_network_found)(wifi_request_id id,
+                                       int net_id,
+                                       wifi_scan_result *result,
+                                       int anqp_len,
+                                       byte *anqp
+                                       );
+} GScanCallbackHandler;
+
+class GScanCommand: public WifiVendorCommand
+{
+private:
+    GScanGetCachedResultsRspParams      *mGetCachedResultsRspParams;
+    GScanCallbackHandler                mHandler;
+    int                                 mRequestId;
+    int                                 *mChannels;
+    int                                 mMaxChannels;
+    int                                 *mNumChannelsPtr;
+
+public:
+    GScanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+    virtual ~GScanCommand();
+
+    /* This function implements creation of GSCAN specific Request
+     * based on  the request type.
+     */
+    virtual wifi_error create();
+    virtual wifi_error requestResponse();
+    virtual int handleResponse(WifiEvent &reply);
+    virtual void setMaxChannels(int max_channels);
+    virtual void setChannels(int *channels);
+    virtual void setNumChannelsPtr(int *num_channels);
+    virtual wifi_error allocRspParams(eGScanRspRarams cmd);
+    virtual void freeRspParams(eGScanRspRarams cmd);
+    virtual wifi_error copyCachedScanResults(int *numResults,
+                                             wifi_cached_scan_results *cached_results);
+    virtual wifi_error gscan_get_cached_results(wifi_cached_scan_results *results,
+                                         struct nlattr **tb_vendor);
+    wifi_error validateGscanConfig(wifi_scan_cmd_params params);
+    wifi_error validateSignificantChangeParams(
+            wifi_significant_change_params params);
+    virtual wifi_error allocCachedResultsTemp(int max,
+                                       wifi_cached_scan_results *results);
+};
+
+#define GSCAN_BASE_PERIOD_MIN 1
+#define GSCAN_MAX_AP_PER_SCAN_MIN 1
+#define GSCAN_REPORT_THRESHOLD_MIN 1
+#define GSCAN_NUM_BUCKETS_MIN 1
+#define GSCAN_BUCKET_INDEX_MIN 0
+#define GSCAN_REPORT_EVENT0 0
+#define GSCAN_REPORT_EVENT1 1
+#define GSCAN_REPORT_EVENT2 2
+#define GSCAN_MIN_CHANNELS 0
+#define GSCAN_ACTIVE_SCAN 0
+#define GSCAN_PASSIVE_SCAN 1
+
+#define BSSID_HOTLIST_NUM_AP_MIN 1
+
+#define RSSI_SAMPLE_SIZE_MIN 1
+#define LOSTAP_SAMPLE_SIZE_MIN 1
+#define MIN_BREACHING_MIN 1
+#define SIGNIFICANT_CHANGE_NUM_AP_MIN 1
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.cpp b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.cpp
similarity index 70%
copy from qcwcn/wifi_hal/ifaceeventhandler.cpp
copy to wcn6740/qcwcn/wifi_hal/ifaceeventhandler.cpp
index 6e70ab5..0c44e25 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.cpp
+++ b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.cpp
@@ -33,6 +33,7 @@
 #include <errno.h>
 
 #include "ifaceeventhandler.h"
+#include "common.h"
 
 /* Used to handle NL command events from driver/firmware. */
 IfaceEventHandlerCommand *mwifiEventHandler = NULL;
@@ -205,7 +206,10 @@
     mCapa = &(info->capa);
     mfilter_packet_read_buffer = NULL;
     mfilter_packet_length = 0;
+    res_size = 0;
+    channel_buff = NULL;
     memset(&mDriverFeatures, 0, sizeof(mDriverFeatures));
+    memset(&mRadarResultParams, 0, sizeof(RadarHistoryResultsParams));
 }
 
 WifihalGeneric::~WifihalGeneric()
@@ -222,6 +226,119 @@
     return WifiCommand::requestResponse(mMsg);
 }
 
+static u32 get_wifi_iftype_masks(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & BIT(NL80211_IFTYPE_STATION)) {
+        op_mask |= BIT(WIFI_INTERFACE_STA);
+        op_mask |= BIT(WIFI_INTERFACE_TDLS);
+    }
+    if (in_mask & BIT(NL80211_IFTYPE_AP))
+        op_mask |= BIT(WIFI_INTERFACE_SOFTAP);
+    if (in_mask & BIT(NL80211_IFTYPE_P2P_CLIENT))
+        op_mask |= BIT(WIFI_INTERFACE_P2P_CLIENT);
+    if (in_mask & BIT(NL80211_IFTYPE_P2P_GO))
+        op_mask |= BIT(WIFI_INTERFACE_P2P_GO);
+    if (in_mask & BIT(NL80211_IFTYPE_NAN))
+        op_mask |= BIT(WIFI_INTERFACE_NAN);
+
+    return op_mask;
+}
+
+static wifi_channel_width get_channel_width(u32 nl_width)
+{
+    switch(nl_width) {
+    case NL80211_CHAN_WIDTH_20:
+         return WIFI_CHAN_WIDTH_20;
+    case NL80211_CHAN_WIDTH_40:
+         return WIFI_CHAN_WIDTH_40;
+    case NL80211_CHAN_WIDTH_80:
+         return WIFI_CHAN_WIDTH_80;
+    case NL80211_CHAN_WIDTH_160:
+         return WIFI_CHAN_WIDTH_160;
+    case NL80211_CHAN_WIDTH_80P80:
+         return WIFI_CHAN_WIDTH_80P80;
+    case NL80211_CHAN_WIDTH_5:
+         return WIFI_CHAN_WIDTH_5;
+    case NL80211_CHAN_WIDTH_10:
+         return WIFI_CHAN_WIDTH_10;
+    default:
+         return WIFI_CHAN_WIDTH_INVALID;
+    }
+}
+
+int WifihalGeneric::handle_response_usable_channels(struct nlattr *VendorData,
+                                                    u32 mDataLen)
+{
+    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1];
+    struct nlattr *curr_attr;
+    wifi_usable_channel *chan_info = NULL;
+    int rem;
+    u32 currSize = 0;
+
+    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX,
+                  (struct nlattr *)mVendorData, mDataLen, NULL)) {
+         ALOGE("Failed to parse NL channels list");
+         return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO]) {
+         ALOGE("%s: USABLE_CHANNELS_CHAN_INFO not found", __FUNCTION__);
+         return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    for_each_nested_attribute(curr_attr,
+                     tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO], rem) {
+         struct nlattr *ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX + 1];
+
+         if (currSize >= mSetSizeMax) {
+              ALOGE("Got max channels %d completed", mSetSizeMax);
+              break;
+         }
+
+         if (nla_parse_nested(ch_info, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX,
+                              curr_attr, NULL)) {
+              ALOGE("Failed to get usable channel info");
+              return NL_SKIP;
+         }
+
+         chan_info = &channel_buff[currSize];
+         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]) {
+              ALOGE("%s: CHAN_INFO_PRIMARY_FREQ not found",
+                    __FUNCTION__);
+              return NL_SKIP;
+         }
+
+         chan_info->freq = nla_get_u32(ch_info[
+                                  QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]);
+         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]) {
+              ALOGE("%s: CHAN_INFO_BANDWIDTH not found",
+                    __FUNCTION__);
+              return NL_SKIP;
+         }
+
+         chan_info->width = get_channel_width(nla_get_u32(
+                            ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]));
+         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]) {
+              ALOGE("%s: CHAN_INFO_IFACE_MODE_MASK not found",
+                    __FUNCTION__);
+              return NL_SKIP;
+         }
+
+         chan_info->iface_mode_mask = get_wifi_iftype_masks(nla_get_u32(
+                      ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]));
+         ALOGV("Primary freq %d BW %d iface mask %d", chan_info->freq,
+               chan_info->width, chan_info->iface_mode_mask);
+         currSize++;
+    }
+
+    res_size = currSize;
+    ALOGV("%s: Result size %d", __FUNCTION__, res_size);
+
+    return NL_SKIP;
+}
+
 int WifihalGeneric::handleResponse(WifiEvent &reply)
 {
     ALOGV("Got a Wi-Fi HAL module message from Driver");
@@ -244,7 +361,7 @@
                     return -EINVAL;
                 }
                 mSet = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]);
-                ALOGV("Supported feature set : 0x%" PRIx64, mSet);
+                ALOGV("Supported feature set : %" PRIx64, mSet);
 
                 break;
             }
@@ -304,7 +421,7 @@
                         __func__);
                     for(i = 0; i < *mSetSizePtr; i++)
                     {
-                        ALOGV("0x%" PRIx64, *(mConcurrencySet + i));
+                        ALOGV("%" PRIx64, *(mConcurrencySet + i));
                     }
                 }
             }
@@ -436,6 +553,29 @@
                 }
             }
             break;
+        case QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS:
+            return handle_response_usable_channels((struct nlattr *)mVendorData,
+                                                   mDataLen);
+        case QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY:
+            {
+                wifiParseRadarHistory();
+            }
+            break;
+        case QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY:
+            {
+                struct nlattr *tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX + 1];
+                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX,
+                          (struct nlattr *)mVendorData,mDataLen, NULL);
+
+                if (tb_vendor[QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION])
+                {
+                    mInfo->sar_version = (qca_wlan_vendor_sar_version) nla_get_u32(tb_vendor[
+                                               QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION]);
+                }
+                ALOGV("%s: sar_version return %d", __func__, mInfo->sar_version);
+            }
+            break;
         default :
             ALOGE("%s: Wrong Wi-Fi HAL event received %d", __func__, mSubcmd);
     }
@@ -550,8 +690,8 @@
     }
 
     if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID]) {
-        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID not found. Set to 0.",
-              __FUNCTION__);
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
+            "_NUM_BLACKLIST_BSSID not found. Set to 0.", __FUNCTION__);
         mCapa->roaming_capa.max_blacklist_size = 0;
     } else {
         mCapa->roaming_capa.max_blacklist_size = nla_get_u32(tbVendor[
@@ -560,6 +700,96 @@
     return WIFI_SUCCESS;
 }
 
+wifi_error WifihalGeneric::wifiParseRadarHistory() {
+{
+    // tbVendor
+    struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1];
+    int rem = 0, num_dfs_entries = 0;
+
+    if (nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX,
+          (struct nlattr *)mVendorData,mDataLen, NULL)) {
+        ALOGE("%s: nla_parse fail", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES]) {
+        ALOGE("%s: radar attr entries not present", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    // nested radar history
+    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1];
+    struct nlattr *attr;
+    static struct nla_policy
+      policy[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1] = {
+            [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ] = { .type = NLA_U32 },
+            [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP] = { .type = NLA_U64 },
+            [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED] = { .type = NLA_FLAG },
+    };
+    radar_history_result *newEntry;
+    radar_history_result *temp;
+    u32 totalEntrySize = 0;
+    u32 newEntrySize = sizeof(radar_history_result);
+
+    nla_for_each_nested(attr,
+            tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES],
+            rem) {
+        if ((num_dfs_entries ++) > MAX_NUM_RADAR_HISTORY) {
+            ALOGE("%s: exceeded max entries, drop others", __FUNCTION__);
+            break;
+        }
+        if (nla_parse_nested(tb, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX,
+                attr, policy)) {
+            ALOGI("%s: nla_parse_nested fail", __FUNCTION__);
+            continue;
+        }
+        if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]) {
+            ALOGI("%s: radar attr freq not present", __FUNCTION__);
+            continue;
+        }
+        if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]) {
+            ALOGI("%s: radar attr timestamp not present", __FUNCTION__);
+            continue;
+        }
+
+        // realloc buffer for new entry
+        temp = (radar_history_result *) realloc(
+                mRadarResultParams.entries, totalEntrySize + newEntrySize);
+        if (temp == NULL) {
+            ALOGE("%s: failed to realloc memory", __FUNCTION__);
+            free(mRadarResultParams.entries);
+            mRadarResultParams.entries = NULL;
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+        mRadarResultParams.entries = temp;
+
+        newEntry = (radar_history_result *)(
+                (u8 *) mRadarResultParams.entries + totalEntrySize);
+        memset(newEntry, 0, newEntrySize);
+        totalEntrySize += newEntrySize;
+
+        // save to current radar entry
+        newEntry->freq = nla_get_u32(
+                tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]);
+        newEntry->clock_boottime = nla_get_u64(
+                tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]);
+        newEntry->radar_detected = false;
+        if (tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]) {
+             newEntry->radar_detected = nla_get_flag(
+                     tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]);
+        }
+        mRadarResultParams.num_entries ++;
+
+        ALOGI("Radar history: freq:%d boottime: %" PRId64 " detected:%d",
+                newEntry->freq,
+                newEntry->clock_boottime,
+                newEntry->radar_detected);
+        }
+    }
+
+    return WIFI_SUCCESS;
+}
+
+
 void WifihalGeneric::getResponseparams(feature_set *pset)
 {
     *pset = mSet;
@@ -612,6 +842,17 @@
     return firmware_bus_max_size;
 }
 
+void WifihalGeneric::set_channels_buff(wifi_usable_channel* channels)
+{
+    channel_buff = channels;
+    memset(channel_buff, 0, sizeof(wifi_usable_channel) * mSetSizeMax);
+}
+
+u32 WifihalGeneric::get_results_size(void)
+{
+    return res_size;
+}
+
 wifi_error WifihalGeneric::wifiGetCapabilities(wifi_interface_handle handle)
 {
     wifi_error ret;
@@ -651,3 +892,67 @@
 
     return ret;
 }
+
+wifi_error WifihalGeneric::copyCachedRadarHistory(
+        radar_history_result *resultBuf, int resultBufSize, int *numResults) {
+    *numResults = 0;
+
+    if (mRadarResultParams.entries) {
+        radar_history_result *sEntry = NULL;
+        radar_history_result *tEntry = NULL;
+        u32 offset = 0;
+        int i;
+
+        for (i = 0; i < mRadarResultParams.num_entries; i ++) {
+            if (resultBufSize < (offset + sizeof(radar_history_result))) {
+                break;
+            }
+
+            sEntry = (radar_history_result *)(
+                           (u8 *) mRadarResultParams.entries + offset);
+            tEntry = (radar_history_result *)(
+                           (u8 *) resultBuf + offset);
+            memcpy(tEntry, sEntry, sizeof(radar_history_result));
+            (*numResults) += 1;
+            offset += sizeof(radar_history_result);
+        }
+    }
+
+    return WIFI_SUCCESS;
+}
+
+void WifihalGeneric::freeCachedRadarHistory() {
+    if (mRadarResultParams.entries) {
+        free(mRadarResultParams.entries);
+        mRadarResultParams.entries = NULL;
+        mRadarResultParams.num_entries = 0;
+    }
+}
+
+wifi_error WifihalGeneric::getSarVersion(wifi_interface_handle handle)
+{
+    wifi_error ret;
+    interface_info *ifaceInfo = getIfaceInfo(handle);
+
+
+    /* Create the NL message. */
+    ret = create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to create NL message,  Error:%d", __FUNCTION__, ret);
+        return ret;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to set interface Id of message, Error:%d", __FUNCTION__, ret);
+        return ret;
+    }
+
+    ret = requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
+
+    return ret;
+}
+
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.h b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.h
similarity index 78%
copy from qcwcn/wifi_hal/ifaceeventhandler.h
copy to wcn6740/qcwcn/wifi_hal/ifaceeventhandler.h
index c993a7e..eef9624 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.h
+++ b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.h
@@ -46,6 +46,10 @@
 {
 #endif /* __cplusplus */
 
+typedef struct{
+    int num_entries;
+    radar_history_result *entries;
+} RadarHistoryResultsParams;
 
 class wifiEventHandler: public WifiCommand
 {
@@ -94,13 +98,19 @@
     /* Packet Filter buffer and length */
     u8 *mfilter_packet_read_buffer;
     int mfilter_packet_length;
+    u32 res_size;
+    wifi_usable_channel *channel_buff;
+    RadarHistoryResultsParams mRadarResultParams;
     virtual wifi_error wifiParseCapabilities(struct nlattr **tbVendor);
+    virtual wifi_error wifiParseRadarHistory();
 
 public:
     WifihalGeneric(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
     virtual ~WifihalGeneric();
     virtual wifi_error requestResponse();
     virtual int handleResponse(WifiEvent &reply);
+    virtual int handle_response_usable_channels(struct nlattr *VendorData,
+                                                u32 mDataLen);
     virtual void getResponseparams(feature_set *pset);
     virtual void getDriverFeatures(features_info *pfeatures);
     virtual void setMaxSetSize(int set_size_max);
@@ -111,7 +121,23 @@
     virtual int getFilterLength();
     virtual int getBusSize();
     virtual wifi_error wifiGetCapabilities(wifi_interface_handle handle);
+    virtual void set_channels_buff(wifi_usable_channel *channels);
+    virtual u32 get_results_size(void);
+    virtual wifi_error copyCachedRadarHistory(radar_history_result *resultBuf,
+            int resultBufSize, int *numResults);
+    virtual void freeCachedRadarHistory();
+    virtual wifi_error getSarVersion(wifi_interface_handle handle);
 };
+
+/**
+ * nla_for_each_nested from libnl is throwing implicit conversion from void*
+ * error. Adding a local definition to avoid it.
+ */
+#define for_each_nested_attribute(pos, nla, rem) \
+    for (pos = (struct nlattr *)nla_data(nla), rem = nla_len(nla); \
+         nla_ok(pos, rem); \
+         pos = nla_next(pos, &(rem)))
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/qcwcn/wifi_hal/list.cpp b/wcn6740/qcwcn/wifi_hal/list.cpp
similarity index 100%
copy from qcwcn/wifi_hal/list.cpp
copy to wcn6740/qcwcn/wifi_hal/list.cpp
diff --git a/qcwcn/wifi_hal/list.h b/wcn6740/qcwcn/wifi_hal/list.h
similarity index 100%
copy from qcwcn/wifi_hal/list.h
copy to wcn6740/qcwcn/wifi_hal/list.h
diff --git a/wcn6740/qcwcn/wifi_hal/llstats.cpp b/wcn6740/qcwcn/wifi_hal/llstats.cpp
new file mode 100644
index 0000000..3bed31c
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/llstats.cpp
@@ -0,0 +1,1484 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "llstatscommand.h"
+
+//Singleton Static Instance
+LLStatsCommand* LLStatsCommand::mLLStatsCommandInstance  = NULL;
+
+// This function implements creation of Vendor command
+// For LLStats just call base Vendor command create
+wifi_error LLStatsCommand::create() {
+    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    // insert the oui in the msg
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    // insert the subcmd in the msg
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+
+    return ret;
+}
+
+LLStatsCommand::LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    memset(&mClearRspParams, 0,sizeof(LLStatsClearRspParams));
+    memset(&mResultsParams, 0,sizeof(LLStatsResultsParams));
+    memset(&mHandler, 0,sizeof(mHandler));
+    mRadioStatsSize = 0;
+    mNumRadios = 0;
+    mNumRadiosAllocated = 0;
+}
+
+LLStatsCommand::~LLStatsCommand()
+{
+    mLLStatsCommandInstance = NULL;
+}
+
+LLStatsCommand* LLStatsCommand::instance(wifi_handle handle)
+{
+    if (handle == NULL) {
+        ALOGE("Interface Handle is invalid");
+        return NULL;
+    }
+    if (mLLStatsCommandInstance == NULL) {
+        mLLStatsCommandInstance = new LLStatsCommand(handle, 0,
+                OUI_QCA,
+                QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET);
+        return mLLStatsCommandInstance;
+    }
+    else
+    {
+        if (handle != getWifiHandle(mLLStatsCommandInstance->mInfo))
+        {
+            /* upper layer must have cleaned up the handle and reinitialized,
+               so we need to update the same */
+            ALOGE("Handle different, update the handle");
+            mLLStatsCommandInstance->mInfo = (hal_info *)handle;
+        }
+    }
+    return mLLStatsCommandInstance;
+}
+
+void LLStatsCommand::initGetContext(u32 reqId)
+{
+    mRequestId = reqId;
+    memset(&mHandler, 0,sizeof(mHandler));
+}
+
+void LLStatsCommand::setSubCmd(u32 subcmd)
+{
+    mSubcmd = subcmd;
+}
+
+void LLStatsCommand::setHandler(wifi_stats_result_handler handler)
+{
+    mHandler = handler;
+}
+
+static wifi_error get_wifi_interface_info(wifi_interface_link_layer_info *stats,
+                                          struct nlattr **tb_vendor)
+{
+    u32 len = 0;
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->mode = (wifi_interface_mode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE]);
+
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR]);
+    len = ((sizeof(stats->mac_addr) <= len) ? sizeof(stats->mac_addr) : len);
+    memcpy(&stats->mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR]), len);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->state = (wifi_connection_state)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->roaming = (wifi_roam_state)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->capabilities = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID]);
+    len = ((sizeof(stats->ssid) <= len) ? sizeof(stats->ssid) : len);
+    memcpy(&stats->ssid[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID]), len);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID]);
+    len = ((sizeof(stats->bssid) <= len) ? sizeof(stats->bssid) : len);
+    memcpy(&stats->bssid[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID]), len);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR]);
+    len = ((sizeof(stats->ap_country_str) <= len) ? sizeof(stats->ap_country_str) : len);
+    memcpy(&stats->ap_country_str[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR]),
+           len);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]);
+    len = ((sizeof(stats->country_str) < len) ? sizeof(stats->country_str) : len);
+    memcpy(&stats->country_str[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]),
+           len);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->time_slicing_duty_cycle_percent = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE]);
+#if QC_HAL_DEBUG
+    ALOGV("Mode : %d\n"
+          "Mac addr : "
+          MAC_ADDR_STR
+          "\nState : %d\n"
+          "Roaming : %d\n"
+          "capabilities : %0x\n"
+          "SSID :%s\n"
+          "BSSID : "
+          MAC_ADDR_STR
+          "\nAP country str : %c%c%c\n"
+          "Country String for this Association : %c%c%c\n"
+	  "Time slicing duty cycle : %d",
+          stats->mode,
+          MAC_ADDR_ARRAY(stats->mac_addr),
+          stats->state,
+          stats->roaming,
+          stats->capabilities,
+          stats->ssid,
+          MAC_ADDR_ARRAY(stats->bssid),
+          stats->ap_country_str[0],
+          stats->ap_country_str[1],
+          stats->ap_country_str[2],
+          stats->country_str[0],
+          stats->country_str[1],
+          stats->country_str[2],
+	  stats->time_slicing_duty_cycle_percent);
+#endif
+    return WIFI_SUCCESS;
+}
+
+static wifi_error get_wifi_wmm_ac_stat(wifi_wmm_ac_stat *stats,
+                                       struct nlattr **tb_vendor)
+{
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->ac                     = (wifi_traffic_ac)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->tx_mpdu                = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rx_mpdu                = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->tx_mcast               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rx_mcast               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rx_ampdu               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->tx_ampdu               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->mpdu_lost              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->retries                = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->retries_short          = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->retries_long           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->contention_time_min    = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->contention_time_max    = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->contention_time_avg    = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->contention_num_samples = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES]);
+#ifdef QC_HAL_DEBUG
+    ALOGV("%4u | %6u | %6u | %7u | %7u | %7u |"
+          " %7u | %8u | %7u | %12u |"
+          " %11u | %17u | %17u |"
+          " %17u | %20u",
+          stats->ac,
+          stats->tx_mpdu,
+          stats->rx_mpdu,
+          stats->tx_mcast,
+          stats->rx_mcast,
+          stats->rx_ampdu,
+          stats->tx_ampdu,
+          stats->mpdu_lost,
+          stats->retries,
+          stats->retries_short,
+          stats->retries_long,
+          stats->contention_time_min,
+          stats->contention_time_max,
+          stats->contention_time_avg,
+          stats->contention_num_samples);
+#endif
+    return WIFI_SUCCESS;
+}
+
+static wifi_error get_wifi_rate_stat(wifi_rate_stat *stats,
+                                     struct nlattr **tb_vendor)
+{
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rate.preamble        = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rate.nss             = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rate.bw              = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rate.rateMcsIdx      = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rate.bitrate         = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->tx_mpdu              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rx_mpdu              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->mpdu_lost            = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->retries              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->retries_short        = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->retries_long         = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG]);
+#ifdef QC_HAL_DEBUG
+    ALOGV("%8u | %3u | %2u | %10u | %7u | %6u | %6u | %8u | %7u | %12u | %11u",
+          stats->rate.preamble,
+          stats->rate.nss,
+          stats->rate.bw,
+          stats->rate.rateMcsIdx,
+          stats->rate.bitrate,
+          stats->tx_mpdu,
+          stats->rx_mpdu,
+          stats->mpdu_lost,
+          stats->retries,
+          stats->retries_short,
+          stats->retries_long);
+#endif
+    return WIFI_SUCCESS;
+}
+
+static wifi_error get_wifi_peer_info(wifi_peer_info *stats,
+                                     struct nlattr **tb_vendor)
+{
+    u32 i = 0, len = 0;
+    int rem;
+    wifi_rate_stat * pRateStats;
+    struct nlattr *rateInfo;
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->type                   = (wifi_peer_type)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS]);
+    len = ((sizeof(stats->peer_mac_address) <= len) ? sizeof(stats->peer_mac_address) : len);
+    memcpy((void *)&stats->peer_mac_address[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS]),
+            len);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->capabilities           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->num_rate               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]);
+#ifdef QC_HAL_DEBUG
+    ALOGV("numPeers %u  Peer MAC addr :" MAC_ADDR_STR " capabilities %0x numRate %u",
+           stats->type, MAC_ADDR_ARRAY(stats->peer_mac_address),
+           stats->capabilities, stats->num_rate);
+#endif
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+#ifdef QC_HAL_DEBUG
+    ALOGV("%8s | %3s | %2s | %10s | %7s | %6s | %6s | %8s | %7s | %12s | %11s",
+          "preamble", "nss", "bw", "rateMcsIdx", "bitrate", "txMpdu", "rxMpdu", "mpduLost", "retries", "retriesShort", "retriesLong");
+#endif
+    for (rateInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]);
+            nla_ok(rateInfo, rem);
+            rateInfo = nla_next(rateInfo, &(rem)))
+    {
+        struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
+        pRateStats = (wifi_rate_stat *) ((u8 *)stats->rate_stats + (i++ * sizeof(wifi_rate_stat)));
+
+        nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(rateInfo), nla_len(rateInfo), NULL);
+        ret = get_wifi_rate_stat(pRateStats, tb2);
+        if(ret != WIFI_SUCCESS)
+        {
+            return ret;
+        }
+    }
+    return WIFI_SUCCESS;
+}
+
+wifi_error LLStatsCommand::get_wifi_iface_stats(wifi_iface_stat *stats,
+                                                struct nlattr **tb_vendor)
+{
+    struct nlattr *wmmInfo;
+    wifi_wmm_ac_stat *pWmmStats;
+    int i=0, rem;
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX"
+                "not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->beacon_rx = nla_get_u32(tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET])
+    {
+        stats->average_tsf_offset = 0;
+    } else {
+        stats->average_tsf_offset = nla_get_u64(tb_vendor[
+                QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET]);
+    }
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED])
+    {
+        stats->leaky_ap_detected = 0;
+    } else {
+        stats->leaky_ap_detected = nla_get_u32(tb_vendor[
+                QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED]);
+    }
+
+    if (!tb_vendor[
+        QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED])
+    {
+        stats->leaky_ap_avg_num_frames_leaked = 0;
+    } else {
+        stats->leaky_ap_avg_num_frames_leaked = nla_get_u32(tb_vendor[
+           QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED]);
+    }
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME])
+    {
+        stats->leaky_ap_guard_time = 0;
+    } else {
+        stats->leaky_ap_guard_time = nla_get_u32(tb_vendor[
+                QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME]);
+    }
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX"
+                " not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->mgmt_rx         = nla_get_u32(tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX]);
+
+    if (!tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX])
+    {
+        ALOGE("%s: "
+                "QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX"
+                " not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->mgmt_action_rx  = nla_get_u32(tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX]);
+
+    if (!tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX])
+    {
+        ALOGE("%s: "
+                "QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX"
+                " not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->mgmt_action_tx  = nla_get_u32(tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT"
+                " not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rssi_mgmt       = get_s32(tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA"
+                " not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rssi_data       = get_s32(tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK"
+                " not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rssi_ack        = get_s32(tb_vendor[
+            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK]);
+#ifdef QC_HAL_DEBUG
+    ALOGV("WMM STATS");
+    ALOGV("beaconRx : %u "
+          "mgmtRx : %u "
+          "mgmtActionRx  : %u "
+          "mgmtActionTx : %u "
+          "rssiMgmt : %d "
+          "rssiData : %d "
+          "rssiAck  : %d ",
+          stats->beacon_rx,
+          stats->mgmt_rx,
+          stats->mgmt_action_rx,
+          stats->mgmt_action_tx,
+          stats->rssi_mgmt,
+          stats->rssi_data,
+          stats->rssi_ack);
+#endif
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO"
+                " not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+#ifdef QC_HAL_DEBUG
+    ALOGV("%4s | %6s | %6s | %7s | %7s | %7s |"
+          " %7s | %8s | %7s | %12s |"
+          " %11s | %17s | %17s |"
+          " %17s | %20s",
+          "ac","txMpdu", "rxMpdu", "txMcast", "rxMcast", "rxAmpdu",
+          "txAmpdu", "mpduLost", "retries", "retriesShort",
+          "retriesLong", "contentionTimeMin", "contentionTimeMax",
+          "contentionTimeAvg", "contentionNumSamples");
+#endif
+    for (wmmInfo = (struct nlattr *) nla_data(tb_vendor[
+                QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]),
+            rem = nla_len(tb_vendor[
+                QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]);
+            nla_ok(wmmInfo, rem);
+            wmmInfo = nla_next(wmmInfo, &(rem)))
+    {
+        struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
+        pWmmStats = (wifi_wmm_ac_stat *) ((u8 *)stats->ac
+                + (i++ * sizeof(wifi_wmm_ac_stat)));
+        nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
+                (struct nlattr *) nla_data(wmmInfo),
+                nla_len(wmmInfo), NULL);
+        ret = get_wifi_wmm_ac_stat(pWmmStats, tb2);
+        if(ret != WIFI_SUCCESS)
+        {
+            return ret;
+        }
+    }
+
+    return WIFI_SUCCESS;
+}
+
+static wifi_error get_wifi_radio_stats(wifi_radio_stat *stats,
+                                       struct nlattr **tb_vendor)
+{
+    u32 i = 0;
+    struct nlattr *chInfo;
+    wifi_channel_stat *pChStats;
+    int rem;
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->radio             = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->on_time           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->tx_time           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME]);
+
+    if (stats->num_tx_levels) {
+        if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL]) {
+            ALOGE("%s: num_tx_levels is %u but QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL not found", __func__, stats->num_tx_levels);
+            stats->num_tx_levels = 0;
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        stats->tx_time_per_levels =
+                             (u32 *) malloc(sizeof(u32) * stats->num_tx_levels);
+        if (!stats->tx_time_per_levels) {
+            ALOGE("%s: radio_stat: tx_time_per_levels malloc Failed", __func__);
+            stats->num_tx_levels = 0;
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+
+        nla_memcpy(stats->tx_time_per_levels,
+            tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL],
+            sizeof(u32) * stats->num_tx_levels);
+    }
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->rx_time           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->on_time_scan      = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->on_time_nbd       = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->on_time_gscan     = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->on_time_roam_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->on_time_pno_scan  = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN]);
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20 not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->on_time_hs20      = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20]);
+
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    stats->num_channels                           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]);
+
+    if (stats->num_channels == 0) {
+        return WIFI_SUCCESS;
+    }
+
+    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO])
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    for (chInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]);
+            nla_ok(chInfo, rem);
+            chInfo = nla_next(chInfo, &(rem)))
+    {
+        struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
+        pChStats = (wifi_channel_stat *) ((u8 *)stats->channels + (i++ * (sizeof(wifi_channel_stat))));
+        nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
+
+        if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH])
+        {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        pChStats->channel.width                  = (wifi_channel_width)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH]);
+
+        if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ])
+        {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        pChStats->channel.center_freq            = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ]);
+
+        if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0])
+        {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0 not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        pChStats->channel.center_freq0           = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0]);
+
+        if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1])
+        {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1 not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        pChStats->channel.center_freq1           = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1]);
+
+        if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME])
+        {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        pChStats->on_time                = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME]);
+
+        if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME])
+        {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        pChStats->cca_busy_time          = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME]);
+
+        if (tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME] &&
+            nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME]) <= pChStats->cca_busy_time)
+            pChStats->cca_busy_time -= nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME]);
+
+    }
+    return WIFI_SUCCESS;
+}
+
+void LLStatsCommand::getClearRspParams(u32 *stats_clear_rsp_mask, u8 *stop_rsp)
+{
+    *stats_clear_rsp_mask =  mClearRspParams.stats_clear_rsp_mask;
+    *stop_rsp = mClearRspParams.stop_rsp;
+}
+
+wifi_error LLStatsCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+wifi_error LLStatsCommand::notifyResponse()
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+
+    /* Indicate stats to framework only if both radio and iface stats
+     * are present */
+    if (mResultsParams.radio_stat && mResultsParams.iface_stat) {
+        if (mNumRadios > mNumRadiosAllocated) {
+            ALOGE("%s: Force reset mNumRadios=%d to allocated=%d",
+                    __FUNCTION__, mNumRadios, mNumRadiosAllocated);
+            mNumRadios = mNumRadiosAllocated;
+        }
+        mHandler.on_link_stats_results(mRequestId,
+                                       mResultsParams.iface_stat, mNumRadios,
+                                       mResultsParams.radio_stat);
+        ret = WIFI_SUCCESS;
+    } else {
+        ret = WIFI_ERROR_INVALID_ARGS;
+    }
+
+    clearStats();
+
+    return ret;
+}
+
+
+void LLStatsCommand::clearStats()
+{
+    if(mResultsParams.radio_stat)
+    {
+        wifi_radio_stat *radioStat = mResultsParams.radio_stat;
+        if (mNumRadios > mNumRadiosAllocated) {
+            ALOGE("%s: Force reset mNumRadios=%d to allocated=%d",
+                    __FUNCTION__, mNumRadios, mNumRadiosAllocated);
+            mNumRadios = mNumRadiosAllocated;
+        }
+        for (u8 radio = 0; radio < mNumRadios; radio++) {
+            if (radioStat->tx_time_per_levels) {
+                free(radioStat->tx_time_per_levels);
+                radioStat->tx_time_per_levels = NULL;
+            }
+            radioStat = (wifi_radio_stat *)((u8 *)radioStat +
+                sizeof(wifi_radio_stat) +  (sizeof(wifi_channel_stat) *
+                    radioStat->num_channels));
+        }
+        free(mResultsParams.radio_stat);
+        mResultsParams.radio_stat = NULL;
+        mRadioStatsSize = 0;
+        mNumRadios = 0;
+        mNumRadiosAllocated = 0;
+     }
+     if(mResultsParams.iface_stat)
+     {
+        free(mResultsParams.iface_stat);
+        mResultsParams.iface_stat = NULL;
+     }
+}
+
+
+int LLStatsCommand::handleResponse(WifiEvent &reply)
+{
+    unsigned i=0;
+    int status = WIFI_ERROR_NONE;
+    WifiVendorCommand::handleResponse(reply);
+
+    // Parse the vendordata and get the attribute
+
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET:
+        {
+            u32 resultsBufSize = 0;
+            struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX + 1];
+            int rem;
+            wifi_radio_stat *radioStatsBuf;
+
+            nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
+                    (struct nlattr *)mVendorData,
+                    mDataLen, NULL);
+
+            if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE])
+            {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE not found",
+                        __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+
+            switch(nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE]))
+            {
+                case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_RADIO:
+                {
+                    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS])
+                    {
+                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS"
+                              " not found", __FUNCTION__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                    }
+                    mNumRadios = nla_get_u32(tb_vendor[
+                                    QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS]);
+
+                    if (!tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS
+                        ])
+                    {
+                        ALOGE("%s:"
+                            "QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS"
+                            " not found", __FUNCTION__);
+                        status = WIFI_ERROR_INVALID_ARGS;
+                        goto cleanup;
+                    }
+
+                    resultsBufSize += (nla_get_u32(tb_vendor[
+                            QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS])
+                            * sizeof(wifi_channel_stat)
+                            + sizeof(wifi_radio_stat));
+
+                    radioStatsBuf = (wifi_radio_stat *)realloc(
+                                              mResultsParams.radio_stat,
+                                              mRadioStatsSize + resultsBufSize);
+                    if (!radioStatsBuf)
+                    {
+                        ALOGE("%s: radio_stat: malloc Failed", __FUNCTION__);
+                        status = WIFI_ERROR_OUT_OF_MEMORY;
+                        goto cleanup;
+                    }
+                    mResultsParams.radio_stat = radioStatsBuf;
+
+                    //Move the buffer to populate current radio stats
+                    radioStatsBuf = (wifi_radio_stat *)(
+                                                (u8 *)mResultsParams.radio_stat
+                                                            + mRadioStatsSize);
+                    memset(radioStatsBuf, 0, resultsBufSize);
+                    mRadioStatsSize += resultsBufSize;
+                    mNumRadiosAllocated ++;
+
+                    if (tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS])
+                        radioStatsBuf->num_tx_levels = nla_get_u32(tb_vendor[
+                                            QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS]);
+
+                    wifi_channel_stat *pWifiChannelStats;
+                    status = get_wifi_radio_stats(radioStatsBuf,
+                              tb_vendor);
+                    if(status != WIFI_SUCCESS)
+                    {
+                        goto cleanup;
+                    }
+#ifdef QC_HAL_DEBUG
+                    ALOGV("radio :%u onTime :%u txTime :%u rxTime :%u"
+                          " onTimeScan :%u onTimeNbd :%u onTimeGscan :%u"
+                          " onTimeRoamScan :%u onTimePnoScan :%u"
+                          " onTimeHs20 :%u numChannels :%u num_tx_levels: %u",
+                          radioStatsBuf->radio,
+                          radioStatsBuf->on_time,
+                          radioStatsBuf->tx_time,
+                          radioStatsBuf->rx_time,
+                          radioStatsBuf->on_time_scan,
+                          radioStatsBuf->on_time_nbd,
+                          radioStatsBuf->on_time_gscan,
+                          radioStatsBuf->on_time_roam_scan,
+                          radioStatsBuf->on_time_pno_scan,
+                          radioStatsBuf->on_time_hs20,
+                          radioStatsBuf->num_channels,
+                          radioStatsBuf->num_tx_levels);
+#ifdef QC_HAL_DEBUG
+                    for (i = 0; i < radioStatsBuf->num_tx_levels; i++) {
+                        ALOGV("Power level: %u  tx_time: %u", i,
+                              radioStatsBuf->tx_time_per_levels[i]);
+                    }
+#endif
+                    ALOGV("%5s | %10s | %11s | %11s | %6s | %11s", "width",
+                          "CenterFreq", "CenterFreq0", "CenterFreq1",
+                          "onTime", "ccaBusyTime");
+#endif
+                    for ( i=0; i < radioStatsBuf->num_channels; i++)
+                    {
+                        pWifiChannelStats =
+                            (wifi_channel_stat *) (
+                                (u8 *)radioStatsBuf->channels
+                                + (i * sizeof(wifi_channel_stat)));
+
+#ifdef QC_HAL_DEBUG
+                        ALOGV("%5u | %10u | %11u | %11u | %6u | %11u",
+                              pWifiChannelStats->channel.width,
+                              pWifiChannelStats->channel.center_freq,
+                              pWifiChannelStats->channel.center_freq0,
+                              pWifiChannelStats->channel.center_freq1,
+                              pWifiChannelStats->on_time,
+                              pWifiChannelStats->cca_busy_time);
+#endif
+                    }
+                }
+                break;
+
+                case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_IFACE:
+                {
+                    resultsBufSize = sizeof(wifi_iface_stat);
+                    mResultsParams.iface_stat =
+                        (wifi_iface_stat *) malloc (resultsBufSize);
+                    if (!mResultsParams.iface_stat)
+                    {
+                        ALOGE("%s: iface_stat: malloc Failed", __FUNCTION__);
+                        status = WIFI_ERROR_OUT_OF_MEMORY;
+                        goto cleanup;
+                    }
+                    memset(mResultsParams.iface_stat, 0, resultsBufSize);
+                    status = get_wifi_interface_info(
+                            &mResultsParams.iface_stat->info, tb_vendor);
+                    if(status != WIFI_SUCCESS)
+                    {
+                        goto cleanup;
+                    }
+                    status = get_wifi_iface_stats(mResultsParams.iface_stat,
+                            tb_vendor);
+                    if(status != WIFI_SUCCESS)
+                    {
+                        goto cleanup;
+                    }
+
+                    /* Driver/firmware might send this attribute when there
+                     * are no peers connected.
+                     * So that, the event
+                     * QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS can be
+                     * avoided.
+                     */
+                    if (tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])
+                    {
+                        mResultsParams.iface_stat->num_peers =
+                            nla_get_u32(tb_vendor[
+                                QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]);
+#ifdef QC_HAL_DEBUG
+                        ALOGV("%s: numPeers is %u\n", __FUNCTION__,
+                                mResultsParams.iface_stat->num_peers);
+#endif
+                    }
+                }
+                break;
+
+                case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS:
+                {
+                    struct nlattr *peerInfo;
+                    wifi_iface_stat *pIfaceStat = NULL;
+                    u32 numPeers, num_rates = 0;
+                    if (!tb_vendor[
+                            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])
+                    {
+                        ALOGE("%s:QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS"
+                              " not found", __FUNCTION__);
+                        status = WIFI_ERROR_INVALID_ARGS;
+                        goto cleanup;
+                    }
+#ifdef QC_HAL_DEBUG
+                    ALOGV(" numPeers is %u in %s\n",
+                            nla_get_u32(tb_vendor[
+                            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]),
+                            __FUNCTION__);
+#endif
+                    if((numPeers = nla_get_u32(tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])) > 0)
+                    {
+                        if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO])
+                        {
+                            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO"
+                                    " not found", __FUNCTION__);
+                            status = WIFI_ERROR_INVALID_ARGS;
+                            goto cleanup;
+                        }
+                        for (peerInfo = (struct nlattr *) nla_data(tb_vendor[
+                             QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]),
+                             rem = nla_len(tb_vendor[
+                             QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]);
+                                nla_ok(peerInfo, rem);
+                                peerInfo = nla_next(peerInfo, &(rem)))
+                        {
+                            struct nlattr *tb2[
+                                QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
+
+                            nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
+                                    (struct nlattr *) nla_data(peerInfo),
+                                    nla_len(peerInfo), NULL);
+
+                            if (!tb2[
+                             QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES])
+                            {
+                                ALOGE("%s:"
+                             "QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES"
+                             " not found", __FUNCTION__);
+                                status = WIFI_ERROR_INVALID_ARGS;
+                                goto cleanup;
+                            }
+                            num_rates += nla_get_u32(tb2[
+                            QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]);
+                        }
+                        resultsBufSize += (numPeers * sizeof(wifi_peer_info)
+                                + num_rates * sizeof(wifi_rate_stat)
+                                + sizeof (wifi_iface_stat));
+                        pIfaceStat = (wifi_iface_stat *) malloc (
+                                resultsBufSize);
+                        if (!pIfaceStat)
+                        {
+                            ALOGE("%s: pIfaceStat: malloc Failed", __FUNCTION__);
+                            status = WIFI_ERROR_OUT_OF_MEMORY;
+                            goto cleanup;
+                        }
+
+                        memset(pIfaceStat, 0, resultsBufSize);
+                        if(mResultsParams.iface_stat) {
+                            if(resultsBufSize >= sizeof(wifi_iface_stat)) {
+                                memcpy ( pIfaceStat, mResultsParams.iface_stat,
+                                    sizeof(wifi_iface_stat));
+                                free (mResultsParams.iface_stat);
+                                mResultsParams.iface_stat = pIfaceStat;
+                            } else {
+                                ALOGE("%s: numPeers = %u, num_rates= %u, "
+                                      "either numPeers or num_rates is invalid",
+                                      __FUNCTION__,numPeers,num_rates);
+                                status = WIFI_ERROR_UNKNOWN;
+                                free(pIfaceStat);
+                                goto cleanup;
+                            }
+                        }
+                        wifi_peer_info *pPeerStats;
+                        pIfaceStat->num_peers = numPeers;
+
+                        if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO])
+                        {
+                            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO"
+                                  " not found", __FUNCTION__);
+                            status = WIFI_ERROR_INVALID_ARGS;
+                            goto cleanup;
+                        }
+                        num_rates = 0;
+                        for (peerInfo = (struct nlattr *) nla_data(tb_vendor[
+                            QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]),
+                            rem = nla_len(tb_vendor[
+                                QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]);
+                                nla_ok(peerInfo, rem);
+                                peerInfo = nla_next(peerInfo, &(rem)))
+                        {
+                            struct nlattr *tb2[
+                                QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
+                            pPeerStats = (wifi_peer_info *) (
+                                           (u8 *)pIfaceStat->peer_info
+                                           + (i++ * sizeof(wifi_peer_info))
+                                           + (num_rates * sizeof(wifi_rate_stat)));
+                            nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
+                                (struct nlattr *) nla_data(peerInfo),
+                                nla_len(peerInfo), NULL);
+                            status = get_wifi_peer_info(pPeerStats, tb2);
+                            if(status != WIFI_SUCCESS)
+                            {
+                                goto cleanup;
+                            }
+                            num_rates += pPeerStats->num_rate;
+                        }
+                    }
+
+                }
+                break;
+
+                case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_INVALID:
+                default:
+                    //error case should not happen print log
+                    ALOGE("%s: Wrong LLStats subcmd received %d", __FUNCTION__,
+                           mSubcmd);
+            }
+        }
+        break;
+
+        case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR:
+        {
+            struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
+            nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
+                    (struct nlattr *)mVendorData,
+                    mDataLen, NULL);
+
+            if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK])
+            {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            ALOGI("Resp mask : %d\n", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK]));
+
+            if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP])
+            {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            ALOGI("STOP resp : %d\n", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP]));
+
+            if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK])
+            {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            mClearRspParams.stats_clear_rsp_mask = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK]);
+
+            if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP])
+            {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            mClearRspParams.stop_rsp = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP]);
+            break;
+        }
+        default :
+            ALOGE("%s: Wrong LLStats subcmd received %d", __FUNCTION__, mSubcmd);
+    }
+    return NL_SKIP;
+
+cleanup:
+    clearStats();
+    return status;
+}
+
+//Implementation of the functions exposed in linklayer.h
+wifi_error wifi_set_link_stats(wifi_interface_handle iface,
+                               wifi_link_layer_params params)
+{
+    wifi_error ret;
+    LLStatsCommand *LLCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(handle);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_LINK_LAYER_STATS)) {
+        ALOGI("%s: LLS is not supported by driver", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ALOGI("mpdu_size_threshold : %u, aggressive_statistics_gathering : %u",
+          params.mpdu_size_threshold, params.aggressive_statistics_gathering);
+    LLCommand = LLStatsCommand::instance(handle);
+    if (LLCommand == NULL) {
+        ALOGE("%s: Error LLStatsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET);
+
+    /* create the message */
+    ret = LLCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = LLCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /*add the attributes*/
+    nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    /**/
+    ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD,
+                                  params.mpdu_size_threshold);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    /**/
+    ret = LLCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING,
+                params.aggressive_statistics_gathering);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    LLCommand->attr_end(nl_data);
+
+    ret = LLCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    return ret;
+}
+
+//Implementation of the functions exposed in LLStats.h
+wifi_error wifi_get_link_stats(wifi_request_id id,
+                               wifi_interface_handle iface,
+                               wifi_stats_result_handler handler)
+{
+    wifi_error ret;
+    LLStatsCommand *LLCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(handle);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_LINK_LAYER_STATS)) {
+        ALOGI("%s: LLS is not supported by driver", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    LLCommand = LLStatsCommand::instance(handle);
+    if (LLCommand == NULL) {
+        ALOGE("%s: Error LLStatsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET);
+
+    LLCommand->initGetContext(id);
+
+    LLCommand->setHandler(handler);
+
+    /* create the message */
+    ret = LLCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = LLCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    /*add the attributes*/
+    nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID,
+                                  id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK,
+                                  7);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /**/
+    LLCommand->attr_end(nl_data);
+
+    ret = LLCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+    if (ret != WIFI_SUCCESS) {
+        LLCommand->clearStats();
+        goto cleanup;
+    }
+
+    if (ret == WIFI_SUCCESS)
+        ret = LLCommand->notifyResponse();
+
+cleanup:
+    return ret;
+}
+
+
+//Implementation of the functions exposed in LLStats.h
+wifi_error wifi_clear_link_stats(wifi_interface_handle iface,
+                                 u32 stats_clear_req_mask,
+                                 u32 *stats_clear_rsp_mask,
+                                 u8 stop_req, u8 *stop_rsp)
+{
+    wifi_error ret;
+    LLStatsCommand *LLCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(handle);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_LINK_LAYER_STATS)) {
+        ALOGI("%s: LLS is not supported by driver", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ALOGI("clear_req : %x, stop_req : %u", stats_clear_req_mask, stop_req);
+    LLCommand = LLStatsCommand::instance(handle);
+    if (LLCommand == NULL) {
+        ALOGE("%s: Error LLStatsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR);
+
+    /* create the message */
+    ret = LLCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = LLCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    /*add the attributes*/
+    nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    /**/
+    ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK,
+                                  stats_clear_req_mask);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    /**/
+    ret = LLCommand->put_u8(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ,
+                                   stop_req);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    LLCommand->attr_end(nl_data);
+
+    ret = LLCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+    LLCommand->getClearRspParams(stats_clear_rsp_mask, stop_rsp);
+
+cleanup:
+    delete LLCommand;
+    return ret;
+}
diff --git a/qcwcn/wifi_hal/llstatscommand.h b/wcn6740/qcwcn/wifi_hal/llstatscommand.h
similarity index 100%
copy from qcwcn/wifi_hal/llstatscommand.h
copy to wcn6740/qcwcn/wifi_hal/llstatscommand.h
diff --git a/wcn6740/qcwcn/wifi_hal/nan.cpp b/wcn6740/qcwcn/wifi_hal/nan.cpp
new file mode 100644
index 0000000..1690a86
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/nan.cpp
@@ -0,0 +1,2156 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sync.h"
+
+#include "wifi_hal.h"
+#include "nan_i.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include <utils/Log.h>
+#include <errno.h>
+#include "nancommand.h"
+#include "vendor_definitions.h"
+#include "wificonfigcommand.h"
+#include <ctype.h>
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+
+#ifdef __GNUC__
+#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
+#define STRUCT_PACKED __attribute__ ((packed))
+#else
+#define PRINTF_FORMAT(a,b)
+#define STRUCT_PACKED
+#endif
+
+#define OUT_OF_BAND_SERVICE_INSTANCE_ID 0
+
+//Singleton Static Instance
+NanCommand* NanCommand::mNanCommandInstance  = NULL;
+
+//Implementation of the functions exposed in nan.h
+wifi_error nan_register_handler(wifi_interface_handle iface,
+                                NanCallbackHandler handlers)
+{
+    // Obtain the singleton instance
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    nanCommand = NanCommand::instance(wifiHandle);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->setCallbackHandler(handlers);
+    return ret;
+}
+
+wifi_error nan_get_version(wifi_handle handle,
+                           NanVersion* version)
+{
+    *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
+    return WIFI_SUCCESS;
+}
+
+/*  Function to send enable request to the wifi driver.*/
+wifi_error nan_enable_request(transaction_id id,
+                              wifi_interface_handle iface,
+                              NanEnableRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    NanCommand *t_nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanEnable(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanEnable Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+    if (ret == WIFI_SUCCESS) {
+        t_nanCommand = NanCommand::instance(wifiHandle);
+        if (t_nanCommand != NULL) {
+            t_nanCommand->allocSvcParams();
+        }
+    }
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send disable request to the wifi driver.*/
+wifi_error nan_disable_request(transaction_id id,
+                               wifi_interface_handle iface)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    NanCommand *t_nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanDisable(id);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanDisable Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
+
+    if (ret == WIFI_SUCCESS) {
+        t_nanCommand = NanCommand::instance(wifiHandle);
+        if (t_nanCommand != NULL) {
+            t_nanCommand->deallocSvcParams();
+        }
+    }
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send publish request to the wifi driver.*/
+wifi_error nan_publish_request(transaction_id id,
+                               wifi_interface_handle iface,
+                               NanPublishRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanPublish(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanPublish Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send publish cancel to the wifi driver.*/
+wifi_error nan_publish_cancel_request(transaction_id id,
+                                      wifi_interface_handle iface,
+                                      NanPublishCancelRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanPublishCancel(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanPublishCancel Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send Subscribe request to the wifi driver.*/
+wifi_error nan_subscribe_request(transaction_id id,
+                                 wifi_interface_handle iface,
+                                 NanSubscribeRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanSubscribe(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanSubscribe Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to cancel subscribe to the wifi driver.*/
+wifi_error nan_subscribe_cancel_request(transaction_id id,
+                                        wifi_interface_handle iface,
+                                        NanSubscribeCancelRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    NanCommand *t_nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanSubscribeCancel(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanSubscribeCancel Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+    if (ret == WIFI_SUCCESS) {
+        t_nanCommand = NanCommand::instance(wifiHandle);
+        if (t_nanCommand != NULL) {
+            t_nanCommand->deleteServiceId(msg->subscribe_id,
+                                          0, NAN_ROLE_SUBSCRIBER);
+        }
+    }
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send NAN follow up request to the wifi driver.*/
+wifi_error nan_transmit_followup_request(transaction_id id,
+                                         wifi_interface_handle iface,
+                                         NanTransmitFollowupRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanTransmitFollowup(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanTransmitFollowup Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send NAN statistics request to the wifi driver.*/
+wifi_error nan_stats_request(transaction_id id,
+                             wifi_interface_handle iface,
+                             NanStatsRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanStats(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanStats Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send NAN configuration request to the wifi driver.*/
+wifi_error nan_config_request(transaction_id id,
+                              wifi_interface_handle iface,
+                              NanConfigRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanConfig(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanConfig Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send NAN request to the wifi driver.*/
+wifi_error nan_tca_request(transaction_id id,
+                           wifi_interface_handle iface,
+                           NanTCARequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanTCA(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanTCA Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to send NAN Beacon sdf payload to the wifi driver.
+    This instructs the Discovery Engine to begin publishing the
+    received payload in any Beacon or Service Discovery Frame
+    transmitted*/
+wifi_error nan_beacon_sdf_payload_request(transaction_id id,
+                                         wifi_interface_handle iface,
+                                         NanBeaconSdfPayloadRequest* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanBeaconSdfPayload(id, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanBeaconSdfPayload Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+wifi_error nan_get_sta_parameter(transaction_id id,
+                                 wifi_interface_handle iface,
+                                 NanStaParameter* msg)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    nanCommand = NanCommand::instance(wifiHandle);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->getNanStaParameter(iface, msg);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: getNanStaParameter Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    return ret;
+}
+
+/*  Function to get NAN capabilities */
+wifi_error nan_get_capabilities(transaction_id id,
+                                wifi_interface_handle iface)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanCapabilities(id);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanCapabilities Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+/*  Function to get NAN capabilities */
+wifi_error nan_debug_command_config(transaction_id id,
+                                   wifi_interface_handle iface,
+                                   NanDebugParams debug,
+                                   int debug_msg_length)
+{
+    wifi_error ret;
+    NanCommand *nanCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    if (debug_msg_length <= 0) {
+        ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
+                                                       debug_msg_length);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nanCommand = new NanCommand(wifiHandle,
+                                0,
+                                OUI_QCA,
+                                info->support_nan_ext_cmd?
+                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nanCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = nanCommand->putNanDebugCommand(debug, debug_msg_length);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+wifi_error nan_initialize_vendor_cmd(wifi_interface_handle iface,
+                                     NanCommand **nanCommand)
+{
+    wifi_error ret;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    if (nanCommand == NULL) {
+        ALOGE("%s: Error nanCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    *nanCommand = new NanCommand(wifiHandle,
+                                 0,
+                                 OUI_QCA,
+                                 QCA_NL80211_VENDOR_SUBCMD_NDP);
+    if (*nanCommand == NULL) {
+        ALOGE("%s: Object creation failed", __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    /* Create the message */
+    ret = (*nanCommand)->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = (*nanCommand)->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    return WIFI_SUCCESS;
+
+cleanup:
+    delete *nanCommand;
+    return ret;
+}
+
+wifi_error nan_data_interface_create(transaction_id id,
+                                     wifi_interface_handle iface,
+                                     char* iface_name)
+{
+    ALOGV("NAN_DP_INTERFACE_CREATE");
+    wifi_error ret;
+    struct nlattr *nlData;
+    NanCommand *nanCommand = NULL;
+    WiFiConfigCommand *wifiConfigCommand;
+    wifi_handle handle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(handle);
+    bool ndi_created = false;
+
+    if (iface_name == NULL) {
+        ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (!info || info->num_interfaces < 1) {
+        ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
+              __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    if (check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
+                      &info->driver_supported_features)) {
+        wifiConfigCommand = new WiFiConfigCommand(handle,
+                                                  get_requestid(), 0, 0);
+        if (wifiConfigCommand == NULL) {
+            ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+            return WIFI_ERROR_UNKNOWN;
+        }
+        wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE);
+        wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
+                                   info->interfaces[0]->id);
+        wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, iface_name);
+        wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE,
+                                   NL80211_IFTYPE_STATION);
+        /* Send the NL msg. */
+        wifiConfigCommand->waitForRsp(false);
+        ret = wifiConfigCommand->requestEvent();
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: Create intf failed, Error:%d", __FUNCTION__, ret);
+            delete wifiConfigCommand;
+            return ret;
+        }
+        ndi_created = true;
+        delete wifiConfigCommand;
+    }
+
+    ret = nan_initialize_vendor_cmd(iface, &nanCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        goto delete_ndi;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+            QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE) ||
+        nanCommand->put_u16(
+            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+            id) ||
+        nanCommand->put_string(
+            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
+            iface_name)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    nanCommand->attr_end(nlData);
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+
+delete_ndi:
+    if (ndi_created && ret != WIFI_SUCCESS) {
+        wifiConfigCommand = new WiFiConfigCommand(handle,
+                                                  get_requestid(), 0, 0);
+        if (wifiConfigCommand == NULL) {
+            ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+            return ret;
+        }
+        wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
+        wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
+                                   if_nametoindex(iface_name));
+        /* Send the NL msg. */
+        wifiConfigCommand->waitForRsp(false);
+        if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS)
+            ALOGE("%s: Delete intf failed", __FUNCTION__);
+
+        delete wifiConfigCommand;
+    }
+    return ret;
+}
+
+wifi_error nan_data_interface_delete(transaction_id id,
+                                     wifi_interface_handle iface,
+                                     char* iface_name)
+{
+    ALOGV("NAN_DP_INTERFACE_DELETE");
+    wifi_error ret;
+    struct nlattr *nlData;
+    NanCommand *nanCommand = NULL;
+    WiFiConfigCommand *wifiConfigCommand;
+    wifi_handle handle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(handle);
+
+    if (iface_name == NULL) {
+        ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (!info || info->num_interfaces < 1) {
+        ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
+          __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = nan_initialize_vendor_cmd(iface,
+                                    &nanCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        goto delete_ndi;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+            QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE) ||
+        nanCommand->put_u16(
+            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+            id) ||
+        nanCommand->put_string(
+            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
+            iface_name)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    nanCommand->attr_end(nlData);
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+
+delete_ndi:
+    if ((check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
+                       &info->driver_supported_features)) &&
+        if_nametoindex(iface_name)) {
+        wifiConfigCommand = new WiFiConfigCommand(handle,
+                                                  get_requestid(), 0, 0);
+        if (wifiConfigCommand == NULL) {
+            ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+            return WIFI_ERROR_UNKNOWN;
+        }
+        wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
+        wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
+                                   if_nametoindex(iface_name));
+        /* Send the NL msg. */
+        wifiConfigCommand->waitForRsp(false);
+        if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS) {
+            ALOGE("%s: Delete intf failed", __FUNCTION__);
+        }
+        delete wifiConfigCommand;
+    }
+
+    return ret;
+}
+
+/* Service ID using SHA256 */
+static bool
+ndp_create_service_id(const u8 *service_name,
+                      u32 service_name_len, u8 *service_id)
+{
+    u8 out_service_id[NAN_SVC_HASH_SIZE] = {0};
+    u8 *mod_service_name;
+    unsigned char prop_oob_service_name[NAN_DEF_SVC_NAME_LEN + 1] =
+                                                        "Wi-Fi Aware Data Path";
+    unsigned char prop_oob_service_name_lowercase[NAN_DEF_SVC_NAME_LEN + 1] =
+                                                        "wi-fi aware data path";
+    bool is_default = false;
+    int i;
+
+    if (!service_name) {
+        ALOGE("%s: NULL service name", __FUNCTION__);
+        return false;
+    }
+
+    if (!service_name_len) {
+        ALOGE("%s: Zero service name length", __FUNCTION__);
+        return false;
+    }
+
+    if (!service_id) {
+        ALOGE("%s: NULL service ID", __FUNCTION__);
+        return false;
+    }
+
+    mod_service_name = (u8 *)malloc(service_name_len);
+    if (!mod_service_name) {
+        ALOGE("%s: malloc failed", __FUNCTION__);
+        return false;
+    }
+
+    memset(mod_service_name, 0, service_name_len);
+    memcpy(mod_service_name, service_name, service_name_len);
+    if ((service_name_len == NAN_DEF_SVC_NAME_LEN) &&
+        (!memcmp(mod_service_name, prop_oob_service_name, service_name_len)
+         || !memcmp(mod_service_name,
+                    prop_oob_service_name_lowercase, service_name_len)))
+        is_default = true;
+
+    for (i = 0; i < service_name_len; i++) {
+    /*
+     * As per NAN spec, the only acceptable singlebyte UTF-8 symbols for a
+     * Service Name are alphanumeric values (A-Z, a-z, 0-9), the hyphen ('-'),
+     * the underscore ('_'), and the period ('.').
+     * These checks are added for all service names except the above defined
+     * default service name.
+     */
+        if (!is_default && !isalnum(mod_service_name[i]) &&
+            (mod_service_name[i] != '_') && (mod_service_name[i] != '-') &&
+            (mod_service_name[i] != '.')) {
+             free(mod_service_name);
+             return false;
+        }
+
+        if ((mod_service_name[i] == ' ') && (is_default))
+             goto end;
+
+        /*
+         * The service_name hash SHALL always be done on a lower-case
+         * version of service_name which was passed down. Therefore,
+         * before passing the service_name to the SHA256 function first
+         * run through the string and call tolower on each byte.
+         */
+        mod_service_name[i] = tolower(mod_service_name[i]);
+    }
+
+end:
+    SHA256(mod_service_name, service_name_len, out_service_id);
+    /*
+     * As per NAN spec, Service ID is the first 48 bits of the SHA-256 hash
+     * of the Service Name
+     */
+    memcpy(service_id, out_service_id, NAN_SVC_ID_SIZE);
+
+    free(mod_service_name);
+    return true;
+}
+
+/*
+ * PMK = PBKDF2(<pass phrase>, <Salt Version>||<Cipher Suite ID>||<Service ID>||
+ *              <Publisher NMI>, 4096, 32)
+ * ndp_passphrase_to_pmk: API to calculate the service ID and PMK.
+ * @pmk: output value of Hash
+ * @passphrase: secret key
+ * @salt_version: 00
+ * @csid: cipher suite ID: 01
+ * As per NAN spec, below are the values defined for CSID attribute:
+ *     1 - NCS-SK-128 Cipher Suite
+ *     2 - NCS-SK-256 Cipher Suite
+ *     3 - NCS-PK-2WDH-128 Cipher Suite
+ *     4 - NCS-PK-2WDH-256 Cipher Suite
+ *     Other values are reserved
+ * @service_id: Hash value of SHA256 on service_name
+ * @peer_mac: Publisher NAN Management Interface address
+ * @iterations: 4096
+ * @pmk_len: 32
+ */
+static int
+ndp_passphrase_to_pmk(u32 cipher_type, u8 *pmk, u8 *passphrase,
+                      u32 passphrase_len, u8 *service_name,
+                      u32 service_name_len, u8 *svc_id, u8 *peer_mac)
+{
+    int result = 0;
+    u8 pmk_hex[NAN_PMK_INFO_LEN] = {0};
+    u8 salt[NAN_SECURITY_SALT_SIZE] = {0};
+    u8 service_id[NAN_SVC_ID_SIZE] = {0};
+    unsigned char *pos = NULL;
+    unsigned char salt_version = 0;
+    u8 csid;
+    /* We read only first 3-bits, as only 1-4 values are expected currently */
+    csid = (u8)(cipher_type & 0x7);
+    if (csid == 0)
+        csid = NAN_DEFAULT_NCS_SK;
+
+    if (svc_id != NULL) {
+        ALOGV("Service ID received from the pool");
+        memcpy(service_id, svc_id, NAN_SVC_ID_SIZE);
+    } else if (ndp_create_service_id((const u8 *)service_name,
+                                     service_name_len, service_id) == false) {
+        ALOGE("Failed to create service ID");
+        return result;
+    }
+
+    pos = salt;
+    /* salt version */
+    *pos++ = salt_version;
+    /* CSID */
+    *pos++ = csid;
+    /* Service ID */
+    memcpy(pos, service_id, NAN_SVC_ID_SIZE);
+    pos += NAN_SVC_ID_SIZE;
+    /* Publisher NMI */
+    memcpy(pos, peer_mac, NAN_MAC_ADDR_LEN);
+    pos += NAN_MAC_ADDR_LEN;
+
+    ALOGV("salt dump");
+    hexdump(salt, NAN_SECURITY_SALT_SIZE);
+
+    result = PKCS5_PBKDF2_HMAC((const char *)passphrase, passphrase_len, salt,
+                               sizeof(salt), NAN_PMK_ITERATIONS,
+                               (const EVP_MD *) EVP_sha256(),
+                               NAN_PMK_INFO_LEN, pmk_hex);
+    if (result)
+        memcpy(pmk, pmk_hex, NAN_PMK_INFO_LEN);
+
+    return result;
+}
+
+wifi_error nan_data_request_initiator(transaction_id id,
+                                      wifi_interface_handle iface,
+                                      NanDataPathInitiatorRequest* msg)
+{
+    ALOGV("NAN_DP_REQUEST_INITIATOR");
+    wifi_error ret;
+    struct nlattr *nlData, *nlCfgQos;
+    NanCommand *nanCommand = NULL;
+    NanCommand *t_nanCommand = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    if (msg == NULL)
+        return WIFI_ERROR_INVALID_ARGS;
+
+    ret = nan_initialize_vendor_cmd(iface,
+                                    &nanCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        return ret;
+    }
+
+    t_nanCommand = NanCommand::instance(wifiHandle);
+    if (t_nanCommand == NULL)
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+
+    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
+        (msg->key_info.body.pmk_info.pmk_len == 0) &&
+        (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
+        ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
+               __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
+        (msg->requestor_instance_id == OUT_OF_BAND_SERVICE_INSTANCE_ID) &&
+        (msg->service_name_len == 0)) {
+        ALOGE("%s: Failed-Initiator req, missing service name for out of band request",
+              __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+            QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST) ||
+        nanCommand->put_u16(
+            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+            id) ||
+        nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
+            msg->requestor_instance_id) ||
+        nanCommand->put_bytes(
+            QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
+            (char *)msg->peer_disc_mac_addr,
+            NAN_MAC_ADDR_LEN) ||
+        nanCommand->put_string(
+            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
+            msg->ndp_iface)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (msg->channel_request_type != NAN_DP_CHANNEL_NOT_REQUESTED) {
+        if (nanCommand->put_u32 (
+                QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG,
+                msg->channel_request_type) ||
+            nanCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
+                msg->channel)){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+
+    if (msg->app_info.ndp_app_info_len != 0) {
+        if (nanCommand->put_bytes(
+                QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
+                (char *)msg->app_info.ndp_app_info,
+                msg->app_info.ndp_app_info_len)) {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+
+    if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
+        nlCfgQos =
+            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
+        if (!nlCfgQos){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        /* TBD Qos Info */
+        nanCommand->attr_end(nlCfgQos);
+    }
+    if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
+        if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
+                msg->cipher_type)){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+    if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
+        if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Invalid pmk len:%d", __FUNCTION__,
+                  msg->key_info.body.pmk_info.pmk_len);
+            goto cleanup;
+        }
+        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+            (char *)msg->key_info.body.pmk_info.pmk,
+            msg->key_info.body.pmk_info.pmk_len)){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
+        if (msg->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN ||
+            msg->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__,
+                  msg->key_info.body.passphrase_info.passphrase_len);
+            goto cleanup;
+        }
+        u8 *service_id = NULL;
+
+        if (t_nanCommand != NULL)
+            service_id = t_nanCommand->getServiceId(msg->requestor_instance_id,
+                                                    NAN_ROLE_SUBSCRIBER);
+        if (service_id == NULL)
+            ALOGE("%s: Entry not found for Instance ID:%d",
+                  __FUNCTION__, msg->requestor_instance_id);
+        if (((service_id != NULL) || (msg->service_name_len)) &&
+            ndp_passphrase_to_pmk(msg->cipher_type,
+                                  msg->key_info.body.pmk_info.pmk,
+                                  msg->key_info.body.passphrase_info.passphrase,
+                                  msg->key_info.body.passphrase_info.passphrase_len,
+                                  msg->service_name, msg->service_name_len,
+                                  service_id, msg->peer_disc_mac_addr)) {
+            msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+                (char *)msg->key_info.body.pmk_info.pmk,
+                msg->key_info.body.pmk_info.pmk_len)){
+                if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+                    (char *)msg->key_info.body.passphrase_info.passphrase,
+                    msg->key_info.body.passphrase_info.passphrase_len)){
+                    ret = WIFI_ERROR_UNKNOWN;
+                    goto cleanup;
+                }
+            }
+        } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+                   (char *)msg->key_info.body.passphrase_info.passphrase,
+                   msg->key_info.body.passphrase_info.passphrase_len)) {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+    if (msg->service_name_len) {
+        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+            (char *)msg->service_name, msg->service_name_len)){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+    nanCommand->attr_end(nlData);
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+wifi_error nan_data_indication_response(transaction_id id,
+                                        wifi_interface_handle iface,
+                                        NanDataPathIndicationResponse* msg)
+{
+    ALOGV("NAN_DP_INDICATION_RESPONSE");
+    wifi_error ret;
+    struct nlattr *nlData, *nlCfgQos;
+    NanCommand *nanCommand = NULL;
+    NanCommand *t_nanCommand = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    if (msg == NULL)
+        return WIFI_ERROR_INVALID_ARGS;
+
+    ret = nan_initialize_vendor_cmd(iface,
+                                    &nanCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        return ret;
+    }
+
+    t_nanCommand = NanCommand::instance(wifiHandle);
+    if (t_nanCommand == NULL)
+        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
+
+    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
+        (msg->key_info.body.pmk_info.pmk_len == 0) &&
+        (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
+        ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
+               __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+            QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST) ||
+        nanCommand->put_u16(
+            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+            id) ||
+        nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
+            msg->ndp_instance_id) ||
+        nanCommand->put_string(
+            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
+            msg->ndp_iface) ||
+        nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
+            msg->rsp_code)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    if (msg->app_info.ndp_app_info_len != 0) {
+        if (nanCommand->put_bytes(
+                QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
+                (char *)msg->app_info.ndp_app_info,
+                msg->app_info.ndp_app_info_len)) {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+    if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
+        nlCfgQos =
+            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
+        if (!nlCfgQos){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+
+        /* TBD Qos Info */
+        nanCommand->attr_end(nlCfgQos);
+    }
+    if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
+        if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
+                msg->cipher_type)){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+    if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
+        if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Invalid pmk len:%d", __FUNCTION__,
+                  msg->key_info.body.pmk_info.pmk_len);
+            goto cleanup;
+        }
+        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+            (char *)msg->key_info.body.pmk_info.pmk,
+            msg->key_info.body.pmk_info.pmk_len)){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
+        if (msg->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN ||
+            msg->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__,
+                  msg->key_info.body.passphrase_info.passphrase_len);
+            goto cleanup;
+        }
+        u8 *service_id = NULL;
+
+        if (t_nanCommand != NULL)
+            service_id = t_nanCommand->getServiceId(msg->ndp_instance_id,
+                                                    NAN_ROLE_PUBLISHER);
+        if (service_id == NULL)
+            ALOGE("%s: Entry not found for Instance ID:%d",
+                  __FUNCTION__, msg->ndp_instance_id);
+        if (((service_id != NULL) || (msg->service_name_len)) &&
+            (t_nanCommand != NULL) &&
+            ndp_passphrase_to_pmk(msg->cipher_type,
+                                  msg->key_info.body.pmk_info.pmk,
+                                  msg->key_info.body.passphrase_info.passphrase,
+                                  msg->key_info.body.passphrase_info.passphrase_len,
+                                  msg->service_name, msg->service_name_len,
+                                  service_id, t_nanCommand->getNmi())) {
+            msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+                (char *)msg->key_info.body.pmk_info.pmk,
+                msg->key_info.body.pmk_info.pmk_len))
+                if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+                    (char *)msg->key_info.body.passphrase_info.passphrase,
+                    msg->key_info.body.passphrase_info.passphrase_len)){
+                    ret = WIFI_ERROR_UNKNOWN;
+                    goto cleanup;
+                }
+        } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+                   (char *)msg->key_info.body.passphrase_info.passphrase,
+                   msg->key_info.body.passphrase_info.passphrase_len)) {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+
+    if (msg->service_name_len) {
+        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+            (char *)msg->service_name, msg->service_name_len)){
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+    }
+    nanCommand->attr_end(nlData);
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+wifi_error nan_data_end(transaction_id id,
+                        wifi_interface_handle iface,
+                        NanDataPathEndRequest* msg)
+{
+    wifi_error ret;
+    ALOGV("NAN_DP_END");
+    struct nlattr *nlData;
+    NanCommand *nanCommand = NULL;
+
+    if (msg == NULL)
+        return WIFI_ERROR_INVALID_ARGS;
+
+    ret = nan_initialize_vendor_cmd(iface,
+                                    &nanCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        return ret;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (nanCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+            QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST) ||
+        nanCommand->put_u16(
+            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+            id) ||
+        nanCommand->put_bytes(
+            QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
+            (char *)msg->ndp_instance_id,
+            msg->num_ndp_instances * sizeof(u32))) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    nanCommand->attr_end(nlData);
+
+    ret = nanCommand->requestEvent();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete nanCommand;
+    return ret;
+}
+
+// Implementation related to nan class common functions
+// Constructor
+//Making the constructor private since this class is a singleton
+NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    memset(&mHandler, 0,sizeof(mHandler));
+    mNanVendorEvent = NULL;
+    mNanDataLen = 0;
+    mStaParam = NULL;
+    memset(mNmiMac, 0, sizeof(mNmiMac));
+    mStorePubParams = NULL;
+    mStoreSubParams = NULL;
+    mNanMaxPublishes = 0;
+    mNanMaxSubscribes = 0;
+    mNanDiscAddrIndDisabled = false;
+}
+
+NanCommand* NanCommand::instance(wifi_handle handle)
+{
+    hal_info *info;
+
+    if (handle == NULL) {
+        ALOGE("Handle is invalid");
+        return NULL;
+    }
+    info = getHalInfo(handle);
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return NULL;
+    }
+
+    if (mNanCommandInstance == NULL) {
+        mNanCommandInstance = new NanCommand(handle, 0,
+                                             OUI_QCA,
+                                             info->support_nan_ext_cmd?
+                                             QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
+                                             QCA_NL80211_VENDOR_SUBCMD_NAN);
+        ALOGV("NanCommand %p created", mNanCommandInstance);
+        return mNanCommandInstance;
+    } else {
+        if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
+            /* upper layer must have cleaned up the handle and reinitialized,
+               so we need to update the same */
+            ALOGI("Handle different, update the handle");
+            mNanCommandInstance->mInfo = (hal_info *)handle;
+        }
+    }
+    ALOGV("NanCommand %p created already", mNanCommandInstance);
+    return mNanCommandInstance;
+}
+
+void NanCommand::cleanup()
+{
+    //free the VendorData
+    if (mVendorData) {
+        free(mVendorData);
+    }
+    mVendorData = NULL;
+    //cleanup the mMsg
+    mMsg.destroy();
+}
+
+NanCommand::~NanCommand()
+{
+    ALOGV("NanCommand %p destroyed", this);
+}
+
+int NanCommand::handleResponse(WifiEvent &reply){
+    return NL_SKIP;
+}
+
+/* Save NAN Management Interface address */
+void NanCommand::saveNmi(u8 *mac)
+{
+    memcpy(mNmiMac, mac, NAN_MAC_ADDR_LEN);
+}
+
+/* Get NAN Management Interface address */
+u8 *NanCommand::getNmi()
+{
+    return mNmiMac;
+}
+
+/*
+ * Save the service ID along with Subscribe/Publish ID and Instance ID, which
+ * will be used later for Passphrase to PMK calculation.
+ *
+ * service_id - Service ID received from Firmware either in NAN/NDP Indication
+ * sub_pub_handle - Subscribe/Publish ID received in NAN/NDP Indication
+ * instance_id - Service/NDP instance ID received in NAN/NDP Indication
+ * pool - Subscriber/Publisher entry based on NAN/NDP Indication
+ */
+void NanCommand::saveServiceId(u8 *service_id, u16 sub_pub_handle,
+                               u32 instance_id, NanRole pool)
+{
+    int i;
+
+    if ((service_id == NULL) || (!sub_pub_handle) || (!instance_id)) {
+        ALOGE("%s: Null Parameter received, sub_pub_handle=%d instance_id=%d",
+              __FUNCTION__, sub_pub_handle, instance_id);
+        return;
+    }
+    switch(pool) {
+    case NAN_ROLE_PUBLISHER:
+        if ((mStorePubParams == NULL) || !mNanMaxPublishes)
+            return;
+        for (i = 0; i < mNanMaxPublishes; i++) {
+            /* In 1:n case there can be multiple publish entries with same
+             * publish ID, hence save the new entry if instance ID doesn't match
+             * with the existing entries in the pool
+             */
+            if ((mStorePubParams[i].subscriber_publisher_id) &&
+                (mStorePubParams[i].instance_id != instance_id))
+                continue;
+
+            memset(&mStorePubParams[i], 0, sizeof(mStorePubParams));
+            memcpy(mStorePubParams[i].service_id, service_id, NAN_SVC_ID_SIZE);
+            mStorePubParams[i].subscriber_publisher_id = sub_pub_handle;
+            mStorePubParams[i].instance_id = instance_id;
+            ALOGV("Added new entry in Publisher pool at index=%d with "
+                  "Publish ID=%d and Instance ID=%d", i,
+                  mStorePubParams[i].subscriber_publisher_id,
+                  mStorePubParams[i].instance_id);
+            return;
+        }
+        if (i == mNanMaxPublishes)
+            ALOGV("No empty slot found in publisher pool, entry not saved");
+    break;
+    case NAN_ROLE_SUBSCRIBER:
+        if ((mStoreSubParams == NULL) || !mNanMaxSubscribes)
+            return;
+        for (i = 0; i < mNanMaxSubscribes; i++) {
+            /* In 1:n case there can be multiple subscribe entries with same
+             * subscribe ID, hence save new entry if instance ID doesn't match
+             * with the existing entries in the pool
+             */
+            if ((mStoreSubParams[i].subscriber_publisher_id) &&
+                (mStoreSubParams[i].instance_id != instance_id))
+                continue;
+
+            memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams));
+            memcpy(mStoreSubParams[i].service_id, service_id, NAN_SVC_ID_SIZE);
+            mStoreSubParams[i].subscriber_publisher_id = sub_pub_handle;
+            mStoreSubParams[i].instance_id = instance_id;
+            ALOGV("Added new entry in Subscriber pool at index=%d with "
+                  "Subscribe ID=%d and Instance ID=%d", i,
+                  mStoreSubParams[i].subscriber_publisher_id,
+                  mStoreSubParams[i].instance_id);
+            return;
+        }
+        if (i == mNanMaxSubscribes)
+            ALOGV("No empty slot found in subscriber pool, entry not saved");
+    break;
+    default:
+        ALOGE("Invalid Pool: %d", pool);
+    break;
+    }
+}
+
+/*
+ * Get the Service ID from the pool based on the Service/NDP instance ID that
+ * will be used for Passphrase to PMK calculation in Initiator/Responder request
+ *
+ * instance_id - Service/NDP instance ID received in NAN/NDP Indication
+ * pool - Subscriber/Publisher role based on the Initiator/Responder
+ */
+u8 *NanCommand::getServiceId(u32 instance_id, NanRole pool)
+{
+    int i;
+
+    switch(pool) {
+    case NAN_ROLE_PUBLISHER:
+        if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes)
+            return NULL;
+        ALOGV("Getting Service ID from publisher pool for instance ID=%d", instance_id);
+        for (i = 0; i < mNanMaxPublishes; i++) {
+            if (mStorePubParams[i].instance_id == instance_id)
+                return mStorePubParams[i].service_id;
+        }
+    break;
+    case NAN_ROLE_SUBSCRIBER:
+        if ((mStoreSubParams == NULL )|| (!instance_id) || !mNanMaxSubscribes)
+            return NULL;
+        ALOGV("Getting Service ID from subscriber pool for instance ID=%d", instance_id);
+        for (i = 0; i < mNanMaxSubscribes; i++) {
+            if (mStoreSubParams[i].instance_id == instance_id)
+                return mStoreSubParams[i].service_id;
+        }
+    break;
+    default:
+        ALOGE("Invalid Pool: %d", pool);
+    break;
+    }
+    return NULL;
+}
+
+/*
+ * Delete service ID entry from the pool based on the subscriber/Instance ID
+ *
+ * sub_handle - Subscriber ID received from the Subscribe Cancel
+ * instance_id - NDP Instance ID received from the NDP End Indication
+ */
+void NanCommand::deleteServiceId(u16 sub_handle,
+                                 u32 instance_id, NanRole pool)
+{
+    int i;
+
+    switch(pool) {
+    case NAN_ROLE_PUBLISHER:
+        if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes)
+            return;
+        for (i = 0; i < mNanMaxPublishes; i++) {
+            /* Delete all the entries that has the matching Instance ID */
+            if (mStorePubParams[i].instance_id == instance_id) {
+                ALOGV("Deleted entry at index=%d from publisher pool "
+                      "with publish ID=%d and instance ID=%d", i,
+                      mStorePubParams[i].subscriber_publisher_id,
+                      mStorePubParams[i].instance_id);
+                memset(&mStorePubParams[i], 0, sizeof(mStorePubParams));
+            }
+        }
+    break;
+    case NAN_ROLE_SUBSCRIBER:
+        if ((mStoreSubParams == NULL) || (!sub_handle) || !mNanMaxSubscribes)
+            return;
+        for (i = 0; i < mNanMaxSubscribes; i++) {
+            /* Delete all the entries that has the matching subscribe ID */
+            if (mStoreSubParams[i].subscriber_publisher_id == sub_handle) {
+                ALOGV("Deleted entry at index=%d from subsriber pool "
+                      "with subscribe ID=%d and instance ID=%d", i,
+                      mStoreSubParams[i].subscriber_publisher_id,
+                      mStoreSubParams[i].instance_id);
+                memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams));
+            }
+        }
+    break;
+    default:
+        ALOGE("Invalid Pool: %d", pool);
+    break;
+    }
+}
+
+/*
+ * Allocate the memory for the Subscribe and Publish pools using the Max values
+ * mStorePubParams - Points the Publish pool
+ * mStoreSubParams - Points the Subscribe pool
+ */
+void NanCommand::allocSvcParams()
+{
+    if (mNanMaxPublishes < NAN_DEF_PUB_SUB)
+        mNanMaxPublishes = NAN_DEF_PUB_SUB;
+    if (mNanMaxSubscribes < NAN_DEF_PUB_SUB)
+        mNanMaxSubscribes = NAN_DEF_PUB_SUB;
+
+    if ((mStorePubParams == NULL) && mNanMaxPublishes) {
+        mStorePubParams =
+        (NanStoreSvcParams *)malloc(mNanMaxPublishes*sizeof(NanStoreSvcParams));
+        if (mStorePubParams == NULL) {
+            ALOGE("%s: Publish pool malloc failed", __FUNCTION__);
+            deallocSvcParams();
+            return;
+        }
+        ALOGV("%s: Allocated the Publish pool for max %d entries",
+              __FUNCTION__, mNanMaxPublishes);
+    }
+    if ((mStoreSubParams == NULL) && mNanMaxSubscribes) {
+        mStoreSubParams =
+        (NanStoreSvcParams *)malloc(mNanMaxSubscribes*sizeof(NanStoreSvcParams));
+        if (mStoreSubParams == NULL) {
+            ALOGE("%s: Subscribe pool malloc failed", __FUNCTION__);
+            deallocSvcParams();
+            return;
+        }
+        ALOGV("%s: Allocated the Subscribe pool for max %d entries",
+              __FUNCTION__, mNanMaxSubscribes);
+    }
+}
+
+/*
+ * Reallocate the memory for Subscribe and Publish pools using the Max values
+ * mStorePubParams - Points the Publish pool
+ * mStoreSubParams - Points the Subscribe pool
+ */
+void NanCommand::reallocSvcParams(NanRole pool)
+{
+    switch(pool) {
+    case NAN_ROLE_PUBLISHER:
+        if ((mStorePubParams != NULL) && mNanMaxPublishes) {
+            mStorePubParams =
+            (NanStoreSvcParams *)realloc(mStorePubParams,
+                                         mNanMaxPublishes*sizeof(NanStoreSvcParams));
+            if (mStorePubParams == NULL) {
+                ALOGE("%s: Publish pool realloc failed", __FUNCTION__);
+                deallocSvcParams();
+                return;
+            }
+            ALOGV("%s: Reallocated the Publish pool for max %d entries",
+                   __FUNCTION__, mNanMaxPublishes);
+        }
+    break;
+    case NAN_ROLE_SUBSCRIBER:
+        if ((mStoreSubParams != NULL) && mNanMaxSubscribes) {
+            mStoreSubParams =
+            (NanStoreSvcParams *)realloc(mStoreSubParams,
+                                         mNanMaxSubscribes*sizeof(NanStoreSvcParams));
+            if (mStoreSubParams == NULL) {
+                ALOGE("%s: Subscribe pool realloc failed", __FUNCTION__);
+                deallocSvcParams();
+                return;
+            }
+            ALOGV("%s: Reallocated the Subscribe pool for max %d entries",
+                  __FUNCTION__, mNanMaxSubscribes);
+        }
+    break;
+    default:
+        ALOGE("Invalid Pool: %d", pool);
+    break;
+    }
+}
+
+/*
+ * Deallocate the Subscribe and Publish pools
+ * mStorePubParams - Points the Publish pool
+ * mStoreSubParams - Points the Subscribe pool
+ */
+void NanCommand::deallocSvcParams()
+{
+    if (mStorePubParams != NULL) {
+        free(mStorePubParams);
+        mStorePubParams = NULL;
+        ALOGV("%s: Deallocated Publish pool", __FUNCTION__);
+    }
+    if (mStoreSubParams != NULL) {
+        free(mStoreSubParams);
+        mStoreSubParams = NULL;
+        ALOGV("%s: Deallocated Subscribe pool", __FUNCTION__);
+    }
+}
+
+wifi_error NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
+{
+    wifi_error res;
+    mHandler = nHandler;
+    res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NAN);
+    if (res != WIFI_SUCCESS) {
+        //error case should not happen print log
+        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
+              "subcmd=QCA_NL80211_VENDOR_SUBCMD_NAN", __FUNCTION__, mVendor_id);
+        return res;
+    }
+
+    res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NDP);
+    if (res != WIFI_SUCCESS) {
+        //error case should not happen print log
+        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
+              "subcmd=QCA_NL80211_VENDOR_SUBCMD_NDP", __FUNCTION__, mVendor_id);
+        return res;
+    }
+    return res;
+}
+
+/* This function implements creation of Vendor command */
+wifi_error NanCommand::create() {
+    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+
+    /* Insert the oui in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+    /* Insert the subcmd in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+
+out:
+    if (ret != WIFI_SUCCESS)
+        mMsg.destroy();
+    return ret;
+}
+
+// This function will be the main handler for incoming event
+// QCA_NL80211_VENDOR_SUBCMD_NAN
+//Call the appropriate callback handler after parsing the vendor data.
+int NanCommand::handleEvent(WifiEvent &event)
+{
+    WifiVendorCommand::handleEvent(event);
+    ALOGV("%s: Subcmd=%u Vendor data len received:%d",
+          __FUNCTION__, mSubcmd, mDataLen);
+    hexdump(mVendorData, mDataLen);
+
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
+        // Parse the vendordata and get the NAN attribute
+        struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+        nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
+                  (struct nlattr *)mVendorData,
+                  mDataLen, NULL);
+        // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
+        mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
+        mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
+
+        if (isNanResponse()) {
+            //handleNanResponse will parse the data and call
+            //the response callback handler with the populated
+            //NanResponseMsg
+            handleNanResponse();
+        } else {
+            //handleNanIndication will parse the data and call
+            //the corresponding Indication callback handler
+            //with the corresponding populated Indication event
+            handleNanIndication();
+        }
+    } else if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NDP) {
+        // Parse the vendordata and get the NAN attribute
+        u32 ndpCmdType;
+        struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
+        nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
+                  (struct nlattr *)mVendorData,
+                  mDataLen, NULL);
+
+        if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
+            ndpCmdType =
+                nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
+                ALOGD("%s: NDP Cmd Type : val 0x%x",
+                      __FUNCTION__, ndpCmdType);
+                switch (ndpCmdType) {
+                case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
+                    handleNdpResponse(NAN_DP_INTERFACE_CREATE, tb_vendor);
+                    break;
+                case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
+                    handleNdpResponse(NAN_DP_INTERFACE_DELETE, tb_vendor);
+                    break;
+                case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE:
+                    handleNdpResponse(NAN_DP_INITIATOR_RESPONSE, tb_vendor);
+                    break;
+                case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE:
+                    handleNdpResponse(NAN_DP_RESPONDER_RESPONSE, tb_vendor);
+                    break;
+                case QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE:
+                    handleNdpResponse(NAN_DP_END, tb_vendor);
+                    break;
+                case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND:
+                case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
+                case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
+                case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
+                    handleNdpIndication(ndpCmdType, tb_vendor);
+                    break;
+                default:
+                    ALOGE("%s: Invalid NDP subcmd response received %d",
+                          __FUNCTION__, ndpCmdType);
+                }
+        }
+    } else {
+        //error case should not happen print log
+        ALOGE("%s: Wrong NAN subcmd received %d", __FUNCTION__, mSubcmd);
+    }
+    mNanVendorEvent = NULL;
+    return NL_SKIP;
+}
+
+/*Helper function to Write and Read TLV called in indication as well as request */
+u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
+{
+    u16 writeLen = 0;
+    u16 i;
+
+    if (!pInTlv)
+    {
+        ALOGE("NULL pInTlv");
+        return writeLen;
+    }
+
+    if (!pOutTlv)
+    {
+        ALOGE("NULL pOutTlv");
+        return writeLen;
+    }
+
+    *pOutTlv++ = pInTlv->type & 0xFF;
+    *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
+    writeLen += 2;
+
+    ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
+
+    *pOutTlv++ = pInTlv->length & 0xFF;
+    *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
+    writeLen += 2;
+
+    ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
+
+    for (i=0; i < pInTlv->length; ++i)
+    {
+        *pOutTlv++ = pInTlv->value[i];
+    }
+
+    writeLen += pInTlv->length;
+    ALOGV("WRITE TLV value, writeLen %u", writeLen);
+    return writeLen;
+}
+
+u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv, int inBufferSize)
+{
+    u16 readLen = 0;
+
+    if (!pInTlv)
+    {
+        ALOGE("NULL pInTlv");
+        return readLen;
+    }
+
+    if (!pOutTlv)
+    {
+        ALOGE("NULL pOutTlv");
+        return readLen;
+    }
+
+    if(inBufferSize < NAN_TLV_HEADER_SIZE) {
+        ALOGE("Insufficient length to process TLV header, inBufferSize = %d",
+              inBufferSize);
+        return readLen;
+    }
+
+    pOutTlv->type = *pInTlv++;
+    pOutTlv->type |= *pInTlv++ << 8;
+    readLen += 2;
+
+    ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
+
+    pOutTlv->length = *pInTlv++;
+    pOutTlv->length |= *pInTlv++ << 8;
+    readLen += 2;
+
+    if(pOutTlv->length > (u16)(inBufferSize - NAN_TLV_HEADER_SIZE)) {
+        ALOGE("Insufficient length to process TLV header, inBufferSize = %d",
+              inBufferSize);
+        return readLen;
+    }
+
+    ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
+
+    if (pOutTlv->length) {
+        pOutTlv->value = pInTlv;
+        readLen += pOutTlv->length;
+    } else {
+        pOutTlv->value = NULL;
+    }
+
+    ALOGV("READ TLV  readLen %u", readLen);
+    return readLen;
+}
+
+u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
+{
+   NanTlv nanTlv;
+   u16 len;
+
+   nanTlv.type = type;
+   nanTlv.length = length;
+   nanTlv.value = (u8*)value;
+
+   len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
+   return (pOutTlv + len);
+}
diff --git a/wcn6740/qcwcn/wifi_hal/nan_cert.h b/wcn6740/qcwcn/wifi_hal/nan_cert.h
new file mode 100644
index 0000000..19b2882
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/nan_cert.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NAN_CERT_H__
+#define __NAN_CERT_H__
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#ifndef PACKED
+#define PACKED  __attribute__((packed))
+#endif
+#define NAN_CERT_VERSION                        5
+#define NAN_MAX_DEBUG_MESSAGE_DATA_LEN          100
+#define NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL       16
+
+typedef struct {
+    /* NAN master rank being advertised by DE */
+    u64 master_rank;
+    /* NAN master preference being advertised by DE */
+    u8 master_pref;
+    /* random value being advertised by DE */
+    u8 random_factor;
+    /* hop_count from anchor master */
+    u8 hop_count;
+    u32 beacon_transmit_time;
+    /* NDP channel Frequency */
+    u32 ndp_channel_freq;
+} NanStaParameter;
+
+/* NAN Data Path Supported Band */
+typedef enum {
+    NAN_DATA_PATH_SUPPORTED_BAND_2G = 1,
+    NAN_DATA_PATH_SUPPORTED_BAND_5G = 2,
+    NAN_DATA_PATH_SUPPORT_DUAL_BAND = 3
+} NdpSupportedBand;
+
+/* NAN Responder mode policy */
+typedef enum {
+    NAN_DATA_RESPONDER_MODE_AUTO    = 0,
+    NAN_DATA_RESPONDER_MODE_ACCEPT  = 1,
+    NAN_DATA_RESPONDER_MODE_REJECT  = 2,
+    NAN_DATA_RESPONDER_MODE_COUNTER = 3,
+    NAN_DATA_RESPONDER_MODE_COUNTER_NO_CHANNEL_CHANGE = 4
+} NanDataResponderMode;
+
+/* NAN Data Path M4 response type */
+typedef enum {
+    NAN_DATA_PATH_M4_RESPONSE_ACCEPT = 1,
+    NAN_DATA_PATH_M4_RESPONSE_REJECT = 2,
+    NAN_DATA_PATH_M4_RESPONSE_BADMIC = 3
+} NdpM4ResponseType;
+
+/* NAN NMF Security Clear type */
+typedef enum {
+    NAN_NMF_CLEAR_DISABLE = 0,
+    NAN_NMF_CLEAR_ENABLE = 1
+} NanNmfClearConfig;
+
+/* NAN Schedule type */
+typedef enum {
+    NAN_SCHED_VALID = 0,
+    NAN_SCHED_INVALID_BAD_FA = 1,
+    NAN_SCHED_INVALID_BAD_NDC = 2,
+    NAN_SCHED_INVALID_BAD_IMMU = 3
+} NanSchedType;
+
+/* NAN device type */
+typedef enum {
+    NAN_DEVICE_TYPE_TEST_BED = 1,
+    NAN_DEVICE_TYPE_DUT = 2
+} NanDeviceType;
+
+/* NAN NDPE absent or present */
+typedef enum {
+    NAN_NDPE_ATTR_PRESENT = 0,
+    NAN_NDPE_ATTR_ABSENT = 1
+} NanNdpeAttrType;
+
+/* NAN NDP absent or present */
+typedef enum {
+    NAN_NDP_ATTR_ABSENT = 0,
+    NAN_NDP_ATTR_PRESENT = 1
+} NanNdpAttrType;
+
+/* NAN IPV6 implicit or explicit */
+typedef enum {
+   NAN_IPV6_EXPLICIT = 0,
+   NAN_IPV6_IMPLICIT = 1
+} NanIPv6Type;
+
+/* NAN IPV6 address, port number and protocol type */
+#define NAN_MSG_IPV6_INTF_ADDR_LEN    16
+
+typedef struct PACKED
+{
+    /* Presence of ipv6_intf_addr */
+    u32 ipv6_addr_present;
+    /* Presence of transport Port */
+    u32 trans_port_present;
+    /* Presence of  transport Protocol */
+    u32 trans_proto_present;
+    /* ipv6 Interface address */
+    u8  ipv6_intf_addr[NAN_MSG_IPV6_INTF_ADDR_LEN];
+    /* Transport Port */
+    u32 transport_port;
+    /* Transport Protocol */
+    u32 transport_protocol;
+} NdpIpTransParams, *pNdpIpTransParams;
+
+ /*
+  * Definitions of debug subcommand type for the
+  * generic debug command.
+  */
+typedef enum {
+    NAN_TEST_MODE_CMD_NAN_AVAILABILITY = 1,
+    NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE = 2,
+    NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL = 3,
+    NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS = 4,
+    NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE = 5,
+    NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE = 6,
+    NAN_TEST_MODE_CMD_NAN_SCHED_TYPE = 7,
+    NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG = 8,
+    NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY = 9,
+    NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE = 10,
+    NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY = 11,
+    NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER = 12,
+    NAN_TEST_MODE_CMD_CONFIG_QOS = 13,
+    NAN_TEST_MODE_CMD_DEVICE_TYPE = 14,
+    NAN_TEST_MODE_CMD_DISABLE_NDPE = 15,
+    NAN_TEST_MODE_CMD_ENABLE_NDP = 16,
+    NAN_TEST_MODE_CMD_DISABLE_IPV6_LINK_LOCAL = 17,
+    NAN_TEST_MODE_CMD_TRANSPORT_IP_PARAM = 18,
+} NanDebugModeCmd;
+
+/*
+ * This debug command carries any one command type
+ * followed by corresponding command data content
+ * as indicated below.
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_AVAILABILITY
+ * content: NAN Avaiability attribute blob
+ *
+ * command: NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE
+ * content: u32 value (0 - Ignore 1 - Include immuatable,
+ *                     2 - Don't include immutable)
+ *
+ * command: NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL
+ * content: u32 channel_frequency; (0 - Ignore)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS
+ * content: u32 supported_bands; (0 . Ignore, 1 . 2g,
+ *                                2 . 5g, 3 . 2g & 5g)
+ *
+ * command: NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE
+ * content: u32 auto_resp_mode; (0 . Auto, 1 . Accept,
+ *                               2 . Reject, 3 . Counter)
+ *
+ * command: NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE
+ * content: u32 m4_response_type; (0.Ignore, 1.Accept,
+ *                                 2.Reject, 3.BadMic)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_TYPE
+ * content: u32 invalid_nan_schedule; (0. Valid sched,
+ *                                     1.Invalid Sched bad FA,
+ *                                     2.Invalid schedbad NDC,
+ *                                     3.Invalid sched bad Immutable)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG
+ * content: u32 nmf_security_config_val;(0:NAN_NMF_CLEAR_DISABLE,
+ *                                       1:NAN_NMF_CLEAR_ENABLE)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY
+ * content: u32 channel_availability;(0/1)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE
+ * content: responder_nmi_mac (Responder NMI Mac Address)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY
+ * content: NONE
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER
+ * content: u32 map_order_val; (0/1)
+ *
+ */
+typedef struct PACKED {
+    /*
+     * To indicate the debug command type.
+     */
+    u32 cmd;
+    /*
+     * To hold the data for the above command
+     * type.
+     */
+    u8 debug_cmd_data[NAN_MAX_DEBUG_MESSAGE_DATA_LEN];
+} NanDebugParams;
+
+/*
+   Function to get the sta_parameter expected by Sigma
+   as per CAPI spec.
+*/
+wifi_error nan_get_sta_parameter(transaction_id id,
+                                 wifi_interface_handle iface,
+                                 NanStaParameter* msg);
+
+wifi_error nan_debug_command_config(transaction_id id,
+                                   wifi_interface_handle iface,
+                                   NanDebugParams msg,
+                                   int debug_msg_length);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __NAN_CERT_H__ */
+
diff --git a/wcn6740/qcwcn/wifi_hal/nan_i.h b/wcn6740/qcwcn/wifi_hal/nan_i.h
new file mode 100644
index 0000000..ad69e18
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/nan_i.h
@@ -0,0 +1,1328 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NAN_I_H__
+#define __NAN_I_H__
+
+#include "common.h"
+#include "cpp_bindings.h"
+#include "wifi_hal.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#ifndef PACKED
+#define PACKED  __attribute__((packed))
+#endif
+#define BIT_NONE            0x00
+#define BIT_0               0x01
+#define BIT_1               0x02
+#define BIT_2               0x04
+#define BIT_3               0x08
+#define BIT_4               0x10
+#define BIT_5               0x20
+#define BIT_6               0x40
+#define BIT_7               0x80
+#define BIT_8               0x0100
+#define BIT_9               0x0200
+#define BIT_10              0x0400
+#define BIT_11              0x0800
+#define BIT_12              0x1000
+#define BIT_13              0x2000
+#define BIT_14              0x4000
+#define BIT_15              0x8000
+#define BIT_16              0x010000
+#define BIT_17              0x020000
+#define BIT_18              0x040000
+#define BIT_19              0x080000
+#define BIT_20              0x100000
+#define BIT_21              0x200000
+#define BIT_22              0x400000
+#define BIT_23              0x800000
+#define BIT_24              0x01000000
+#define BIT_25              0x02000000
+#define BIT_26              0x04000000
+#define BIT_27              0x08000000
+#define BIT_28              0x10000000
+#define BIT_29              0x20000000
+#define BIT_30              0x40000000
+#define BIT_31              0x80000000
+
+/** macro to convert FW MAC address from WMI word format to User Space MAC char array */
+#define FW_MAC_ADDR_TO_CHAR_ARRAY(fw_mac_addr, mac_addr) do { \
+     (mac_addr)[0] =    ((fw_mac_addr).mac_addr31to0) & 0xff; \
+     (mac_addr)[1] =  (((fw_mac_addr).mac_addr31to0) >> 8) & 0xff; \
+     (mac_addr)[2] =  (((fw_mac_addr).mac_addr31to0) >> 16) & 0xff; \
+     (mac_addr)[3] =  (((fw_mac_addr).mac_addr31to0) >> 24) & 0xff; \
+     (mac_addr)[4] =    ((fw_mac_addr).mac_addr47to32) & 0xff; \
+     (mac_addr)[5] =  (((fw_mac_addr).mac_addr47to32) >> 8) & 0xff; \
+} while (0)
+
+/** macro to convert User space MAC address from char array to FW WMI word format */
+#define CHAR_ARRAY_TO_MAC_ADDR(mac_addr, fw_mac_addr)  do { \
+    (fw_mac_addr).mac_addr31to0  =                   \
+         ((mac_addr)[0] | ((mac_addr)[1] << 8)            \
+           | ((mac_addr)[2] << 16) | ((mac_addr)[3] << 24));          \
+    (fw_mac_addr).mac_addr47to32  =                  \
+         ((mac_addr)[4] | ((mac_addr)[5] << 8));          \
+} while (0)
+
+/*---------------------------------------------------------------------------
+* WLAN NAN CONSTANTS
+*--------------------------------------------------------------------------*/
+
+typedef enum
+{
+    NAN_MSG_ID_ERROR_RSP                    = 0,
+    NAN_MSG_ID_CONFIGURATION_REQ            = 1,
+    NAN_MSG_ID_CONFIGURATION_RSP            = 2,
+    NAN_MSG_ID_PUBLISH_SERVICE_REQ          = 3,
+    NAN_MSG_ID_PUBLISH_SERVICE_RSP          = 4,
+    NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ   = 5,
+    NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP   = 6,
+    NAN_MSG_ID_PUBLISH_REPLIED_IND          = 7,
+    NAN_MSG_ID_PUBLISH_TERMINATED_IND       = 8,
+    NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ        = 9,
+    NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP        = 10,
+    NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ = 11,
+    NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP = 12,
+    NAN_MSG_ID_MATCH_IND                    = 13,
+    NAN_MSG_ID_MATCH_EXPIRED_IND            = 14,
+    NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND     = 15,
+    NAN_MSG_ID_DE_EVENT_IND                 = 16,
+    NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ        = 17,
+    NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP        = 18,
+    NAN_MSG_ID_FOLLOWUP_IND                 = 19,
+    NAN_MSG_ID_STATS_REQ                    = 20,
+    NAN_MSG_ID_STATS_RSP                    = 21,
+    NAN_MSG_ID_ENABLE_REQ                   = 22,
+    NAN_MSG_ID_ENABLE_RSP                   = 23,
+    NAN_MSG_ID_DISABLE_REQ                  = 24,
+    NAN_MSG_ID_DISABLE_RSP                  = 25,
+    NAN_MSG_ID_DISABLE_IND                  = 26,
+    NAN_MSG_ID_TCA_REQ                      = 27,
+    NAN_MSG_ID_TCA_RSP                      = 28,
+    NAN_MSG_ID_TCA_IND                      = 29,
+    NAN_MSG_ID_BEACON_SDF_REQ               = 30,
+    NAN_MSG_ID_BEACON_SDF_RSP               = 31,
+    NAN_MSG_ID_BEACON_SDF_IND               = 32,
+    NAN_MSG_ID_CAPABILITIES_REQ             = 33,
+    NAN_MSG_ID_CAPABILITIES_RSP             = 34,
+    NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND   = 35,
+    NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND   = 36,
+    NAN_MSG_ID_RANGING_RESULT_IND           = 37,
+    NAN_MSG_ID_TESTMODE_REQ                 = 1025,
+    NAN_MSG_ID_TESTMODE_RSP                 = 1026
+} NanMsgId;
+
+/*
+  Various TLV Type ID sent as part of NAN Stats Response
+  or NAN TCA Indication
+*/
+typedef enum
+{
+    NAN_TLV_TYPE_FIRST = 0,
+
+    /* Service Discovery Frame types */
+    NAN_TLV_TYPE_SDF_FIRST = NAN_TLV_TYPE_FIRST,
+    NAN_TLV_TYPE_SERVICE_NAME = NAN_TLV_TYPE_SDF_FIRST,
+    NAN_TLV_TYPE_SDF_MATCH_FILTER,
+    NAN_TLV_TYPE_TX_MATCH_FILTER,
+    NAN_TLV_TYPE_RX_MATCH_FILTER,
+    NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO,
+    NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO =5,
+    NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT = 6,
+    NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE = 7,
+    NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE = 8,
+    NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE = 9,
+    NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE = 10,
+    NAN_TLV_TYPE_NAN_DATA_PATH_PARAMS = 11,
+    NAN_TLV_TYPE_NAN_DATA_SUPPORTED_BAND = 12,
+    NAN_TLV_TYPE_2G_COMMITTED_DW = 13,
+    NAN_TLV_TYPE_5G_COMMITTED_DW = 14,
+    NAN_TLV_TYPE_NAN_DATA_RESPONDER_MODE = 15,
+    NAN_TLV_TYPE_NAN_DATA_ENABLED_IN_MATCH = 16,
+    NAN_TLV_TYPE_NAN_SERVICE_ACCEPT_POLICY = 17,
+    NAN_TLV_TYPE_NAN_CSID = 18,
+    NAN_TLV_TYPE_NAN_SCID = 19,
+    NAN_TLV_TYPE_NAN_PMK = 20,
+    NAN_TLV_TYPE_SDEA_CTRL_PARAMS = 21,
+    NAN_TLV_TYPE_NAN_RANGING_CFG = 22,
+    NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS = 23,
+    NAN_TLV_TYPE_NAN20_RANGING_REQUEST = 24,
+    NAN_TLV_TYPE_NAN20_RANGING_RESULT = 25,
+    NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED = 26,
+    NAN_TLV_TYPE_NAN_PASSPHRASE = 27,
+    NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO = 28,
+    NAN_TLV_TYPE_DEV_CAP_ATTR_CAPABILITY = 29,
+    NAN_TLV_TYPE_IP_TRANSPORT_PARAM = 30,
+    NAN_TLV_TYPE_SERVICE_ID = 31,
+    NAN_TLV_TYPE_SDF_LAST = 4095,
+
+    /* Configuration types */
+    NAN_TLV_TYPE_CONFIG_FIRST = 4096,
+    NAN_TLV_TYPE_24G_SUPPORT = NAN_TLV_TYPE_CONFIG_FIRST,
+    NAN_TLV_TYPE_24G_BEACON,
+    NAN_TLV_TYPE_24G_SDF,
+    NAN_TLV_TYPE_24G_RSSI_CLOSE,
+    NAN_TLV_TYPE_24G_RSSI_MIDDLE = 4100,
+    NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY,
+    NAN_TLV_TYPE_5G_SUPPORT,
+    NAN_TLV_TYPE_5G_BEACON,
+    NAN_TLV_TYPE_5G_SDF,
+    NAN_TLV_TYPE_5G_RSSI_CLOSE,
+    NAN_TLV_TYPE_5G_RSSI_MIDDLE,
+    NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
+    NAN_TLV_TYPE_SID_BEACON,
+    NAN_TLV_TYPE_HOP_COUNT_LIMIT,
+    NAN_TLV_TYPE_MASTER_PREFERENCE = 4110,
+    NAN_TLV_TYPE_CLUSTER_ID_LOW,
+    NAN_TLV_TYPE_CLUSTER_ID_HIGH,
+    NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE,
+    NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID,
+    NAN_TLV_TYPE_SOURCE_MAC_ADDRESS,
+    NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF,
+    NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
+    NAN_TLV_TYPE_DEBUGGING_FLAGS,
+    NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
+    NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT = 4120,
+    NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
+    NAN_TLV_TYPE_HOP_COUNT_FORCE,
+    NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
+    NAN_TLV_TYPE_RANDOM_UPDATE_TIME = 4124,
+    NAN_TLV_TYPE_EARLY_WAKEUP,
+    NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL,
+    NAN_TLV_TYPE_DW_INTERVAL = 4128,
+    NAN_TLV_TYPE_DB_INTERVAL,
+    NAN_TLV_TYPE_FURTHER_AVAILABILITY,
+    NAN_TLV_TYPE_24G_CHANNEL,
+    NAN_TLV_TYPE_5G_CHANNEL,
+    NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL,
+    NAN_TLV_TYPE_RANGING_AUTO_RESPONSE_CFG = 4134,
+    NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON = 4135,
+    NAN_TLV_TYPE_DW_EARLY_TERMINATION = 4136,
+    NAN_TLV_TYPE_TX_RX_CHAINS = 4137,
+    NAN_TLV_TYPE_ENABLE_DEVICE_RANGING = 4138,
+    NAN_TLV_TYPE_CONFIG_LAST = 8191,
+
+    /* Attributes types */
+    NAN_TLV_TYPE_ATTRS_FIRST = 8192,
+    NAN_TLV_TYPE_AVAILABILITY_INTERVALS_MAP = NAN_TLV_TYPE_ATTRS_FIRST,
+    NAN_TLV_TYPE_WLAN_MESH_ID,
+    NAN_TLV_TYPE_MAC_ADDRESS,
+    NAN_TLV_TYPE_RECEIVED_RSSI_VALUE,
+    NAN_TLV_TYPE_CLUSTER_ATTRIBUTE,
+    NAN_TLV_TYPE_WLAN_INFRA_SSID,
+    NAN_TLV_TYPE_ATTRS_LAST = 12287,
+
+    /* Events Type */
+    NAN_TLV_TYPE_EVENTS_FIRST = 12288,
+    NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS = NAN_TLV_TYPE_EVENTS_FIRST,
+    NAN_TLV_TYPE_EVENT_STARTED_CLUSTER,
+    NAN_TLV_TYPE_EVENT_JOINED_CLUSTER,
+    NAN_TLV_TYPE_EVENT_CLUSTER_SCAN_RESULTS,
+    NAN_TLV_TYPE_FAW_MEM_AVAIL,
+    NAN_TLV_TYPE_EVENTS_LAST = 16383,
+
+    /* TCA types */
+    NAN_TLV_TYPE_TCA_FIRST = 16384,
+    NAN_TLV_TYPE_CLUSTER_SIZE_REQ = NAN_TLV_TYPE_TCA_FIRST,
+    NAN_TLV_TYPE_CLUSTER_SIZE_RSP,
+    NAN_TLV_TYPE_TCA_LAST = 32767,
+
+    /* Statistics types */
+    NAN_TLV_TYPE_STATS_FIRST = 32768,
+    NAN_TLV_TYPE_DE_PUBLISH_STATS = NAN_TLV_TYPE_STATS_FIRST,
+    NAN_TLV_TYPE_DE_SUBSCRIBE_STATS,
+    NAN_TLV_TYPE_DE_MAC_STATS,
+    NAN_TLV_TYPE_DE_TIMING_SYNC_STATS,
+    NAN_TLV_TYPE_DE_DW_STATS,
+    NAN_TLV_TYPE_DE_STATS,
+    NAN_TLV_TYPE_STATS_LAST = 36863,
+
+    /* Testmode types */
+    NAN_TLV_TYPE_TESTMODE_FIRST = 36864,
+    NAN_TLV_TYPE_TESTMODE_GENERIC_CMD = NAN_TLV_TYPE_TESTMODE_FIRST,
+    NAN_TLV_TYPE_TESTMODE_LAST = 37000,
+
+    NAN_TLV_TYPE_LAST = 65535
+} NanTlvType;
+
+/* 8-byte control message header used by NAN*/
+typedef struct PACKED
+{
+   u16 msgVersion:4;
+   u16 msgId:12;
+   u16 msgLen;
+   u16 handle;
+   u16 transactionId;
+} NanMsgHeader, *pNanMsgHeader;
+
+/* Enumeration for Version */
+typedef enum
+{
+   NAN_MSG_VERSION1 = 1,
+}NanMsgVersion;
+
+typedef struct PACKED
+{
+    u16 type;
+    u16 length;
+    u8* value;
+} NanTlv, *pNanTlv;
+
+#define SIZEOF_TLV_HDR (sizeof(NanTlv::type) + sizeof(NanTlv::length))
+/* NAN TLV Groups and Types */
+typedef enum
+{
+    NAN_TLV_GROUP_FIRST = 0,
+    NAN_TLV_GROUP_SDF = NAN_TLV_GROUP_FIRST,
+    NAN_TLV_GROUP_CONFIG,
+    NAN_TLV_GROUP_STATS,
+    NAN_TLV_GROUP_ATTRS,
+    NAN_TLV_NUM_GROUPS,
+    NAN_TLV_GROUP_LAST = NAN_TLV_NUM_GROUPS
+} NanTlvGroup;
+
+/* NAN Miscellaneous Constants */
+#define NAN_TTL_INFINITE            0
+#define NAN_REPLY_COUNT_INFINITE    0
+
+/* NAN Confguration 5G Channel Access Bit */
+#define NAN_5G_CHANNEL_ACCESS_UNSUPPORTED   0
+#define NAN_5G_CHANNEL_ACCESS_SUPPORTED     1
+
+/* NAN Configuration Service IDs Enclosure Bit */
+#define NAN_SIDS_NOT_ENCLOSED_IN_BEACONS    0
+#define NAN_SIBS_ENCLOSED_IN_BEACONS        1
+
+/* NAN Configuration Priority */
+#define NAN_CFG_PRIORITY_SERVICE_DISCOVERY  0
+#define NAN_CFG_PRIORITY_DATA_CONNECTION    1
+
+/* NAN Configuration 5G Channel Usage */
+#define NAN_5G_CHANNEL_USAGE_SYNC_AND_DISCOVERY 0
+#define NAN_5G_CHANNEL_USAGE_DISCOVERY_ONLY     1
+
+/* NAN Configuration TX_Beacon Content */
+#define NAN_TX_BEACON_CONTENT_OLD_AM_INFO       0
+#define NAN_TX_BEACON_CONTENT_UPDATED_AM_INFO   1
+
+/* NAN Configuration Miscellaneous Constants */
+#define NAN_MAC_INTERFACE_PERIODICITY_MIN   30
+#define NAN_MAC_INTERFACE_PERIODICITY_MAX   255
+
+#define NAN_DW_RANDOM_TIME_MIN  120
+#define NAN_DW_RANDOM_TIME_MAX  240
+
+#define NAN_INITIAL_SCAN_MIN_IDEAL_PERIOD   200
+#define NAN_INITIAL_SCAN_MAX_IDEAL_PERIOD   300
+
+#define NAN_ONGOING_SCAN_MIN_PERIOD 10
+#define NAN_ONGOING_SCAN_MAX_PERIOD 30
+
+#define NAN_HOP_COUNT_LIMIT 5
+
+#define NAN_WINDOW_DW   0
+#define NAN_WINDOW_FAW  1
+
+#define NAN_TLV_HEADER_SIZE 4
+
+/* NAN Error Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    u16 status;
+    u16 value;
+} NanErrorRspMsg, *pNanErrorRspMsg;
+
+//* NAN Publish Service Req */
+typedef struct PACKED
+{
+    u16 ttl;
+    u16 period;
+    u32 replyIndFlag:1;
+    u32 publishType:2;
+    u32 txType:1;
+    u32 rssiThresholdFlag:1;
+    u32 ota_flag:1;
+    u32 matchAlg:2;
+    u32 count:8;
+    u32 connmap:8;
+    u32 pubTerminatedIndDisableFlag:1;
+    u32 pubMatchExpiredIndDisableFlag:1;
+    u32 followupRxIndDisableFlag:1;
+    u32 reserved2:5;
+    /*
+     * Excludes TLVs
+     *
+     * Required: Service Name,
+     * Optional: Tx Match Filter, Rx Match Filter, Service Specific Info,
+     */
+} NanPublishServiceReqParams, *pNanPublishServiceReqParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanPublishServiceReqParams publishServiceReqParams;
+    u8 ptlv[];
+} NanPublishServiceReqMsg, *pNanPublishServiceReqMsg;
+
+/* NAN Publish Service Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanPublishServiceRspMsg, *pNanPublishServiceRspMsg;
+
+/* NAN Publish Service Cancel Req */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+} NanPublishServiceCancelReqMsg, *pNanPublishServiceCancelReqMsg;
+
+/* NAN Publish Service Cancel Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanPublishServiceCancelRspMsg, *pNanPublishServiceCancelRspMsg;
+
+/* NAN Publish Terminated Ind */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* reason for the termination */
+    u16 reason;
+    u16 reserved;
+} NanPublishTerminatedIndMsg, *pNanPublishTerminatedIndMsg;
+
+/* Params for NAN Publish Replied Ind */
+typedef struct PACKED
+{
+  u32  matchHandle;
+} NanPublishRepliedIndParams;
+
+/* NAN Publish Replied Ind */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanPublishRepliedIndParams publishRepliedIndParams;
+    /*
+     * Excludes TLVs
+     *
+     * Required: MAC Address
+     * Optional: Received RSSI Value
+     *
+     */
+    u8 ptlv[];
+} NanPublishRepliedIndMsg, *pNanPublishRepliedIndMsg;
+
+/* NAN Device Capability Attribute */
+typedef struct PACKED
+{
+    u32 dfs_master:1;
+    u32 ext_key_id:1;
+    u32 simu_ndp_data_recept:1;
+    u32 ndpe_attr_supp:1;
+    u32 reserved:28;
+} NanDevCapAttrCap, *pNanDevCapAttrCap;
+
+/* NAN Subscribe Service Req */
+typedef struct PACKED
+{
+    u16 ttl;
+    u16 period;
+    u32 subscribeType:1;
+    u32 srfAttr:1;
+    u32 srfInclude:1;
+    u32 srfSend:1;
+    u32 ssiRequired:1;
+    u32 matchAlg:2;
+    u32 xbit:1;
+    u32 count:8;
+    u32 rssiThresholdFlag:1;
+    u32 ota_flag:1;
+    u32 subTerminatedIndDisableFlag:1;
+    u32 subMatchExpiredIndDisableFlag:1;
+    u32 followupRxIndDisableFlag:1;
+    u32 reserved:3;
+    u32 connmap:8;
+    /*
+     * Excludes TLVs
+     *
+     * Required: Service Name
+     * Optional: Rx Match Filter, Tx Match Filter, Service Specific Info,
+     */
+} NanSubscribeServiceReqParams, *pNanSubscribeServiceReqParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanSubscribeServiceReqParams subscribeServiceReqParams;
+    u8 ptlv[];
+} NanSubscribeServiceReqMsg, *pNanSubscribeServiceReqMsg;
+
+/* NAN Subscribe Service Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanSubscribeServiceRspMsg, *pNanSubscribeServiceRspMsg;
+
+/* NAN Subscribe Service Cancel Req */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+} NanSubscribeServiceCancelReqMsg, *pNanSubscribeServiceCancelReqMsg;
+
+/* NAN Subscribe Service Cancel Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanSubscribeServiceCancelRspMsg, *pNanSubscribeServiceCancelRspMsg;
+
+/* NAN Subscribe Match Ind */
+typedef struct PACKED
+{
+    u32 matchHandle;
+    u32 matchOccuredFlag:1;
+    u32 outOfResourceFlag:1;
+    u32 reserved:30;
+} NanMatchIndParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanMatchIndParams matchIndParams;
+    u8 ptlv[];
+} NanMatchIndMsg, *pNanMatchIndMsg;
+
+/* NAN Subscribe Unmatch Ind */
+typedef struct PACKED
+{
+    u32 matchHandle;
+} NanmatchExpiredIndParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanmatchExpiredIndParams matchExpiredIndParams;
+} NanMatchExpiredIndMsg, *pNanMatchExpiredIndMsg;
+
+/* NAN Subscribe Terminated Ind */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* reason for the termination */
+    u16 reason;
+    u16 reserved;
+} NanSubscribeTerminatedIndMsg, *pNanSubscribeTerminatedIndMsg;
+
+/* Event Ind */
+typedef struct PACKED
+{
+    u32 eventId:8;
+    u32 reserved:24;
+} NanEventIndParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    u8 ptlv[];
+} NanEventIndMsg, *pNanEventIndMsg;
+
+/* NAN Transmit Followup Req */
+typedef struct PACKED
+{
+    u32 matchHandle;
+    u32 priority:4;
+    u32 window:1;
+    u32 followupTxRspDisableFlag:1;
+    u32 reserved:26;
+    /*
+     * Excludes TLVs
+     *
+     * Required: Service Specific Info or Extended Service Specific Info
+     */
+} NanTransmitFollowupReqParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanTransmitFollowupReqParams transmitFollowupReqParams;
+    u8 ptlv[];
+} NanTransmitFollowupReqMsg, *pNanTransmitFollowupReqMsg;
+
+/* NAN Transmit Followup Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanTransmitFollowupRspMsg, *pNanTransmitFollowupRspMsg;
+
+/* NAN Publish Followup Ind */
+typedef struct PACKED
+{
+    u32 matchHandle;
+    u32 window:1;
+    u32 reserved:31;
+    /*
+     * Excludes TLVs
+     *
+     * Required: Service Specific Info or Extended Service Specific Info
+     */
+} NanFollowupIndParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanFollowupIndParams followupIndParams;
+    u8 ptlv[];
+} NanFollowupIndMsg, *pNanFollowupIndMsg;
+
+/* NAN Statistics Req */
+typedef struct PACKED
+{
+    u32 statsType:8;
+    u32 clear:1;
+    u32 reserved:23;
+} NanStatsReqParams, *pNanStatsReqParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanStatsReqParams statsReqParams;
+} NanStatsReqMsg, *pNanStatsReqMsg;
+
+/* NAN Statistics Rsp */
+typedef struct PACKED
+{
+    /* status of the request */
+    u16 status;
+    u16 value;
+    u8 statsType;
+    u8 reserved;
+} NanStatsRspParams, *pNanStatsRspParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    NanStatsRspParams statsRspParams;
+    u8 ptlv[];
+} NanStatsRspMsg, *pNanStatsRspMsg;
+
+typedef struct PACKED
+{
+    u8 count:7;
+    u8 s:1;
+} NanSidAttr, *pSidAttr;
+
+
+/* NAN Configuration Req */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*
+     * TLVs:
+     *
+     * Required: None.
+     * Optional: SID, Random Time, Master Preference, WLAN Intra Attr,
+     *           P2P Operation Attr, WLAN IBSS Attr, WLAN Mesh Attr
+     */
+    u8 ptlv[];
+} NanConfigurationReqMsg, *pNanConfigurationReqMsg;
+
+/*
+ * Because the Configuration Req message has TLVs in it use the macro below
+ * for the size argument to buffer allocation functions (vs. sizeof(msg)).
+ */
+#define NAN_MAX_CONFIGURATION_REQ_SIZE                       \
+    (                                                        \
+        sizeof(NanMsgHeader)                             +   \
+        SIZEOF_TLV_HDR + sizeof(u8)  /* SID Beacon    */ +   \
+        SIZEOF_TLV_HDR + sizeof(u8)  /* Random Time   */ +   \
+        SIZEOF_TLV_HDR + sizeof(u8)  /* Master Pref   */     \
+    )
+
+/* NAN Configuration Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanConfigurationRspMsg, *pNanConfigurationRspMsg;
+
+/*
+ * Because the Enable Req message has TLVs in it use the macro below for
+ * the size argument to buffer allocation functions (vs. sizeof(msg)).
+ */
+#define NAN_MAX_ENABLE_REQ_SIZE                                 \
+    (                                                           \
+        sizeof(NanMsgHeader)                                +   \
+        SIZEOF_TLV_HDR + sizeof(u16) /* Cluster Low   */    +   \
+        SIZEOF_TLV_HDR + sizeof(u16) /* Cluster High  */    +   \
+        SIZEOF_TLV_HDR + sizeof(u8)  /* Master Pref   */        \
+    )
+
+/* Config Discovery Indication */
+ typedef struct PACKED
+ {
+    u32 disableDiscoveryMacAddressEvent:1;
+    u32 disableDiscoveryStartedClusterEvent:1;
+    u32 disableDiscoveryJoinedClusterEvent:1;
+    u32 reserved:29;
+ } NanConfigDiscoveryIndications;
+
+/* NAN Enable Req */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*
+     * TLVs:
+     *
+     * Required: Cluster Low, Cluster High, Master Preference,
+     * Optional: 5G Support, SID, 5G Sync Disc, RSSI Close, RSSI Medium,
+     *           Hop Count Limit, Random Time, Master Preference,
+     *           WLAN Intra Attr, P2P Operation Attr, WLAN IBSS Attr,
+     *           WLAN Mesh Attr
+     */
+    u8 ptlv[];
+} NanEnableReqMsg, *pNanEnableReqMsg;
+
+/* NAN Enable Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanEnableRspMsg, *pNanEnableRspMsg;
+
+/* NAN Disable Req */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+} NanDisableReqMsg, *pNanDisableReqMsg;
+
+/* NAN Disable Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 reserved;
+} NanDisableRspMsg, *pNanDisableRspMsg;
+
+/* NAN Disable Ind */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* reason for the termination */
+    u16 reason;
+    u16 reserved;
+} NanDisableIndMsg, *pNanDisableIndMsg;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    u8 ptlv[];
+} NanTcaReqMsg, *pNanTcaReqMsg;
+
+/* NAN TCA Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader   fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 value;
+} NanTcaRspMsg, *pNanTcaRspMsg;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*
+     * TLVs:
+     *
+     * Optional: Cluster size.
+     */
+    u8 ptlv[];
+} NanTcaIndMsg, *pNanTcaIndMsg;
+
+/*
+ * Because the TCA Ind message has TLVs in it use the macro below for the
+ * size argument to buffer allocation functions (vs. sizeof(msg)).
+ */
+#define NAN_MAX_TCA_IND_SIZE                                 \
+    (                                                        \
+        sizeof(NanMsgHeader)                             +   \
+        sizeof(NanTcaIndParams)                          +   \
+        SIZEOF_TLV_HDR + sizeof(u16) /* Cluster Size */      \
+    )
+
+/* Function Declarations */
+u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv);
+u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv, int inBufferSize);
+u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv);
+
+/* NAN Beacon Sdf Payload Req */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*
+     * TLVs:
+     *
+     * Optional: Vendor specific attribute
+     */
+    u8 ptlv[];
+} NanBeaconSdfPayloadReqMsg, *pNanBeaconSdfPayloadReqMsg;
+
+/* NAN Beacon Sdf Payload Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader   fwHeader;
+    /* status of the request */
+    u16 status;
+    u16 reserved;
+} NanBeaconSdfPayloadRspMsg, *pNanBeaconSdfPayloadRspMsg;
+
+/* NAN Beacon Sdf Payload Ind */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*
+     * TLVs:
+     *
+     * Required: Mac address
+     * Optional: Vendor specific attribute, sdf payload
+     * receive
+     */
+    u8 ptlv[];
+} NanBeaconSdfPayloadIndMsg, *pNanBeaconSdfPayloadIndMsg;
+
+typedef struct PACKED
+{
+    u8 availIntDuration:2;
+    u8 mapId:4;
+    u8 reserved:2;
+} NanApiEntryCtrl;
+
+/*
+ * Valid Operating Classes were derived from IEEE Std. 802.11-2012 Annex E
+ * Table E-4 Global Operating Classe and, filtered by channel, are: 81, 83,
+ * 84, 103, 114, 115, 116, 124, 125.
+ */
+typedef struct PACKED
+{
+    NanApiEntryCtrl entryCtrl;
+    u8 opClass;
+    u8 channel;
+    u8 availIntBitmap[4];
+} NanFurtherAvailabilityChan, *pNanFurtherAvailabilityChan;
+
+typedef struct PACKED
+{
+    u8 numChan;
+    u8 pFaChan[];
+} NanFurtherAvailabilityMapAttrTlv, *pNanFurtherAvailabilityMapAttrTlv;
+
+/* Publish statistics. */
+typedef struct PACKED
+{
+    u32 validPublishServiceReqMsgs;
+    u32 validPublishServiceRspMsgs;
+    u32 validPublishServiceCancelReqMsgs;
+    u32 validPublishServiceCancelRspMsgs;
+    u32 validPublishRepliedIndMsgs;
+    u32 validPublishTerminatedIndMsgs;
+    u32 validActiveSubscribes;
+    u32 validMatches;
+    u32 validFollowups;
+    u32 invalidPublishServiceReqMsgs;
+    u32 invalidPublishServiceCancelReqMsgs;
+    u32 invalidActiveSubscribes;
+    u32 invalidMatches;
+    u32 invalidFollowups;
+    u32 publishCount;
+    u32 publishNewMatchCount;
+    u32 pubsubGlobalNewMatchCount;
+} FwNanPublishStats, *pFwNanPublishStats;
+
+/* Subscribe statistics. */
+typedef struct PACKED
+{
+    u32 validSubscribeServiceReqMsgs;
+    u32 validSubscribeServiceRspMsgs;
+    u32 validSubscribeServiceCancelReqMsgs;
+    u32 validSubscribeServiceCancelRspMsgs;
+    u32 validSubscribeTerminatedIndMsgs;
+    u32 validSubscribeMatchIndMsgs;
+    u32 validSubscribeUnmatchIndMsgs;
+    u32 validSolicitedPublishes;
+    u32 validMatches;
+    u32 validFollowups;
+    u32 invalidSubscribeServiceReqMsgs;
+    u32 invalidSubscribeServiceCancelReqMsgs;
+    u32 invalidSubscribeFollowupReqMsgs;
+    u32 invalidSolicitedPublishes;
+    u32 invalidMatches;
+    u32 invalidFollowups;
+    u32 subscribeCount;
+    u32 bloomFilterIndex;
+    u32 subscribeNewMatchCount;
+    u32 pubsubGlobalNewMatchCount;
+} FwNanSubscribeStats, *pFwNanSubscribeStats;
+
+/* NAN MAC Statistics. Used for MAC and DW statistics. */
+typedef struct PACKED
+{
+    /* RX stats */
+    u32 validFrames;
+    u32 validActionFrames;
+    u32 validBeaconFrames;
+    u32 ignoredActionFrames;
+    u32 ignoredBeaconFrames;
+    u32 invalidFrames;
+    u32 invalidActionFrames;
+    u32 invalidBeaconFrames;
+    u32 invalidMacHeaders;
+    u32 invalidPafHeaders;
+    u32 nonNanBeaconFrames;
+
+    u32 earlyActionFrames;
+    u32 inDwActionFrames;
+    u32 lateActionFrames;
+
+    /* TX stats */
+    u32 framesQueued;
+    u32 totalTRSpUpdates;
+    u32 completeByTRSp;
+    u32 completeByTp75DW;
+    u32 completeByTendDW;
+    u32 lateActionFramesTx;
+
+    /* Misc stats - ignored for DW. */
+    u32 twIncreases;
+    u32 twDecreases;
+    u32 twChanges;
+    u32 twHighwater;
+    u32 bloomFilterIndex;
+} FwNanMacStats, *pFwNanMacStats;
+
+/* NAN Sync and DW Statistics*/
+typedef struct PACKED
+{
+    u64 currTsf;
+    u64 myRank;
+    u64 currAmRank;
+    u64 lastAmRank;
+    u32 currAmBTT;
+    u32 lastAmBTT;
+    u8  currAmHopCount;
+    u8  currRole;
+    u16 currClusterId;
+    u32 reserved1;
+
+    u64 timeSpentInCurrRole;
+    u64 totalTimeSpentAsMaster;
+    u64 totalTimeSpentAsNonMasterSync;
+    u64 totalTimeSpentAsNonMasterNonSync;
+    u32 transitionsToAnchorMaster;
+    u32 transitionsToMaster;
+    u32 transitionsToNonMasterSync;
+    u32 transitionsToNonMasterNonSync;
+    u32 amrUpdateCount;
+    u32 amrUpdateRankChangedCount;
+    u32 amrUpdateBTTChangedCount;
+    u32 amrUpdateHcChangedCount;
+    u32 amrUpdateNewDeviceCount;
+    u32 amrExpireCount;
+    u32 mergeCount;
+    u32 beaconsAboveHcLimit;
+    u32 beaconsBelowRssiThresh;
+    u32 beaconsIgnoredNoSpace;
+    u32 beaconsForOurCluster;
+    u32 beaconsForOtherCluster;
+    u32 beaconCancelRequests;
+    u32 beaconCancelFailures;
+    u32 beaconUpdateRequests;
+    u32 beaconUpdateFailures;
+    u32 syncBeaconTxAttempts;
+    u32 syncBeaconTxFailures;
+    u32 discBeaconTxAttempts;
+    u32 discBeaconTxFailures;
+    u32 amHopCountExpireCount;
+    u32 ndpChannelFreq;
+    u32 ndpChannelFreq2;
+    u32 schedUpdateChannelFreq;
+} FwNanSyncStats, *pFwNanSyncStats;
+
+/* NAN Misc DE Statistics */
+typedef struct PACKED
+{
+    u32 validErrorRspMsgs;
+    u32 validTransmitFollowupReqMsgs;
+    u32 validTransmitFollowupRspMsgs;
+    u32 validFollowupIndMsgs;
+    u32 validConfigurationReqMsgs;
+    u32 validConfigurationRspMsgs;
+    u32 validStatsReqMsgs;
+    u32 validStatsRspMsgs;
+    u32 validEnableReqMsgs;
+    u32 validEnableRspMsgs;
+    u32 validDisableReqMsgs;
+    u32 validDisableRspMsgs;
+    u32 validDisableIndMsgs;
+    u32 validEventIndMsgs;
+    u32 validTcaReqMsgs;
+    u32 validTcaRspMsgs;
+    u32 validTcaIndMsgs;
+    u32 invalidTransmitFollowupReqMsgs;
+    u32 invalidConfigurationReqMsgs;
+    u32 invalidStatsReqMsgs;
+    u32 invalidEnableReqMsgs;
+    u32 invalidDisableReqMsgs;
+    u32 invalidTcaReqMsgs;
+} FwNanDeStats, *pFwNanDeStats;
+
+/*
+  Definition of various NanIndication(events)
+*/
+typedef enum {
+    NAN_INDICATION_PUBLISH_REPLIED         =0,
+    NAN_INDICATION_PUBLISH_TERMINATED      =1,
+    NAN_INDICATION_MATCH                   =2,
+    NAN_INDICATION_MATCH_EXPIRED           =3,
+    NAN_INDICATION_SUBSCRIBE_TERMINATED    =4,
+    NAN_INDICATION_DE_EVENT                =5,
+    NAN_INDICATION_FOLLOWUP                =6,
+    NAN_INDICATION_DISABLED                =7,
+    NAN_INDICATION_TCA                     =8,
+    NAN_INDICATION_BEACON_SDF_PAYLOAD      =9,
+    NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP  =10,
+    NAN_INDICATION_RANGING_REQUEST_RECEIVED =11,
+    NAN_INDICATION_RANGING_RESULT           =12,
+    NAN_INDICATION_UNKNOWN                 =0xFFFF
+} NanIndicationType;
+
+/* NAN Capabilities Req */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+} NanCapabilitiesReqMsg, *pNanCapabilitiesReqMsg;
+
+/* NAN Capabilities Rsp */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /* status of the request */
+    u32 status;
+    u32 value;
+    u32 max_concurrent_nan_clusters;
+    u32 max_publishes;
+    u32 max_subscribes;
+    u32 max_service_name_len;
+    u32 max_match_filter_len;
+    u32 max_total_match_filter_len;
+    u32 max_service_specific_info_len;
+    u32 max_vsa_data_len;
+    u32 max_mesh_data_len;
+    u32 max_ndi_interfaces;
+    u32 max_ndp_sessions;
+    u32 max_app_info_len;
+    u32 max_queued_transmit_followup_msgs;
+    u32 ndp_supported_bands;
+    u32 cipher_suites_supported;
+    u32 max_scid_len;
+    u32 is_ndp_security_supported:1;
+    u32 max_sdea_service_specific_info_len:16;
+    u32 reserved1:5;
+    u32 reserved2:5;
+    u32 ndpe_attr_supported:1;
+    u32 reserved:4;
+    u32 max_subscribe_address;
+} NanCapabilitiesRspMsg, *pNanCapabilitiesRspMsg;
+
+/* NAN Self Transmit Followup */
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    u32 reason;
+} NanSelfTransmitFollowupIndMsg, *pNanSelfTransmitFollowupIndMsg;
+
+/* NAN Cipher Suite Shared Key */
+typedef struct PACKED
+{
+    u32 csid_type;
+} NanCsidType;
+
+/* Service Discovery Extended Attribute params */
+typedef struct PACKED
+{
+    u32 fsd_required:1;
+    u32 fsd_with_gas:1;
+    u32 data_path_required:1;
+    u32 data_path_type:1;
+    u32 multicast_type:1;
+    u32 qos_required:1;
+    u32 security_required:1;
+    u32 ranging_required:1;
+    u32 range_limit_present:1;
+    u32 service_update_ind_present:1;
+    u32 reserved1:6;
+    u32 range_report:1;
+    u32 reserved2:15;
+} NanFWSdeaCtrlParams;
+
+/* NAN Ranging Configuration params */
+typedef struct PACKED
+{
+    u32  inner_threshold;
+    u32  outer_threshold;
+} NanFWGeoFenceDescriptor;
+
+typedef struct PACKED
+{
+    u32 range_resolution;
+    u32 range_interval;
+    u32 ranging_indication_event;
+    NanFWGeoFenceDescriptor geo_fence_threshold;
+} NanFWRangeConfigParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*
+      Excludes TLVs
+      Optional: Nan Availability
+    */
+    u8 ptlv[];
+} NanTestModeReqMsg, *pNanTestModeReqMsg;
+
+/*
+  NAN Status codes exchanged between firmware
+  and WifiHal.
+*/
+typedef enum {
+    /* NAN Protocol Response Codes */
+    NAN_I_STATUS_SUCCESS = 0,
+    NAN_I_STATUS_TIMEOUT = 1,
+    NAN_I_STATUS_DE_FAILURE = 2,
+    NAN_I_STATUS_INVALID_MSG_VERSION = 3,
+    NAN_I_STATUS_INVALID_MSG_LEN = 4,
+    NAN_I_STATUS_INVALID_MSG_ID = 5,
+    NAN_I_STATUS_INVALID_HANDLE = 6,
+    NAN_I_STATUS_NO_SPACE_AVAILABLE = 7,
+    NAN_I_STATUS_INVALID_PUBLISH_TYPE = 8,
+    NAN_I_STATUS_INVALID_TX_TYPE = 9,
+    NAN_I_STATUS_INVALID_MATCH_ALGORITHM = 10,
+    NAN_I_STATUS_DISABLE_IN_PROGRESS = 11,
+    NAN_I_STATUS_INVALID_TLV_LEN = 12,
+    NAN_I_STATUS_INVALID_TLV_TYPE = 13,
+    NAN_I_STATUS_MISSING_TLV_TYPE = 14,
+    NAN_I_STATUS_INVALID_TOTAL_TLVS_LEN = 15,
+    NAN_I_STATUS_INVALID_REQUESTER_INSTANCE_ID= 16,
+    NAN_I_STATUS_INVALID_TLV_VALUE = 17,
+    NAN_I_STATUS_INVALID_TX_PRIORITY = 18,
+    NAN_I_STATUS_INVALID_CONNECTION_MAP = 19,
+    NAN_I_STATUS_INVALID_THRESHOLD_CROSSING_ALERT_ID = 20,
+    NAN_I_STATUS_INVALID_STATS_ID = 21,
+    NAN_I_STATUS_NAN_NOT_ALLOWED = 22,
+    NAN_I_STATUS_NO_OTA_ACK = 23,
+    NAN_I_STATUS_TX_FAIL = 24,
+    NAN_I_STATUS_NAN_ALREADY_ENABLED = 25,
+    NAN_I_STATUS_FOLLOWUP_QUEUE_FULL = 26,
+    /* 27-4095 Reserved */
+    /* NAN Configuration Response codes */
+    NAN_I_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096,
+    NAN_I_STATUS_INVALID_RSSI_MIDDLE_VALUE = 4097,
+    NAN_I_STATUS_INVALID_HOP_COUNT_LIMIT = 4098,
+    NAN_I_STATUS_INVALID_MASTER_PREFERENCE_VALUE = 4099,
+    NAN_I_STATUS_INVALID_LOW_CLUSTER_ID_VALUE = 4100,
+    NAN_I_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE = 4101,
+    NAN_I_STATUS_INVALID_BACKGROUND_SCAN_PERIOD = 4102,
+    NAN_I_STATUS_INVALID_RSSI_PROXIMITY_VALUE = 4103,
+    NAN_I_STATUS_INVALID_SCAN_CHANNEL = 4104,
+    NAN_I_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP = 4105,
+    NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_NUMCHAN_VALUE = 4106,
+    NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_DURATION_VALUE = 4107,
+    NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CLASS_VALUE = 4108,
+    NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CHANNEL_VALUE = 4109,
+    NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE = 4110,
+    NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_MAP_ID = 4111,
+    NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE = 4112,
+    NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE = 4113,
+    NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE = 4114,
+    NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE = 4115,
+    NAN_I_STATUS_MISSING_FUTHER_AVAILABILITY_MAP = 4116,
+    NAN_I_STATUS_INVALID_BAND_CONFIG_FLAGS = 4117,
+    NAN_I_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE = 4118,
+    NAN_I_STATUS_INVALID_ONGOING_SCAN_PERIOD = 4119,
+    NAN_I_STATUS_INVALID_DW_INTERVAL_VALUE = 4120,
+    NAN_I_STATUS_INVALID_DB_INTERVAL_VALUE = 4121,
+    /* 4122-8191 RESERVED */
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_INVALID = 8192,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_TIMEOUT = 8193,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_USER_REQUEST = 8194,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_FAILURE = 8195,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_COUNT_REACHED = 8196,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_DE_SHUTDOWN = 8197,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_DISABLE_IN_PROGRESS = 8198,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED = 8199,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED = 8200,
+    NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY = 8201,
+    /* 9000-9500 NDP Status type */
+    NDP_I_UNSUPPORTED_CONCURRENCY = 9000,
+    NDP_I_NAN_DATA_IFACE_CREATE_FAILED = 9001,
+    NDP_I_NAN_DATA_IFACE_DELETE_FAILED = 9002,
+    NDP_I_DATA_INITIATOR_REQUEST_FAILED = 9003,
+    NDP_I_DATA_RESPONDER_REQUEST_FAILED = 9004,
+    NDP_I_INVALID_SERVICE_INSTANCE_ID = 9005,
+    NDP_I_INVALID_NDP_INSTANCE_ID = 9006,
+    NDP_I_INVALID_RESPONSE_CODE = 9007,
+    NDP_I_INVALID_APP_INFO_LEN = 9008,
+    /* OTA failures and timeouts during negotiation */
+    NDP_I_MGMT_FRAME_REQUEST_FAILED = 9009,
+    NDP_I_MGMT_FRAME_RESPONSE_FAILED = 9010,
+    NDP_I_MGMT_FRAME_CONFIRM_FAILED = 9011,
+    NDP_I_END_FAILED = 9012,
+    NDP_I_MGMT_FRAME_END_REQUEST_FAILED = 9013,
+    NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED = 9014,
+
+    /* 9500 onwards vendor specific error codes */
+    NDP_I_VENDOR_SPECIFIC_ERROR = 9500
+} NanInternalStatusType;
+
+/* This is the TLV used for range report */
+typedef struct PACKED
+{
+    u32 publish_id;
+    u32 event_type;
+    u32 range_measurement;
+} NanFWRangeReportParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*TLV Required:
+        MANDATORY
+            1. MAC_ADDRESS
+            2. NanFWRangeReportParams
+        OPTIONAL:
+            1. A_UINT32 event type
+    */
+    u8 ptlv[1];
+} NanFWRangeReportInd, *pNanFWRangeReportInd;
+
+/** 2 word representation of MAC addr */
+typedef struct {
+    /** upper 4 bytes of  MAC address */
+    u32 mac_addr31to0;
+    /** lower 2 bytes of  MAC address */
+    u32 mac_addr47to32;
+} fw_mac_addr;
+
+/* This is the TLV used to trigger ranging requests*/
+typedef struct PACKED
+{
+    fw_mac_addr  range_mac_addr;
+    u32 range_id; //Match handle in match_ind, publish_id in result ind
+    u32 ranging_accept:1;
+    u32 ranging_reject:1;
+    u32 ranging_cancel:1;
+    u32 reserved:29;
+} NanFWRangeReqMsg, *pNanFWRangeReqMsg;
+
+typedef struct PACKED
+{
+    fw_mac_addr  range_mac_addr;
+    u32 range_id;//This will publish_id in case of receiving publish.
+} NanFWRangeReqRecvdMsg, *pNanFWRangeReqRecvdMsg;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*TLV Required
+       1. t_nan_range_req_recvd_msg
+    */
+    u8 ptlv[1];
+} NanFWRangeReqRecvdInd, *pNanFWRangeReqRecvdInd;
+
+/* Function for NAN error translation
+   For NanResponse, NanPublishTerminatedInd, NanSubscribeTerminatedInd,
+   NanDisabledInd, NanTransmitFollowupInd:
+   function to translate firmware specific errors
+   to generic freamework error along with the error string
+*/
+void NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd,
+                         u32 valueRcvd,
+                         void *pRsp,
+                         bool is_ndp_rsp);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __NAN_I_H__ */
+
diff --git a/wcn6740/qcwcn/wifi_hal/nan_ind.cpp b/wcn6740/qcwcn/wifi_hal/nan_ind.cpp
new file mode 100644
index 0000000..47ad8f8
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/nan_ind.cpp
@@ -0,0 +1,1452 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sync.h"
+#include <utils/Log.h>
+#include <errno.h>
+#include "wifi_hal.h"
+#include "nan_i.h"
+#include "nancommand.h"
+#include <errno.h>
+
+//Function which calls the necessaryIndication callback
+//based on the indication type
+int NanCommand::handleNanIndication()
+{
+    //Based on the message_id in the header determine the Indication type
+    //and call the necessary callback handler
+    u16 msg_id;
+    int res = 0;
+
+    msg_id = getIndicationType();
+
+    ALOGV("handleNanIndication msg_id:%u", msg_id);
+    switch (msg_id) {
+    case NAN_INDICATION_PUBLISH_REPLIED:
+        NanPublishRepliedInd publishRepliedInd;
+        memset(&publishRepliedInd, 0, sizeof(publishRepliedInd));
+        res = getNanPublishReplied(&publishRepliedInd);
+        if (!res && mHandler.EventPublishReplied) {
+            (*mHandler.EventPublishReplied)(&publishRepliedInd);
+        }
+        break;
+
+    case NAN_INDICATION_PUBLISH_TERMINATED:
+        NanPublishTerminatedInd publishTerminatedInd;
+        memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd));
+        res = getNanPublishTerminated(&publishTerminatedInd);
+        if (!res && mHandler.EventPublishTerminated) {
+            (*mHandler.EventPublishTerminated)(&publishTerminatedInd);
+        }
+        break;
+
+    case NAN_INDICATION_MATCH:
+        NanMatchInd matchInd;
+        memset(&matchInd, 0, sizeof(matchInd));
+        res = getNanMatch(&matchInd);
+        if (!res && mHandler.EventMatch) {
+            (*mHandler.EventMatch)(&matchInd);
+        }
+        break;
+
+    case NAN_INDICATION_MATCH_EXPIRED:
+        NanMatchExpiredInd matchExpiredInd;
+        memset(&matchExpiredInd, 0, sizeof(matchExpiredInd));
+        res = getNanMatchExpired(&matchExpiredInd);
+        if (!res && mHandler.EventMatchExpired) {
+            (*mHandler.EventMatchExpired)(&matchExpiredInd);
+        }
+        break;
+
+    case NAN_INDICATION_SUBSCRIBE_TERMINATED:
+        NanSubscribeTerminatedInd subscribeTerminatedInd;
+        memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd));
+        res = getNanSubscribeTerminated(&subscribeTerminatedInd);
+        if (!res && mHandler.EventSubscribeTerminated) {
+            (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd);
+        }
+        break;
+
+    case NAN_INDICATION_DE_EVENT:
+        NanDiscEngEventInd discEngEventInd;
+        memset(&discEngEventInd, 0, sizeof(discEngEventInd));
+        res = getNanDiscEngEvent(&discEngEventInd);
+        /* Save the self MAC address received in DE indication event to use it
+         * in Passphrase to PMK calculation. And do not call the handler if the
+         * framework has disabled the self MAC address indication.
+         */
+        if (!res &&
+            (discEngEventInd.event_type == NAN_EVENT_ID_DISC_MAC_ADDR)) {
+            mNanCommandInstance->saveNmi(discEngEventInd.data.mac_addr.addr);
+            if (mNanCommandInstance->mNanDiscAddrIndDisabled)
+                break;
+        }
+        if (!res && mHandler.EventDiscEngEvent) {
+            (*mHandler.EventDiscEngEvent)(&discEngEventInd);
+        }
+        break;
+
+    case NAN_INDICATION_FOLLOWUP:
+        NanFollowupInd followupInd;
+        memset(&followupInd, 0, sizeof(followupInd));
+        res = getNanFollowup(&followupInd);
+        if (!res && mHandler.EventFollowup) {
+            (*mHandler.EventFollowup)(&followupInd);
+        }
+        break;
+
+    case NAN_INDICATION_DISABLED:
+        NanDisabledInd disabledInd;
+        memset(&disabledInd, 0, sizeof(disabledInd));
+        res = getNanDisabled(&disabledInd);
+        if (!res && mHandler.EventDisabled) {
+            (*mHandler.EventDisabled)(&disabledInd);
+        }
+        break;
+
+    case NAN_INDICATION_TCA:
+        NanTCAInd tcaInd;
+        memset(&tcaInd, 0, sizeof(tcaInd));
+        res = getNanTca(&tcaInd);
+        if (!res && mHandler.EventTca) {
+            (*mHandler.EventTca)(&tcaInd);
+        }
+        break;
+
+    case NAN_INDICATION_BEACON_SDF_PAYLOAD:
+        NanBeaconSdfPayloadInd beaconSdfPayloadInd;
+        memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd));
+        res = getNanBeaconSdfPayload(&beaconSdfPayloadInd);
+        if (!res && mHandler.EventBeaconSdfPayload) {
+            (*mHandler.EventBeaconSdfPayload)(&beaconSdfPayloadInd);
+        }
+        break;
+
+    case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP:
+        NanTransmitFollowupInd transmitFollowupInd;
+        memset(&transmitFollowupInd, 0, sizeof(NanTransmitFollowupInd));
+        res = getNanTransmitFollowupInd(&transmitFollowupInd);
+        if (!res && mHandler.EventTransmitFollowup) {
+            (*mHandler.EventTransmitFollowup)(&transmitFollowupInd);
+        }
+        break;
+
+    case NAN_INDICATION_RANGING_REQUEST_RECEIVED:
+        NanRangeRequestInd rangeRequestInd;
+        memset(&rangeRequestInd, 0, sizeof(NanRangeRequestInd));
+        res = getNanRangeRequestReceivedInd(&rangeRequestInd);
+        if (!res && mHandler.EventRangeRequest) {
+            (*mHandler.EventRangeRequest)(&rangeRequestInd);
+        }
+        break;
+
+    case NAN_INDICATION_RANGING_RESULT:
+        NanRangeReportInd rangeReportInd;
+        memset(&rangeReportInd, 0, sizeof(NanRangeReportInd));
+        res = getNanRangeReportInd(&rangeReportInd);
+        if (!res && mHandler.EventRangeReport) {
+            (*mHandler.EventRangeReport)(&rangeReportInd);
+        }
+        break;
+
+    default:
+        ALOGE("handleNanIndication error invalid msg_id:%u", msg_id);
+        res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
+        break;
+    }
+    return res;
+}
+
+//Function which will return the Nan Indication type based on
+//the initial few bytes of mNanVendorEvent
+NanIndicationType NanCommand::getIndicationType()
+{
+    if (mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid argument mNanVendorEvent:%p",
+              __func__, mNanVendorEvent);
+        return NAN_INDICATION_UNKNOWN;
+    }
+
+    NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
+
+    switch (pHeader->msgId) {
+    case NAN_MSG_ID_PUBLISH_REPLIED_IND:
+        return NAN_INDICATION_PUBLISH_REPLIED;
+    case NAN_MSG_ID_PUBLISH_TERMINATED_IND:
+        return NAN_INDICATION_PUBLISH_TERMINATED;
+    case NAN_MSG_ID_MATCH_IND:
+        return NAN_INDICATION_MATCH;
+    case NAN_MSG_ID_MATCH_EXPIRED_IND:
+        return NAN_INDICATION_MATCH_EXPIRED;
+    case NAN_MSG_ID_FOLLOWUP_IND:
+        return NAN_INDICATION_FOLLOWUP;
+    case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND:
+        return NAN_INDICATION_SUBSCRIBE_TERMINATED;
+    case  NAN_MSG_ID_DE_EVENT_IND:
+        return NAN_INDICATION_DE_EVENT;
+    case NAN_MSG_ID_DISABLE_IND:
+        return NAN_INDICATION_DISABLED;
+    case NAN_MSG_ID_TCA_IND:
+        return NAN_INDICATION_TCA;
+    case NAN_MSG_ID_BEACON_SDF_IND:
+        return NAN_INDICATION_BEACON_SDF_PAYLOAD;
+    case NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND:
+        return NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP;
+    case NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND:
+        return NAN_INDICATION_RANGING_REQUEST_RECEIVED;
+    case NAN_MSG_ID_RANGING_RESULT_IND:
+        return NAN_INDICATION_RANGING_RESULT;
+    default:
+        return NAN_INDICATION_UNKNOWN;
+    }
+}
+
+int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanPublishRepliedIndMsg pRsp = (pNanPublishRepliedIndMsg)mNanVendorEvent;
+    event->requestor_instance_id = pRsp->publishRepliedIndParams.matchHandle;
+
+    event->rssi_value = 0;
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+    int remainingLen = (mNanDataLen - \
+        (sizeof(NanMsgHeader)));
+
+    if (remainingLen <= 0) {
+        ALOGI("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_MAC_ADDRESS:
+            if (outputTlv.length > sizeof(event->addr)) {
+                outputTlv.length = sizeof(event->addr);
+            }
+            memcpy(event->addr, outputTlv.value, outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
+            if (outputTlv.length > sizeof(event->rssi_value)) {
+                outputTlv.length = sizeof(event->rssi_value);
+            }
+            memcpy(&event->rssi_value, outputTlv.value,
+                   outputTlv.length);
+            break;
+        default:
+            ALOGI("Unknown TLV type skipped");
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv, 0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent;
+    event->publish_id = pRsp->fwHeader.handle;
+    NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
+                        (void*)event, false);
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanMatch(NanMatchInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent;
+    event->publish_subscribe_id = pRsp->fwHeader.handle;
+    event->requestor_instance_id = pRsp->matchIndParams.matchHandle;
+    event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag;
+    event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag;
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+    int remainingLen = (mNanDataLen - \
+        (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams)));
+    int ret = 0, idx = 0;
+
+    //Has SDF match filter and service specific info TLV
+    if (remainingLen <= 0) {
+        ALOGV("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
+            if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) {
+                outputTlv.length = NAN_MAX_SERVICE_NAME_LEN;
+            }
+            event->service_specific_info_len = outputTlv.length;
+            memcpy(event->service_specific_info, outputTlv.value,
+                   outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_SDF_MATCH_FILTER:
+            if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) {
+                outputTlv.length = NAN_MAX_MATCH_FILTER_LEN;
+            }
+            event->sdf_match_filter_len = outputTlv.length;
+            memcpy(event->sdf_match_filter, outputTlv.value,
+                   outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_MAC_ADDRESS:
+            if (outputTlv.length > sizeof(event->addr)) {
+                outputTlv.length = sizeof(event->addr);
+            }
+            memcpy(event->addr, outputTlv.value, outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
+            if (outputTlv.length > sizeof(event->rssi_value)) {
+                outputTlv.length = sizeof(event->rssi_value);
+            }
+            memcpy(&event->rssi_value, outputTlv.value,
+                   outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
+            if (outputTlv.length != sizeof(u32)) {
+                ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE"
+                      "Incorrect size:%d expecting %zu", outputTlv.length,
+                      sizeof(u32));
+                break;
+            }
+            event->is_conn_capability_valid = 1;
+            /* Populate conn_capability from received TLV */
+            getNanReceivePostConnectivityCapabilityVal(outputTlv.value,
+                                                       &event->conn_capability);
+            break;
+        case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
+            /* Populate receive discovery attribute from
+               received TLV */
+            idx = event->num_rx_discovery_attr;
+            if (idx < 0 || idx >= NAN_MAX_POSTDISCOVERY_LEN) {
+                ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
+                      " Incorrect index:%d >= %d", idx, NAN_MAX_POSTDISCOVERY_LEN);
+                break;
+            }
+            ret = getNanReceivePostDiscoveryVal(outputTlv.value,
+                                                outputTlv.length,
+                                                &event->discovery_attr[idx]);
+            if (ret == 0) {
+                event->num_rx_discovery_attr++;
+            } else {
+                ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
+                      "Incorrect");
+            }
+            break;
+        case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
+            /* Populate further availability bitmap from
+               received TLV */
+            ret = getNanFurtherAvailabilityMap(outputTlv.value,
+                                               outputTlv.length,
+                                               &event->num_chans,
+                                               &event->famchan[0]);
+            if (ret < 0)
+                ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
+                      "Incorrect");
+            break;
+        case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE:
+            if (outputTlv.length > sizeof(event->cluster_attribute)) {
+                outputTlv.length = sizeof(event->cluster_attribute);
+            }
+            memcpy(event->cluster_attribute,
+                   outputTlv.value, outputTlv.length);
+            event->cluster_attribute_len = outputTlv.length;
+            break;
+        case NAN_TLV_TYPE_NAN_CSID:
+            if (outputTlv.length > sizeof(event->peer_cipher_type)) {
+                outputTlv.length = sizeof(event->peer_cipher_type);
+            }
+            memcpy(&event->peer_cipher_type, outputTlv.value,
+                   outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_NAN_SCID:
+            if (outputTlv.length > sizeof(event->scid)) {
+                outputTlv.length = sizeof(event->scid);
+            }
+            event->scid_len = outputTlv.length;
+            memcpy(event->scid, outputTlv.value, outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_SDEA_CTRL_PARAMS:
+            if (outputTlv.length != sizeof(u32)) {
+                ALOGE("NAN_TLV_TYPE_SDEA_CTRL_PARAMS"
+                      "Incorrect size:%d expecting %zu", outputTlv.length,
+                      sizeof(u32));
+                break;
+            }
+            getNanReceiveSdeaCtrlParams(outputTlv.value,
+                                             &event->peer_sdea_params);
+            break;
+        case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
+            if (outputTlv.length > sizeof(event->range_info)) {
+                outputTlv.length = sizeof(event->range_info);
+            }
+            memcpy(&event->range_info, outputTlv.value, outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
+            if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
+            }
+            event->sdea_service_specific_info_len = outputTlv.length;
+            memcpy(event->sdea_service_specific_info, outputTlv.value,
+                   outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_SERVICE_ID:
+            mNanCommandInstance->saveServiceId(outputTlv.value,
+                                               event->publish_subscribe_id,
+                                               event->requestor_instance_id,
+                                               NAN_ROLE_SUBSCRIBER);
+            break;
+        default:
+            ALOGV("Unknown TLV type skipped");
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv, 0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanMatchExpired(NanMatchExpiredInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanMatchExpiredIndMsg pRsp = (pNanMatchExpiredIndMsg)mNanVendorEvent;
+    event->publish_subscribe_id = pRsp->fwHeader.handle;
+    event->requestor_instance_id = pRsp->matchExpiredIndParams.matchHandle;
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent;
+    event->subscribe_id = pRsp->fwHeader.handle;
+    NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
+                        (void*)event, false);
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanFollowup(NanFollowupInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent;
+    event->publish_subscribe_id = pRsp->fwHeader.handle;
+    event->requestor_instance_id = pRsp->followupIndParams.matchHandle;
+    event->dw_or_faw = pRsp->followupIndParams.window;
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams)));
+
+    //Has service specific info and extended service specific info TLV
+    if (remainingLen <= 0) {
+        ALOGV("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
+        case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
+            if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+                outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN;
+            }
+            event->service_specific_info_len = outputTlv.length;
+            memcpy(event->service_specific_info, outputTlv.value,
+                   outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_MAC_ADDRESS:
+            if (outputTlv.length > sizeof(event->addr)) {
+                outputTlv.length = sizeof(event->addr);
+            }
+            memcpy(event->addr, outputTlv.value, outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
+            if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
+            }
+            event->sdea_service_specific_info_len = outputTlv.length;
+            memcpy(event->sdea_service_specific_info, outputTlv.value,
+                   outputTlv.length);
+            break;
+        default:
+            ALOGV("Unknown TLV type skipped");
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv, 0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent;
+    memset(&event->data, 0, sizeof(event->data));
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader)));
+
+    //Has Self-STA Mac TLV
+    if (remainingLen <= 0) {
+        ALOGE("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS:
+            if (outputTlv.length > NAN_MAC_ADDR_LEN) {
+                ALOGV("%s: Reading only first %d bytes of TLV",
+                      __func__, NAN_MAC_ADDR_LEN);
+                outputTlv.length = NAN_MAC_ADDR_LEN;
+            }
+            memcpy(event->data.mac_addr.addr, outputTlv.value,
+                   outputTlv.length);
+            event->event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
+            break;
+        case NAN_TLV_TYPE_EVENT_STARTED_CLUSTER:
+            if (outputTlv.length > NAN_MAC_ADDR_LEN) {
+                ALOGV("%s: Reading only first %d bytes of TLV",
+                      __func__, NAN_MAC_ADDR_LEN);
+                outputTlv.length = NAN_MAC_ADDR_LEN;
+            }
+            memcpy(event->data.cluster.addr, outputTlv.value,
+                   outputTlv.length);
+            event->event_type = NAN_EVENT_ID_STARTED_CLUSTER;
+            break;
+        case NAN_TLV_TYPE_EVENT_JOINED_CLUSTER:
+            if (outputTlv.length > NAN_MAC_ADDR_LEN) {
+                ALOGV("%s: Reading only first %d bytes of TLV",
+                      __func__, NAN_MAC_ADDR_LEN);
+                outputTlv.length = NAN_MAC_ADDR_LEN;
+            }
+            memcpy(event->data.cluster.addr, outputTlv.value,
+                   outputTlv.length);
+            event->event_type = NAN_EVENT_ID_JOINED_CLUSTER;
+            break;
+        default:
+            ALOGV("Unhandled TLV type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanDisabled(NanDisabledInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent;
+    NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
+                        (void*)event, false);
+    return WIFI_SUCCESS;
+
+}
+
+int NanCommand::getNanTca(NanTCAInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent;
+    memset(&event->data, 0, sizeof(event->data));
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader)));
+
+    //Has NAN_TCA_ID_CLUSTER_SIZE
+    if (remainingLen <= 0) {
+        ALOGE("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_CLUSTER_SIZE_RSP:
+            if (outputTlv.length != 2 * sizeof(u32)) {
+                ALOGE("%s: Wrong length %d in Tca Indication expecting %zu bytes",
+                      __func__, outputTlv.length, 2 * sizeof(u32));
+                break;
+            }
+            event->rising_direction_evt_flag = outputTlv.value[0] & 0x01;
+            event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1;
+            memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4],
+                   sizeof(event->data.cluster.cluster_size));
+            event->tca_type = NAN_TCA_ID_CLUSTER_SIZE;
+            break;
+        default:
+            ALOGV("Unhandled TLV type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent;
+    memset(&event->data, 0, sizeof(event->data));
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader)));
+
+    //Has Mac address
+    if (remainingLen <= 0) {
+        ALOGV("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_MAC_ADDRESS:
+            if (outputTlv.length > sizeof(event->addr)) {
+                outputTlv.length = sizeof(event->addr);
+            }
+            memcpy(event->addr, outputTlv.value,
+                   outputTlv.length);
+            break;
+
+        case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
+        {
+            NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa;
+            if (outputTlv.length < sizeof(u32)) {
+                ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE"
+                      "Incorrect length:%d", outputTlv.length);
+                break;
+            }
+            event->is_vsa_received = 1;
+            recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07;
+            memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1],
+                   3);
+            recvVsaattr->attr_len = outputTlv.length - 4;
+            if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) {
+                recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN;
+            }
+            if (recvVsaattr->attr_len) {
+                memcpy(recvVsaattr->vsa, &outputTlv.value[4],
+                       recvVsaattr->attr_len);
+            }
+            break;
+        }
+
+        case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
+            event->is_beacon_sdf_payload_received = 1;
+            event->data.frame_len = outputTlv.length;
+            if (event->data.frame_len > NAN_MAX_FRAME_DATA_LEN) {
+                event->data.frame_len = NAN_MAX_FRAME_DATA_LEN;
+            }
+            memcpy(&event->data.frame_data, &outputTlv.value[0],
+                   event->data.frame_len);
+            break;
+
+        default:
+            ALOGV("Unhandled TLV Type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+void NanCommand::getNanReceivePostConnectivityCapabilityVal(
+    const u8 *pInValue,
+    NanReceivePostConnectivityCapability *pRxCapab)
+{
+    if (pInValue && pRxCapab) {
+        pRxCapab->is_mesh_supported = (pInValue[0] & (0x01 << 5));
+        pRxCapab->is_ibss_supported = (pInValue[0] & (0x01 << 4));
+        pRxCapab->wlan_infra_field = (pInValue[0] & (0x01 << 3));
+        pRxCapab->is_tdls_supported = (pInValue[0] & (0x01 << 2));
+        pRxCapab->is_wfds_supported = (pInValue[0] & (0x01 << 1));
+        pRxCapab->is_wfd_supported = pInValue[0] & 0x01;
+    }
+}
+
+void NanCommand::getNanReceiveSdeaCtrlParams(const u8* pInValue,
+    NanSdeaCtrlParams *pPeerSdeaParams)
+{
+    if (pInValue && pPeerSdeaParams) {
+        pPeerSdeaParams->security_cfg =
+                          (NanDataPathSecurityCfgStatus)((pInValue[0] & BIT_6) ?
+                           NAN_DP_CONFIG_SECURITY : NAN_DP_CONFIG_NO_SECURITY);
+        pPeerSdeaParams->ranging_state =
+                           (NanRangingState)((pInValue[0] & BIT_7) ?
+                            NAN_RANGING_ENABLE : NAN_RANGING_DISABLE);
+#if 0
+        pPeerSdeaParams->enable_ranging_limit =
+                         (NanRangingLimitState)((pInValue[0] & BIT_8) ?
+                          NAN_RANGING_LIMIT_ENABLE : NAN_RANGING_LIMIT_DISABLE);
+#endif
+    }
+    return;
+}
+
+int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue,
+                                              u32 length,
+                                              NanReceivePostDiscovery *pRxDisc)
+{
+    int ret = 0;
+
+    if (length <= 8 || pInValue == NULL) {
+        ALOGE("%s: Invalid Arg TLV Len %d < 4",
+              __func__, length);
+        return -1;
+    }
+
+    pRxDisc->type = (NanConnectionType) pInValue[0];
+    pRxDisc->role = (NanDeviceRole) pInValue[1];
+    pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03);
+    pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F);
+    memcpy(&pRxDisc->avail_interval_bitmap,
+           &pInValue[4],
+           sizeof(pRxDisc->avail_interval_bitmap));
+
+    u8 *pInputTlv = (u8 *)&pInValue[8];
+    NanTlv outputTlv;
+    u16 readLen = 0;
+    int remainingLen = (length - 8);
+
+    //Has Mac address
+    if (remainingLen <= 0) {
+        ALOGE("%s: No TLV's present",__func__);
+        return -1;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_MAC_ADDRESS:
+            if (outputTlv.length > sizeof(pRxDisc->addr)) {
+                outputTlv.length = sizeof(pRxDisc->addr);
+            }
+            memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length);
+            break;
+        case NAN_TLV_TYPE_WLAN_MESH_ID:
+            if (outputTlv.length > sizeof(pRxDisc->mesh_id)) {
+                outputTlv.length = sizeof(pRxDisc->mesh_id);
+            }
+            memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length);
+            pRxDisc->mesh_id_len = outputTlv.length;
+            break;
+        case NAN_TLV_TYPE_WLAN_INFRA_SSID:
+            if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) {
+                outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val);
+            }
+            memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value,
+                   outputTlv.length);
+            pRxDisc->infrastructure_ssid_len = outputTlv.length;
+            break;
+        default:
+            ALOGV("Unhandled TLV Type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return ret;
+}
+
+int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue,
+                                             u32 length,
+                                             u8 *num_chans,
+                                             NanFurtherAvailabilityChannel *pFac)
+{
+    int idx = 0;
+
+    if ((length == 0) || pInValue == NULL) {
+        ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL",
+              __func__, length);
+        return -1;
+    }
+
+    *num_chans = pInValue[0];
+    if (*num_chans > NAN_MAX_FAM_CHANNELS) {
+        ALOGE("%s: Unable to accommodate numchans %d",
+              __func__, *num_chans);
+        return -1;
+    }
+
+    if (length < (sizeof(u8) +
+        (*num_chans * sizeof(NanFurtherAvailabilityChan)))) {
+        ALOGE("%s: Invalid TLV Length", __func__);
+        return -1;
+    }
+
+    for (idx = 0; idx < *num_chans; idx++) {
+        pNanFurtherAvailabilityChan pRsp = \
+              (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \
+              (idx * sizeof(NanFurtherAvailabilityChan)));
+
+        pFac->entry_control = \
+            (NanAvailDuration)(pRsp->entryCtrl.availIntDuration);
+        pFac->mapid = pRsp->entryCtrl.mapId;
+        pFac->class_val = pRsp->opClass;
+        pFac->channel = pRsp->channel;
+        memcpy(&pFac->avail_interval_bitmap,
+               &pRsp->availIntBitmap,
+               sizeof(pFac->avail_interval_bitmap));
+        pFac++;
+    }
+    return 0;
+}
+
+wifi_error NanCommand::getNanStaParameter(wifi_interface_handle iface,
+                                   NanStaParameter *pRsp)
+{
+    wifi_error ret = WIFI_ERROR_NONE;
+    transaction_id id = 1;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+
+    ret = create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /*
+       Construct NL message to get the sync stats parameter
+       which has all the parameter required by staparameter.
+    */
+    NanStatsRequest syncStats;
+    memset(&syncStats, 0, sizeof(syncStats));
+    syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC;
+    syncStats.clear = 0;
+
+    mStaParam = pRsp;
+    ret = putNanStats(id, &syncStats);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: putNanStats Error:%d",__func__, ret);
+        goto cleanup;
+    }
+    ret = requestEvent();
+    if (ret != 0) {
+        ALOGE("%s: requestEvent Error:%d",__func__, ret);
+        goto cleanup;
+    }
+
+    struct timespec abstime;
+    abstime.tv_sec = 4;
+    abstime.tv_nsec = 0;
+    ret = mCondition.wait(abstime);
+    if (ret == WIFI_ERROR_TIMED_OUT)
+    {
+        ALOGE("%s: Time out happened.", __func__);
+        goto cleanup;
+    }
+    ALOGV("%s: NanStaparameter Master_pref:%x," \
+          " Random_factor:%x, hop_count:%x " \
+          " beacon_transmit_time:%d" \
+          " ndp_channel_freq:%d", __func__,
+          pRsp->master_pref, pRsp->random_factor,
+          pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq);
+cleanup:
+    mStaParam = NULL;
+    return ret;
+}
+
+int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent;
+    event->id = pRsp->fwHeader.transactionId;
+    NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
+                        (void*)event, false);
+    return WIFI_SUCCESS;
+}
+
+//Function which calls the necessaryIndication callback
+//based on the indication type
+int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor)
+{
+    //Based on the message_id in the header determine the Indication type
+    //and call the necessary callback handler
+    int res = 0;
+
+    ALOGI("handleNdpIndication msg_id:%u", ndpCmdType);
+    switch (ndpCmdType) {
+    case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND:
+        NanDataPathRequestInd ndpRequestInd;
+        memset(&ndpRequestInd, 0, sizeof(ndpRequestInd));
+
+        res = getNdpRequest(tb_vendor, &ndpRequestInd);
+        if (!res && mHandler.EventDataRequest) {
+            (*mHandler.EventDataRequest)(&ndpRequestInd);
+        }
+        break;
+
+    case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
+        NanDataPathConfirmInd ndpConfirmInd;
+        memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd));
+
+        res = getNdpConfirm(tb_vendor, &ndpConfirmInd);
+        if (!res && mHandler.EventDataConfirm) {
+            (*mHandler.EventDataConfirm)(&ndpConfirmInd);
+        }
+        break;
+
+    case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
+    {
+        NanDataPathEndInd *ndpEndInd = NULL;
+        u8 num_ndp_ids = 0;
+        u8 i;
+
+        if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
+        ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
+
+        if (num_ndp_ids) {
+            ndpEndInd =
+                (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids));
+            if (!ndpEndInd) {
+                ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__);
+                return WIFI_ERROR_OUT_OF_MEMORY;
+            }
+            ndpEndInd->num_ndp_instances = num_ndp_ids;
+            nla_memcpy(ndpEndInd->ndp_instance_id,
+                       tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
+                       sizeof(u32) * ndpEndInd->num_ndp_instances);
+        }
+        for (i = 0; i < num_ndp_ids; i++) {
+            mNanCommandInstance->deleteServiceId(0,
+                                                 ndpEndInd->ndp_instance_id[i],
+                                                 NAN_ROLE_PUBLISHER);
+        }
+        if (mHandler.EventDataEnd) {
+            (*mHandler.EventDataEnd)(ndpEndInd);
+        }
+        free(ndpEndInd);
+        break;
+    }
+
+    case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
+    {
+        NanDataPathScheduleUpdateInd *pNdpScheduleUpdateInd;
+        u32 num_channels = 0, num_ndp_ids = 0;
+
+        if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
+            (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]) ||
+            (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])) {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
+             num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
+             ALOGD("%s: num_channels = %d", __FUNCTION__, num_channels);
+             if ((num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
+                 (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
+                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
+                 return WIFI_ERROR_INVALID_ARGS;
+            }
+        }
+        num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
+        ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
+
+        pNdpScheduleUpdateInd =
+            (NanDataPathScheduleUpdateInd *)malloc(sizeof(NanDataPathScheduleUpdateInd)
+            + (sizeof(u32) * num_ndp_ids));
+        if (!pNdpScheduleUpdateInd) {
+            ALOGE("%s: NdpScheduleUpdate malloc Failed", __FUNCTION__);
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+        pNdpScheduleUpdateInd->num_channels = num_channels;
+        pNdpScheduleUpdateInd->num_ndp_instances = num_ndp_ids;
+
+        res = getNdpScheduleUpdate(tb_vendor, pNdpScheduleUpdateInd);
+        if (!res && mHandler.EventScheduleUpdate) {
+            (*mHandler.EventScheduleUpdate)(pNdpScheduleUpdateInd);
+        }
+        free(pNdpScheduleUpdateInd);
+        break;
+    }
+    default:
+        ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType);
+        res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
+        break;
+    }
+    return res;
+}
+
+int NanCommand::getNdpRequest(struct nlattr **tb_vendor,
+                              NanDataPathRequestInd *event)
+{
+    u32 len = 0;
+
+    if (event == NULL || tb_vendor == NULL) {
+        ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
+              __FUNCTION__, event, tb_vendor);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) ||
+        (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
+        (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
+    ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id);
+
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
+    len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len);
+    memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
+
+    event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
+    ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id);
+    if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
+        len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
+        len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
+        memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
+        event->app_info.ndp_app_info_len = len;
+    } else {
+        ALOGD("%s: NDP App Info not present", __FUNCTION__);
+    }
+
+    if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID]) {
+            mNanCommandInstance->saveServiceId((u8 *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID]),
+                                               event->service_instance_id,
+                                               event->ndp_instance_id,
+                                               NAN_ROLE_PUBLISHER);
+    } else {
+        ALOGD("%s: Service ID not present", __FUNCTION__);
+    }
+
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
+                              NanDataPathConfirmInd *event)
+{
+    u32 len = 0;
+    NanInternalStatusType drv_reason_code;
+    struct nlattr *chInfo;
+    NanChannelInfo *pChInfo;
+    int rem;
+    u32 i = 0;
+
+    if (event == NULL || tb_vendor == NULL) {
+        ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
+              __FUNCTION__, event, tb_vendor);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) ||
+        (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) ||
+        (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
+    ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id);
+
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]);
+    len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len);
+    memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len);
+
+    event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
+    ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code);
+
+    if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
+        len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
+        len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
+        memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
+        event->app_info.ndp_app_info_len = len;
+    } else {
+        ALOGD("%s: NDP App Info not present", __FUNCTION__);
+    }
+    drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]);
+    ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code);
+    switch (drv_reason_code) {
+        case NDP_I_MGMT_FRAME_REQUEST_FAILED:
+        case NDP_I_MGMT_FRAME_RESPONSE_FAILED:
+        case NDP_I_MGMT_FRAME_CONFIRM_FAILED:
+        case NDP_I_MGMT_FRAME_END_REQUEST_FAILED:
+        case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED:
+            event->reason_code = NAN_STATUS_PROTOCOL_FAILURE;
+            break;
+        case NDP_I_END_FAILED:
+            event->reason_code = NAN_STATUS_INTERNAL_FAILURE;
+            break;
+        default:
+            event->reason_code = (NanStatusType)drv_reason_code;
+            break;
+    }
+    ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code);
+
+    if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
+        event->num_channels =
+            nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
+        ALOGD("%s: num_channels = %d", __FUNCTION__, event->num_channels);
+        if ((event->num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
+            (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+    }
+
+    if (event->num_channels != 0) {
+        for (chInfo =
+            (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
+            rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
+            (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
+            chInfo = nla_next(chInfo, &(rem))) {
+             struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
+
+             pChInfo =
+                 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
+             nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
+                 (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
+
+            if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
+            ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
+
+            if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
+            ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
+
+            if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
+            ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
+        }
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNdpScheduleUpdate(struct nlattr **tb_vendor,
+                                     NanDataPathScheduleUpdateInd *event)
+{
+    u32 len = 0;
+    struct nlattr *chInfo;
+    NanChannelInfo *pChInfo;
+    int rem;
+    u32 i = 0;
+
+    len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
+    len = ((sizeof(event->peer_mac_addr) <= len) ? sizeof(event->peer_mac_addr) : len);
+    memcpy(&event->peer_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
+
+    event->schedule_update_reason_code = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]);
+    ALOGD("%s: Reason code %d", __FUNCTION__, event->schedule_update_reason_code);
+
+    if (event->num_channels != 0) {
+        for (chInfo =
+            (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
+            rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
+            (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
+            chInfo = nla_next(chInfo, &(rem))) {
+            struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
+
+            pChInfo =
+                (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
+            nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
+                (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
+
+            if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
+            ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
+
+            if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
+            ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
+
+           if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
+            ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
+        }
+    }
+
+    if (event->num_ndp_instances) {
+        nla_memcpy(event->ndp_instance_id,
+                   tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
+                   sizeof(u32) * event->num_ndp_instances);
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent;
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader)));
+
+    if (remainingLen <= 0) {
+        ALOGE("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED:
+            NanFWRangeReqRecvdMsg fwRangeReqRecvd;
+            if (outputTlv.length > sizeof(fwRangeReqRecvd)) {
+                outputTlv.length = sizeof(fwRangeReqRecvd);
+            }
+            memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length);
+            FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr);
+            event->publish_id = fwRangeReqRecvd.range_id;
+            break;
+        default:
+            ALOGV("Unhandled TLV type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanRangeReportInd(NanRangeReportInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent;
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader)));
+
+    if (remainingLen <= 0) {
+        ALOGE("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_MAC_ADDRESS:
+            if (outputTlv.length > NAN_MAC_ADDR_LEN) {
+                outputTlv.length = NAN_MAC_ADDR_LEN;
+            }
+            memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length);
+            break;
+
+        case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
+            NanFWRangeReportParams range_params;
+            if (outputTlv.length > sizeof(NanFWRangeReportParams)) {
+                outputTlv.length = sizeof(NanFWRangeReportParams);
+            }
+            memcpy(&range_params, outputTlv.value, outputTlv.length);
+            event->range_measurement_mm = range_params.range_measurement;
+            event->publish_id = range_params.publish_id;
+//          event->event_type = range_params.event_type;
+            break;
+        default:
+            ALOGV("Unhandled TLV type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
diff --git a/qcwcn/wifi_hal/nan_req.cpp b/wcn6740/qcwcn/wifi_hal/nan_req.cpp
similarity index 80%
copy from qcwcn/wifi_hal/nan_req.cpp
copy to wcn6740/qcwcn/wifi_hal/nan_req.cpp
index fd8516f..1350623 100644
--- a/qcwcn/wifi_hal/nan_req.cpp
+++ b/wcn6740/qcwcn/wifi_hal/nan_req.cpp
@@ -12,6 +12,40 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "sync.h"
@@ -25,12 +59,18 @@
     wifi_error ret;
     ALOGV("NAN_ENABLE");
     size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
+    int freq_24g;
 
     if (pReq == NULL) {
         cleanup();
         return WIFI_ERROR_INVALID_ARGS;
     }
 
+    if (pReq->config_24g_channel == 0)
+        freq_24g = 2437;
+    else
+        freq_24g = pReq->channel_24g_val;
+
     message_len += \
         (
           pReq->config_support_5g ? (SIZEOF_TLV_HDR + \
@@ -117,8 +157,8 @@
           sizeof(pReq->hop_count_force_val)) : 0 \
         ) + \
         (
-          pReq->config_24g_channel ? (SIZEOF_TLV_HDR + \
-          sizeof(u32)) : 0 \
+          /* always include 24g channel/freq */
+          SIZEOF_TLV_HDR +  sizeof(u32) \
         ) + \
         (
           pReq->config_5g_channel ? (SIZEOF_TLV_HDR + \
@@ -159,10 +199,6 @@
         (
            pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
            sizeof(u32)) : 0 \
-        ) + \
-        (
-          pReq->config_ndpe_attr? (SIZEOF_TLV_HDR + \
-           sizeof(NanDevCapAttrCap)) : 0 \
         );
 
     pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
@@ -288,11 +324,9 @@
                       sizeof(pReq->hop_count_force_val),
                       (const u8*)&pReq->hop_count_force_val, tlvs);
     }
-    if (pReq->config_24g_channel) {
-        tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL,
+    tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL,
                       sizeof(u32),
-                      (const u8*)&pReq->channel_24g_val, tlvs);
-    }
+                      (const u8*)&freq_24g, tlvs);
     if (pReq->config_5g_channel) {
         tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL,
                       sizeof(u32),
@@ -316,6 +350,17 @@
 
     u32 config_discovery_indications;
     config_discovery_indications = (u32)pReq->discovery_indication_cfg;
+    /* Save the discovery MAC indication config if it is disabled from the
+     * framework and use it later to decide if the framework to be notified of
+     * the response. And enable the self MAC discovery indication from firmware
+     * by resetting the bit in config to get the Self MAC.
+     */
+    if (config_discovery_indications & NAN_DISC_ADDR_IND_DISABLED) {
+        mNanCommandInstance->mNanDiscAddrIndDisabled = true;
+        config_discovery_indications &= ~NAN_DISC_ADDR_IND_DISABLED;
+    } else {
+        mNanCommandInstance->mNanDiscAddrIndDisabled = false;
+    }
     tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
                   sizeof(u32),
                   (const u8*)&config_discovery_indications, tlvs);
@@ -341,23 +386,52 @@
         tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
                       (const u8*)&pReq->enable_dw_termination, tlvs);
     }
-    if (pReq->config_ndpe_attr) {
-        NanDevCapAttrCap nanDevCapAttr;
-        memset(&nanDevCapAttr, 0, sizeof(nanDevCapAttr));
-        nanDevCapAttr.ndpe_attr_supp = pReq->use_ndpe_attr;
-        tlvs = addTlv(NAN_TLV_TYPE_DEV_CAP_ATTR_CAPABILITY,
-                      sizeof(NanDevCapAttrCap),
-                      (const u8*)&nanDevCapAttr, tlvs);
-    }
+
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    //Insert the vendor specific data
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        //Insert the vendor specific data
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE,
+                           QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ) ||
+            mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ,
+                           freq_24g)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (pReq->config_5g_channel) {
+            if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ,
+                               pReq->channel_5g_val)) {
+                ALOGE("%s: put attr error", __func__);
+                cleanup();
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -385,11 +459,32 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE,
+                           QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ) ||
+            mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -486,10 +581,6 @@
         (
            pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
            sizeof(u32)) : 0 \
-        ) + \
-        (
-          pReq->config_ndpe_attr? (SIZEOF_TLV_HDR + \
-           sizeof(NanDevCapAttrCap)) : 0 \
         );
 
     if (pReq->num_config_discovery_attr) {
@@ -617,10 +708,22 @@
 
     u32 config_discovery_indications;
     config_discovery_indications = (u32)(pReq->discovery_indication_cfg);
+    /* Save the discovery MAC indication config if it is disabled from the
+     * framework and use it later to decide if the framework to be notified of
+     * the response. And enable the self MAC discovery indication from firmware
+     * by resetting the bit in config to get the Self MAC.
+     */
+    if (config_discovery_indications & NAN_DISC_ADDR_IND_DISABLED) {
+        mNanCommandInstance->mNanDiscAddrIndDisabled = true;
+        config_discovery_indications &= ~NAN_DISC_ADDR_IND_DISABLED;
+    } else {
+        mNanCommandInstance->mNanDiscAddrIndDisabled = false;
+    }
     /* Always include the discovery cfg TLV as there is no cfg flag */
     tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
                   sizeof(u32),
                   (const u8*)&config_discovery_indications, tlvs);
+
     if (pReq->config_nss) {
         tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32),
                       (const u8*)&pReq->nss, tlvs);
@@ -633,23 +736,33 @@
         tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
                       (const u8*)&pReq->enable_dw_termination, tlvs);
     }
-    if (pReq->config_ndpe_attr) {
-        NanDevCapAttrCap nanDevCapAttr;
-        memset(&nanDevCapAttr, 0, sizeof(nanDevCapAttr));
-        nanDevCapAttr.ndpe_attr_supp = pReq->use_ndpe_attr;
-        tlvs = addTlv(NAN_TLV_TYPE_DEV_CAP_ATTR_CAPABILITY,
-                      sizeof(NanDevCapAttrCap),
-                      (const u8*)&nanDevCapAttr, tlvs);
-    }
 
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -709,7 +822,7 @@
     if (pReq->publish_id == 0) {
         pFwReq->fwHeader.handle = 0xFFFF;
     } else {
-        pFwReq->fwHeader.handle = pReq->publish_id;
+        pFwReq->fwHeader.handle = (pReq->publish_id & 0xFF);
     }
     pFwReq->fwHeader.transactionId = id;
 
@@ -863,11 +976,29 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -895,17 +1026,36 @@
     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
     pFwReq->fwHeader.msgLen = message_len;
-    pFwReq->fwHeader.handle = pReq->publish_id;
+    pFwReq->fwHeader.handle = (pReq->publish_id & 0xFF);
     pFwReq->fwHeader.transactionId = id;
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -944,6 +1094,7 @@
     message_len += \
         (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
 
+
     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN))
         message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN;
@@ -955,6 +1106,7 @@
         message_len += SIZEOF_TLV_HDR +
                        pReq->key_info.body.passphrase_info.passphrase_len;
 
+
     pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
     if (pFwReq == NULL) {
         cleanup();
@@ -969,7 +1121,7 @@
     if (pReq->subscribe_id == 0) {
         pFwReq->fwHeader.handle = 0xFFFF;
     } else {
-        pFwReq->fwHeader.handle = pReq->subscribe_id;
+        pFwReq->fwHeader.handle = (pReq->subscribe_id & 0xFF);
     }
     pFwReq->fwHeader.transactionId = id;
 
@@ -1123,11 +1275,30 @@
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1156,16 +1327,35 @@
     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
     pFwReq->fwHeader.msgLen = message_len;
-    pFwReq->fwHeader.handle = pReq->subscribe_id;
+    pFwReq->fwHeader.handle = (pReq->subscribe_id & 0xFF);
     pFwReq->fwHeader.transactionId = id;
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1201,7 +1391,7 @@
     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
     pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
     pFwReq->fwHeader.msgLen = message_len;
-    pFwReq->fwHeader.handle = pReq->publish_subscribe_id;
+    pFwReq->fwHeader.handle = (pReq->publish_subscribe_id & 0xFF);
     pFwReq->fwHeader.transactionId = id;
 
     pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id;
@@ -1235,11 +1425,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1276,11 +1485,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1332,11 +1560,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1399,11 +1646,30 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1454,7 +1720,7 @@
 {
     wifi_error res;
     int status;
-    struct nl_cb * cb;
+    struct nl_cb * cb = NULL;
 
     cb = nl_cb_alloc(NL_CB_DEFAULT);
     if (!cb) {
@@ -1489,6 +1755,7 @@
 
     res = mapKernelErrortoWifiHalError(status);
 out:
+    nl_cb_put(cb);
     //free the VendorData
     if (mVendorData) {
         free(mVendorData);
@@ -1668,11 +1935,30 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
@@ -1711,12 +1997,31 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    /* Write the TLVs to the message. */
-    ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: put_bytes Error:%d",__func__, ret);
-        cleanup();
-        return ret;
+    ret = WIFI_SUCCESS;
+    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) {
+        /* Write the TLVs to the message. */
+        ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: put_bytes Error:%d",__func__, ret);
+            cleanup();
+            return ret;
+        }
+    } else {
+        struct nlattr *nl_data;
+
+        nl_data = attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        if (!nl_data) {
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA,
+                             mVendorData, mDataLen)) {
+            ALOGE("%s: put attr error", __func__);
+            cleanup();
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        attr_end(nl_data);
     }
     hexdump(mVendorData, mDataLen);
     return ret;
diff --git a/wcn6740/qcwcn/wifi_hal/nan_rsp.cpp b/wcn6740/qcwcn/wifi_hal/nan_rsp.cpp
new file mode 100644
index 0000000..060de7f
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/nan_rsp.cpp
@@ -0,0 +1,1006 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sync.h"
+#include <utils/Log.h>
+#include "wifi_hal.h"
+#include "nan_i.h"
+#include "nancommand.h"
+
+
+int NanCommand::isNanResponse()
+{
+    if (mNanVendorEvent == NULL) {
+        ALOGE("NULL check failed");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
+
+    switch (pHeader->msgId) {
+    case NAN_MSG_ID_ERROR_RSP:
+    case NAN_MSG_ID_CONFIGURATION_RSP:
+    case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP:
+    case NAN_MSG_ID_PUBLISH_SERVICE_RSP:
+    case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP:
+    case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP:
+    case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP:
+    case NAN_MSG_ID_STATS_RSP:
+    case NAN_MSG_ID_ENABLE_RSP:
+    case NAN_MSG_ID_DISABLE_RSP:
+    case NAN_MSG_ID_TCA_RSP:
+    case NAN_MSG_ID_BEACON_SDF_RSP:
+    case NAN_MSG_ID_CAPABILITIES_RSP:
+    case NAN_MSG_ID_TESTMODE_RSP:
+        return 1;
+    default:
+        return 0;
+    }
+}
+
+struct verboseTlv {
+    NanTlvType tlvType;
+    char strTlv[NAN_ERROR_STR_LEN];
+};
+
+struct verboseTlv tlvToStr[] = {
+    {NAN_TLV_TYPE_SDF_MATCH_FILTER, " SDF match filter"},
+    {NAN_TLV_TYPE_TX_MATCH_FILTER, " Tx match filter"},
+    {NAN_TLV_TYPE_RX_MATCH_FILTER, " Rx match filter"},
+    {NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO,
+     " Service specific info"},
+    {NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO,
+     " Extended Service specific info"},
+    {NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT,
+     " Vendor specific attribute transmit"},
+    {NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE,
+     " Vendor specific attribute receive"},
+    {NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE,
+     " Post Nan connectivity capability receive"},
+    {NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE,
+     " Post Nan discovery attribute receive"},
+    {NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE,
+     " Beacon SDF payload receive"},
+
+    /* Configuration types */
+    {NAN_TLV_TYPE_CONFIG_FIRST, " Config first"},
+    {NAN_TLV_TYPE_24G_SUPPORT, " 2.4G support"},
+    {NAN_TLV_TYPE_24G_BEACON, " 2.4G beacon"},
+    {NAN_TLV_TYPE_24G_SDF, " 2.4G SDF"},
+    {NAN_TLV_TYPE_24G_RSSI_CLOSE, " 2.4G RSSI close"},
+    {NAN_TLV_TYPE_24G_RSSI_MIDDLE, " 2.4G RSSI middle"},
+    {NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY,
+     " 2.4G RSSI close proximity"},
+    {NAN_TLV_TYPE_5G_SUPPORT, " 5G support"},
+    {NAN_TLV_TYPE_5G_BEACON, " 5G beacon"},
+    {NAN_TLV_TYPE_5G_SDF, " 5G SDF"},
+    {NAN_TLV_TYPE_5G_RSSI_CLOSE, " 5G RSSI close"},
+    {NAN_TLV_TYPE_5G_RSSI_MIDDLE, " 5G RSSI middle"},
+    {NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
+     " 5G RSSI close proximity"},
+    {NAN_TLV_TYPE_SID_BEACON, " SID beacon"},
+    {NAN_TLV_TYPE_HOP_COUNT_LIMIT, " Hop count limit"},
+    {NAN_TLV_TYPE_MASTER_PREFERENCE, " Master preference"},
+    {NAN_TLV_TYPE_CLUSTER_ID_LOW, " Cluster ID low"},
+    {NAN_TLV_TYPE_CLUSTER_ID_HIGH, " Cluster ID high"},
+    {NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE,
+     " RSSI averaging window size"},
+    {NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID,
+     " Cluster OUI network ID"},
+    {NAN_TLV_TYPE_SOURCE_MAC_ADDRESS,
+     " Source MAC address"},
+    {NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF,
+     " Cluster attribute in SDF"},
+    {NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
+     " Social channel scan params"},
+    {NAN_TLV_TYPE_DEBUGGING_FLAGS, " Debugging flags"},
+    {NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
+     " Post nan connectivity capabilities transmit"},
+    {NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
+     " Post nan discovery attribute transmit"},
+    {NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
+     " Further availability map"},
+    {NAN_TLV_TYPE_HOP_COUNT_FORCE, " Hop count force"},
+    {NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
+     " Random factor force"},
+    {NAN_TLV_TYPE_RANDOM_UPDATE_TIME,
+     " Random update time"},
+    {NAN_TLV_TYPE_EARLY_WAKEUP, " Early wakeup"},
+    {NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL,
+     " Periodic scan interval"},
+    {NAN_TLV_TYPE_DW_INTERVAL, " DW interval"},
+    {NAN_TLV_TYPE_DB_INTERVAL, " DB interval"},
+    {NAN_TLV_TYPE_FURTHER_AVAILABILITY,
+     " Further availability"},
+    {NAN_TLV_TYPE_24G_CHANNEL, " 2.4G channel"},
+    {NAN_TLV_TYPE_5G_CHANNEL, " 5G channel"},
+    {NAN_TLV_TYPE_CONFIG_LAST, " Config last"},
+
+    /* Attributes types */
+    {NAN_TLV_TYPE_ATTRS_FIRST, " Attributes first"},
+    {NAN_TLV_TYPE_AVAILABILITY_INTERVALS_MAP,
+     " Availability intervals map"},
+    {NAN_TLV_TYPE_WLAN_MESH_ID, " WLAN mesh ID"},
+    {NAN_TLV_TYPE_MAC_ADDRESS, " MAC address"},
+    {NAN_TLV_TYPE_RECEIVED_RSSI_VALUE,
+     " Received RSSI value"},
+    {NAN_TLV_TYPE_CLUSTER_ATTRIBUTE,
+     " Cluster attribute"},
+    {NAN_TLV_TYPE_WLAN_INFRA_SSID, " WLAN infra SSID"},
+    {NAN_TLV_TYPE_ATTRS_LAST, " Attributes last"},
+
+    /* Events Type */
+    {NAN_TLV_TYPE_EVENTS_FIRST, " Events first"},
+    {NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS,
+     " Event Self station MAC address"},
+    {NAN_TLV_TYPE_EVENT_STARTED_CLUSTER,
+     " Event started cluster"},
+    {NAN_TLV_TYPE_EVENT_JOINED_CLUSTER,
+     " Event joined cluster"},
+    {NAN_TLV_TYPE_EVENT_CLUSTER_SCAN_RESULTS,
+     " Event cluster scan results"},
+    {NAN_TLV_TYPE_FAW_MEM_AVAIL,
+     " FAW memory availability"},
+    {NAN_TLV_TYPE_EVENTS_LAST, " Events last"},
+
+    /* TCA types */
+    {NAN_TLV_TYPE_TCA_FIRST, " TCA-Threshold Crossing Alert first"},
+    {NAN_TLV_TYPE_CLUSTER_SIZE_REQ,
+     " Cluster size request"},
+    {NAN_TLV_TYPE_CLUSTER_SIZE_RSP,
+     " Cluster size response"},
+    {NAN_TLV_TYPE_TCA_LAST, " TCA last"},
+
+    /* Statistics types */
+    {NAN_TLV_TYPE_STATS_FIRST, " Stats first"},
+    {NAN_TLV_TYPE_DE_PUBLISH_STATS,
+     " Discovery engine publish stats"},
+    {NAN_TLV_TYPE_DE_SUBSCRIBE_STATS,
+     " Discovery engine subscribe stats"},
+    {NAN_TLV_TYPE_DE_MAC_STATS,
+     " Discovery engine MAC stats"},
+    {NAN_TLV_TYPE_DE_TIMING_SYNC_STATS,
+     " Discovery engine timing sync stats"},
+    {NAN_TLV_TYPE_DE_DW_STATS,
+     " Discovery engine DW stats"},
+    {NAN_TLV_TYPE_DE_STATS, " Discovery engine stats"},
+    {NAN_TLV_TYPE_STATS_LAST, " Stats last"},
+
+    {NAN_TLV_TYPE_LAST, " Last"}
+};
+
+struct errorCode {
+    NanStatusType frameworkError;
+    NanInternalStatusType firmwareError;
+    char nan_error[NAN_ERROR_STR_LEN];
+};
+
+struct errorCode errorCodeTranslation[] = {
+    {NAN_STATUS_SUCCESS, NAN_I_STATUS_SUCCESS,
+     "NAN status success"},
+
+    {NAN_STATUS_INTERNAL_FAILURE, NAN_I_STATUS_DE_FAILURE,
+     "NAN Discovery engine failure"},
+
+    {NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID, NAN_I_STATUS_INVALID_HANDLE,
+     "Invalid Publish/Subscribe ID"},
+
+    {NAN_STATUS_NO_RESOURCE_AVAILABLE, NAN_I_STATUS_NO_SPACE_AVAILABLE,
+     "No space available"},
+
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_PUBLISH_TYPE,
+     "Invalid Publish type, can be 0 or 1"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TX_TYPE,
+     "Invalid Tx type"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_VERSION,
+     "Invalid internal message version"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_LEN,
+     "Invalid message length"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_ID,
+     "Invalid message ID"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MATCH_ALGORITHM,
+     "Invalid matching algorithm, can be 0(match once), 1(match continuous) or 2(match never)"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_LEN,
+     "Invalid TLV length"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_TYPE,
+     "Invalid TLV type"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_MISSING_TLV_TYPE,
+     "Missing TLV type"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TOTAL_TLVS_LEN,
+     "Invalid total TLV length"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_VALUE,
+     "Invalid TLV value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TX_PRIORITY,
+     "Invalid Tx priority"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_CONNECTION_MAP,
+     "Invalid connection map"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_THRESHOLD_CROSSING_ALERT_ID,
+     "Invalid TCA-Threshold Crossing Alert ID"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_STATS_ID,
+     "Invalid STATS ID"},
+
+    {NAN_STATUS_PROTOCOL_FAILURE, NAN_I_STATUS_TX_FAIL,
+     "Tx Fail"},
+
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RSSI_CLOSE_VALUE,
+     "Invalid RSSI close value range is 20dbm to 60dbm"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RSSI_MIDDLE_VALUE,
+     "Invalid RSSI middle value range is 20dbm to 75dbm"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_HOP_COUNT_LIMIT,
+     "Invalid hop count limit, max hop count limit is 5"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE,
+     "Invalid cluster ID value. Please set the cluster id high greater than the cluster id low"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_BACKGROUND_SCAN_PERIOD,
+     "Invalid background scan period. The range is 10 to 30 milliseconds"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_SCAN_CHANNEL,
+     "Invalid scan channel. Only valid channels are the NAN social channels"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP,
+     "Invalid post nan connectivity bitmap"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_NUMCHAN_VALUE,
+     "Invalid further availability map number of channel value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_DURATION_VALUE,
+     "Invalid further availability map duration value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CLASS_VALUE,
+     "Invalid further availability map class value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CHANNEL_VALUE,
+     "Invalid further availability map channel value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE,
+     "Invalid further availability map availability interval bitmap value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_MAP_ID,
+     "Invalid further availability map map ID"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE,
+     "Invalid post nan discovery connection type value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE,
+     "Invalid post nan discovery device role value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE,
+     "Invalid post nan discovery duration value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE,
+     "Invalid post nan discovery bitmap value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_MISSING_FUTHER_AVAILABILITY_MAP,
+     "Missing further availability map"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_BAND_CONFIG_FLAGS,
+     "Invalid band configuration flags"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE,
+     "Invalid random factor update time value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_ONGOING_SCAN_PERIOD,
+     "Invalid ongoing scan period"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_DW_INTERVAL_VALUE,
+     "Invalid DW interval value"},
+    {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_DB_INTERVAL_VALUE,
+     "Invalid DB interval value"},
+
+    {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_TIMEOUT,
+     "Terminated Reason: Timeout"},
+    {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_USER_REQUEST,
+     "Terminated Reason: User Request"},
+    {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_COUNT_REACHED,
+     "Terminated Reason: Count Reached"},
+
+    {NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID, NAN_I_STATUS_INVALID_REQUESTER_INSTANCE_ID,
+     "Invalid match handle"},
+    {NAN_STATUS_NAN_NOT_ALLOWED, NAN_I_STATUS_NAN_NOT_ALLOWED,
+     "Nan not allowed"},
+    {NAN_STATUS_NO_OTA_ACK, NAN_I_STATUS_NO_OTA_ACK,
+     "No OTA ack"},
+    {NAN_STATUS_ALREADY_ENABLED, NAN_I_STATUS_NAN_ALREADY_ENABLED,
+     "NAN is Already enabled"},
+    {NAN_STATUS_FOLLOWUP_QUEUE_FULL, NAN_I_STATUS_FOLLOWUP_QUEUE_FULL,
+     "Follow-up queue full"},
+
+    {NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED, NDP_I_UNSUPPORTED_CONCURRENCY,
+     "Unsupported Concurrency"},
+
+    {NAN_STATUS_INTERNAL_FAILURE, NDP_I_NAN_DATA_IFACE_CREATE_FAILED,
+     "NAN data interface create failed"},
+    {NAN_STATUS_INTERNAL_FAILURE, NDP_I_NAN_DATA_IFACE_DELETE_FAILED,
+     "NAN data interface delete failed"},
+    {NAN_STATUS_INTERNAL_FAILURE, NDP_I_DATA_INITIATOR_REQUEST_FAILED,
+     "NAN data initiator request failed"},
+    {NAN_STATUS_INTERNAL_FAILURE, NDP_I_DATA_RESPONDER_REQUEST_FAILED,
+     "NAN data responder request failed"},
+
+    {NAN_STATUS_INVALID_NDP_ID, NDP_I_INVALID_NDP_INSTANCE_ID,
+     "Invalid NDP instance ID"},
+
+    {NAN_STATUS_INVALID_PARAM, NDP_I_INVALID_RESPONSE_CODE,
+     "Invalid response code"},
+    {NAN_STATUS_INVALID_PARAM, NDP_I_INVALID_APP_INFO_LEN,
+     "Invalid app info length"},
+
+    {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_REQUEST_FAILED,
+     "Management frame request failed"},
+    {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_RESPONSE_FAILED,
+     "Management frame response failed"},
+    {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_CONFIRM_FAILED,
+     "Management frame confirm failed"},
+
+    {NAN_STATUS_INTERNAL_FAILURE, NDP_I_END_FAILED,
+     "NDP end failed"},
+
+    {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_END_REQUEST_FAILED,
+     "Management frame end request failed"},
+
+    {NAN_STATUS_INTERNAL_FAILURE, NDP_I_VENDOR_SPECIFIC_ERROR,
+     "Vendor specific error"}
+};
+
+void NanCommand::NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd,
+                                     u32 valueRcvd,
+                                     void* pResponse,
+                                     bool is_ndp_rsp)
+{
+    int i = 0, j = 0;
+    u16 msg_id; /* Based on the message_id in the header determine the Indication type */
+    NanResponseMsg *pRsp;
+    NanPublishTerminatedInd* pRspInd;
+    NanDisabledInd* pRspdInd;
+    char tlvInfo[NAN_ERROR_STR_LEN];
+    tlvInfo[0] = '\0';
+
+    if ((is_ndp_rsp == true) || isNanResponse()) {
+        pRsp = (NanResponseMsg*)pResponse;
+        for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) {
+            if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) {
+                pRsp->status =  errorCodeTranslation[i].frameworkError;
+                strlcpy(pRsp->nan_error, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN);
+                if (NAN_I_STATUS_INVALID_TLV_TYPE == firmwareErrorRecvd) {
+                    for (j = 0; j < (int)(sizeof(tlvToStr)/sizeof(verboseTlv)); j++) {
+                        if (tlvToStr[j].tlvType == valueRcvd) {
+                            strlcpy(tlvInfo, tlvToStr[i].strTlv, NAN_ERROR_STR_LEN);
+                            break;
+                        }
+                    }
+                }
+                strlcat(pRsp->nan_error, tlvInfo, sizeof(pRsp->nan_error));
+                break;
+            }
+        }
+        if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) {
+                pRsp->status =  NAN_STATUS_INTERNAL_FAILURE;
+                strlcpy(pRsp->nan_error, "NAN Discovery engine failure", NAN_ERROR_STR_LEN);
+        }
+        ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRsp->status, valueRcvd, pRsp->nan_error);
+    } else {
+        msg_id = getIndicationType();
+
+        switch(msg_id) {
+        case NAN_INDICATION_PUBLISH_TERMINATED:
+        case NAN_INDICATION_SUBSCRIBE_TERMINATED:
+        case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP:
+                pRspInd = (NanPublishTerminatedInd*)pResponse;
+                for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) {
+                        if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) {
+                                pRspInd->reason =  errorCodeTranslation[i].frameworkError;
+                                strlcpy(pRspInd->nan_reason, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN);
+                                break;
+                        }
+                }
+                if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) {
+                        pRspInd->reason =  NAN_STATUS_INTERNAL_FAILURE;
+                        strlcpy(pRspInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN);
+                }
+                ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspInd->reason, valueRcvd, pRspInd->nan_reason);
+                break;
+        case NAN_INDICATION_DISABLED:
+                pRspdInd = (NanDisabledInd*)pResponse;
+                for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) {
+                        if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) {
+                                pRspdInd->reason =  errorCodeTranslation[i].frameworkError;
+                                strlcpy(pRspdInd->nan_reason, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN);
+                                break;
+                        }
+                }
+                if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) {
+                        pRspdInd->reason =  NAN_STATUS_INTERNAL_FAILURE;
+                        strlcpy(pRspdInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN);
+                }
+                ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspdInd->reason, valueRcvd, pRspdInd->nan_reason);
+                break;
+        }
+    }
+}
+
+int NanCommand::getNanResponse(transaction_id *id, NanResponseMsg *pRsp)
+{
+    if (mNanVendorEvent == NULL || pRsp == NULL) {
+        ALOGE("NULL check failed");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
+
+    switch (pHeader->msgId) {
+        case NAN_MSG_ID_ERROR_RSP:
+        {
+            pNanErrorRspMsg pFwRsp = \
+                (pNanErrorRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_ERROR;
+            break;
+        }
+        case NAN_MSG_ID_CONFIGURATION_RSP:
+        {
+            pNanConfigurationRspMsg pFwRsp = \
+                (pNanConfigurationRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_CONFIG;
+        }
+        break;
+        case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP:
+        {
+            pNanPublishServiceCancelRspMsg pFwRsp = \
+                (pNanPublishServiceCancelRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_PUBLISH_CANCEL;
+            pRsp->body.publish_response.publish_id = \
+                pFwRsp->fwHeader.handle;
+            break;
+        }
+        case NAN_MSG_ID_PUBLISH_SERVICE_RSP:
+        {
+            pNanPublishServiceRspMsg pFwRsp = \
+                (pNanPublishServiceRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_PUBLISH;
+            pRsp->body.publish_response.publish_id = \
+                pFwRsp->fwHeader.handle;
+            break;
+        }
+        case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP:
+        {
+            pNanSubscribeServiceRspMsg pFwRsp = \
+                (pNanSubscribeServiceRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_SUBSCRIBE;
+            pRsp->body.subscribe_response.subscribe_id = \
+                pFwRsp->fwHeader.handle;
+        }
+        break;
+        case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP:
+        {
+            pNanSubscribeServiceCancelRspMsg pFwRsp = \
+                (pNanSubscribeServiceCancelRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_SUBSCRIBE_CANCEL;
+            pRsp->body.subscribe_response.subscribe_id = \
+                pFwRsp->fwHeader.handle;
+            break;
+        }
+        case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP:
+        {
+            pNanTransmitFollowupRspMsg pFwRsp = \
+                (pNanTransmitFollowupRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_TRANSMIT_FOLLOWUP;
+            break;
+        }
+        case NAN_MSG_ID_STATS_RSP:
+        {
+            pNanStatsRspMsg pFwRsp = \
+                (pNanStatsRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->statsRspParams.status,
+                                            pFwRsp->statsRspParams.value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_STATS;
+            pRsp->body.stats_response.stats_type = \
+                (NanStatsType)pFwRsp->statsRspParams.statsType;
+            ALOGV("%s: stats_type:%d",__func__,
+                  pRsp->body.stats_response.stats_type);
+            u8 *pInputTlv = pFwRsp->ptlv;
+            NanTlv outputTlv;
+            memset(&outputTlv, 0, sizeof(outputTlv));
+            u16 readLen = 0;
+            int remainingLen = (mNanDataLen -  \
+                (sizeof(NanMsgHeader) + sizeof(NanStatsRspParams)));
+            if (remainingLen > 0) {
+                readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen);
+                ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+                      __func__, remainingLen, readLen, outputTlv.type,
+                      outputTlv.length);
+                if (outputTlv.length <= \
+                    sizeof(pRsp->body.stats_response.data)) {
+                    handleNanStatsResponse(pRsp->body.stats_response.stats_type,
+                                           (char *)outputTlv.value,
+                                           &pRsp->body.stats_response,
+                                           outputTlv.length);
+                }
+            } else
+                ALOGV("%s: No TLV's present",__func__);
+            break;
+        }
+        case NAN_MSG_ID_ENABLE_RSP:
+        {
+            pNanEnableRspMsg pFwRsp = \
+                (pNanEnableRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_ENABLED;
+            break;
+        }
+        case NAN_MSG_ID_DISABLE_RSP:
+        {
+            pNanDisableRspMsg pFwRsp = \
+                (pNanDisableRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, 0, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_DISABLED;
+            break;
+        }
+        case NAN_MSG_ID_TCA_RSP:
+        {
+            pNanTcaRspMsg pFwRsp = \
+                (pNanTcaRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_TCA;
+            break;
+        }
+        case NAN_MSG_ID_BEACON_SDF_RSP:
+        {
+            pNanBeaconSdfPayloadRspMsg pFwRsp = \
+                (pNanBeaconSdfPayloadRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, 0, pRsp, false);
+            pRsp->response_type = NAN_RESPONSE_BEACON_SDF_PAYLOAD;
+            break;
+        }
+        case NAN_MSG_ID_CAPABILITIES_RSP:
+        {
+            pNanCapabilitiesRspMsg pFwRsp = \
+                (pNanCapabilitiesRspMsg)mNanVendorEvent;
+            *id = (transaction_id)pFwRsp->fwHeader.transactionId;
+            NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false);
+            pRsp->response_type = NAN_GET_CAPABILITIES;
+            pRsp->body.nan_capabilities.max_concurrent_nan_clusters = \
+                        pFwRsp->max_concurrent_nan_clusters;
+            pRsp->body.nan_capabilities.max_publishes = \
+                        pFwRsp->max_publishes;
+            pRsp->body.nan_capabilities.max_subscribes = \
+                        pFwRsp->max_subscribes;
+            pRsp->body.nan_capabilities.max_service_name_len = \
+                        pFwRsp->max_service_name_len;
+            pRsp->body.nan_capabilities.max_match_filter_len = \
+                        pFwRsp->max_match_filter_len;
+            pRsp->body.nan_capabilities.max_total_match_filter_len = \
+                        pFwRsp->max_total_match_filter_len;
+            pRsp->body.nan_capabilities.max_service_specific_info_len = \
+                        pFwRsp->max_service_specific_info_len;
+            pRsp->body.nan_capabilities.max_vsa_data_len = \
+                        pFwRsp->max_vsa_data_len;
+            pRsp->body.nan_capabilities.max_mesh_data_len = \
+                        pFwRsp->max_mesh_data_len;
+            pRsp->body.nan_capabilities.max_ndi_interfaces = \
+                       pFwRsp->max_ndi_interfaces;
+            pRsp->body.nan_capabilities.max_ndp_sessions = \
+                       pFwRsp->max_ndp_sessions;
+            pRsp->body.nan_capabilities.max_app_info_len = \
+                       pFwRsp->max_app_info_len;
+            pRsp->body.nan_capabilities.max_queued_transmit_followup_msgs = \
+                       pFwRsp->max_queued_transmit_followup_msgs;
+            pRsp->body.nan_capabilities.ndp_supported_bands = \
+                       pFwRsp->ndp_supported_bands;
+            pRsp->body.nan_capabilities.cipher_suites_supported = \
+                       pFwRsp->cipher_suites_supported;
+            pRsp->body.nan_capabilities.max_scid_len = \
+                       pFwRsp->max_scid_len;
+            pRsp->body.nan_capabilities.is_ndp_security_supported = \
+                       pFwRsp->is_ndp_security_supported;
+            pRsp->body.nan_capabilities.max_sdea_service_specific_info_len = \
+                       pFwRsp->max_sdea_service_specific_info_len;
+            pRsp->body.nan_capabilities.max_subscribe_address = \
+                       pFwRsp->max_subscribe_address;
+            if (pFwRsp->max_publishes > NAN_DEF_PUB_SUB) {
+                mNanCommandInstance->mNanMaxPublishes = pFwRsp->max_publishes;
+                mNanCommandInstance->reallocSvcParams(NAN_ROLE_PUBLISHER);
+            }
+            if (pFwRsp->max_subscribes > NAN_DEF_PUB_SUB) {
+                mNanCommandInstance->mNanMaxSubscribes = pFwRsp->max_subscribes;
+                mNanCommandInstance->reallocSvcParams(NAN_ROLE_SUBSCRIBER);
+            }
+
+            break;
+        }
+        default:
+            return  -1;
+    }
+    return  0;
+}
+
+int NanCommand::handleNanResponse()
+{
+    //parse the data and call
+    //the response callback handler with the populated
+    //NanResponseMsg
+    NanResponseMsg  rsp_data;
+    int ret;
+    transaction_id id;
+
+    ALOGV("handleNanResponse called %p", this);
+    memset(&rsp_data, 0, sizeof(rsp_data));
+    //get the rsp_data
+    ret = getNanResponse(&id, &rsp_data);
+
+    ALOGI("handleNanResponse ret:%d status:%u value:%s response_type:%u",
+          ret, rsp_data.status, rsp_data.nan_error, rsp_data.response_type);
+    if (ret == 0 && (rsp_data.response_type == NAN_RESPONSE_STATS) &&
+        (mStaParam != NULL) &&
+        (rsp_data.body.stats_response.stats_type == NAN_STATS_ID_DE_TIMING_SYNC)) {
+        /*
+           Fill the staParam with appropriate values and return from here.
+           No need to call NotifyResponse as the request is for getting the
+           STA response
+        */
+        NanSyncStats *pSyncStats = &rsp_data.body.stats_response.data.sync_stats;
+        mStaParam->master_rank = pSyncStats->myRank;
+        mStaParam->master_pref = (pSyncStats->myRank & 0xFF00000000000000) >> 56;
+        mStaParam->random_factor = (pSyncStats->myRank & 0x00FF000000000000) >> 48;
+        mStaParam->hop_count = pSyncStats->currAmHopCount;
+        mStaParam->beacon_transmit_time = pSyncStats->currAmBTT;
+        mStaParam->ndp_channel_freq = pSyncStats->ndpChannelFreq;
+
+        ALOGI("%s:0x%02x master_pref 0x%02x random_factor 0x%02x hop_count %u Channel",
+                __func__, mStaParam->master_pref, mStaParam->random_factor,
+                mStaParam->hop_count, mStaParam->ndp_channel_freq);
+
+        return ret;
+    }
+    //Call the NotifyResponse Handler
+    if (ret == 0 && mHandler.NotifyResponse) {
+        (*mHandler.NotifyResponse)(id, &rsp_data);
+    }
+    return ret;
+}
+
+void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
+                                       char *rspBuf,
+                                       NanStatsResponse *pRsp,
+                                       u32 message_len)
+{
+    if (stats_type == NAN_STATS_ID_DE_PUBLISH) {
+        NanPublishStats publish_stats;
+        if (message_len != sizeof(NanPublishStats)) {
+            ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n",
+                    __func__, stats_type, message_len, sizeof(NanPublishStats));
+            return;
+        }
+        FwNanPublishStats *pPubStats = (FwNanPublishStats *)rspBuf;
+
+        publish_stats.validPublishServiceReqMsgs =
+                                    pPubStats->validPublishServiceReqMsgs;
+        publish_stats.validPublishServiceRspMsgs =
+                                    pPubStats->validPublishServiceRspMsgs;
+        publish_stats.validPublishServiceCancelReqMsgs =
+                                    pPubStats->validPublishServiceCancelReqMsgs;
+        publish_stats.validPublishServiceCancelRspMsgs =
+                                    pPubStats->validPublishServiceCancelRspMsgs;
+        publish_stats.validPublishRepliedIndMsgs =
+                                    pPubStats->validPublishRepliedIndMsgs;
+        publish_stats.validPublishTerminatedIndMsgs =
+                                    pPubStats->validPublishTerminatedIndMsgs;
+        publish_stats.validActiveSubscribes = pPubStats->validActiveSubscribes;
+        publish_stats.validMatches = pPubStats->validMatches;
+        publish_stats.validFollowups = pPubStats->validFollowups;
+        publish_stats.invalidPublishServiceReqMsgs =
+                                    pPubStats->invalidPublishServiceReqMsgs;
+        publish_stats.invalidPublishServiceCancelReqMsgs =
+                                pPubStats->invalidPublishServiceCancelReqMsgs;
+        publish_stats.invalidActiveSubscribes =
+                                pPubStats->invalidActiveSubscribes;
+        publish_stats.invalidMatches = pPubStats->invalidMatches;
+        publish_stats.invalidFollowups = pPubStats->invalidFollowups;
+        publish_stats.publishCount = pPubStats->publishCount;
+        publish_stats.publishNewMatchCount = pPubStats->publishNewMatchCount;
+        publish_stats.pubsubGlobalNewMatchCount =
+                               pPubStats->pubsubGlobalNewMatchCount;
+        memcpy(&pRsp->data.publish_stats, &publish_stats, sizeof(NanPublishStats));
+    } else if (stats_type == NAN_STATS_ID_DE_SUBSCRIBE) {
+        NanSubscribeStats sub_stats;
+        if (message_len != sizeof(NanSubscribeStats)) {
+            ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n",
+                   __func__, stats_type, message_len, sizeof(NanSubscribeStats));
+            return;
+        }
+        FwNanSubscribeStats *pSubStats = (FwNanSubscribeStats *)rspBuf;
+
+        sub_stats.validSubscribeServiceReqMsgs =
+                                pSubStats->validSubscribeServiceReqMsgs;
+        sub_stats.validSubscribeServiceRspMsgs =
+                                pSubStats->validSubscribeServiceRspMsgs;
+        sub_stats.validSubscribeServiceCancelReqMsgs =
+                                pSubStats->validSubscribeServiceCancelReqMsgs;
+        sub_stats.validSubscribeServiceCancelRspMsgs =
+                                pSubStats->validSubscribeServiceCancelRspMsgs;
+        sub_stats.validSubscribeTerminatedIndMsgs =
+                                pSubStats->validSubscribeTerminatedIndMsgs;
+        sub_stats.validSubscribeMatchIndMsgs =
+                                pSubStats->validSubscribeMatchIndMsgs;
+        sub_stats.validSubscribeUnmatchIndMsgs =
+                                pSubStats->validSubscribeUnmatchIndMsgs;
+        sub_stats.validSolicitedPublishes =
+                                pSubStats->validSolicitedPublishes;
+        sub_stats.validMatches = pSubStats->validMatches;
+        sub_stats.validFollowups = pSubStats->validFollowups;
+        sub_stats.invalidSubscribeServiceReqMsgs =
+                            pSubStats->invalidSubscribeServiceReqMsgs;
+        sub_stats.invalidSubscribeServiceCancelReqMsgs =
+                            pSubStats->invalidSubscribeServiceCancelReqMsgs;
+        sub_stats.invalidSubscribeFollowupReqMsgs =
+                            pSubStats->invalidSubscribeFollowupReqMsgs;
+        sub_stats.invalidSolicitedPublishes =
+                            pSubStats->invalidSolicitedPublishes;
+        sub_stats.invalidMatches = pSubStats->invalidMatches;
+        sub_stats.invalidFollowups = pSubStats->invalidFollowups;
+        sub_stats.subscribeCount = pSubStats->subscribeCount;
+        sub_stats.bloomFilterIndex = pSubStats->bloomFilterIndex;
+        sub_stats.subscribeNewMatchCount = pSubStats->subscribeNewMatchCount;
+        sub_stats.pubsubGlobalNewMatchCount =
+                                      pSubStats->pubsubGlobalNewMatchCount;
+        memcpy(&pRsp->data.subscribe_stats, &sub_stats, sizeof(NanSubscribeStats));
+    } else if (stats_type == NAN_STATS_ID_DE_DW) {
+        NanDWStats dw_stats;
+        if (message_len != sizeof(NanDWStats)) {
+            ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n",
+                   __func__, stats_type, message_len, sizeof(NanDWStats));
+            return;
+        }
+        FwNanMacStats *pMacStats = (FwNanMacStats *)rspBuf;
+
+        dw_stats.validFrames = pMacStats->validFrames;
+        dw_stats.validActionFrames = pMacStats->validActionFrames;
+        dw_stats.validBeaconFrames = pMacStats->validBeaconFrames;
+        dw_stats.ignoredActionFrames = pMacStats->ignoredActionFrames;
+        dw_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames;
+        dw_stats.invalidFrames = pMacStats->invalidFrames;
+        dw_stats.invalidActionFrames = pMacStats->invalidActionFrames;
+        dw_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames;
+        dw_stats.invalidMacHeaders = pMacStats->invalidMacHeaders;
+        dw_stats.invalidPafHeaders  = pMacStats->invalidPafHeaders;
+        dw_stats.nonNanBeaconFrames = pMacStats->nonNanBeaconFrames;
+        dw_stats.earlyActionFrames = pMacStats->earlyActionFrames;
+        dw_stats.inDwActionFrames = pMacStats->inDwActionFrames;
+        dw_stats.lateActionFrames = pMacStats->lateActionFrames;
+        dw_stats.framesQueued =  pMacStats->framesQueued;
+        dw_stats.totalTRSpUpdates = pMacStats->totalTRSpUpdates;
+        dw_stats.completeByTRSp = pMacStats->completeByTRSp;
+        dw_stats.completeByTp75DW = pMacStats->completeByTp75DW;
+        dw_stats.completeByTendDW = pMacStats->completeByTendDW;
+        dw_stats.lateActionFramesTx = pMacStats->lateActionFramesTx;
+        memcpy(&pRsp->data.dw_stats, &dw_stats, sizeof(NanDWStats));
+    } else if (stats_type == NAN_STATS_ID_DE_MAC) {
+        NanMacStats mac_stats;
+        if (message_len != sizeof(NanMacStats)) {
+            ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n",
+                   __func__, stats_type, message_len, sizeof(NanMacStats));
+            return;
+        }
+        FwNanMacStats *pMacStats = (FwNanMacStats *)rspBuf;
+
+        mac_stats.validFrames = pMacStats->validFrames;
+        mac_stats.validActionFrames = pMacStats->validActionFrames;
+        mac_stats.validBeaconFrames = pMacStats->validBeaconFrames;
+        mac_stats.ignoredActionFrames = pMacStats->ignoredActionFrames;
+        mac_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames;
+        mac_stats.invalidFrames = pMacStats->invalidFrames;
+        mac_stats.invalidActionFrames = pMacStats->invalidActionFrames;
+        mac_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames;
+        mac_stats.invalidMacHeaders = pMacStats->invalidMacHeaders;
+        mac_stats.invalidPafHeaders  = pMacStats->invalidPafHeaders;
+        mac_stats.nonNanBeaconFrames = pMacStats->nonNanBeaconFrames;
+        mac_stats.earlyActionFrames = pMacStats->earlyActionFrames;
+        mac_stats.inDwActionFrames = pMacStats->inDwActionFrames;
+        mac_stats.lateActionFrames = pMacStats->lateActionFrames;
+        mac_stats.framesQueued =  pMacStats->framesQueued;
+        mac_stats.totalTRSpUpdates = pMacStats->totalTRSpUpdates;
+        mac_stats.completeByTRSp = pMacStats->completeByTRSp;
+        mac_stats.completeByTp75DW = pMacStats->completeByTp75DW;
+        mac_stats.completeByTendDW = pMacStats->completeByTendDW;
+        mac_stats.lateActionFramesTx = pMacStats->lateActionFramesTx;
+        mac_stats.twIncreases = pMacStats->twIncreases;
+        mac_stats.twDecreases = pMacStats->twDecreases;
+        mac_stats.twChanges = pMacStats->twChanges;
+        mac_stats.twHighwater = pMacStats->twHighwater;
+        mac_stats.bloomFilterIndex = pMacStats->bloomFilterIndex;
+        memcpy(&pRsp->data.mac_stats, &mac_stats, sizeof(NanMacStats));
+    } else if (stats_type == NAN_STATS_ID_DE_TIMING_SYNC) {
+        NanSyncStats sync_stats;
+        if (message_len != sizeof(NanSyncStats)) {
+            ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n",
+                   __func__, stats_type, message_len, sizeof(NanSyncStats));
+            return;
+        }
+        FwNanSyncStats *pSyncStats = (FwNanSyncStats *)rspBuf;
+
+        sync_stats.currTsf = pSyncStats->currTsf;
+        sync_stats.myRank = pSyncStats->myRank;
+        sync_stats.currAmRank = pSyncStats->currAmRank;
+        sync_stats.lastAmRank = pSyncStats->lastAmRank;
+        sync_stats.currAmBTT = pSyncStats->currAmBTT;
+        sync_stats.lastAmBTT = pSyncStats->lastAmBTT;
+        sync_stats.currAmHopCount = pSyncStats->currAmHopCount;
+        sync_stats.currRole = pSyncStats->currRole;
+        sync_stats.currClusterId = pSyncStats->currClusterId;
+
+        sync_stats.timeSpentInCurrRole = pSyncStats->timeSpentInCurrRole;
+        sync_stats.totalTimeSpentAsMaster = pSyncStats->totalTimeSpentAsMaster;
+        sync_stats.totalTimeSpentAsNonMasterSync =
+                            pSyncStats->totalTimeSpentAsNonMasterSync;
+        sync_stats.totalTimeSpentAsNonMasterNonSync =
+                            pSyncStats->totalTimeSpentAsNonMasterNonSync;
+        sync_stats.transitionsToAnchorMaster =
+                            pSyncStats->transitionsToAnchorMaster;
+        sync_stats.transitionsToMaster =
+                            pSyncStats->transitionsToMaster;
+        sync_stats.transitionsToNonMasterSync =
+                            pSyncStats->transitionsToNonMasterSync;
+        sync_stats.transitionsToNonMasterNonSync =
+                            pSyncStats->transitionsToNonMasterNonSync;
+        sync_stats.amrUpdateCount = pSyncStats->amrUpdateCount;
+        sync_stats.amrUpdateRankChangedCount =
+                            pSyncStats->amrUpdateRankChangedCount;
+        sync_stats.amrUpdateBTTChangedCount =
+                            pSyncStats->amrUpdateBTTChangedCount;
+        sync_stats.amrUpdateHcChangedCount =
+                            pSyncStats->amrUpdateHcChangedCount;
+        sync_stats.amrUpdateNewDeviceCount =
+                            pSyncStats->amrUpdateNewDeviceCount;
+        sync_stats.amrExpireCount = pSyncStats->amrExpireCount;
+        sync_stats.mergeCount = pSyncStats->mergeCount;
+        sync_stats.beaconsAboveHcLimit = pSyncStats->beaconsAboveHcLimit;
+        sync_stats.beaconsBelowRssiThresh = pSyncStats->beaconsBelowRssiThresh;
+        sync_stats.beaconsIgnoredNoSpace = pSyncStats->beaconsIgnoredNoSpace;
+        sync_stats.beaconsForOurCluster = pSyncStats->beaconsForOtherCluster;
+        sync_stats.beaconsForOtherCluster = pSyncStats->beaconsForOtherCluster;
+        sync_stats.beaconCancelRequests = pSyncStats->beaconCancelRequests;
+        sync_stats.beaconCancelFailures = pSyncStats->beaconCancelFailures;
+        sync_stats.beaconUpdateRequests = pSyncStats->beaconUpdateRequests;
+        sync_stats.beaconUpdateFailures = pSyncStats->beaconUpdateFailures;
+        sync_stats.syncBeaconTxAttempts = pSyncStats->syncBeaconTxAttempts;
+        sync_stats.syncBeaconTxFailures = pSyncStats->syncBeaconTxFailures;
+        sync_stats.discBeaconTxAttempts = pSyncStats->discBeaconTxAttempts;
+        sync_stats.discBeaconTxFailures = pSyncStats->discBeaconTxFailures;
+        sync_stats.amHopCountExpireCount = pSyncStats->amHopCountExpireCount;
+        sync_stats.ndpChannelFreq = pSyncStats->ndpChannelFreq;
+        sync_stats.ndpChannelFreq2 = pSyncStats->ndpChannelFreq2;
+        sync_stats.schedUpdateChannelFreq = pSyncStats->schedUpdateChannelFreq;
+        memcpy(&pRsp->data.sync_stats, &sync_stats, sizeof(NanSyncStats));
+    } else if (stats_type == NAN_STATS_ID_DE) {
+        NanDeStats de_stats;
+        if (message_len != sizeof(NanDeStats)) {
+            ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n",
+                   __func__, stats_type, message_len, sizeof(NanDeStats));
+            return;
+        }
+        FwNanDeStats *pDeStats = (FwNanDeStats *)rspBuf;
+
+        de_stats.validErrorRspMsgs = pDeStats->validErrorRspMsgs;
+        de_stats.validTransmitFollowupReqMsgs =
+                        pDeStats->validTransmitFollowupReqMsgs;
+        de_stats.validTransmitFollowupRspMsgs =
+                        pDeStats->validTransmitFollowupRspMsgs;
+        de_stats.validFollowupIndMsgs =
+                        pDeStats->validFollowupIndMsgs;
+        de_stats.validConfigurationReqMsgs =
+                        pDeStats->validConfigurationReqMsgs;
+        de_stats.validConfigurationRspMsgs =
+                        pDeStats->validConfigurationRspMsgs;
+        de_stats.validStatsReqMsgs = pDeStats->validStatsReqMsgs;
+        de_stats.validStatsRspMsgs = pDeStats->validStatsRspMsgs;
+        de_stats.validEnableReqMsgs = pDeStats->validEnableReqMsgs;
+        de_stats.validEnableRspMsgs = pDeStats->validEnableRspMsgs;
+        de_stats.validDisableReqMsgs = pDeStats->validDisableReqMsgs;
+        de_stats.validDisableRspMsgs = pDeStats->validDisableRspMsgs;
+        de_stats.validDisableIndMsgs = pDeStats->validDisableIndMsgs;
+        de_stats.validEventIndMsgs = pDeStats->validEventIndMsgs;
+        de_stats.validTcaReqMsgs = pDeStats->validTcaReqMsgs;
+        de_stats.validTcaRspMsgs = pDeStats->validTcaRspMsgs;
+        de_stats.validTcaIndMsgs = pDeStats->validTcaIndMsgs;
+        de_stats.invalidTransmitFollowupReqMsgs =
+                            pDeStats->invalidTransmitFollowupReqMsgs;
+        de_stats.invalidConfigurationReqMsgs =
+                            pDeStats->invalidConfigurationReqMsgs;
+        de_stats.invalidStatsReqMsgs = pDeStats->invalidStatsReqMsgs;
+        de_stats.invalidEnableReqMsgs = pDeStats->invalidEnableReqMsgs;
+        de_stats.invalidDisableReqMsgs = pDeStats->invalidDisableReqMsgs;
+        de_stats.invalidTcaReqMsgs = pDeStats->invalidTcaReqMsgs;
+        memcpy(&pRsp->data.de_stats, &de_stats, sizeof(NanDeStats));
+    } else {
+        ALOGE("Unknown stats_type:%d\n", stats_type);
+    }
+}
+
+int NanCommand::handleNdpResponse(NanResponseType ndpCmdType,
+                                  struct nlattr **tb_vendor)
+{
+    //parse the data and call
+    //the response callback handler with the populated
+    //NanResponseMsg
+    NanResponseMsg  rsp_data;
+    transaction_id id;
+
+    memset(&rsp_data, 0, sizeof(rsp_data));
+
+    if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) ||
+        (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE]) ||
+        (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]))
+    {
+        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+    ALOGD("%s: Transaction id : val %d", __FUNCTION__, id);
+
+    NanErrorTranslation((NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE]),
+                        nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]), &rsp_data, true);
+    rsp_data.response_type = ndpCmdType;
+
+    if (ndpCmdType == NAN_DP_INITIATOR_RESPONSE)
+    {
+        if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])
+        {
+            ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        rsp_data.body.data_request_response.ndp_instance_id =
+        nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
+    }
+    //Call the NotifyResponse Handler
+    if (mHandler.NotifyResponse) {
+        (*mHandler.NotifyResponse)(id, &rsp_data);
+    }
+    return WIFI_SUCCESS;
+}
diff --git a/wcn6740/qcwcn/wifi_hal/nancommand.h b/wcn6740/qcwcn/wifi_hal/nancommand.h
new file mode 100644
index 0000000..ac2a64b
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/nancommand.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_NAN_COMMAND_H__
+#define __WIFI_HAL_NAN_COMMAND_H__
+
+#include "common.h"
+#include "cpp_bindings.h"
+#include "wifi_hal.h"
+#include "nan_cert.h"
+
+/*
+ * NAN Salt is a concatenation of salt_version, CSID, Service ID, PeerMac
+ * resulting in a total length of 14 bytes
+ */
+#define NAN_SECURITY_SALT_SIZE 14
+/* In Service ID calculation SHA-256 hash size is of max. 64 bytes */
+#define NAN_SVC_HASH_SIZE 64
+/* Service ID is the first 48 bits of the SHA-256 hash of the Service Name */
+#define NAN_SVC_ID_SIZE 6
+/* Default Service name length is 21 bytes */
+#define NAN_DEF_SVC_NAME_LEN 21
+/* As per NAN spec, 4096 iterations to be used for PMK calculation */
+#define NAN_PMK_ITERATIONS 4096
+/* Keep NCS-SK-128 Cipher Suite as default i.e. HMAC-SHA-256 algorithm */
+#define NAN_DEFAULT_NCS_SK NAN_CIPHER_SUITE_SHARED_KEY_128_MASK
+/* Currently by default max 6 Publishes/Subscribes are allowed */
+#define NAN_DEF_PUB_SUB 6
+/*
+ * First bit of discovery_indication_cfg in NanEnableRequest indicates
+ * disableDiscoveryAddressChangeIndication
+ */
+#define NAN_DISC_ADDR_IND_DISABLED 0x01
+
+typedef struct PACKED
+{
+    u32 instance_id;
+    u16 subscriber_publisher_id;
+    u8 service_id[NAN_SVC_ID_SIZE];
+} NanStoreSvcParams;
+
+typedef enum
+{
+    NAN_ROLE_NONE,
+    NAN_ROLE_PUBLISHER,
+    NAN_ROLE_SUBSCRIBER
+} NanRole;
+
+class NanCommand : public WifiVendorCommand
+{
+private:
+    NanCallbackHandler mHandler;
+    char *mNanVendorEvent;
+    u32 mNanDataLen;
+    NanStaParameter *mStaParam;
+    u8 mNmiMac[NAN_MAC_ADDR_LEN];
+    u32 mNanMaxPublishes;
+    u32 mNanMaxSubscribes;
+    NanStoreSvcParams *mStorePubParams;
+    NanStoreSvcParams *mStoreSubParams;
+    bool mNanDiscAddrIndDisabled;
+
+    //Function to check the initial few bytes of data to
+    //determine whether NanResponse or NanEvent
+    int isNanResponse();
+    //Function which unparses the data and calls the NotifyResponse
+    int handleNanResponse();
+    //Function which will parse the mVendorData and gets
+    // the rsp_data appropriately.
+    int getNanResponse(transaction_id *id, NanResponseMsg *pRsp);
+    //Function which will return the Nan Indication type based on
+    //the initial few bytes of mVendorData
+    NanIndicationType getIndicationType();
+    //Function which calls the necessaryIndication callback
+    //based on the indication type
+    int handleNanIndication();
+    //Various Functions to get the appropriate indications
+    int getNanPublishReplied(NanPublishRepliedInd *event);
+    int getNanPublishTerminated(NanPublishTerminatedInd *event);
+    int getNanMatch(NanMatchInd *event);
+    int getNanMatchExpired(NanMatchExpiredInd *event);
+    int getNanSubscribeTerminated(NanSubscribeTerminatedInd *event);
+    int getNanFollowup(NanFollowupInd *event);
+    int getNanDiscEngEvent(NanDiscEngEventInd *event);
+    int getNanDisabled(NanDisabledInd *event);
+    int getNanTca(NanTCAInd *event);
+    int getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event);
+    //Internal cleanup function
+    void cleanup();
+
+    static NanCommand *mNanCommandInstance;
+
+    // Other private helper functions
+    int calcNanTransmitPostDiscoverySize(
+        const NanTransmitPostDiscovery *pPostDiscovery);
+    void fillNanSocialChannelParamVal(
+        const NanSocialChannelScanParams *pScanParams,
+        u32* pChannelParamArr);
+    u32 getNanTransmitPostConnectivityCapabilityVal(
+        const NanTransmitPostConnectivityCapability *pCapab);
+    void fillNanTransmitPostDiscoveryVal(
+        const NanTransmitPostDiscovery *pTxDisc,
+        u8 *pOutValue);
+    int calcNanFurtherAvailabilityMapSize(
+        const NanFurtherAvailabilityMap *pFam);
+    void fillNanFurtherAvailabilityMapVal(
+        const NanFurtherAvailabilityMap *pFam,
+        u8 *pOutValue);
+
+    void getNanReceivePostConnectivityCapabilityVal(
+        const u8* pInValue,
+        NanReceivePostConnectivityCapability *pRxCapab);
+    void getNanReceiveSdeaCtrlParams(const u8* pInValue,
+        NanSdeaCtrlParams *pPeerSdeaParams);
+    int getNanReceivePostDiscoveryVal(const u8 *pInValue,
+                                      u32 length,
+                                      NanReceivePostDiscovery *pRxDisc);
+    int getNanFurtherAvailabilityMap(const u8 *pInValue,
+                                     u32 length,
+                                     u8* num_chans,
+                                     NanFurtherAvailabilityChannel *pFac);
+    void handleNanStatsResponse(NanStatsType stats_type,
+                                char* rspBuf,
+                                NanStatsResponse *pRsp,
+                                u32 message_len);
+
+    //Function which unparses the data and calls the NotifyResponse
+    int handleNdpResponse(NanResponseType ndpCmdtyp, struct nlattr **tb_vendor);
+    int handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor);
+    int getNdpRequest(struct nlattr **tb_vendor, NanDataPathRequestInd *event);
+    int getNdpConfirm(struct nlattr **tb_vendor, NanDataPathConfirmInd *event);
+    int getNdpEnd(struct nlattr **tb_vendor, NanDataPathEndInd *event);
+    int getNanTransmitFollowupInd(NanTransmitFollowupInd *event);
+    int getNanRangeRequestReceivedInd(NanRangeRequestInd *event);
+    int getNanRangeReportInd(NanRangeReportInd *event);
+    int getNdpScheduleUpdate(struct nlattr **tb_vendor, NanDataPathScheduleUpdateInd *event);
+public:
+    NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+    static NanCommand* instance(wifi_handle handle);
+    virtual ~NanCommand();
+
+    // This function implements creation of NAN specific Request
+    // based on  the request type
+    virtual wifi_error create();
+    virtual wifi_error requestEvent();
+    virtual int handleResponse(WifiEvent &reply);
+    virtual int handleEvent(WifiEvent &event);
+    wifi_error setCallbackHandler(NanCallbackHandler nHandler);
+
+
+    //Functions to fill the vendor data appropriately
+    wifi_error putNanEnable(transaction_id id, const NanEnableRequest *pReq);
+    wifi_error putNanDisable(transaction_id id);
+    wifi_error putNanPublish(transaction_id id, const NanPublishRequest *pReq);
+    wifi_error putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq);
+    wifi_error putNanSubscribe(transaction_id id, const NanSubscribeRequest *pReq);
+    wifi_error putNanSubscribeCancel(transaction_id id, const NanSubscribeCancelRequest *pReq);
+    wifi_error putNanTransmitFollowup(transaction_id id, const NanTransmitFollowupRequest *pReq);
+    wifi_error putNanStats(transaction_id id, const NanStatsRequest *pReq);
+    wifi_error putNanConfig(transaction_id id, const NanConfigRequest *pReq);
+    wifi_error putNanTCA(transaction_id id, const NanTCARequest *pReq);
+    wifi_error putNanBeaconSdfPayload(transaction_id id, const NanBeaconSdfPayloadRequest *pReq);
+    wifi_error getNanStaParameter(wifi_interface_handle iface, NanStaParameter *pRsp);
+    wifi_error putNanCapabilities(transaction_id id);
+    wifi_error putNanDebugCommand(NanDebugParams debug, int debug_msg_length);
+
+    /* Functions for NAN error translation
+       For NanResponse, NanPublishTerminatedInd, NanSubscribeTerminatedInd,
+       NanDisabledInd, NanTransmitFollowupInd:
+       function to translate firmware specific errors
+       to generic freamework error along with the error string
+    */
+    void NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd,
+                             u32 valueRcvd,
+                             void *pRsp,
+                             bool is_ndp_rsp);
+
+    /* Functions for NAN passphrase to PMK calculation */
+    void saveNmi(u8 *mac);
+    u8 *getNmi();
+    void saveServiceId(u8 *service_id, u16 sub_pub_handle,
+                        u32 instance_id, NanRole Pool);
+    u8 *getServiceId(u32 instance_id, NanRole Pool);
+    void deleteServiceId(u16 sub_handle, u32 instance_id, NanRole pool);
+    void allocSvcParams();
+    void reallocSvcParams(NanRole pool);
+    void deallocSvcParams();
+};
+#endif /* __WIFI_HAL_NAN_COMMAND_H__ */
+
diff --git a/wcn6740/qcwcn/wifi_hal/nud_stats.h b/wcn6740/qcwcn/wifi_hal/nud_stats.h
new file mode 100644
index 0000000..c88b3a9
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/nud_stats.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include "wifi_hal.h"
+#include <bits/in_addr.h>
+
+#define INET6_ADDRSTRLEN 46
+
+extern "C" {
+	const char* inet_ntop(int __af, const void* __src, char* __dst, socklen_t __size);
+}
+
+typedef struct {
+    uint16_t arp_req_count_from_netdev;
+    uint16_t arp_req_count_to_lower_mac;
+    uint16_t arp_req_rx_count_by_lower_mac;
+    uint16_t arp_req_count_tx_success;
+    uint16_t arp_rsp_rx_count_by_lower_mac;
+    uint16_t arp_rsp_rx_count_by_upper_mac;
+    uint16_t arp_rsp_count_to_netdev;
+    uint16_t arp_rsp_count_out_of_order_drop;
+    uint8_t ap_link_active;
+    uint8_t is_duplicate_addr_detection;
+} nud_stats;
+
+typedef struct {
+    uint16_t pkt_req_count_from_netdev;
+    uint16_t pkt_req_count_to_lower_mac;
+    uint16_t pkt_req_rx_count_by_lower_mac;
+    uint16_t pkt_req_count_tx_success;
+    uint16_t pkt_rsp_rx_count_by_lower_mac;
+    uint16_t pkt_rsp_rx_count_by_upper_mac;
+    uint16_t pkt_rsp_count_to_netdev;
+    uint16_t pkt_rsp_count_out_of_order_drop;
+} pkt_stats;
+
+typedef struct{
+    u32 pkt_Type;
+    char* domain_name;
+    u32 src_port;
+    u32 dst_port;
+    struct in_addr ipv4_addr;
+    u8 ipv6_addr[16];
+    pkt_stats stats;
+} cmdData;
+
+/* callback for get NUD stats */
+typedef struct {
+  void (*on_pkt_stats_results) (nud_stats *stats,
+         int mnumStats,  cmdData *pkt_stats);
+} pkt_stats_result_handler;
+
+wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr,
+                              cmdData set_data);
+wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
+                              pkt_stats_result_handler handler);
+wifi_error wifi_clear_nud_stats(wifi_interface_handle iface,
+                                cmdData set_data);
diff --git a/wcn6740/qcwcn/wifi_hal/pkt_stats.h b/wcn6740/qcwcn/wifi_hal/pkt_stats.h
new file mode 100644
index 0000000..e01da3b
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/pkt_stats.h
@@ -0,0 +1,674 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PKT_STATS_H_
+#define _PKT_STATS_H_
+
+/* Types of packet log events.
+ * Tx stats will be sent from driver with the help of multiple events.
+ * Need to parse the events PKTLOG_TYPE_TX_CTRL and PKTLOG_TYPE_TX_STAT
+ * as of now for the required stats. Rest of the events can ignored.
+ */
+#define PKTLOG_TYPE_TX_CTRL         1
+#define PKTLOG_TYPE_TX_STAT         2
+#define PKTLOG_TYPE_TX_MSDU_ID      3
+#define PKTLOG_TYPE_TX_FRM_HDR      4
+/* Rx stats will be sent from driver with event ID- PKTLOG_TYPE_RX_STAT */
+#define PKTLOG_TYPE_RX_STAT         5
+#define PKTLOG_TYPE_RC_FIND         6
+#define PKTLOG_TYPE_RC_UPDATE       7
+#define PKTLOG_TYPE_TX_VIRT_ADDR    8
+#define PKTLOG_TYPE_PKT_STATS       9
+#define PKTLOG_TYPE_PKT_DUMP        10
+#define PKTLOG_TYPE_PKT_DUMP_V2     11
+#define PKTLOG_TYPE_MAX             12
+#define BW_OFFSET 8
+#define INVALID_RSSI 255
+#define INVALID_RATE_CODE 0xff
+
+/* Based on pkt log V2, this type of event will triggered */
+#define PKTLOG_TYPE_PKT_SW_EVENT    10
+#define PKTLOG_TYPE_RX_STATBUF      22   //Full Rx pktlog stats
+#define PKTLOG_TYPE_LITE_T2H        23   //PPDU Level Tx pktlog stats
+#define PKTLOG_TYPE_LITE_RX         24   //PPDU Level Rx pktlog stats
+
+
+#define PKT_INFO_FLG_TX_LOCAL_S          0x1
+#define PKT_INFO_FLG_RX_HOST_RXD         0x2
+#define PKT_INFO_FLG_TX_REMOTE_S         0x4
+#define PKT_INFO_FLG_RX_LOCAL_S          0x8
+#define PKT_INFO_FLG_RX_REMOTE_S         0x10
+#define PKT_INFO_FLG_RX_LOCAL_DISCARD_S  0x20
+#define PKT_INFO_FLG_RX_REMOTE_DISCARD_S 0x40
+#define PKT_INFO_FLG_RX_REORDER_STORE_S  0x80
+#define PKT_INFO_FLG_RX_REORDER_DROP_S   0x100
+#define PKT_INFO_FLG_RX_PEER_INFO_S      0x200
+#define PKT_INFO_FLG_UNKNOWN_S           0x400
+#define PKT_INFO_FLG_PKT_DUMP_V2         0x8000
+
+/* Depend on packet log version V2 this
+ * offset are define, for more info need to
+ * check from firmware side.
+ */
+#define TX_SUCCESS_TMS_OFFSET 56
+#define LINK_LAYER_TX_SQN_OFFSET 66
+#define RATE_CODE_OFFSET 68
+#define TX_STATUS_OFFSET 70
+#define TX_RSSI_OFFSET 71
+#define NO_RETRIES_OFFSET 75
+#define EXT_FLAGS_OFFSET 76
+#define BMAP_FAILED_OFFSET 84
+#define BMAP_ENQUEUED_OFFSET 92
+#define FRAME_CTRL_OFFSET 216
+#define QOS_CTRL_OFFSET 218
+
+/* MAX HT/VHT mcs index */
+#define MAX_VHT_MCS_IDX 10
+#define MAX_HT_MCS_IDX 8
+
+/* MAX CCK/OFDM rate index */
+#define MAX_CCK_MCS_IDX 4
+#define MAX_OFDM_MCS_IDX 8
+
+/* MASK value of flags based on RX_STAT content.
+ * These are the events that carry Rx decriptor
+ */
+#define PKT_INFO_FLG_RX_RXDESC_MASK \
+        (PKT_INFO_FLG_RX_HOST_RXD | \
+         PKT_INFO_FLG_RX_LOCAL_S | \
+         PKT_INFO_FLG_RX_REMOTE_S | \
+         PKT_INFO_FLG_RX_LOCAL_DISCARD_S | \
+         PKT_INFO_FLG_RX_REMOTE_DISCARD_S)
+
+/* Format of the packet stats event*/
+typedef struct {
+    u16 flags;
+    u16 missed_cnt;
+    u16 log_type;
+    u16 size;
+    u32 timestamp;
+} __attribute__((packed)) wh_pktlog_hdr_t;
+
+/* Format of the v2 packet stats event*/
+typedef struct {
+    u16 flags;
+    u16 missed_cnt;
+    u16 log_type        : 8; //[7:0]
+    u16 mac_id          : 8; //[15:8]
+    u16 size;
+    u32 timestamp;
+    u32 reserved;
+} __attribute__((packed)) wh_pktlog_hdr_v2_t;
+
+/*Rx stats specific structures. */
+struct rx_attention {
+    u32 first_mpdu                      :  1; //[0]
+    u32 last_mpdu                       :  1; //[1]
+    u32 reserved1                       :  6; //[7:2]
+    u32 mgmt_type                       :  1; //[8]
+    u32 ctrl_type                       :  1; //[9]
+    u32 reserved2                       :  6; //[15:10]
+    u32 overflow_err                    :  1; //[16]
+    u32 msdu_length_err                 :  1; //[17]
+    u32 tcp_udp_chksum_fail             :  1; //[18]
+    u32 ip_chksum_fail                  :  1; //[19]
+    u32 reserved3                       :  7; //[26:20]
+    u32 mpdu_length_err                 :  1; //[27]
+    u32 tkip_mic_err                    :  1; //[28]
+    u32 decrypt_err                     :  1; //[29]
+    u32 fcs_err                         :  1; //[30]
+    u32 msdu_done                       :  1; //[31]
+} __attribute__((packed));
+
+struct rx_mpdu_start {
+    u32 reserved1                       : 13; //[12:0]
+    u32 encrypted                       :  1; //[13]
+    u32 retry                           :  1; //[14]
+    u32 reserved2                       :  1; //[15]
+    u32 seq_num                         : 12; //[27:16]
+    u32 reserved3                       :  4; //[31:28]
+    u32 reserved4;
+    u32 reserved5                       : 28; //[27:0]
+    u32 tid                             :  4; //[31:28]
+} __attribute__((packed));
+
+/*Indicates the decap-format of the packet*/
+enum {
+    RAW=0,      // RAW: No decapsulation
+    NATIVEWIFI,
+    ETHERNET2,  // (DIX)
+    ETHERNET    // (SNAP/LLC)
+};
+
+struct rx_msdu_start {
+    u32 reserved1[2];
+    u32 reserved2                       :  8; //[7:0]
+    u32 decap_format                    :  2; //[9:8]
+    u32 reserved3                       : 22; //[31:10]
+} __attribute__((packed));
+
+struct rx_msdu_end {
+    u32 reserved1[4];
+    u32 reserved2                       : 15;
+    u32 last_msdu                       :  1; //[15]
+    u32 reserved3                       : 16; //[31:16]
+} __attribute__((packed));
+
+struct rx_mpdu_end {
+    u32 reserved1                       : 13; //[12:0]
+    u32 overflow_err                    :  1; //[13]
+    u32 last_mpdu                       :  1; //[14]
+    u32 post_delim_err                  :  1; //[15]
+    u32 reserved2                       : 12; //[27:16]
+    u32 mpdu_length_err                 :  1; //[28]
+    u32 tkip_mic_err                    :  1; //[29]
+    u32 decrypt_err                     :  1; //[30]
+    u32 fcs_err                         :  1; //[31]
+} __attribute__((packed));
+
+/* structure implemented w.r.t PKT_LOG_V2 Version */
+struct rx_msdu_start_v1 {
+    u32 reserved1[2];
+    u32 reserved2                       :  8; //[7:0]
+    u32 decap_format                    :  2; //[9:8]
+    u32 reserved3                       : 22; //[31:10]
+    u32 reserved4[2];
+} __attribute__((packed));
+
+struct rx_msdu_end_v1 {
+    u32 reserved1[4];
+    u32 reserved2                       : 15; //[14:0]
+    u32 last_msdu                       :  1; //[15]
+    u32 reserved3                       : 16; //[31:16]
+    u32 reserved4[9];
+} __attribute__((packed));
+/************************************************************/
+
+#define PREAMBLE_L_SIG_RATE     0x04
+#define PREAMBLE_VHT_SIG_A_1    0x08
+#define PREAMBLE_VHT_SIG_A_2    0x0c
+
+/* Wifi Logger preamble */
+#define WL_PREAMBLE_CCK  0
+#define WL_PREAMBLE_OFDM 1
+#define WL_PREAMBLE_HT   2
+#define WL_PREAMBLE_VHT  3
+
+#define BITMASK(x) ((1<<(x)) - 1 )
+#define MAX_BA_WINDOW_SIZE 64
+#define SEQ_NUM_RANGE 4096
+#define BITMAP_VAR_SIZE 32
+
+/* Contains MCS related stats */
+struct rx_ppdu_start {
+    u32 reserved1[4];
+    u32 rssi_comb                       :  8; //[7:0]
+    u32 reserved2                       : 24; //[31:8]
+    u32 l_sig_rate                      :  4; //[3:0]
+    u32 l_sig_rate_select               :  1; //[4]
+    u32 reserved3                       : 19; //[23:5]
+    u32 preamble_type                   :  8; //[31:24]
+    u32 ht_sig_vht_sig_a_1              : 24; //[23:0]
+    u32 reserved4                       :  8; //[31:24]
+    u32 ht_sig_vht_sig_a_2              : 24; //[23:0]
+    u32 reserved5                       :  8; //[31:25]
+    u32 reserved6[2];
+} __attribute__((packed));
+
+struct rx_ppdu_end {
+    u32 reserved1[16];
+    u32 tsf_timestamp;
+    u32 reserved2[5];
+} __attribute__((packed));
+
+struct rx_ppdu_end_V1 {
+    u32 reserved1[18];
+    u32 wb_timestamp_lower_32;
+    u32 reserved2[18];
+} __attribute__((packed));
+
+#define MAX_MSDUS_PER_MPDU 3
+#define MAX_RXMPDUS_PER_AMPDU 64
+#define RX_HTT_HDR_STATUS_LEN 64
+/* RX Data length is 256 for PKT_LOG_V2 Version */
+#define RX_HTT_HDR_STATUS_LEN_V1 256
+
+typedef struct {
+    struct rx_attention attention;
+    u32 reserved1;
+    struct rx_mpdu_start mpdu_start;
+    struct rx_msdu_start msdu_start;
+    struct rx_msdu_end   msdu_end;
+    struct rx_mpdu_end   mpdu_end;
+    struct rx_ppdu_start ppdu_start;
+    struct rx_ppdu_end   ppdu_end;
+    char rx_hdr_status[RX_HTT_HDR_STATUS_LEN];
+}__attribute__((packed)) rb_pkt_stats_t;
+
+/* structure implemented w.r.t PKT_LOG_V2 Version */
+typedef struct {
+    struct rx_attention attention;
+    u32 reserved1[2];
+    struct rx_mpdu_start    mpdu_start;
+    struct rx_msdu_start_v1 msdu_start;
+    struct rx_msdu_end_v1   msdu_end;
+    struct rx_mpdu_end      mpdu_end;
+    struct rx_ppdu_start    ppdu_start;
+    struct rx_ppdu_end_V1    ppdu_end;
+    char rx_hdr_status[RX_HTT_HDR_STATUS_LEN_V1];
+}__attribute__((packed)) rb_pkt_stats_t_v1;
+/************************************************************/
+
+/*Tx stats specific structures. */
+struct ppdu_status {
+    u32 ba_start_seq_num                : 12; //[11:0]
+    u32 reserved1                       :  3; //[14:12]
+    u32 ba_status                       :  1; //[15]
+    u32 reserved2                       : 15; //[30:16]
+    u32 tx_ok                           :  1; //[31]
+    u32 ba_bitmap_31_0                  : 32; //[31:0]
+    u32 ba_bitmap_63_32                 : 32; //[31:0]
+    u32 reserved3[8];
+    u32 ack_rssi_ave                    :  8; //[7:0]
+    u32 reserved4                       : 16; //[23:8]
+    u32 total_tries                     :  5; //[28:24]
+    u32 reserved5                       :  3; //[31:29]
+    u32 reserved6[4];
+} __attribute__((packed));
+
+/*Contains tx timestamp*/
+struct try_status {
+    u32 timestamp                       : 23; //[22:0]
+    u32 reserved1                       :  1; //[23]
+    u32 series                          :  1; //[24]
+    u32 reserved2                       :  3; //[27:25]
+    u32 packet_bw                       :  2; //[29:28]
+    u32 reserved3                       :  1; //[30]
+    u32 tx_packet                       :  1; //[31]
+} __attribute__((packed));
+
+struct try_list {
+    struct try_status try_st[16];
+} __attribute__((packed));
+
+
+struct tx_ppdu_end {
+    struct try_list try_list;
+    struct ppdu_status stat;
+} __attribute__((packed));
+
+/*Tx MCS and data rate ralated stats */
+struct series_bw {
+    u32 reserved1                       : 28; //[27:0]
+    u32 short_gi                        :  1; //[28]
+    u32 reserved2                       :  3; //[31:29]
+    u32 reserved3                       : 24; //[23:21]
+    u32 rate                            :  4; //[27:24]
+    u32 nss                             :  2; //[29:28]
+    u32 preamble_type                   :  2; //[31:30]
+    u32 reserved4[2];
+} __attribute__((packed));
+
+enum tx_bw {
+    BW_20_MHZ,
+    BW_40_MHZ,
+    BW_80_MHZ,
+    BW_160_MHZ
+};
+
+#define DATA_PROTECTED 14
+struct tx_ppdu_start {
+    u32 reserved1[2];
+    u32 start_seq_num                   : 12; //[11:0]
+    u32 reserved2                       : 20; //[31:12]
+    u32 seqnum_bitmap_31_0              : 32; //[31:0]
+    u32 seqnum_bitmap_63_32             : 32; //[31:0]
+    u32 reserved3[8];
+    u32 reserved4                       : 15; //[14:0]
+    u32 ampdu                           :  1; //[15]
+    u32 no_ack                          :  1; //[16]
+    u32 reserved5                       : 15; //[31:17]
+    u32 reserved6                       : 16; //[15:0]
+    u32 frame_control                   : 16; //[31:16]
+    u32 reserved7                       : 16; //[23:21]
+    u32 qos_ctl                         : 16; //[31:16]
+    u32 reserved8[4];
+    u32 reserved9                       : 24; //[23:21]
+    u32 valid_s0_bw20                   :  1; //[24]
+    u32 valid_s0_bw40                   :  1; //[25]
+    u32 valid_s0_bw80                   :  1; //[26]
+    u32 valid_s0_bw160                  :  1; //[27]
+    u32 valid_s1_bw20                   :  1; //[28]
+    u32 valid_s1_bw40                   :  1; //[29]
+    u32 valid_s1_bw80                   :  1; //[30]
+    u32 valid_s1_bw160                  :  1; //[31]
+    struct series_bw s0_bw20;
+    struct series_bw s0_bw40;
+    struct series_bw s0_bw80;
+    struct series_bw s0_bw160;
+    struct series_bw s1_bw20;
+    struct series_bw s1_bw40;
+    struct series_bw s1_bw80;
+    struct series_bw s1_bw160;
+    u32 reserved10[3];
+} __attribute__((packed));
+
+#define PKTLOG_MAX_TXCTL_WORDS 57 /* +2 words for bitmap */
+typedef struct {
+    u32 reserved1[3];
+    union {
+        u32 txdesc_ctl[PKTLOG_MAX_TXCTL_WORDS];
+        struct tx_ppdu_start ppdu_start;
+    }u;
+} __attribute__((packed)) wh_pktlog_txctl;
+
+/* Required stats are spread across multiple
+ * events(PKTLOG_TYPE_TX_CTRL and PKTLOG_TYPE_TX_STAT here).
+ * Need to aggregate the stats collected in each event and write to the
+ * ring buffer only after receiving all the expected stats.
+ * Need to preserve the stats in hal_info till then and use tx_stats_events
+ * flag to track the events.
+ * prev_seq_no: Can used to track the events that come from driver and identify
+ * if any event is missed.
+ */
+
+/* PKT_LOG_V2 Base strcuture used to parse buffer */
+typedef struct {
+    u16 frm_ctrl;
+    u8  tx_ok;
+    u16 qos_ctrl;
+    u64 bmap_failed;
+    u64 bmap_enqueued;
+} __attribute__((packed)) node_pkt_stats;
+
+typedef u8 A_RATECODE;
+
+/* Rate Code as per PKT_LOG_V2 Version */
+typedef struct {
+    A_RATECODE rateCode;
+    u8 flags;
+} RATE_CODE;
+
+/* bandwidht type*/
+typedef enum {
+    BW_20MHZ,
+    BW_40MHZ,
+    BW_80MHZ,
+    BW_160MHZ,
+} bandwidth;
+
+/* Preamble type*/
+typedef enum {
+    WIFI_HW_RATECODE_PREAM_OFDM = 0,
+    WIFI_HW_RATECODE_PREAM_CCK  = 1,
+    WIFI_HW_RATECODE_PREAM_HT   = 2,
+    WIFI_HW_RATECODE_PREAM_VHT  = 3,
+    WIFI_HW_RATECODE_PREAM_COUNT,
+} WIFI_HW_RATECODE_PREAM_TYPE;
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @rate_index: cck  rate index
+ * @cck_rate: CCK supported rate table
+ */
+struct index_data_rate_cck_type {
+    uint8_t  rate_index;
+    uint16_t cck_rate[2];
+};
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @rate_index: ofdm  rate index
+ * @ofdm__rate: OFDM supported rate table
+ */
+struct index_data_rate_ofdm_type {
+    uint8_t  rate_index;
+    uint16_t ofdm_rate[2];
+};
+
+/*Below CCK/OFDM table refer from firmware Arch */
+/* Rate Table Based on CCK */
+static struct index_data_rate_cck_type cck_mcs_nss1[] = {
+    /*RC     LKbps   SKbps */
+    {0x40,  {11000,  11000} },
+    {0x41,  {5500,   5500} },
+    {0x42,  {2000,   2000} },
+    {0x43,  {1000,   1000} }
+};
+
+/* Rate Table Based on OFDM */
+static struct index_data_rate_ofdm_type ofdm_mcs_nss1[] = {
+    /*RC     LKbps   SKbps */
+    {0x00,  {48000,  48000} },
+    {0x01,  {34000,  24000} },
+    {0x02,  {12000,  12000} },
+    {0x03,  {6000,   6000} },
+    {0x04,  {54000,  54000} },
+    {0x05,  {36000,  36000} },
+    {0x06,  {18000,  18000} },
+    {0x07,  {9000,   9000} }
+};
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @mcs_index: mcs rate index
+ * @ht20_rate: HT20 supported rate table
+ * @ht40_rate: HT40 supported rate table
+ */
+struct index_data_rate_type {
+    uint8_t  mcs_index;
+    uint16_t ht20_rate[2];
+    uint16_t ht40_rate[2];
+};
+
+/**
+ * struct index_vht_data_rate_type - vht data rate type
+ * @mcs_index: mcs rate index
+ * @ht20_rate: VHT20 supported rate table
+ * @ht40_rate: VHT40 supported rate table
+ * @ht80_rate: VHT80 supported rate table
+ */
+struct index_vht_data_rate_type {
+    uint8_t mcs_index;
+    uint16_t ht20_rate[2];
+    uint16_t ht40_rate[2];
+    uint16_t ht80_rate[2];
+};
+
+/*Below HT/VHT table refer from Host Driver
+ * MCS Based rate table
+ * HT MCS parameters with Nss = 1
+ */
+static struct index_data_rate_type mcs_nss1[] = {
+    /* MCS L20  S20   L40   S40 */
+    {0,  {65,  72},  {135,  150 } },
+    {1,  {130, 144}, {270,  300 } },
+    {2,  {195, 217}, {405,  450 } },
+    {3,  {260, 289}, {540,  600 } },
+    {4,  {390, 433}, {815,  900 } },
+    {5,  {520, 578}, {1080, 1200} },
+    {6,  {585, 650}, {1215, 1350} },
+    {7,  {650, 722}, {1350, 1500} }
+};
+
+/* HT MCS parameters with Nss = 2 */
+static struct index_data_rate_type mcs_nss2[] = {
+    /* MCS L20  S20    L40   S40 */
+    {0,  {130,  144},  {270,  300 } },
+    {1,  {260,  289},  {540,  600 } },
+    {2,  {390,  433},  {810,  900 } },
+    {3,  {520,  578},  {1080, 1200} },
+    {4,  {780,  867},  {1620, 1800} },
+    {5,  {1040, 1156}, {2160, 2400} },
+    {6,  {1170, 1300}, {2430, 2700} },
+    {7,  {1300, 1440}, {2700, 3000} }
+};
+
+/* MCS Based VHT rate table
+ * MCS parameters with Nss = 1
+ */
+static struct index_vht_data_rate_type vht_mcs_nss1[] = {
+    /* MCS L20  S20    L40   S40    L80   S80 */
+    {0,  {65,   72 }, {135,  150},  {293,  325} },
+    {1,  {130,  144}, {270,  300},  {585,  650} },
+    {2,  {195,  217}, {405,  450},  {878,  975} },
+    {3,  {260,  289}, {540,  600},  {1170, 1300} },
+    {4,  {390,  433}, {810,  900},  {1755, 1950} },
+    {5,  {520,  578}, {1080, 1200}, {2340, 2600} },
+    {6,  {585,  650}, {1215, 1350}, {2633, 2925} },
+    {7,  {650,  722}, {1350, 1500}, {2925, 3250} },
+    {8,  {780,  867}, {1620, 1800}, {3510, 3900} },
+    {9,  {865,  960}, {1800, 2000}, {3900, 4333} }
+};
+
+/*MCS parameters with Nss = 2*/
+static struct index_vht_data_rate_type vht_mcs_nss2[] = {
+    /* MCS L20  S20    L40    S40    L80    S80 */
+    {0,  {130,  144},  {270,  300},  { 585,  650} },
+    {1,  {260,  289},  {540,  600},  {1170, 1300} },
+    {2,  {390,  433},  {810,  900},  {1755, 1950} },
+    {3,  {520,  578},  {1080, 1200}, {2340, 2600} },
+    {4,  {780,  867},  {1620, 1800}, {3510, 3900} },
+    {5,  {1040, 1156}, {2160, 2400}, {4680, 5200} },
+    {6,  {1170, 1300}, {2430, 2700}, {5265, 5850} },
+    {7,  {1300, 1444}, {2700, 3000}, {5850, 6500} },
+    {8,  {1560, 1733}, {3240, 3600}, {7020, 7800} },
+    {9,  {1730, 1920}, {3600, 4000}, {7800, 8667} }
+};
+/*********************************************************/
+
+#define RING_BUF_ENTRY_SIZE 512
+#define PKT_STATS_BUF_SIZE 128
+struct pkt_stats_s {
+    u8 tx_stats_events;
+    /* TODO: Need to handle the case if size of the stats are more
+     * than 512 bytes. Currently, the tx size is 34 bytes and ring buffer entry
+     * size is 12 bytes.
+     */
+    u8 tx_stats[PKT_STATS_BUF_SIZE];
+    u8 num_msdu;
+    u16 start_seq_num;
+    u16 ba_seq_num;
+    u32 ba_bitmap_31_0;
+    u32 ba_bitmap_63_32;
+    u32 tx_seqnum_bitmap_31_0;
+    u32 tx_seqnum_bitmap_63_32;
+    u32 shifted_bitmap_31_0;
+    u32 shifted_bitmap_63_32;
+    bool isBlockAck;
+    u8 tx_bandwidth;
+    u8 series;
+};
+
+typedef union {
+    struct {
+        u16 rate                            :  4;
+        u16 nss                             :  2;
+        u16 preamble                        :  2;
+        u16 bw                              :  2;
+        u16 short_gi                        :  1;
+        u16 reserved                        :  5;
+    } mcs_s;
+    u16 mcs;
+} MCS;
+
+typedef struct {
+    MCS RxMCS;
+    u16 last_transmit_rate;
+    u16 rssi;
+    u32 timestamp;
+    u8  tid;
+} rx_aggr_stats;
+
+
+typedef struct drv_msg_s
+{
+    u16 length;
+    u16 event_type;
+    u32 timestamp_low;
+    u32 timestamp_high;
+    union {
+        struct {
+            u32 version;
+            u32 msg_seq_no;
+            u32 payload_len;
+            u8  payload[0];
+        } __attribute__((packed)) pkt_stats_event;
+    } u;
+} __attribute__((packed)) drv_msg_t;
+
+typedef enum {
+    START_MONITOR = 1,
+    STOP_MONITOR,
+    TX_MGMT_PKT,
+    TX_DATA_PKT,
+    RX_MGMT_PKT,
+    RX_DATA_PKT,
+} pktdump_event_type;
+
+typedef struct {
+    u8 status;
+    u8 type;
+    u32 driver_ts;
+    u16 fw_ts;
+} __attribute__((packed)) pktdump_hdr;
+
+typedef struct {
+    frame_type payload_type;
+    u32 driver_timestamp_usec;
+    u32 firmware_timestamp_usec;
+    size_t frame_len;
+    char *frame_content;
+} frame_info_i;
+
+typedef struct {
+    // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+    // content is not provided, prefix of MD5 hash over the same data
+    // that would be in frame_content, if frame content were provided.
+    char md5_prefix[MD5_PREFIX_LEN];  // Prefix of MD5 hash of packet bytes
+    wifi_tx_packet_fate fate;
+    frame_info_i frame_inf;
+} wifi_tx_report_i;
+
+typedef struct {
+    // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+    // content is not provided, prefix of MD5 hash over the same data
+    // that would be in frame_content, if frame content were provided.
+    char md5_prefix[MD5_PREFIX_LEN];
+    wifi_rx_packet_fate fate;
+    frame_info_i frame_inf;
+} wifi_rx_report_i;
+
+typedef struct {
+    wifi_tx_report_i tx_fate_stats[MAX_FATE_LOG_LEN];
+    size_t n_tx_stats_collected;
+    wifi_rx_report_i rx_fate_stats[MAX_FATE_LOG_LEN];
+    size_t n_rx_stats_collected;
+} packet_fate_monitor_info;
+
+#endif
diff --git a/qcwcn/wifi_hal/qca-vendor_copy.h b/wcn6740/qcwcn/wifi_hal/qca-vendor_copy.h
similarity index 66%
copy from qcwcn/wifi_hal/qca-vendor_copy.h
copy to wcn6740/qcwcn/wifi_hal/qca-vendor_copy.h
index 11442ee..1faccff 100644
--- a/qcwcn/wifi_hal/qca-vendor_copy.h
+++ b/wcn6740/qcwcn/wifi_hal/qca-vendor_copy.h
@@ -1,10 +1,41 @@
 /*
  * Qualcomm Atheros OUI and vendor specific assignments
  * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
- * Copyright (c) 2018-2019, The Linux Foundation
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef QCA_VENDOR_H
@@ -512,7 +543,9 @@
  * @QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG: This command is used to
  *	configure parameters per peer to capture Channel Frequency Response
  *	(CFR) and enable Periodic CFR capture. The attributes for this command
- *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr.
+ *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr. This command
+ *	can also be used to send CFR data from the driver to userspace when
+ *	netlink events are used to send CFR data.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: Event to indicate changes
  *	in throughput dynamically. The driver estimates the throughput based on
@@ -620,7 +653,14 @@
  *	This new command is alternative to existing command
  *	QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY since existing command/event
  *	is using stream of bytes instead of structured data using vendor
- *	attributes.
+ *	attributes. User space sends unsafe frequency ranges to the driver using
+ *	a nested attribute %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE. On
+ *	reception of this command, the driver shall check if an interface is
+ *	operating on an unsafe frequency and the driver shall try to move to a
+ *	safe channel when needed. If the driver is not able to find a safe
+ *	channel the interface can keep operating on an unsafe channel with the
+ *	TX power limit derived based on internal configurations	like
+ *	regulatory/SAR rules.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE: This vendor subcommand is used to
  *	add the STA node details in driver/firmware. Attributes for this event
@@ -664,36 +704,212 @@
  *	qca_wlan_vendor_attr_driver_disconnect_reason.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC: This vendor subcommand is used to
- *     add/delete TSPEC for each AC. One command is for one specific AC only.
- *     This command can only be used in STA mode and the STA must be
- *     associated with an AP when the command is issued. Uses attributes
- *     defined in enum qca_wlan_vendor_attr_config_tspec.
+ *	add/delete TSPEC for each AC. One command is for one specific AC only.
+ *	This command can only be used in STA mode and the STA must be
+ *	associated with an AP when the command is issued. Uses attributes
+ *	defined in enum qca_wlan_vendor_attr_config_tspec.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT: Vendor subcommand to configure TWT.
- *     Uses attributes defined in enum qca_wlan_vendor_attr_config_twt.
+ *	Uses attributes defined in enum qca_wlan_vendor_attr_config_twt.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_GETBAND: Command to get the enabled band(s) from
- *     the driver. The band configurations obtained are referred through
- *     QCA_WLAN_VENDOR_ATTR_SETBAND_MASK.
+ *	the driver. The band configurations obtained are referred through
+ *	QCA_WLAN_VENDOR_ATTR_SETBAND_MASK.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS: Vendor subcommand/event for medium
- *     assessment.
- *     Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess.
+ *	assessment.
+ *	Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID: This acts as a vendor event and is
- *     used to update SSID information in hostapd when it is updated in the
- *     driver. Uses the attribute NL80211_ATTR_SSID.
+ *	used to update SSID information in hostapd when it is updated in the
+ *	driver. Uses the attribute NL80211_ATTR_SSID.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS: This vendor subcommand is used by
- *     the driver to send opaque data from the firmware to userspace. The
- *     driver sends an event to userspace whenever such data is received from
- *     the firmware.
+ *	the driver to send opaque data from the firmware to userspace. The
+ *	driver sends an event to userspace whenever such data is received from
+ *	the firmware.
  *
- *     QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to
- *     send this opaque data for this event.
+ *	QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to
+ *	send this opaque data for this event.
  *
- *     The format of the opaque data is specific to the particular firmware
- *     version and there is no guarantee of the format remaining same.
+ *	The format of the opaque data is specific to the particular firmware
+ *	version and there is no guarantee of the format remaining same.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS: This acts as an event.
+ *	The host driver selects Tx VDEV, and notifies user. The attributes
+ *	used with this event are defined in enum
+ *	qca_wlan_vendor_attr_mbssid_tx_vdev_status.
+ *	This event contains Tx VDEV group information, other VDEVs
+ *	interface index, and status information.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_POLICY: Vendor command to
+ *	configure the concurrent session policies when multiple interfaces
+ *	are (getting) active. The attributes used by this command are defined
+ *	in enum qca_wlan_vendor_attr_concurrent_policy.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS: Userspace can use this command
+ *	to query usable channels for different interface types such as STA,
+ *	AP, P2P GO, P2P Client, NAN, etc. The driver shall report all usable
+ *	channels in the response based on country code, different static
+ *	configurations, concurrency combinations, etc. The attributes used
+ *	with this command are defined in
+ *	enum qca_wlan_vendor_attr_usable_channels.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY: This vendor subcommand is used
+ *	to get DFS radar history from the driver to userspace. The driver
+ *	returns QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES attribute with an
+ *	array of nested entries.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD: Userspace can use this command to
+ *	enable/disable mDNS offload to the firmware. The attributes used with
+ *	this command are defined in enum qca_wlan_vendor_attr_mdns_offload.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used
+ *	to set packet monitor mode that aims to send the specified set of TX and
+ *	RX frames on the current client interface to an active monitor
+ *	interface. If this monitor mode is set, the driver will send the
+ *	configured frames, from the interface on which the command is issued, to
+ *	an active monitor interface. The attributes used with this command are
+ *	defined in enum qca_wlan_vendor_attr_set_monitor_mode.
+ *
+ *	Though the monitor mode is configured for the respective
+ *	Data/Management/Control frames, it is up to the respective WLAN
+ *	driver/firmware/hardware designs to consider the possibility of sending
+ *	these frames over the monitor interface. For example, the Control frames
+ *	are handled within the hardware and thus passing such frames over the
+ *	monitor interface is left to the respective designs.
+ *
+ *	Also, this monitor mode is governed to behave accordingly in
+ *	suspend/resume states. If the firmware handles any of such frames in
+ *	suspend state without waking up the host and if the monitor mode is
+ *	configured to notify all such frames, the firmware is expected to resume
+ *	the host and forward the respective frames to the monitor interface.
+ *	Please note that such a request to get the frames over the monitor
+ *	interface will have a definite power implication.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both
+ *	as a request to set the driver/firmware with the parameters to trigger
+ *	the roaming events, and also used by the driver/firmware to pass on the
+ *	various roam events to userspace.
+ *	Applicable only for the STA mode. The attributes used with this command
+ *	are defined in enum qca_wlan_vendor_attr_roam_events.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG: Subcommand to set or reset the
+ *	rate mask config for a list of PHY types. Userspace shall provide an
+ *	array of the vendor attributes defined in
+ *	enum qca_wlan_vendor_attr_ratemask_params.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA: Multi-channel Concurrency (MCC) occurs
+ *	when two interfaces are active on the same band, using two different
+ *	home channels, and only supported by a single radio. In this scenario
+ *	the device must split the use of the radio between the two interfaces.
+ *	The percentage of time allocated to a given interface is the quota.
+ *	Depending on the configuration, the quota can either be fixed or
+ *	dynamic.
+ *
+ *	When used as an event, the device will report the quota type, and for
+ *	all interfaces operating in MCC it will report the current quota.
+ *	When used as a command, the device can be configured for a specific
+ *	quota type, and in the case of a fixed quota, the quota to apply to one
+ *	of the interfaces.
+ *
+ *	Applications can use the event to do TX bitrate control based on the
+ *	information, and can use the command to explicitly set the quota to
+ *	enhance performance in specific scenarios.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_mcc_quota.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_RADIO_COMBINATION_MATRIX: Vendor command to
+ *	get the WLAN radio combinations matrix supported by the device which
+ *	provides the device simultaneous radio configurations such as
+ *	standalone, dual band simultaneous, and single band simultaneous.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_radio_combination_matrix.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_DRIVER_READY: Event indicating to the user space
+ *	that the driver is ready for operations again after recovering from
+ *	internal failures. This occurs following a failure that was indicated by
+ *	@QCA_NL80211_VENDOR_SUBCMD_HANG.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_PASN: Subcommand used to offload preassociation
+ *	security negotiation and key generation to user space.
+ *
+ *	When used as an event, the driver requests userspace to trigger the PASN
+ *	authentication or dropping of a PTKSA for the indicated peer devices.
+ *	When used as a command response, userspace indicates a consolidated
+ *	status report for all the peers that were requested for.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_pasn.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_SECURE_RANGING_CONTEXT: Subcommand used to set
+ *	secure ranging context such as TK and LTF keyseed for each peer
+ *	requested by the driver with a @QCA_NL80211_VENDOR_SUBCMD_PASN event.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_secure_ranging_ctx.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_COAP_OFFLOAD: This vendor subcommand is used to
+ *	enable/disable offload processing in firmware during system/runtime
+ *	suspend for CoAP messages (see RFC7252: The Constrained Application
+ *	Protocol) and fetch information of the CoAP messages cached during
+ *	offload processing.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_coap_offload.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_SCS_RULE_CONFIG: Subcommand to configure
+ *	(add, remove, or change) a Stream Classification Service (SCS) rule.
+ *
+ *      The attributes used with this event are defined in
+ *      enum qca_wlan_vendor_attr_scs_rule_config.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY: Fetch SAR capabilities
+ *	supported by the WLAN firmware.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_sar_capability.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_SR: Subcommand used to implement Spatial Reuse
+ *	(SR) feature. This command is used by userspace to configure SR
+ *	parameters to the driver and to get the SR related parameters and
+ *	statistics with synchronous responses from the driver.
+ *	The driver also uses this command to send asynchronous events to
+ *	userspace to indicate suspend/resume of SR feature and changes
+ *	in SR parameters.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_sr.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MLO_PEER_PRIM_NETDEV_EVENT: Subcommand used to
+ *	notify application layer about the primary netdev of an MLO connection.
+ *	In some implementations, MLO has multiple netdevs out of which one
+ *	netdev is designated as primary to provide a unified interface to the
+ *	bridge. In those implementations this event is sent on every MLO peer
+ *	connection.
+ *
+ *	The attributes used with this event are defined in
+ *	enum qca_wlan_vendor_attr_mlo_peer_prim_netdev_event.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_AFC_EVENT: This vendor command is used by the
+ *	driver to notify different AFC events to userspace. The attributes used
+ *	with this command are defined in enum qca_wlan_vendor_attr_afc_event.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_AFC_RESPONSE: This vendor command is used by
+ *	userspace to deliver AFC response data to driver. The attributes used
+ *	with this command are defined in enum qca_wlan_vendor_attr_afc_response.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_DOZED_AP: Subcommand to configure AP interface to
+ *	operate in doze mode.
+ *
+ *	Userspace uses this command to configure the AP interface to enter or
+ *	exit from doze mode. The driver sends this event after it enters or
+ *	exits the doze mode with the updated AP doze mode settings.
+ *
+ *	The attributes used with this subcommand are defined in
+ *	enum qca_wlan_vendor_attr_dozed_ap.
  */
 enum qca_nl80211_vendor_subcmds {
 	QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@@ -879,8 +1095,37 @@
 	QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS = 193,
 	QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID = 194,
 	QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS = 195,
+	QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS = 196,
+	QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_POLICY = 197,
+	QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198,
+	QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY = 199,
+	QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD = 200,
+	/* 201 - reserved for QCA */
+	QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202,
+	QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203,
+	QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG = 204,
+	QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA = 205,
+	/* 206..212 - reserved for QCA */
+	QCA_NL80211_VENDOR_SUBCMD_GET_RADIO_COMBINATION_MATRIX = 213,
+	QCA_NL80211_VENDOR_SUBCMD_DRIVER_READY = 214,
+	QCA_NL80211_VENDOR_SUBCMD_PASN = 215,
+	QCA_NL80211_VENDOR_SUBCMD_SECURE_RANGING_CONTEXT = 216,
+	QCA_NL80211_VENDOR_SUBCMD_COAP_OFFLOAD = 217,
+	QCA_NL80211_VENDOR_SUBCMD_SCS_RULE_CONFIG = 218,
+	QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY = 219,
+	QCA_NL80211_VENDOR_SUBCMD_SR = 220,
+	QCA_NL80211_VENDOR_SUBCMD_MLO_PEER_PRIM_NETDEV_EVENT = 221,
+	QCA_NL80211_VENDOR_SUBCMD_AFC_EVENT = 222,
+	QCA_NL80211_VENDOR_SUBCMD_AFC_RESPONSE = 223,
+	QCA_NL80211_VENDOR_SUBCMD_DOZED_AP = 224,
 };
 
+/* Compatibility defines for previously used subcmd names.
+ * These values should not be used in any new implementation.
+ */
+#define QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY \
+	QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_POLICY
+
 enum qca_wlan_vendor_attr {
 	QCA_WLAN_VENDOR_ATTR_INVALID = 0,
 	/* used by QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY */
@@ -1117,7 +1362,7 @@
  * @QCA_ROAM_REASON_CONGESTION: Roam triggered considering the connected channel
  * or environment being very noisy or congested.
  *
- * @QCA_ROAM_REASON_EXPLICIT_REQUEST: Roam triggered due to an explicit request
+ * @QCA_ROAM_REASON_USER_TRIGGER: Roam triggered due to an explicit request
  * from the user (user space).
  *
  * @QCA_ROAM_REASON_BTM: Roam triggered due to BTM Request frame received from
@@ -1125,6 +1370,26 @@
  *
  * @QCA_ROAM_REASON_BSS_LOAD: Roam triggered due to the channel utilization
  * breaching out the configured threshold.
+ *
+ * @QCA_ROAM_REASON_WTC: Roam triggered due to Wireless to Cellular BSS
+ * transition request.
+ *
+ * @QCA_ROAM_REASON_IDLE: Roam triggered when device is suspended, there is no
+ * data activity with the AP and the current RSSI falls below a certain
+ * threshold.
+ *
+ * @QCA_ROAM_REASON_DISCONNECTION: Roam triggered due to Deauthentication or
+ * Disassociation frames received from the connected AP.
+ *
+ * @QCA_ROAM_REASON_PERIODIC_TIMER: Roam triggered as part of the periodic scan
+ * that happens when there is no candidate AP found during the poor RSSI scan
+ * trigger.
+ *
+ * @QCA_ROAM_REASON_BACKGROUND_SCAN: Roam triggered based on the scan results
+ * obtained from an external scan (not aimed at roaming).
+ *
+ * @QCA_ROAM_REASON_BT_ACTIVITY: Roam triggered due to Bluetooth connection is
+ * established when the station is connected in the 2.4 GHz band.
  */
 enum qca_roam_reason {
 	QCA_ROAM_REASON_UNKNOWN,
@@ -1136,10 +1401,19 @@
 	QCA_ROAM_REASON_USER_TRIGGER,
 	QCA_ROAM_REASON_BTM,
 	QCA_ROAM_REASON_BSS_LOAD,
+	QCA_ROAM_REASON_WTC,
+	QCA_ROAM_REASON_IDLE,
+	QCA_ROAM_REASON_DISCONNECTION,
+	QCA_ROAM_REASON_PERIODIC_TIMER,
+	QCA_ROAM_REASON_BACKGROUND_SCAN,
+	QCA_ROAM_REASON_BT_ACTIVITY,
 };
 
 enum qca_wlan_vendor_attr_roam_auth {
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_INVALID = 0,
+	/* Indicates BSSID of the roamed AP for non-MLO roaming and MLD address
+	 * of the roamed AP for MLO roaming.
+	 */
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
@@ -1184,6 +1458,11 @@
 	 * Defined by enum qca_roam_reason.
 	 */
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON = 14,
+	/* A nested attribute containing per-link information of all the links
+	 * of MLO connection done while roaming. The attributes used inside this
+	 * nested attribute are defined in enum qca_wlan_vendor_attr_mlo_links.
+	 */
+	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MLO_LINKS = 15,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST,
@@ -1355,6 +1634,22 @@
  * Used with event to notify the EDMG channel number selected in ACS
  * operation.
  * EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP: Optional (u16).
+ * Used with event to notify the puncture pattern selected in ACS operation.
+ * Encoding for this attribute will follow the convention used in the Disabled
+ * Subchannel Bitmap field of the EHT Operation IE.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED: Flag attribute.
+ * Used with command to configure ACS operation for EHT mode.
+ * Disable (flag attribute not present) - EHT disabled and
+ * Enable (flag attribute present) - EHT enabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_LAST_SCAN_AGEOUT_TIME: Optional (u32).
+ * Used with command to configure how older scan can be considered for ACS
+ * scoring. In case scan was performed on a partial set of channels configured
+ * with this command within last QCA_WLAN_VENDOR_ATTR_ACS_LAST_SCAN_AGEOUT_TIME
+ * (in ms), scan only the remaining channels.
  */
 enum qca_wlan_vendor_attr_acs_offload {
 	QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
@@ -1375,6 +1670,9 @@
 	QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17,
+	QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP = 18,
+	QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED = 19,
+	QCA_WLAN_VENDOR_ATTR_ACS_LAST_SCAN_AGEOUT_TIME = 20,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
@@ -1438,6 +1736,61 @@
  *	%QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL and
  *	%QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW attributes from
  *	userspace.
+ * @QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R: Device supports Adaptive 11r.
+ *	With Adaptive 11r feature, access points advertise the vendor
+ *	specific IEs and MDE but do not include FT AKM in the RSNE.
+ *	The Adaptive 11r supported stations are expected to identify
+ *	such vendor specific IEs and connect to the AP in FT mode though
+ *	the profile is configured in non-FT mode.
+ *	The driver-based SME cases also need to have this support for
+ *	Adaptive 11r to handle the connection and roaming scenarios.
+ *	This flag indicates the support for the same to the user space.
+ * @QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS: Device supports
+ *	concurrent network sessions on different Wi-Fi bands. This feature
+ *	capability is attributed to the hardware's capability to support
+ *	the same (e.g., DBS).
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT: Flag indicating whether the
+ *	responses for the respective TWT operations are asynchronous (separate
+ *	event message) from the driver. If not specified, the responses are
+ *	synchronous (in vendor command reply) to the request. Each TWT
+ *	operation is specifically mentioned (against its respective
+ *	documentation) to support either of these or both modes.
+ * @QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI: Flag indicates
+ *	that the driver requires add/del virtual interface path using the
+ *	generic nl80211 commands for NDP interface create/delete and to
+ *	register/unregister the netdev instead of creating/deleting the NDP
+ *	interface using the vendor commands
+ *	QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE and
+ *	QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE. With the latest kernel
+ *	(5.12 version onward), interface creation/deletion is not allowed using
+ *	vendor commands as it leads to a deadlock while acquiring the RTNL_LOCK
+ *	during the register/unregister of netdev. Create and delete NDP
+ *	interface using NL80211_CMD_NEW_INTERFACE and NL80211_CMD_DEL_INTERFACE
+ *	commands respectively if the driver advertises this capability set.
+ * @QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_STA: Flag indicates that the device in
+ *	station mode supports secure LTF. If NL80211_EXT_FEATURE_SECURE_LTF is
+ *	set, then QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_STA will be ignored.
+ * @QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_AP: Flag indicates that the device in AP
+ *	mode supports secure LTF. If NL80211_EXT_FEATURE_SECURE_LTF is set, then
+ *	QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_AP will be ignored.
+ * @QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_STA: Flag indicates that the device in
+ *	station mode supports secure RTT measurement exchange. If
+ *	NL80211_EXT_FEATURE_SECURE_RTT is set,
+ *	QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_STA will be ignored.
+ * @QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_AP: Flag indicates that the device in AP
+ *	mode supports secure RTT measurement exchange. If
+ *	NL80211_EXT_FEATURE_SECURE_RTT is set,
+ *	QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_AP will be ignored.
+ * @QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_STA: Flag indicates that
+ *	the device in station mode supports protection of range negotiation and
+ *	measurement management frames. If
+ *	NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE is set, then
+ *	QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_STA will be ignored.
+ * @QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_AP: Flag indicates that
+ *	the device in AP mode supports protection of range negotiation and
+ *	measurement management frames. If
+ *	NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE is set, then
+ *	QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_AP will be ignored.
  * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
  */
 enum qca_wlan_vendor_features {
@@ -1449,10 +1802,20 @@
 	QCA_WLAN_VENDOR_FEATURE_OCE_AP                  = 5,
 	QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON            = 6,
 	QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY = 7,
-	QCA_WLAN_VENDOR_FEATURE_TWT 			= 8,
+	QCA_WLAN_VENDOR_FEATURE_TWT			= 8,
 	QCA_WLAN_VENDOR_FEATURE_11AX			= 9,
 	QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT		= 10,
 	QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG		= 11,
+	QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R		= 12,
+	QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13,
+	QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT	= 14,
+	QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI = 15,
+	QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_STA		= 16,
+	QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_AP		= 17,
+	QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_STA		= 18,
+	QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_AP		= 19,
+	QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_STA = 20,
+	QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_AP = 21,
 	NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
 };
 
@@ -1658,32 +2021,62 @@
 };
 
 /**
- * enum qca_vendor_attr_get_tsf: Vendor attributes for TSF capture
- * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: enum qca_tsf_operation (u32)
- * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Unsigned 64 bit TSF timer value
- * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Unsigned 64 bit Synchronized
- *	SOC timer value at TSF capture
+ * enum qca_vendor_attr_tsf_cmd: Vendor attributes for TSF capture
+ * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: Required (u32)
+ * Specify the TSF command. Possible values are defined in
+ * &enum qca_tsf_cmd.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Optional (u64)
+ * This attribute contains TSF timer value. This attribute is only available
+ * in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Optional (u64)
+ * This attribute contains SOC timer value at TSF capture. This attribute is
+ * only available in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL: Optional (u32)
+ * This attribute is used to provide TSF sync interval and only applicable when
+ * TSF command is %QCA_TSF_SYNC_START. If this attribute is not provided, the
+ * driver will use the default value. Time unit is in milliseconds.
  */
 enum qca_vendor_attr_tsf_cmd {
 	QCA_WLAN_VENDOR_ATTR_TSF_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_TSF_CMD,
 	QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE,
 	QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE,
+	QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL,
 	QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_TSF_MAX =
 	QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST - 1
 };
 
 /**
- * enum qca_tsf_operation: TSF driver commands
+ * enum qca_tsf_cmd: TSF driver commands
  * @QCA_TSF_CAPTURE: Initiate TSF Capture
  * @QCA_TSF_GET: Get TSF capture value
  * @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value
+ * @QCA_TSF_AUTO_REPORT_ENABLE: Used in STA mode only. Once set, the target
+ * will automatically send TSF report to the host. To query
+ * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY, this operation needs to be
+ * initiated first.
+ * @QCA_TSF_AUTO_REPORT_DISABLE: Used in STA mode only. Once set, the target
+ * will not automatically send TSF report to the host. If
+ * %QCA_TSF_AUTO_REPORT_ENABLE is initiated and
+ * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY is not queried anymore, this
+ * operation needs to be initiated.
+ * @QCA_TSF_SYNC_START: Start periodic TSF sync feature. The driver periodically
+ * fetches TSF and host time mapping from the firmware with interval configured
+ * through the %QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL attribute. If the
+ * interval value is not provided the driver will use the default value. The
+ * userspace can query the TSF and host time mapping via the %QCA_TSF_GET
+ * command.
+ * @QCA_TSF_SYNC_STOP: Stop periodic TSF sync feature.
  */
 enum qca_tsf_cmd {
 	QCA_TSF_CAPTURE,
 	QCA_TSF_GET,
 	QCA_TSF_SYNC_GET,
+	QCA_TSF_AUTO_REPORT_ENABLE,
+	QCA_TSF_AUTO_REPORT_DISABLE,
+	QCA_TSF_SYNC_START,
+	QCA_TSF_SYNC_STOP,
 };
 
 /**
@@ -1777,6 +2170,23 @@
 };
 
 /**
+ * enum qca_wlan_vendor_scan_priority - Specifies the valid values that the
+ * vendor scan attribute QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY can take.
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW: Very low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW: Low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM: Medium priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH: High priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH: Very high priority
+ */
+enum qca_wlan_vendor_scan_priority {
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW = 0,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW = 1,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM = 2,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH = 3,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH = 4,
+};
+
+/**
  * enum qca_wlan_vendor_attr_scan - Specifies vendor scan attributes
  *
  * @QCA_WLAN_VENDOR_ATTR_SCAN_IE: IEs that should be included as part of scan
@@ -1801,6 +2211,11 @@
  * @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in
  *	microseconds. This is a common value which applies across all
  *	frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES.
+ * @QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY: Priority of vendor scan relative to
+ *	other scan requests. It is a u32 attribute and takes values from enum
+ *	qca_wlan_vendor_scan_priority. This is an optional attribute.
+ *	If this attribute is not configured, the driver shall use
+ *	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH as the priority of vendor scan.
  */
 enum qca_wlan_vendor_attr_scan {
 	QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0,
@@ -1816,6 +2231,7 @@
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10,
 	QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11,
 	QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12,
+	QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13,
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAX =
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1
@@ -2173,7 +2589,10 @@
 	QCA_WLAN_VENDOR_ATTR_CONFIG_DISCONNECT_IES = 58,
 
 	/* 8-bit unsigned value for ELNA bypass.
-	 * 1-Enable, 0-Disable
+	 * 0 - Disable eLNA bypass.
+	 * 1 - Enable eLNA bypass.
+	 * 2 - Reset eLNA bypass configuration, the driver should
+	 *	revert to the default configuration of eLNA bypass.
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS = 59,
 
@@ -2278,6 +2697,10 @@
 	 * frame. The updated NSS value after the connection shall not be
 	 * greater than the one negotiated during the connection. Any such
 	 * higher value configuration shall be returned with a failure.
+	 * Only symmetric NSS configuration (such as 2X2 or 1X1) can be done
+	 * using this attribute. QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes shall be used to
+	 * configure the asymmetric NSS configuration (such as 1X2).
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_NSS = 70,
 	/* 8-bit unsigned value to trigger Optimized Power Management:
@@ -2295,6 +2718,14 @@
 	 * Set the value to QCA_WLAN_AC_BK if the QoS upgrade needs to be
 	 * disabled, as BK is of the lowest priority and an upgrade to it does
 	 * not result in any changes for the frames.
+	 *
+	 * If only UDP frames of BE or BK access category needs to be upgraded
+	 * without changing the access category of VO or VI UDP frames, refer to
+	 * attribute QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE_FOR_BE_BK.
+	 *
+	 * This attribute is not recommended to be used as it blindly forces all
+	 * UDP packets to a higher access category which could impact the
+	 * traffic pattern of all apps using UDP and can cause unknown behavior.
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE = 72,
 
@@ -2326,6 +2757,145 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL = 76,
 
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for transmitting the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The TX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver
+	 * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77,
+
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for receiving the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The RX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver
+	 * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78,
+
+	/*
+	 * 8-bit unsigned value. This attribute, when set, indicates whether the
+	 * specified interface is the primary STA interface when there are more
+	 * than one STA interfaces concurrently active.
+	 *
+	 * This configuration helps the firmware/hardware to support certain
+	 * features (e.g., roaming) on this primary interface, if the same
+	 * cannot be supported on the concurrent STA interfaces simultaneously.
+	 *
+	 * This configuration is only applicable for a single STA interface on
+	 * a device and gives the priority for it only over other concurrent STA
+	 * interfaces.
+	 *
+	 * If the device is a multi wiphy/soc, this configuration applies to a
+	 * single STA interface across the wiphys.
+	 *
+	 * 1-Enable (is the primary STA), 0-Disable (is not the primary STA)
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY = 79,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * driver to enable/disable FT-over-DS feature. Possible values for
+	 * this attribute are 1-Enable and 0-Disable.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS = 80,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * firmware to enable/disable ARP/NS offload feature. Possible values
+	 * for this attribute are 0-Disable and 1-Enable.
+	 *
+	 * This attribute is only applicable for STA/P2P-Client interface,
+	 * and is optional, default behavior is ARP/NS offload enabled.
+	 *
+	 * This attribute can be set in disconnected and connected state, and
+	 * will restore to the default behavior if the interface is closed.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD = 81,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * data path mode to be followed for audio traffic. Possible values
+	 * are defined in enum qca_wlan_audio_data_path.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_AUDIO_DATA_PATH = 82,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * Dedicated Bluetooth Antenna Mode (DBAM) feature. Possible values for
+	 * this attribute are defined in the enum qca_wlan_dbam_config.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_DBAM = 83,
+
+	/* 8-bit unsigned value. This attribute takes the QoS/access category
+	 * value represented by the enum qca_wlan_ac_type and expects the driver
+	 * to upgrade the UDP frames of BE or BK access category to this access
+	 * category. This attribute will not modify UDP frames of VO or VI
+	 * access category. The value of QCA_WLAN_AC_ALL is invalid for this
+	 * attribute.
+	 *
+	 * This will override the DSCP value configured in the frame with the
+	 * intention to only upgrade the access category. That said, it is not
+	 * intended to downgrade the access category for the frames.
+	 * Set the value to QCA_WLAN_AC_BK if the QoS upgrade needs to be
+	 * disabled, as BK is of the lowest priority and an upgrade to it does
+	 * not result in any changes for the frames.
+	 *
+	 * This attribute behavior is similar to
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE with the difference that
+	 * only UDP frames of BE or BK access category are upgraded and not
+	 * UDP frames of VI or VO access category.
+	 *
+	 * This attribute is not recommended to be used as it blindly forces all
+	 * UDP packets of BE or BK access category to a higher access category
+	 * which could impact the traffic pattern of all apps using UDP and can
+	 * cause unknown behavior.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE_FOR_BE_BK = 84,
+
+	/* 8-bit unsigned value to configure the driver to enable/disable the
+	 * periodic sounding for Tx beamformer functionality. The default
+	 * behavior uses algorithm to do sounding based on packet stats.
+	 *
+	 * 0 - Default behavior.
+	 * 1 - Enable the periodic sounding for Tx beamformer.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_BEAMFORMER_PERIODIC_SOUNDING = 85,
+
+	/* 8-bit unsigned value, whenever wifi calling (wfc) begins or ends,
+	 * userspace sends this information to the driver/firmware to configure
+	 * wfc state. The driver/firmware uses this information to
+	 * optimize power savings, rate adaption, roaming, etc.
+	 *
+	 * 1 - wfc is on.
+	 * 0 - wfc is off.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE = 86,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@@ -2341,6 +2911,19 @@
 	QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_REPORT_FAIL
 
 /**
+ * enum qca_dbam_config - Specifies DBAM config mode
+ * @QCA_DBAM_DISABLE: Firmware disables DBAM
+ * @QCA_DBAM_ENABLE: Firmware enables DBAM opportunistically when
+ * internal criteria are met.
+ * @QCA_DBAM_FORCE_ENABLE: Firmware enables DBAM forcefully.
+ */
+enum qca_dbam_config {
+	QCA_DBAM_DISABLE = 0,
+	QCA_DBAM_ENABLE = 1,
+	QCA_DBAM_FORCE_ENABLE = 2,
+};
+
+/**
  * enum qca_wlan_ani_setting - ANI setting type
  * @QCA_WLAN_ANI_SETTING_AUTO: Automatically determine ANI level
  * @QCA_WLAN_ANI_SETTING_FIXED: Fix ANI level to the dBm parameter
@@ -2421,23 +3004,50 @@
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
  * %QCA_WLAN_VENDOR_GPIO_OUTPUT.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Optional (u32)
  * value to specify the GPIO pull type. Please refer to enum qca_gpio_pull_type
  * for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Optional (u32)
  * value to specify the GPIO interrupt mode. Please refer to enum
  * qca_gpio_interrupt_mode for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Optional (u32)
  * value to specify the GPIO direction. Please refer to enum qca_gpio_direction
  * for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG: Optional (u32)
+ * Value to specify the mux config. Meaning of a given value is dependent
+ * on the target chipset and GPIO pin. Must be of the range 0-15.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to 0.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE: Optional (u32)
+ * Value to specify the drive, refer to enum qca_gpio_drive.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to QCA_WLAN_GPIO_DRIVE_2MA(0).
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG: Optional (flag)
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. When present this attribute signals that all
+ * other parameters for the given GPIO will be obtained from internal
+ * configuration. Only %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM must be
+ * specified to indicate the GPIO pin being configured.
  */
 enum qca_wlan_gpio_attr {
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INVALID = 0,
@@ -2453,6 +3063,12 @@
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE = 5,
 	/* Unsigned 32-bit attribute for GPIO direction to configure */
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR = 6,
+	/* Unsigned 32-bit attribute for GPIO mux config */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG = 7,
+	/* Unsigned 32-bit attribute for GPIO drive */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE = 8,
+	/* Flag attribute for using internal GPIO configuration */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG = 9,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST,
@@ -2528,6 +3144,30 @@
 };
 
 /**
+ * enum qca_gpio_drive - GPIO drive
+ * @QCA_WLAN_GPIO_DRIVE_2MA: drive 2MA
+ * @QCA_WLAN_GPIO_DRIVE_4MA: drive 4MA
+ * @QCA_WLAN_GPIO_DRIVE_6MA: drive 6MA
+ * @QCA_WLAN_GPIO_DRIVE_8MA: drive 8MA
+ * @QCA_WLAN_GPIO_DRIVE_10MA: drive 10MA
+ * @QCA_WLAN_GPIO_DRIVE_12MA: drive 12MA
+ * @QCA_WLAN_GPIO_DRIVE_14MA: drive 14MA
+ * @QCA_WLAN_GPIO_DRIVE_16MA: drive 16MA
+ * @QCA_WLAN_GPIO_DRIVE_MAX: invalid GPIO drive
+ */
+enum qca_gpio_drive {
+	QCA_WLAN_GPIO_DRIVE_2MA = 0,
+	QCA_WLAN_GPIO_DRIVE_4MA = 1,
+	QCA_WLAN_GPIO_DRIVE_6MA = 2,
+	QCA_WLAN_GPIO_DRIVE_8MA = 3,
+	QCA_WLAN_GPIO_DRIVE_10MA = 4,
+	QCA_WLAN_GPIO_DRIVE_12MA = 5,
+	QCA_WLAN_GPIO_DRIVE_14MA = 6,
+	QCA_WLAN_GPIO_DRIVE_16MA = 7,
+	QCA_WLAN_GPIO_DRIVE_MAX,
+};
+
+/**
  * qca_wlan_set_qdepth_thresh_attr - Parameters for setting
  * MSDUQ depth threshold per peer per tid in the target
  *
@@ -3688,6 +4328,30 @@
 	 * QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO.
 	 */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85,
+	/* u8 value representing the channel load percentage. Possible values
+	 * are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86,
+	/* u8 value representing the time slicing duty cycle percentage.
+	 * Possible values are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87,
+	/* Unsigned 32 bit value. The number of Beacon frames which are received
+	 * from the associated AP and indicate buffered unicast frame(s) for us
+	 * in the TIM element.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_TIM_BEACON = 88,
+	/* Unsigned 32 bit value. The total number of Beacon frames received
+	 * from the associated AP that have wrongly indicated buffered unicast
+	 * traffic in the TIM element for us.
+	 * Below scenarios will be considered as wrong TIM element beacon:
+	 * 1)	The related TIM element is set in the beacon for STA but STA
+	 *      doesn’t receive any unicast data after this beacon.
+	 * 2)	The related TIM element is still set in the beacon for STA
+	 *	after STA has indicated power save exit by QoS Null Data frame.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_TIM_BEACON_ERR = 89,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX =
@@ -4035,6 +4699,30 @@
 	QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_roam_scan_scheme: Scan scheme
+ *
+ * @QCA_ROAM_SCAN_SCHEME_NO_SCAN: No frequencies specified to scan.
+ *     Indicates the driver to not scan on a Roam Trigger scenario, but
+ *     disconnect. E.g., on a BTM request from the AP the driver/firmware shall
+ *     disconnect from the current connected AP by notifying a failure
+ *     code in the BTM response.
+ *
+ * @QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN: Indicates the driver/firmware to
+ *     trigger partial frequency scans. These frequencies are the ones learned
+ *     or maintained by the driver based on the probability of finding the
+ *     BSSIDs in the ESS for which the roaming is triggered.
+ *
+ * @QCA_ROAM_SCAN_SCHEME_FULL_SCAN: Indicates the driver/firmware to
+ *     trigger the scan on all the valid frequencies to find better
+ *     candidates to roam.
+ */
+enum qca_roam_scan_scheme {
+	QCA_ROAM_SCAN_SCHEME_NO_SCAN = 0,
+	QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN = 1,
+	QCA_ROAM_SCAN_SCHEME_FULL_SCAN = 2,
+};
+
 /*
  * enum qca_vendor_roam_triggers: Bitmap of roaming triggers
  *
@@ -4055,6 +4743,18 @@
  *	when BTM Request frame is received from the connected AP.
  * @QCA_ROAM_TRIGGER_REASON_BSS_LOAD: Set if the roam has to be triggered
  *	when the channel utilization is goes above the configured threshold.
+ * @QCA_ROAM_TRIGGER_REASON_USER_TRIGGER: Set if the roam has to be triggered
+ *	based on the request from the user (space).
+ * @QCA_ROAM_TRIGGER_REASON_DEAUTH: Set if the roam has to be triggered when
+ *	device receives Deauthentication/Disassociation frame from connected AP.
+ * @QCA_ROAM_TRIGGER_REASON_IDLE: Set if the roam has to be triggered when the
+ *	device is in idle state (no TX/RX) and suspend mode, if the current RSSI
+ *	is determined to be a poor one.
+ * @QCA_ROAM_TRIGGER_REASON_TX_FAILURES: Set if the roam has to be triggered
+ *	based on continuous TX Data frame failures to the connected AP.
+ * @QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN: Set if the roam has to be triggered
+ *	based on the scan results obtained from an external scan (not triggered
+ *	to aim roaming).
  *
  * Set the corresponding roam trigger reason bit to consider it for roam
  * trigger.
@@ -4070,6 +4770,144 @@
 	QCA_ROAM_TRIGGER_REASON_DENSE		= 1 << 5,
 	QCA_ROAM_TRIGGER_REASON_BTM		= 1 << 6,
 	QCA_ROAM_TRIGGER_REASON_BSS_LOAD	= 1 << 7,
+	QCA_ROAM_TRIGGER_REASON_USER_TRIGGER	= 1 << 8,
+	QCA_ROAM_TRIGGER_REASON_DEAUTH          = 1 << 9,
+	QCA_ROAM_TRIGGER_REASON_IDLE		= 1 << 10,
+	QCA_ROAM_TRIGGER_REASON_TX_FAILURES	= 1 << 11,
+	QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN	= 1 << 12,
+};
+
+/*
+ * enum qca_vendor_roam_fail_reasons: Defines the various roam
+ * fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED: Roam module in the firmware is not
+ * able to trigger the scan.
+ * @QCA_ROAM_FAIL_REASON_NO_AP_FOUND: No roamable APs found during roam scan.
+ * @QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: No candidate APs found during roam
+ * scan.
+ * @QCA_ROAM_FAIL_REASON_HOST: Roam fail due to disconnect issued from host.
+ * @QCA_ROAM_FAIL_REASON_AUTH_SEND: Unable to send Authentication frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_RECV: Received Authentication frame with error
+ * status code.
+ * @QCA_ROAM_FAIL_REASON_NO_AUTH_RESP: Authentication frame not received.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_SEND: Unable to send Reassociation Request
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_RECV: Received Reassociation Response frame
+ * with error status code.
+ * @QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP: Reassociation Response frame not
+ * received.
+ * @QCA_ROAM_FAIL_REASON_SCAN_FAIL: Scan module not able to start scan.
+ * @QCA_ROAM_FAIL_REASON_AUTH_NO_ACK: No ACK is received for Authentication
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: Authentication frame is dropped
+ * internally before transmission.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK: No ACK is received for Reassociation
+ * Request frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: Reassociation Request frame is
+ * dropped internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT: EAPOL-Key M1 is not received and
+ * times out.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND: Unable to send EAPOL-Key M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: EAPOL-Key M2 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: No ACK is received for EAPOL-Key
+ * M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: EAPOL-Key M3 frame is not received.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND: Unable to send EAPOL-Key M4 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: EAPOL-Key M4 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: No ACK is received for EAPOL-Key M4
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS: Roam scan is not
+ * started for final beacon miss case.
+ * @QCA_ROAM_FAIL_REASON_DISCONNECT: Deauthentication or Disassociation frame
+ * received from the AP during roaming handoff.
+ * @QCA_ROAM_FAIL_REASON_RESUME_ABORT: Firmware roams to the AP when the Apps
+ * or host is suspended and gives the indication of the last roamed AP only
+ * when the Apps is resumed. If the Apps is resumed while the roaming is in
+ * progress, this ongoing roaming is aborted and the last roamed AP is
+ * indicated to host.
+ * @QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID: WPA3-SAE invalid PMKID.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: WPA3-SAE pre-authentication times
+ * out.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: WPA3-SAE pre-authentication fails.
+ */
+enum qca_vendor_roam_fail_reasons {
+	QCA_ROAM_FAIL_REASON_NONE = 0,
+	QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED = 1,
+	QCA_ROAM_FAIL_REASON_NO_AP_FOUND = 2,
+	QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND = 3,
+	QCA_ROAM_FAIL_REASON_HOST = 4,
+	QCA_ROAM_FAIL_REASON_AUTH_SEND = 5,
+	QCA_ROAM_FAIL_REASON_AUTH_RECV = 6,
+	QCA_ROAM_FAIL_REASON_NO_AUTH_RESP = 7,
+	QCA_ROAM_FAIL_REASON_REASSOC_SEND = 8,
+	QCA_ROAM_FAIL_REASON_REASSOC_RECV = 9,
+	QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP = 10,
+	QCA_ROAM_FAIL_REASON_SCAN_FAIL = 11,
+	QCA_ROAM_FAIL_REASON_AUTH_NO_ACK = 12,
+	QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP = 13,
+	QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK = 14,
+	QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP = 15,
+	QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT = 16,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND = 17,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP = 18,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK = 19,
+	QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT = 20,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND = 21,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP = 22,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK = 23,
+	QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS = 24,
+	QCA_ROAM_FAIL_REASON_DISCONNECT = 25,
+	QCA_ROAM_FAIL_REASON_RESUME_ABORT = 26,
+	QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID = 27,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT = 28,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL = 29,
+};
+
+/*
+ * enum qca_vendor_roam_invoke_fail_reasons: Defines the various roam
+ * invoke fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_INVOKE_STATUS_IFACE_INVALID: Invalid interface ID is passed
+ * in roam invoke command.
+ * @QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE: Roam offload in firmware is not
+ * enabled.
+ * @QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID: Connected AP profile SSID
+ * length is invalid.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW: Firmware internal roaming is already
+ * in progress.
+ * @QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP: Host sends the Beacon/Probe Response
+ * of the AP in the roam invoke command to firmware. This reason is sent by the
+ * firmware when the given AP is configured to be ignored or SSID/security
+ * does not match.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL: Roam handoff failed because of
+ * firmware internal reasons.
+ * @QCA_ROAM_INVOKE_STATUS_DISALLOW: Roam invoke trigger is not enabled.
+ * @QCA_ROAM_INVOKE_STATUS_SCAN_FAIL: Scan start fail for roam invoke.
+ * @QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL: Roam handoff start fail.
+ * @QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS: Roam invoke parameters are invalid.
+ * @QCA_ROAM_INVOKE_STATUS_NO_CAND_AP: No candidate AP found to roam to.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_FAIL: Roam handoff failed.
+ */
+enum qca_vendor_roam_invoke_fail_reasons {
+	QCA_ROAM_INVOKE_STATUS_NONE = 0,
+	QCA_ROAM_INVOKE_STATUS_IFACE_INVALID = 1,
+	QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE = 2,
+	QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID = 3,
+	QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW = 4,
+	QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP = 5,
+	QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL = 6,
+	QCA_ROAM_INVOKE_STATUS_DISALLOW = 7,
+	QCA_ROAM_INVOKE_STATUS_SCAN_FAIL = 8,
+	QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL = 9,
+	QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS = 10,
+	QCA_ROAM_INVOKE_STATUS_NO_CAND_AP = 11,
+	QCA_ROAM_INVOKE_STATUS_ROAM_FAIL = 12,
+
 };
 
 /**
@@ -4127,7 +4965,7 @@
 
 /**
  * enum qca_vendor_attr_roam_control - Attributes to carry roam configuration
- * 	The following attributes are used to set/get/clear the respective
+ *	The following attributes are used to set/get/clear the respective
  *	configurations to/from the driver.
  *	For the get, the attribute for the configuration to be queried shall
  *	carry any of its acceptable values to the driver. In return, the driver
@@ -4226,6 +5064,151 @@
  *
  *	Clears the selection criteria configured in the driver when specified
  *	with clear command.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME: Unsigned 32-bit value.
+ *	Represents value of the scan frequency scheme from enum
+ *	qca_roam_scan_scheme.
+ *	It's an optional attribute. If this attribute is not configured, the
+ *	driver shall proceed with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD: Signed 32-bit value in dBm,
+ *	signifying the RSSI threshold of the current connected AP, indicating
+ *	the driver to trigger roam only when the current connected AP's RSSI
+ *	is less than this threshold.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD: Signed 32-bit value in dBm,
+ *	signifying the RSSI threshold of the candidate AP, indicating
+ *	the driver to trigger roam only to the candidate AP with RSSI
+ *	better than this threshold. If RSSI thresholds for candidate APs found
+ *	in the 2.4 GHz, 5 GHz, and 6 GHz bands are configured separately using
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ,
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ, and/or
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ, those values will
+ *	take precedence over the value configured using the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_USER_REASON: Unsigned 32-bit value. Represents the
+ *	user defined reason code to be sent to the AP in response to AP's
+ *	request to trigger the roam if the roaming cannot be triggered.
+ *	Applies to all the scenarios of AP assisted roaming (e.g., BTM).
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS: Unsigned 32-bit value.
+ *	Carries a bitmap of the roam triggers specified in
+ *	enum qca_vendor_roam_triggers.
+ *	Represents the roam triggers for which the specific scan scheme from
+ *	enum qca_roam_scan_scheme has to be applied.
+ *	It's an optional attribute. If this attribute is not configured, but
+ *	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is specified, the scan scheme
+ *	specified through QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is applicable for
+ *	all the roams.
+ *	If both QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME and
+ *	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS are not specified, the
+ *	driver shall proceed with the default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ: Signed 32-bit value
+ *	in dBm, signifying the RSSI threshold of the candidate AP found in the
+ *	2.4 GHz band. The driver/firmware shall trigger roaming to the candidate
+ *	AP found in the 2.4 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 5
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 5 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by tge
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 6
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 6 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_BAND_MASK: Unsigned 32-bit value.
+ *	Carries bitmask value of bits from &enum qca_set_band and represents
+ *	all the bands in which roaming is allowed. The configuration is valid
+ *	until next disconnection. If this attribute is not present, the
+ *	existing configuration shall be used. By default, roaming is allowed on
+ *	all bands supported by the local device. When the value is set to
+ *	%QCA_SETBAND_AUTO, all supported bands shall be enabled.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for active channels in the 2.4/5 GHz
+ *	bands. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for passive channels in the 5 GHz
+ *	band. If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME: u16 value in milliseconds.
+ *	Optional parameter. The minimum duration to stay on the connected AP
+ *	channel during the channel scanning. If this attribute is not
+ *	configured, the driver shall proceed with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME: u16 value in milliseconds.
+ *	Optional parameter. The maximum duration for which the radio can scan
+ *	foreign channels consecutively without coming back to home channel. If
+ *	this attribute is not configured, the driver shall proceed with default
+ *	behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Preferred Scanning Channels.
+ *	If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Non Preferred Scanning
+ *	Channels. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_RX_LINKSPEED_THRESHOLD: u16 value in Mbps.
+ *	Optional parameter. RX link speed threshold to disable roaming.
+ *	If the current RX link speed is above the threshold, roaming is not
+ *	needed. If this attribute is not configured, or if it is set to 0, the
+ *	driver will not consider the RX link speed in the roaming decision.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_HO_DELAY_FOR_RX: u16 value in milliseconds.
+ *	Optional parameter. This configuration delays hand-off by the
+ *	specified duration to receive pending RX frames from the current BSS.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_FULL_SCAN_NO_REUSE_PARTIAL_SCAN_FREQ: Unsigned 8-bit
+ *	value.
+ *	During the roam scan, if there are no desired APs found in the partial
+ *	frequency list, an immediate full scan on all the supported frequencies
+ *	is initiated as a fallback. This flag controls the frequency list
+ *	creation for the full scan on the following lines.
+ *	1 - Full scan to exclude the frequencies that were already scanned by
+ *	    the previous partial scan.
+ *	0 - Full scan to include all the supported frequencies irrespective of
+ *	    the ones part of the earlier partial scan.
+ *	If this flag is not specified, a full scan shall include all the
+ *	supported frequencies irrespective of the ones part of an earlier
+ *	partial scan.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_FULL_SCAN_6GHZ_ONLY_ON_PRIOR_DISCOVERY: Unsigned 8-bit
+ *	value.
+ *	During the roam scan, if there are no desired APs found in the partial
+ *	frequency list, an immediate full scan on all the supported frequencies
+ *	is initiated as a fallback. This full scan would add the 2.4/5/6 GHz
+ *	frequencies, including all PSC frequencies by default. This attribute
+ *	controls the inclusion of the 6 GHz PSC frequencies for the full scan
+ *	as following.
+ *	1 - Full scan to include the supported 6 GHz PSC frequencies only on the
+ *	   prior discovery of any 6 GHz frequency support in the environment.
+ *	   This discovery can happen through a prior RNR, 11k neighbor
+ *	request, 11v BTM request, host scan, etc.
+ *	0 - Default behavior. Full scan to include all the supported 6 GHz
+ *	   PSC frequencies regardless of whether 6 GHz BSSs have been
+ *	   discovered.
+ *	The default behavior if this flag is not specified is to include all
+ *	the supported 6 GHz PSC frequencies in the roam full scan.
  */
 enum qca_vendor_attr_roam_control {
 	QCA_ATTR_ROAM_CONTROL_ENABLE = 1,
@@ -4236,6 +5219,25 @@
 	QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD = 6,
 	QCA_ATTR_ROAM_CONTROL_TRIGGERS = 7,
 	QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA = 8,
+	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME = 9,
+	QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD = 10,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD = 11,
+	QCA_ATTR_ROAM_CONTROL_USER_REASON = 12,
+	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS = 13,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ = 14,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ = 15,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ = 16,
+	QCA_ATTR_ROAM_CONTROL_BAND_MASK = 17,
+	QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME = 18,
+	QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME = 19,
+	QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME = 20,
+	QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME = 21,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME = 22,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME = 23,
+	QCA_ATTR_ROAM_CONTROL_LINKSPEED_THRESHOLD = 24,
+	QCA_ATTR_ROAM_CONTROL_HO_DELAY_FOR_RX = 25,
+	QCA_ATTR_ROAM_CONTROL_FULL_SCAN_NO_REUSE_PARTIAL_SCAN_FREQ = 26,
+	QCA_ATTR_ROAM_CONTROL_FULL_SCAN_6GHZ_ONLY_ON_PRIOR_DISCOVERY = 27,
 
 	/* keep last */
 	QCA_ATTR_ROAM_CONTROL_AFTER_LAST,
@@ -4258,14 +5260,14 @@
  *	ignored BSSIDs and accordingly clear the respective ones with the
  *	matching ID.
  *
- * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS: Unsigned
- *	32-bit value.Represents the number of whitelist SSIDs configured.
+ * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS: Unsigned
+ *	32-bit value. Represents the number of allowlist SSIDs configured.
  *
- * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST: Nested attribute
- *	to carry the list of Whitelist SSIDs.
+ * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST: Nested attribute
+ *	to carry the list of allowlist SSIDs.
  *
- * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID: SSID (binary attribute,
- *	0..32 octets). Represents the white list SSID. Whitelist SSIDs
+ * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID: SSID (binary attribute,
+ *	0..32 octets). Represents the allow list SSID. Allowlist SSIDs
  *	represent the list of SSIDs to which the firmware/driver can consider
  *	to roam to.
  *
@@ -4303,7 +5305,7 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE: Unsigned 32-bit
  *	value. 1-Enable, 0-Disable. Represents "Lazy" mode, where
- *	firmware is hunting for a better BSSID or white listed SSID even though
+ *	firmware is hunting for a better BSSID or allow listed SSID even though
  *	the RSSI of the link is good. The parameters enabling the roaming are
  *	configured through the PARAM_A_BAND_XX attrbutes.
  *
@@ -4345,10 +5347,10 @@
 	QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD = 1,
 	QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID = 2,
 
-	/* Attributes for wifi_set_ssid_white_list */
-	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS = 3,
-	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST = 4,
-	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID = 5,
+	/* Attributes for wifi_set_ssid_allow_list */
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST = 4,
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID = 5,
 
 	/* Attributes for set_roam_params */
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD = 6,
@@ -4383,16 +5385,24 @@
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST - 1,
 };
 
+/* old names for API compatibility */
+#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS
+#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST
+#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID
+
 /*
  * enum qca_wlan_vendor_roaming_subcmd: Referred by
  * QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD.
  *
- * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST: Sub command to
- *	configure the white list SSIDs. These are configured through
+ * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST: Sub command to
+ *	configure the allow list SSIDs. These are configured through
  *	the following attributes.
- *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS,
- *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST,
- *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID
+ *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS,
+ *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST,
+ *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID
  *
  * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS: Sub command to
  *	configure the Roam params. These parameters are evaluated on the GScan
@@ -4408,7 +5418,7 @@
  *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS to set the BSSID
  *	preference.
  *
- * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID: Sets the list of BSSIDs
+ * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID: Sets the list of BSSIDs
  *	to ignore in roaming decision. Uses
  *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS to set the list.
  *
@@ -4432,17 +5442,23 @@
  */
 enum qca_wlan_vendor_roaming_subcmd {
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_INVALID = 0,
-	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST = 1,
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST = 1,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS = 2,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_LAZY_ROAM = 3,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PREFS = 4,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PARAMS = 5,
-	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID = 6,
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID = 6,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET = 7,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET = 8,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR = 9,
 };
 
+/* old names for API compatibility */
+#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST \
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST
+#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID \
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID
+
 enum qca_wlan_vendor_attr_gscan_config_params {
 	QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_INVALID = 0,
 
@@ -4801,7 +5817,7 @@
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID
 	= 43,
 	/* Unsigned 32-bit value; a GSCAN Capabilities attribute. */
-	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID
+	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID
 	= 44,
 
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED = 45,
@@ -4809,10 +5825,10 @@
 	/* Unsigned 32-bit value; a GSCAN Capabilities attribute.
 	 * This is used to limit the maximum number of BSSIDs while sending
 	 * the vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM with subcmd
-	 * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID and attribute
+	 * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID and attribute
 	 * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID.
 	 */
-	QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID = 46,
+	QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID = 46,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST,
@@ -4820,6 +5836,12 @@
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST - 1,
 };
 
+/* old names for API compatibility */
+#define QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID \
+	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID
+#define QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID \
+	QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID
+
 enum qca_wlan_vendor_attr_pno_config_params {
 	QCA_WLAN_VENDOR_ATTR_PNO_INVALID = 0,
 	/* Attributes for data used by
@@ -4949,6 +5971,8 @@
 	 * current channel.
 	 */
 	QCA_WLAN_VENDOR_ACS_SELECT_REASON_JAMMER_INTERFERENCE,
+	/* Represents the reason that ACS triggered by AFC */
+	QCA_WLAN_VENDOR_ACS_SELECT_REASON_AFC_TRIGGER,
 };
 
 /**
@@ -5031,7 +6055,7 @@
 	/* HE 40 with extension channel below */
 	QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40MINUS     = 1 << 30,
 	/* HE 40 intolerant */
-	QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40INTOL     = 1 << 31,
+	QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40INTOL     = 1U << 31,
 };
 
 /**
@@ -5117,6 +6141,22 @@
 	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS_2 = 11,
 
 	/*
+	 * Segment 0 in MHz (u32).
+	 *
+	 * For 20/40/80 MHz bandwidth, this indicates the channel center
+	 * frequency index for the 20/40/80 MHz operating channel.
+	 * For 160 MHz bandwidth, this indicates the channel center
+	 * frequency of the primary 80 MHz channel.
+	 * For 320 MHz bandwidth, indicates the channel center frequency
+	 * of the primary 160 MHz channel.
+	 *
+	 * To maintain backward compatibility,
+	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0
+	 * is also maintained.
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_SEG_0 = 12,
+	/* Legacy alias for the Segment 0 attribute.
+	 *
 	 * VHT segment 0 in MHz (u32) and the attribute is mandatory.
 	 * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes
 	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0
@@ -5134,9 +6174,25 @@
 	 * is still used if either of the driver or user space application
 	 * doesn't support the 6 GHz band.
 	 */
-	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 = 12,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 =
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_SEG_0,
 
 	/*
+	 * Segment 1 in MHz (u32).
+	 *
+	 * For 20/40/80 MHz bandwidth, this is set to 0.
+	 * For 160 MHz bandwidth, indicates the channel center frequency of the
+	 * 160 MHz channel.
+	 * For 320 MHz bandwidth, indicates the channel center frequency of the
+	 * 320 MHz channel.
+	 *
+	 * To maintain backward compatibility,
+	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1
+	 * is also maintained.
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_SEG_1 = 13,
+	/* Legacy alias for the Segment 1 attribute.
+	 *
 	 * VHT segment 1 in MHz (u32) and the attribute is mandatory.
 	 * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes
 	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1
@@ -5154,7 +6210,50 @@
 	 * is still used if either of the driver or user space application
 	 * doesn't support the 6 GHz band.
 	 */
-	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 = 13,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 =
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_SEG_1,
+
+	/*
+	 * 16-bit attribute of bits indicating the AP power modes supported by
+	 * the channel (u16).
+	 * Note: Currently, only 3 bits are used in the attribute and each bit
+	 * corresponds to the power mode mentioned in enum
+	 * qca_wlan_vendor_external_acs_chan_power_mode and a given bit is
+	 * set if the associated mode is supported.
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_SUPP_POWER_MODES
+									= 14,
+	/* Array of nested attributes for each power mode. It takes attr as
+	 * defined in enum
+	 * qca_wlan_vendor_external_acs_event_chan_power_info_attr.
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR	= 15,
+	/*
+	 * This indicates the overlapping 320 MHz center frequency in MHz
+	 * (u32), if the given primary channel supports more than one
+	 * 320 MHz channel bonding.
+	 *
+	 * Example:
+	 * For 6 GHz, channel frequency 6115 MHz (channel number 33) segment 0
+	 * center frequency (primary 160 MHz) is 6185 MHz and there can be two
+	 * possible segment 2 frequencies for this (320 MHz center
+	 * frequencies):
+	 *
+	 * 1) Center frequency 6105 MHz (channel 31): 320 MHz channel bonding
+	 *    from frequency 5945 MHz - 6265 MHz
+	 * 2) Center frequency 6265 MHz (channel 63): 320 MHz channel bonding
+	 *    from frequency 6105 MHz - 6425 MHz
+	 *
+	 * In this case,
+	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_SEG_0 will
+	 * return 6185 MHz.
+	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_SEG_1 will
+	 * return 6105 MHz.
+	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_OVERLAP_SEG_1
+	 * will return 6265 MHz.
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_OVERLAP_SEG_1
+									= 16,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST,
@@ -5163,6 +6262,56 @@
 };
 
 /**
+ * qca_wlan_vendor_external_acs_chan_power_mode - Specifies the valid
+ * values that the vendor external ACS channel power attribute
+ * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_MODE can
+ * take.
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_LOW_POWER: Low power/Indoor mode
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_STANDARD_POWER: Standard power mode
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_VERY_LOW_POWER: Very low power mode
+ */
+enum qca_wlan_vendor_external_acs_chan_power_level {
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_LOW_POWER = 0,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_STANDARD_POWER = 1,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_VERY_LOW_POWER = 2,
+};
+
+/**
+ * qca_wlan_vendor_external_acs_event_chan_power_info_attr: Represents nested
+ * attributes for power mode type and power values corresponding to that.
+ * These attributes are sent as part of
+ * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR.
+ */
+enum qca_wlan_vendor_external_acs_event_chan_power_info_attr {
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_INVALID = 0,
+	/*
+	 * Power mode (u8) takes the values defined in enum
+	 * qca_wlan_vendor_external_acs_chan_power_mode
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_MODE
+									= 1,
+	/*
+	 * Indicates if power value is a PSD/EIRP value (flag). If flag is
+	 * present, it indicates a PSD value.
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_PSD_FLAG = 2,
+	/*
+	 * Power value (u32) PSD/EIRP as indicated by
+	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_PSD_FLAG,
+	 * for power mode corresponding to the
+	 * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_MODE.
+	 * Units for PSD - dBm/MHz
+	 * Units for EIRP - dBm
+	 */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_VALUE
+									= 3,
+	/* keep last */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_LAST,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_MAX =
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_LAST - 1,
+};
+
+/**
  * qca_wlan_vendor_attr_pcl: Represents attributes for
  * preferred channel list (PCL). These attributes are sent as part of
  * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL and
@@ -5186,6 +6335,10 @@
 	 * bit 3 set: channel should be excluded in GO negotiation
 	 */
 	QCA_WLAN_VENDOR_ATTR_PCL_FLAG = 4,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_PCL_LAST,
+	QCA_WLAN_VENDOR_ATTR_PCL_MAX = QCA_WLAN_VENDOR_ATTR_PCL_LAST - 1
 };
 
 /**
@@ -5248,6 +6401,10 @@
 	 * qca_wlan_vendor_attr_rropavail_info.
 	 */
 	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_RROPAVAIL_INFO = 14,
+	/* Flag attribute to indicate if driver supports 6 GHz AFC trigger
+	 * for External ACS
+	 */
+	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_AFC_CAPABILITY = 15,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LAST,
@@ -5350,6 +6507,11 @@
  * VHT seg1 channel frequency in MHz
  * Note: If user-space application has no support of the 6 GHz band, this
  * attribute is optional.
+ * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_PUNCTURE_BITMAP: Required (u16)
+ * Puncture Bitmap for selected primary channel. Optional if no support
+ * for EHT (IEEE 802.11be). Encoding for this attribute follows the
+ * convention used in the Disabled Subchannel Bitmap field of the EHT Operation
+ * element.
  */
 enum qca_wlan_vendor_attr_external_acs_channels {
 	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_INVALID = 0,
@@ -5385,6 +6547,7 @@
 	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY = 11,
 	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 = 12,
 	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 = 13,
+	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_PUNCTURE_BITMAP = 14,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LAST,
@@ -5843,6 +7006,20 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2 = 29,
+	/* This attribute specifies the bandwidth to be used for spectral scan
+	 * operation. This is an u8 attribute and uses the values in enum
+	 * nl80211_chan_width. This is an optional attribute.
+	 * If this attribute is not populated, the driver should configure the
+	 * spectral scan bandwidth to the maximum value supported by the target
+	 * for the current operating bandwidth.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH = 30,
+	/* Spectral FFT recapture flag attribute, to enable FFT recapture.
+	 * Recapture can only be enabled for scan period greater than 52 us.
+	 * If this attribute is enabled, re-triggers will be enabled when AGC
+	 * gain changes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_RECAPTURE = 31,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX =
@@ -5953,6 +7130,14 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ = 18,
+	/* Flag attribute to indicate agile spectral scan capability
+	 * for 320 MHz mode.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320 = 19,
+	/* Number of spectral detectors used for scan in 320 MHz.
+	 * u32 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ = 20,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX =
@@ -6135,6 +7320,16 @@
 	 * the FW on a specific VDEV.
 	 */
 	QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22,
+	/* WMI sequence mismatch between WMI command and Tx completion */
+	QCA_WLAN_HANG_WMI_BUF_SEQUENCE_MISMATCH = 23,
+	/* Write to Device HAL register failed */
+	QCA_WLAN_HANG_REG_WRITE_FAILURE = 24,
+	/* No credit left to send the wow_wakeup_from_sleep to firmware */
+	QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25,
+	/* Bus failure */
+	QCA_WLAN_HANG_BUS_FAILURE = 26,
+	/* tasklet/credit latency found */
+	QCA_WLAN_HANG_TASKLET_CREDIT_LATENCY_DETECT = 27,
 };
 
 /**
@@ -6160,6 +7355,28 @@
 };
 
 /**
+ * enum qca_wlan_vendor_flush_pending_policy: Represents values for
+ * the policy to flush pending frames, configured via
+ * %QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING. This enumeration defines the
+ * valid values for %QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY.
+ *
+ * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE: This value clears all
+ * the flush policy configured before. This command basically disables the
+ * flush config set by the user.
+ * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE: This value configures
+ * the flush policy to be immediate. All pending packets for the peer/TID are
+ * flushed when this command/policy is received.
+ * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END: This value configures
+ * the flush policy to the end of TWT SP. All pending packets for the peer/TID
+ * are flushed when the end of TWT SP is reached.
+ */
+enum qca_wlan_vendor_flush_pending_policy  {
+	QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE = 0,
+	QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE = 1,
+	QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_flush_pending - Attributes for
  * flushing pending traffic in firmware.
  *
@@ -6167,12 +7384,25 @@
  * @QCA_WLAN_VENDOR_ATTR_AC: Configure access category of the pending
  * packets. It is u8 value with bit 0~3 represent AC_BE, AC_BK,
  * AC_VI, AC_VO respectively. Set the corresponding bit to 1 to
- * flush packets with access category.
+ * flush packets with access category. This is optional. See below.
+ * @QCA_WLAN_VENDOR_ATTR_TID_MASK: Configure TID mask of the pending packets.
+ * It is a u32 value with bit 0-7 representing TID 0-7. Set corresponding
+ * bit to 1 to act upon the TID. This is optional. Either this attribute or
+ * %QCA_WLAN_VENDOR_ATTR_AC must be provided. If both are provided,
+ * %QCA_WLAN_VENDOR_ATTR_TID_MASK takes precedence. If neither are provided
+ * it is an error.
+ * @QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY: Policy of flushing the pending
+ * packets corresponding to the peer/TID provided. It is a u32 value,
+ * represented by %enum qca_wlan_vendor_flush_pending_policy. This
+ * value is honored only when TID mask is provided. This is not honored when AC
+ * mask is provided.
  */
 enum qca_wlan_vendor_attr_flush_pending {
 	QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_PEER_ADDR = 1,
 	QCA_WLAN_VENDOR_ATTR_AC = 2,
+	QCA_WLAN_VENDOR_ATTR_TID_MASK = 3,
+	QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY = 4,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_AFTER_LAST,
@@ -6289,10 +7519,11 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL:
  *	Default WLAN operation level which throughput orientated.
- * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE:
- *	Use moderate level to improve latency by limit scan duration.
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR:
+ *	Use XR level to benefit XR (extended reality) application to achieve
+ *	latency and power by via constraint scan/roaming/adaptive PS.
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW:
- *	Use low latency level to benifit application like concurrent
+ *	Use low latency level to benefit application like concurrent
  *	downloading or video streaming via constraint scan/adaptive PS.
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW:
  *	Use ultra low latency level to benefit for gaming/voice
@@ -6301,7 +7532,10 @@
 enum qca_wlan_vendor_attr_config_latency_level {
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL = 1,
-	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE = 2,
+	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR = 2,
+	/* legacy name */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE =
+	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW = 3,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW = 4,
 
@@ -6613,6 +7847,14 @@
 	 * 1:support 0:not support
 	 */
 	QCA_WLAN_VENDOR_ATTR_PEER_NDPE_SUPPORT = 30,
+	/* As per Wi-Fi Aware Specification v3.2 Service Id is the first
+	 * 48 bits of the SHA-256 hash of the Service Name.
+	 * A lower-case representation of the Service Name shall be used to
+	 * calculate the Service ID.
+	 * Array of u8: length is 6 bytes
+	 * This attribute is used and optional for ndp indication.
+	 */
+	QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID = 31,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST,
@@ -6622,9 +7864,24 @@
 
 enum qca_wlan_ndp_sub_cmd {
 	QCA_WLAN_VENDOR_ATTR_NDP_INVALID = 0,
-	/* Command to create a NAN data path interface */
+	/* Command to create a NAN data path interface.
+	 * This command was initially designed to both create and start a NAN
+	 * data path interface. However, changes to Linux 5.12 no longer allow
+	 * interface creation via vendor commands. When the driver advertises
+	 * QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI
+	 * userspace must explicitly first create the interface using
+	 * NL80211_CMD_NEW_INTERFACE before subsequently invoking this command
+	 * to start the interface.
+	 */
 	QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE = 1,
-	/* Command to delete a NAN data path interface */
+	/* Command to delete a NAN data path interface.
+	 * This command was initially designed to both stop and delete a NAN
+	 * data path interface. However, changes to Linux 5.12 no longer allow
+	 * interface deletion via vendor commands. When the driver advertises
+	 * QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI
+	 * userspace must explicitly delete the interface using
+	 * NL80211_CMD_DEL_INTERFACE after calling this command.
+	 */
 	QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE = 2,
 	/* Command to initiate a NAN data path session */
 	QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST = 3,
@@ -6801,8 +8058,9 @@
 
 /**
  * enum qca_wlan_vendor_thermal_level - Defines various thermal levels
- * configured by userspace to the driver/firmware. The values will be
- * encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL attribute.
+ * configured by userspace to the driver/firmware.
+ * The values can be encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL or
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL attribute.
  * The driver/firmware takes actions requested by userspace such as throttling
  * wifi TX etc. in order to mitigate high temperature.
  *
@@ -6836,8 +8094,9 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE = 1,
 	/* Userspace uses this attribute to configure thermal level to the
-	 * driver/firmware. Used in request, u32 attribute, possible values
-	 * are defined in enum qca_wlan_vendor_thermal_level.
+	 * driver/firmware, or get thermal level from the driver/firmware.
+	 * Used in request or response, u32 attribute,
+	 * possible values are defined in enum qca_wlan_vendor_thermal_level.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL = 2,
 	/* Userspace uses this attribute to configure the time in which the
@@ -6850,6 +8109,15 @@
 	 * there is any critical ongoing operation.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3,
+	/* Nested attribute, the driver/firmware uses this attribute to report
+	 * thermal statistics of different thermal levels to userspace when
+	 * requested using the
+	 * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command
+	 * type. This attribute contains a nested array of records of thermal
+	 * statistics of multiple levels. The attributes used inside this nested
+	 * attribute are defined in enum qca_wlan_vendor_attr_thermal_stats.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST,
@@ -6875,6 +8143,16 @@
  * resume action.
  * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL: Configure thermal level to
  * the driver/firmware.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current
+ * thermal level from the driver/firmware. The driver should respond with a
+ * thermal level defined in enum qca_wlan_vendor_thermal_level.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the
+ * current thermal statistics from the driver/firmware. The driver should
+ * respond with statistics of all thermal levels encapsulated in the attribute
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear
+ * the current thermal statistics for all thermal levels maintained in the
+ * driver/firmware and start counting from zero again.
  */
 enum qca_wlan_vendor_attr_thermal_cmd_type {
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS,
@@ -6882,6 +8160,9 @@
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS,
 };
 
 /**
@@ -6964,6 +8245,11 @@
 	 * NLA_FLAG attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_RESUME_COMPLETE,
+	/* Thermal level from the driver.
+	 * u32 attribute. Possible values are defined in
+	 * enum qca_wlan_vendor_thermal_level.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL = 3,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST,
@@ -6972,6 +8258,35 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes
+ * to get thermal status from the driver/firmware.
+ * enum values are used for NL attributes encapsulated inside the
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute.
+ *
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each
+ * thermal level in milliseconds. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number
+ * of times the temperature crossed into the temperature range defined by the
+ * thermal level from both higher and lower directions. u32 size.
+ */
+enum qca_wlan_vendor_attr_thermal_stats {
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1,
+};
+
+/**
  * enum he_fragmentation_val - HE fragmentation support values
  * Indicates level of dynamic fragmentation that is supported by
  * a STA as a recipient.
@@ -7130,6 +8445,21 @@
 };
 
 /**
+ * enum qca_wlan_keep_alive_data_type - Keep alive data type configuration
+ *
+ * Indicates the frame types to use for keep alive data.
+ *
+ * @QCA_WLAN_KEEP_ALIVE_DEFAULT: Driver default type used for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_DATA: Data frame type for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_MGMT: Management frame type for keep alive.
+ */
+enum qca_wlan_keep_alive_data_type {
+	QCA_WLAN_KEEP_ALIVE_DEFAULT = 0,
+	QCA_WLAN_KEEP_ALIVE_DATA = 1,
+	QCA_WLAN_KEEP_ALIVE_MGMT = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_he_omi_tx: Represents attributes for
  * HE operating mode control transmit request. These attributes are
  * sent as part of QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX and
@@ -7577,6 +8907,150 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT = 43,
 
+	/* 8-bit unsigned value to configure the driver/firmware to start or
+	 * stop transmitting FILS discovery frames.
+	 * 0 - Stop transmitting FILS discovery frames
+	 * 1 - Start transmitting FILS discovery frames
+	 * This attribute is used to configure the testbed device.
+	 * This attribute can be configured only in AP mode and the
+	 * configuration is valid until AP restart.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX = 44,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable full bandwidth UL MU-MIMO subfield in the HE PHY capabilities
+	 * information field.
+	 * 0 - Disable full bandwidth UL MU-MIMO subfield
+	 * 1 - Enable full bandwidth UL MU-MIMO subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO = 45,
+
+	/* 16-bit unsigned value to configure the driver with a specific BSS
+	 * max idle period to advertise in the BSS Max Idle Period element
+	 * (IEEE Std 802.11-2016, 9.4.2.79) in (Re)Association Request frames.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD = 46,
+
+	/* 8-bit unsigned value to configure the driver to use only RU 242 tone
+	 * for data transmission.
+	 * 0 - Default behavior, 1 - Configure RU 242 tone for data Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX = 47,
+
+	/* 8-bit unsigned value to configure the driver to disable data and
+	 * management response frame transmission to test the BSS max idle
+	 * feature.
+	 * 0 - Default behavior, 1 - Disable data and management response Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX = 48,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Punctured Preamble Rx subfield in the HE PHY capabilities
+	 * information field.
+	 * 0 - Disable Punctured Preamble Rx subfield
+	 * 1 - Enable Punctured Preamble Rx subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX = 49,
+
+	/* 8-bit unsigned value to configure the driver to ignore the SAE H2E
+	 * requirement mismatch for 6 GHz connection.
+	 * 0 - Default behavior, 1 - Ignore SAE H2E requirement mismatch.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE = 50,
+
+	/* 8-bit unsigned value to configure the driver to allow 6 GHz
+	 * connection with all security modes.
+	 * 0 - Default behavior, 1 - Allow 6 GHz connection with all security
+	 * modes.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_6GHZ_SECURITY_TEST_MODE = 51,
+
+	/* 8-bit unsigned value to configure the driver to transmit data with
+	 * ER SU PPDU type.
+	 *
+	 * 0 - Default behavior, 1 - Enable ER SU PPDU type TX.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE = 52,
+
+	/* 8-bit unsigned value to configure the driver to use Data or
+	 * Management frame type for keep alive data.
+	 * Uses enum qca_wlan_keep_alive_data_type values.
+	 *
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE = 53,
+
+	/* 8-bit unsigned value to configure the driver to use scan request
+	 * BSSID value in Probe Request frame RA(A1) during the scan. The
+	 * driver saves this configuration and applies this setting to all user
+	 * space scan requests until the setting is cleared. If this
+	 * configuration is set, the driver uses the BSSID value from the scan
+	 * request to set the RA(A1) in the Probe Request frames during the
+	 * scan.
+	 *
+	 * 0 - Default behavior uses the broadcast RA in Probe Request frames.
+	 * 1 - Uses the scan request BSSID in RA in Probe Request frames.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA = 54,
+
+	/* 8-bit unsigned value to configure the driver to enable/disable the
+	 * BSS max idle period support.
+	 *
+	 * 0 - Disable the BSS max idle support.
+	 * 1 - Enable the BSS max idle support.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Rx control frame to MultiBSS subfield in the HE MAC
+	 * capabilities information field.
+	 * 0 - Disable Rx control frame to MultiBSS subfield
+	 * 1 - Enable Rx control frame to MultiBSS subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS = 56,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Broadcast TWT support subfield in the HE MAC capabilities
+	 * information field.
+	 * 0 - Disable Broadcast TWT support subfield
+	 * 1 - Enable Broadcast TWT support subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT = 57,
+
+	/* 8-bit unsigned value to configure the driver/firmware to allow eMLSR
+	 * mode for IEEE 802.11be MLO capable devices. If the attribute is set
+	 * to 1, and if the firmware supports this capability too, the STA
+	 * advertises this capability to the AP over Association Request frame.
+	 * This attribute will not have any effect on legacy devices with no
+	 * IEEE 802.11be support.
+	 * 0 - Default behavior
+	 * 1 - Enable eMLSR (Enhanced Multi-link Single-Radio) mode
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_11BE_EMLSR_MODE = 58,
+
+	/* 8-bit unsigned value to configure the driver to enable/disable the
+	 * periodic sounding for Tx beamformer functionality. The default
+	 * behavior uses algorithm to do sounding based on packet stats.
+	 *
+	 * 0 - Default behavior.
+	 * 1 - Enable the periodic sounding for Tx beamformer.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BEAMFORMER_PERIODIC_SOUNDING = 59,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@@ -7586,26 +9060,78 @@
 /**
  * enum qca_wlan_twt_operation - Operation of the config TWT request
  * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION.
+ * The response for the respective operations can be either synchronous or
+ * asynchronous (wherever specified). If synchronous, the response to this
+ * operation is obtained in the corresponding vendor command reply to the user
+ * space. For the asynchronous case the response is obtained as an event with
+ * the same operation type.
+ *
+ * Drivers shall support either of these modes but not both simultaneously.
+ * This support for asynchronous mode is advertised through the flag
+ * QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT. If this flag is not advertised,
+ * the driver shall support synchronous mode.
  *
  * @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured
  * through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. Depending upon the
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, this is either a
+ * synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. This is a synchronous operation.
  *
  * @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * This terminate can either get triggered by the user space or can as well be
+ * a notification from the firmware if it initiates a terminate.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * the request from user space can either be a synchronous or asynchronous
+ * operation.
  *
  * @QCA_WLAN_TWT_SUSPEND: Suspend the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * this is either a synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are
  * configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_resume. Valid only after the TWT session is setup.
+ * This can as well be a notification from the firmware on a QCA_WLAN_TWT_NUDGE
+ * request. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_NUDGE: Suspend and resume the TWT session. TWT nudge is a
+ * combination of suspend and resume in a single request. Required parameters
+ * are configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the
+ * enum qca_wlan_vendor_attr_twt_nudge. Valid only after the TWT session is
+ * setup. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_STATS: Get the TWT session traffic statistics information.
+ * Refers the enum qca_wlan_vendor_attr_twt_stats. Valid only after the TWT
+ * session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_CLEAR_STATS: Clear TWT session traffic statistics information.
+ * Valid only after the TWT session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_CAPABILITIES: Get TWT capabilities of this device and its
+ * peer. Refers the enum qca_wlan_vendor_attr_twt_capability. It's a synchronous
+ * operation.
+ *
+ * @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmware is
+ * ready for a new TWT session setup after it issued a TWT teardown.
+ *
+ * @QCA_WLAN_TWT_SET_PARAM: Configure TWT related parameters. Required
+ * parameters are obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refer
+ * the enum qca_wlan_vendor_attr_twt_set_param.
+ *
+ * @QCA_WLAN_TWT_NOTIFY: Used to notify userspace about changes in TWT
+ * related information for example TWT required bit in AP capabilities etc.
+ * The reason for the notification is sent using
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_NOTIFY_STATUS.
  */
 enum qca_wlan_twt_operation {
 	QCA_WLAN_TWT_SET = 0,
@@ -7613,6 +9139,13 @@
 	QCA_WLAN_TWT_TERMINATE = 2,
 	QCA_WLAN_TWT_SUSPEND = 3,
 	QCA_WLAN_TWT_RESUME = 4,
+	QCA_WLAN_TWT_NUDGE = 5,
+	QCA_WLAN_TWT_GET_STATS = 6,
+	QCA_WLAN_TWT_CLEAR_STATS = 7,
+	QCA_WLAN_TWT_GET_CAPABILITIES = 8,
+	QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9,
+	QCA_WLAN_TWT_SET_PARAM = 10,
+	QCA_WLAN_TWT_NOTIFY = 11,
 };
 
 /**
@@ -7626,13 +9159,20 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the
  * parameters configured for TWT. These parameters are represented by
- * enum qca_wlan_vendor_attr_twt_setup or enum qca_wlan_vendor_attr_twt_resume
- * based on the operation.
+ * enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume,
+ * enum qca_wlan_vendor_attr_twt_set_param, or
+ * enum qca_wlan_vendor_attr_twt_stats based on the operation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_NOTIFY_STATUS: Size is u8, mandatory when
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to QCA_WLAN_TWT_NOTIFY.
+ * The values used by this attribute are defined in
+ * enum qca_wlan_vendor_twt_status.
  */
 enum qca_wlan_vendor_attr_config_twt {
 	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION = 1,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS = 2,
+	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_NOTIFY_STATUS = 3,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_AFTER_LAST,
@@ -7788,6 +9328,19 @@
 };
 
 /**
+ * qca_wlan_twt_setup_state: Represents the TWT session states.
+ *
+ * QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: TWT session not established.
+ * QCA_WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active.
+ * QCA_WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is in suspended state.
+ */
+enum qca_wlan_twt_setup_state {
+	QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0,
+	QCA_WLAN_TWT_SETUP_STATE_ACTIVE = 1,
+	QCA_WLAN_TWT_SETUP_STATE_SUSPEND = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_twt_setup: Represents attributes for
  * TWT (Target Wake Time) setup request. These attributes are sent as part of
  * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and
@@ -7837,6 +9390,14 @@
  * 2. TWT GET Request and Response
  * 3. TWT TERMINATE Request and Response
  * 4. TWT SUSPEND Request and Response
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions for the following
+ * 1. TWT TERMINATE Request and Response
+ * 2. TWT SUSPEND Request and Response
+ * 4. TWT CLEAR STATISTICS request
+ * 5. TWT GET STATISTICS request and response
+ * If an invalid dialog ID is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8)
  * This attribute (exp) is used along with the mantissa to derive the
@@ -7887,6 +9448,7 @@
  * 2. TWT TERMINATE Response
  * 3. TWT SUSPEND Response
  * 4. TWT RESUME Response
+ * 5. TWT NUDGE Response
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE: Required (u8)
  * This field is applicable for TWT response only.
@@ -7896,9 +9458,13 @@
  * response.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF: Required (u64)
- * This field is applicable for TWT response only.
- * This field contains absolute TSF value of the wake time received
- * from the TWT responder and is passed to the userspace.
+ * In TWT setup command this field contains absolute TSF that will
+ * be used by TWT requester during setup.
+ * In TWT response this field contains absolute TSF value of the
+ * wake time received from the TWT responder and is passed to
+ * the userspace.
+ * This is an optional parameter for
+ * 1. TWT SET Request
  * This is a required parameter for
  * 1. TWT SET Response
  * 2. TWT GET Response
@@ -7915,14 +9481,87 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer for which the TWT session
  * is being configured. This is used in AP mode to represent the respective
- * client. In AP mode, this is an optional parameter for response and is
- * a required parameter for
- * 1. TWT SET Request
- * 2. TWT GET Request
- * 3. TWT TERMINATE Request
- * 4. TWT SUSPEND Request
+ * client.
+ * In AP mode, this is a required parameter in response for
+ * 1. TWT SET
+ * 2. TWT GET
+ * 3. TWT TERMINATE
+ * 4. TWT SUSPEND
  * In STA mode, this is an optional parameter in request and response for
  * the above four TWT operations.
+ * In AP mode, this is a required parameter in request for
+ * 1. TWT GET
+ * 2. TWT TERMINATE
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL: Optional (u32)
+ * Minimum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL: Optional (u32)
+ * Maximum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION: Optional (u32)
+ * Minimum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION: Optional (u32)
+ * Maximum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE: Optional (u32)
+ * TWT state for the given dialog id. The values for this are represented
+ * by enum qca_wlan_twt_setup_state.
+ * This is obtained through TWT GET operation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA: Optional (u32)
+ * This attribute is used to configure wake interval mantissa.
+ * The unit is microseconds. This attribute, when specified, takes
+ * precedence over QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA.
+ * This parameter is used for
+ * 1. TWT SET Request and Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID: Optional (u8)
+ * This attribute is used to configure Broadcast TWT ID.
+ * The Broadcast TWT ID indicates a specific Broadcast TWT for which the
+ * transmitting STA is providing TWT parameters. The allowed values are 0 to 31.
+ * This parameter is used for
+ * 1. TWT SET Request
+ * 2. TWT TERMINATE Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION: Optional (u8)
+ * This attribute is used to configure Broadcast TWT recommendation.
+ * The Broadcast TWT Recommendation subfield contains a value that indicates
+ * recommendations on the types of frames that are transmitted by TWT
+ * scheduled STAs and scheduling AP during the broadcast TWT SP.
+ * The allowed values are 0 - 3.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE: Optional (u8)
+ * This attribute is used to configure Broadcast TWT Persistence.
+ * The Broadcast TWT Persistence subfield indicates the number of
+ * TBTTs during which the Broadcast TWT SPs corresponding to this
+ * broadcast TWT Parameter set are present. The number of beacon intervals
+ * during which the Broadcast TWT SPs are present is equal to the value in the
+ * Broadcast TWT Persistence subfield plus 1 except that the value 255
+ * indicates that the Broadcast TWT SPs are present until explicitly terminated.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE: Optional (u8)
+ * This attribute contains the value of the Responder PM Mode subfield (0 or 1)
+ * from TWT response frame.
+ * This parameter is used for
+ * 1. TWT SET Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT: Optional (u32)
+ * This attribute is used to configure the announce timeout value (in us) in
+ * the firmware. This timeout value is only applicable for the announced TWT. If
+ * the timeout value is non-zero the firmware waits up to the timeout value to
+ * use Data frame as an announcement frame. If the timeout value is 0 the
+ * firmware sends an explicit QoS NULL frame as the announcement frame on SP
+ * start. The default value in the firmware is 0.
+ * This parameter is used for
+ * 1. TWT SET Request
  */
 enum qca_wlan_vendor_attr_twt_setup {
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0,
@@ -7944,6 +9583,20 @@
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED = 14,
 
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR = 15,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL = 16,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL = 17,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION = 18,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION = 19,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE = 20,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA = 21,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID = 22,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION = 23,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE = 24,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE = 25,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT = 26,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST,
@@ -7971,6 +9624,34 @@
  * @QCA_WLAN_VENDOR_TWT_STATUS_DENIED: AP did not accept the request
  * @QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR: Adding TWT dialog failed due to an
  * unknown reason
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: TWT session already in
+ * suspend state
+ * @QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: FW has dropped the frame due to
+ * invalid IE in the received TWT frame
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: Parameters received from
+ * the responder are not in the specified range
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to request from the responder. Used on the TWT_TERMINATE
+ * notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to roaming. Used on the TWT_TERMINATE notification from the
+ * firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE: FW terminated the
+ * TWT session due to SCC (Single Channel Concurrency) and MCC (Multi Channel
+ * Concurrency). Used on the TWT_TERMINATE notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS: FW rejected the TWT setup
+ * request due to roaming in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS: FW rejected the TWT
+ * setup request due to channel switch in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS: FW rejected the TWT setup
+ * request due to scan in progress.
+ * QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE: The driver requested to
+ * terminate an existing TWT session on power save exit request from userspace.
+ * Used on the TWT_TERMINATE notification from the driver/firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_TWT_REQUIRED: The peer has set the TWT
+ * required bit in its capabilities.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_REQUIRED: The peer has cleared
+ * the TWT required bit(1->0) in its capabilities.
  */
 enum qca_wlan_vendor_twt_status {
 	QCA_WLAN_VENDOR_TWT_STATUS_OK = 0,
@@ -7986,6 +9667,18 @@
 	QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE = 10,
 	QCA_WLAN_VENDOR_TWT_STATUS_DENIED = 11,
 	QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR = 12,
+	QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED = 13,
+	QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID = 14,
+	QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE = 15,
+	QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE = 16,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE = 17,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE = 18,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS = 19,
+	QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS = 20,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS = 21,
+	QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE = 22,
+	QCA_WLAN_VENDOR_TWT_STATUS_TWT_REQUIRED = 23,
+	QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_REQUIRED = 24,
 };
 
 /**
@@ -8012,6 +9705,10 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID: Required (u8).
  * Flow ID is the unique identifier for each TWT session. This attribute
  * represents the respective TWT session to resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer to which TWT Resume is
@@ -8034,6 +9731,240 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_twt_nudge - Represents attributes for
+ * TWT (Target Wake Time) nudge request. TWT nudge is a combination of suspend
+ * and resume in a single request. These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session to suspend and resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in TWT NUDGE request
+ * and response.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME: Required (u32)
+ * This attribute is used as the SP offset which is the offset from
+ * TSF after which the wake happens. The units are in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE: Required (u32)
+ * This attribute represents the next TWT subfield size.
+ * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits,
+ * and 4 for 64 bits.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer to which TWT Suspend and Resume is
+ * being sent. This is used in AP mode to represent the respective
+ * client and is a required parameter. In STA mode, this is an optional
+ * parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF: Optional (u64)
+ * This field contains absolute TSF value of the time at which the TWT
+ * session will be resumed.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_SP_START_OFFSET: Optional (s32)
+ * This field will be used when device supports Flexible TWT.
+ * This field contains an offset value by which to shift the starting time
+ * of the next service period. The value of offset can be negative or positive.
+ * If provided, this attribute will override
+ * QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME. The units are in microseconds.
+ *
+ */
+enum qca_wlan_vendor_attr_twt_nudge {
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE = 3,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF = 5,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_SP_START_OFFSET = 6,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_stats: Represents attributes for
+ * TWT (Target Wake Time) get statistics and clear statistics request.
+ * These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session for get and clear TWT statistics.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which TWT Statistics
+ * is required.
+ * In AP mode this is used to represent the respective
+ * client and is a required parameter for
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request and response
+ * In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION: Required (u32)
+ * This is the duration of the service period in microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION: Required (u32)
+ * Average of the actual wake duration observed so far. Unit is microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS: Required (u32)
+ * The number of TWT service periods elapsed so far.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION: Required (u32)
+ * This is the minimum value of the wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION: Required (u32)
+ * This is the maximum value of wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU: Required (u32)
+ * Average number of MPDUs transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU: Required (u32)
+ * Average number of MPDUs received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE: Required (u32)
+ * Average number of bytes transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE: Required (u32)
+ * Average number of bytes received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS: Required (u32)
+ * Status of the TWT GET STATISTICS request.
+ * This contains status values in enum qca_wlan_vendor_twt_status
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ */
+enum qca_wlan_vendor_attr_twt_stats {
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION = 3,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS = 5,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION = 6,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION = 7,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU = 8,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU = 9,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE = 10,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE = 11,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS = 12,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_twt_get_capa  - Represents the bitmap of TWT capabilities
+ * supported by the device and the peer.
+ * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_GET_CAPABILITIES
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by
+ * TWT non-scheduling STA. This capability is advertised in the HE
+ * Capability/Extended Capabilities information element in the
+ * Association Request frame by the device.
+ *
+ * @QCA_WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by
+ * the TWT scheduling AP. This capability is advertised in the Extended
+ * Capabilities/HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_BROADCAST: On the requestor side, this indicates support
+ * for the broadcast TWT functionality. On the responder side, this indicates
+ * support for the role of broadcast TWT scheduling functionality. This
+ * capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_TWT_FLEXIBLE: The device supports flexible TWT schedule.
+ * This capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate
+ * that it mandates the associated HE STAs to support TWT. This capability is
+ * advertised by AP in the HE Operation Parameters field of the HE Operation
+ * information element.
+ */
+enum qca_wlan_twt_capa {
+	QCA_WLAN_TWT_CAPA_REQUESTOR = BIT(0),
+	QCA_WLAN_TWT_CAPA_RESPONDER = BIT(1),
+	QCA_WLAN_TWT_CAPA_BROADCAST = BIT(2),
+	QCA_WLAN_TWT_CAPA_FLEXIBLE =  BIT(3),
+	QCA_WLAN_TWT_CAPA_REQUIRED =  BIT(4),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_capability  - Represents attributes for TWT
+ * get capabilities request type. Used by QCA_WLAN_TWT_GET_CAPABILITIES TWT
+ * operation.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which the TWT capabilities
+ * are being queried. This is used in AP mode to represent the respective
+ * client. In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF: (u16).
+ * Self TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER: (u16).
+ * Peer TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ */
+enum qca_wlan_vendor_attr_twt_capability {
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER = 3,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_set_param: Represents attributes for
+ * TWT (Target Wake Time) related parameters. It is used when
+ * %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to %QCA_WLAN_TWT_SET_PARAM.
+ * These attributes are sent as part of %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE: Optional (u8)
+ * This attribute configures AC parameters to be used for all TWT
+ * sessions in AP mode.
+ * Uses the enum qca_wlan_ac_type values.
+ */
+enum qca_wlan_vendor_attr_twt_set_param {
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST - 1,
+};
+
+/**
  * enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by
  * the TWT responder
  *
@@ -8124,6 +10055,22 @@
 };
 
 /**
+ * enum qca_wlan_vendor_cfr_data_transport_modes - Defines QCA vendor CFR data
+ * transport modes and is used by the attribute
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE as a part of the vendor
+ * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
+ * @QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS: Use relayfs to send CFR data.
+ * @QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS: Use netlink events to send CFR
+ * data. The data shall be encapsulated within
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA along with the vendor sub command
+ * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an asynchronous event.
+ */
+enum qca_wlan_vendor_cfr_data_transport_modes {
+	QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS = 0,
+	QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS = 1,
+};
+
+/**
  * enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by
  * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor
  * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
@@ -8313,6 +10260,27 @@
  * MAC for CFR capture. This is a bitmask in which each bit represents the
  * corresponding Data frame subtype value per IEEE Std 802.11-2016,
  * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE: Optional (u8)
+ * Userspace can use this attribute to specify the driver about which transport
+ * mode shall be used by the driver to send CFR data to userspace. Uses values
+ * from enum qca_wlan_vendor_cfr_data_transport_modes. When this attribute is
+ * not present, the driver shall use the default transport mechanism which is
+ * QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID: Optional (u32)
+ * Userspace can use this attribute to specify the nl port id of the application
+ * which receives the CFR data and processes it further so that the drivers can
+ * unicast the netlink events to a specific application. Optionally included
+ * when QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE is set to
+ * QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS, not required otherwise. The drivers
+ * shall multicast the netlink events when this attribute is not included.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA: Required (NLA_BINARY).
+ * This attribute will be used by the driver to encapsulate and send CFR data
+ * to userspace along with QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an
+ * asynchronous event when the driver is configured to send CFR data using
+ * netlink events with %QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS.
  */
 enum qca_wlan_vendor_peer_cfr_capture_attr {
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0,
@@ -8341,6 +10309,9 @@
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE = 26,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID = 27,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA = 28,
 
 	/* Keep last */
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST,
@@ -8562,7 +10533,6 @@
  *		has priority over BT_A2DP and ZB_HIGH.
  *	3: BT_A2DP has priority over ZB_HIGH.
  */
-
 enum qca_vendor_attr_coex_config_three_way {
 	QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_INVALID = 0,
 	QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE = 1,
@@ -9027,20 +10997,48 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE: Required
  * Nested attribute containing multiple ranges with following attributes:
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START,
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, and
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START: Required (u32)
  * Starting center frequency in MHz.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END: Required (u32)
  * Ending center frequency in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM:
+ * s32 attribute, optional. It is a per frequency range attribute.
+ * The maximum TX power limit from user space is to be applied on an
+ * unrestricted interface for corresponding frequency range. It is also
+ * possible that the actual TX power may be even lower than this cap due to
+ * other considerations such as regulatory compliance, SAR, etc. In absence of
+ * this attribute the driver shall follow current behavior which means
+ * interface (SAP/P2P) function can keep operating on an unsafe channel with TX
+ * power derived by the driver based on regulatory/SAR during interface up.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK:
+ * u32 attribute, optional. Indicates all the interface types which are
+ * restricted for all frequency ranges provided in
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ * This attribute encapsulates bitmasks of interface types defined in
+ * enum nl80211_iftype. If an interface is marked as restricted the driver must
+ * move to a safe channel and if no safe channel is available the driver shall
+ * terminate that interface functionality. In absence of this attribute,
+ * interface (SAP/P2P) can still continue operating on an unsafe channel with
+ * TX power limit derived from either
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM or based on
+ * regulatory/SAE limits if %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM
+ * is not provided.
  */
 enum qca_wlan_vendor_attr_avoid_frequency_ext {
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE = 1,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START = 2,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END = 3,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM = 4,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK = 5,
 
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_MAX =
@@ -9072,14 +11070,21 @@
  * These values are used by attribute %QCA_VENDOR_ATTR_BTC_CHAIN_MODE of
  * %QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE.
  *
- * @QCA_BTC_CHAIN_SHARED: chains of BT and WLAN 2.4G are shared.
- * @QCA_BTC_CHAIN_SEPARATED: chains of BT and WLAN 2.4G are separated.
+ * @QCA_BTC_CHAIN_SHARED: chains of BT and WLAN 2.4 GHz are shared.
+ * @QCA_BTC_CHAIN_SEPARATED_HYBRID: chains of BT and WLAN 2.4 GHz are
+ * separated, hybrid mode.
+ * @QCA_BTC_CHAIN_SEPARATED_FDD: chains of BT and WLAN 2.4 GHz are
+ * separated, fixed FDD mode.
  */
 enum qca_btc_chain_mode {
 	QCA_BTC_CHAIN_SHARED = 0,
-	QCA_BTC_CHAIN_SEPARATED = 1,
+	QCA_BTC_CHAIN_SEPARATED_HYBRID = 1,
+	QCA_BTC_CHAIN_SEPARATED_FDD = 2,
 };
 
+/* deprecated legacy name */
+#define QCA_BTC_CHAIN_SEPARATED QCA_BTC_CHAIN_SEPARATED_HYBRID
+
 /**
  * enum qca_vendor_attr_btc_chain_mode - Specifies attributes for BT coex
  * chain mode.
@@ -9366,7 +11371,68 @@
  * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT: u32, used in STA mode
  * only. This represents number of Beacon frames received from this station with
  * the packet number less than or equal to the last received packet number when
- * beacon protection is enabled. 
+ * beacon protection is enabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE: u32, used in
+ * STA mode only. The driver uses this attribute to populate the connection
+ * failure reason codes and the values are defined in
+ * enum qca_sta_connect_fail_reason_codes. Userspace applications can send
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command after receiving
+ * a connection failure indication from the driver. The driver shall not
+ * include this attribute in response to the
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no connection
+ * failure observed in the last attempted connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE: u32, latest TX rate (Kbps)
+ * used by the station in its last TX frame while communicating to the AP in the
+ * connected state. When queried in the disconnected state, this represents the
+ * rate used by the STA in the last TX frame to the AP when it was connected.
+ * This attribute is used for STA mode only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX: u32, used in STA mode only.
+ * This represents the rate index used by the STA for the last TX frame to the
+ * AP. When queried in the disconnected state, this gives the last RIX used by
+ * the STA in the last TX frame to the AP when it was connected.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT: u32, used in STA
+ * mode only. This represents the number of times the STA TSF goes out of sync
+ * from the AP after the connection. If queried in the disconnected state, this
+ * gives the count of TSF out of sync for the last connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. This can be queried either in connected state or
+ * disconnected state. Each bit of this attribute represents the different
+ * roam trigger reason code which are defined in enum qca_vendor_roam_triggers.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON: u32, used in STA mode
+ * only. This represents the roam fail reason for the last failed roaming
+ * attempt by the firmware. Different roam failure reason codes are specified
+ * in enum qca_vendor_roam_fail_reasons. This can be queried either in
+ * connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be
+ * queried either in connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY: u32, used in STA mode only.
+ * This represents the average congestion duration of uplink frames in MAC
+ * queue in unit of ms. This can be queried either in connected state or
+ * disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS: Array of u32 nested
+ * values, used in AP mode. This represents the MPDU packet count per MCS
+ * rate value of TX packets. Every index of this nested attribute corresponds
+ * to MCS index, e.g., Index 0 represents MCS0 TX rate. This can be
+ * queried in connected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_RX_PACKETS: Array of u32 nested
+ * values, used in AP mode. This represents the MPDU packet count per MCS
+ * rate value of RX packets. Every index of this nested attribute corresponds
+ * to MCS index, e.g., Index 0 represents MCS0 RX rate. This can be
+ * queried in connected state.
  */
 enum qca_wlan_vendor_attr_get_sta_info {
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0,
@@ -9412,6 +11478,16 @@
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT = 40,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE = 44,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX = 45,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT = 46,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY = 50,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS = 51,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_RX_PACKETS = 52,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST,
@@ -9842,4 +11918,2364 @@
 	QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_wlan_vendor_attr_mbssid_tx_vdev_status - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL:
+ * u8 attribute. Notify the TX VDEV status. Possible values 0, 1
+ * belonging to MBSSID/EMA_AP configuration. 0 means Non-Tx VDEV,
+ * 1 means Tx VDEV. Mandatory attribute for all MBSSID VDEV status events.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT:
+ * u8 attribute, required. 1 means Tx VDEV up event. 0 means Tx VDEV down event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID:
+ * u8 attribute, required. Indicates group id of Tx VDEV.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * group information. The attributes defined in enum
+ * qca_wlan_vendor_attr_mbssid_tx_vdev_group_info
+ * are nested in this attribute.
+ */
+enum qca_wlan_vendor_attr_mbssid_tx_vdev_status {
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT = 2,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID = 3,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_MAX =
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX:
+ * u32 attribute, required. Contains interface index.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS:
+ * u8 attribute, required. 0 - means vdev is in down state.
+ * 1 - means vdev is in up state.
+ */
+enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info {
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS = 2,
+
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO - 1,
+};
+
+/**
+ * enum qca_wlan_concurrent_sta_policy_config - Concurrent STA policies
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY: Preference to the primary
+ * STA interface has to be given while selecting the connection policies
+ * (e.g., BSSID, band, TX/RX chains, etc.) for the subsequent STA interface.
+ * An interface is set as primary through the attribute
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY. This policy is not
+ * applicable if the primary interface has not been set earlier.
+ *
+ * The intention is not to downgrade the primary STA performance, such as:
+ * - Do not reduce the number of TX/RX chains of primary connection.
+ * - Do not optimize DBS vs. MCC/SCC, if DBS ends up reducing the number of
+ *   chains.
+ * - If using MCC, should set the MCC duty cycle of the primary connection to
+ *   be higher than the secondary connection.
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED: The connection policies for the
+ * subsequent STA connection shall be chosen to balance with the existing
+ * concurrent STA's performance.
+ * Such as
+ * - Can choose MCC or DBS mode depending on the MCC efficiency and hardware
+ *   capability.
+ * - If using MCC, set the MCC duty cycle of the primary connection to be equal
+ *   to the secondary.
+ * - Prefer BSSID candidates which will help provide the best "overall"
+ *   performance for all the STA connections.
+ */
+enum qca_wlan_concurrent_sta_policy_config {
+	QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY = 0,
+	QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED = 1,
+};
+
+/**
+ * enum qca_wlan_concurrent_ap_policy_config - Concurrent AP policies
+ *
+ * @QCA_WLAN_CONCURRENT_AP_POLICY_UNSPECIFIED: No specific policy for this AP
+ * interface.
+ *
+ * @QCA_WLAN_CONCURRENT_AP_POLICY_GAMING_AUDIO: Select interface concurrencies
+ * to meet gaming audio latency requirements.
+ *
+ * @QCA_WLAN_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING: Select interface
+ * concurrencies to meet lossless audio streaming requirements.
+ */
+enum qca_wlan_concurrent_ap_policy_config {
+	QCA_WLAN_CONCURRENT_AP_POLICY_UNSPECIFIED = 0,
+	QCA_WLAN_CONCURRENT_AP_POLICY_GAMING_AUDIO = 1,
+	QCA_WLAN_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_concurrent_policy - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_POLICY vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_STA_CONFIG:
+ * u8 attribute. Configures the concurrent STA policy configuration.
+ * Possible values are defined in enum qca_wlan_concurrent_sta_policy_config.
+
+ * @QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_AP_CONFIG:
+ * u8 attribute. Configures the concurrent AP policy configuration.
+ * Possible values are defined in enum qca_wlan_concurrent_ap_policy_config.
+ */
+enum qca_wlan_vendor_attr_concurrent_policy {
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_STA_CONFIG = 1,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_AP_CONFIG = 2,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_MAX =
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_AFTER_LAST - 1,
+
+};
+
+/* Compatibility defines for previously used enum
+ * qca_wlan_vendor_attr_concurrent_policy names. These values should not be used
+ * in any new implementation.
+ */
+#define QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG \
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_STA_CONFIG
+#define QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_MAX \
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_POLICY_MAX
+#define qca_wlan_vendor_attr_concurrent_sta_policy \
+	qca_wlan_vendor_attr_concurrent_policy
+
+/**
+ * enum qca_sta_connect_fail_reason_codes - Defines values carried
+ * by QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE vendor
+ * attribute.
+ * @QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND: No Probe Response frame received
+ *	for unicast Probe Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL: STA failed to send auth request.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED: AP didn't send ACK for
+ *	auth request.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED: Auth response is not
+ *	received from AP.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL: STA failed to send
+ *	Association Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED: AP didn't send ACK for
+ *	Association Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED: Association Response
+ *	frame is not received from AP.
+ */
+enum qca_sta_connect_fail_reason_codes {
+	QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND = 1,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL = 2,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED = 3,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED = 4,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL = 5,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED = 6,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED = 7,
+};
+
+/**
+ * enum qca_wlan_vendor_usable_channels_filter - Bitmask of different
+ * filters defined in this enum are used in attribute
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK.
+ *
+ * @QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX: When this bit is set, the driver
+ * shall filter the channels which are not usable because of coexistence with
+ * cellular radio.
+ * @QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY: When this bit is set, the driver
+ * shall filter the channels which are not usable because of existing active
+ * interfaces in the driver and will result in Multi Channel Concurrency, etc.
+ *
+ */
+enum qca_wlan_vendor_usable_channels_filter {
+	QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX = 0,
+	QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_chan_info - Attributes used inside
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ:
+ * u32 attribute, required. Indicates the center frequency of the primary
+ * channel in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ:
+ * u32 attribute. Indicates the center frequency of the primary segment of the
+ * channel in MHz. This attribute is required when reporting 40 MHz, 80 MHz,
+ * 160 MHz, and 320 MHz channels.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ:
+ * u32 attribute. Indicates the center frequency of the secondary segment of
+ * 80+80 channel in MHz. This attribute is required only when
+ * QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH is set to NL80211_CHAN_WIDTH_80P80.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH:
+ * u32 attribute, required. Indicates the bandwidth of the channel, possible
+ * values are defined in enum nl80211_chan_width.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK:
+ * u32 attribute, required. Indicates all the interface types for which this
+ * channel is usable. This attribute encapsulates bitmasks of interface types
+ * defined in enum nl80211_iftype.
+ *
+ */
+enum qca_wlan_vendor_attr_chan_info {
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ = 1,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH = 4,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_usable_channels - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK:
+ * u32 attribute. Indicates the bands from which the channels should be reported
+ * in response. This attribute encapsulates bit masks of bands defined in enum
+ * nl80211_band. Optional attribute, if not present in the request the driver
+ * shall return channels from all supported bands.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK:
+ * u32 attribute. Indicates all the interface types for which the usable
+ * channels information is requested. This attribute encapsulates bitmasks of
+ * interface types defined in enum nl80211_iftype. Optional attribute, if not
+ * present in the request the driver shall send information of all supported
+ * interface modes.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK:
+ * u32 attribute. This attribute carries information of all filters that shall
+ * be applied while populating usable channels information by the driver. This
+ * attribute carries bit masks of different filters defined in enum
+ * qca_wlan_vendor_usable_channels_filter. Optional attribute, if not present
+ * in the request the driver shall send information of channels without applying
+ * any of the filters that can be configured through this attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * usability information of each channel. The attributes defined in enum
+ * qca_wlan_vendor_attr_chan_info are used inside this attribute.
+ */
+enum qca_wlan_vendor_attr_usable_channels {
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK = 1,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK = 2,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK = 3,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX =
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_radar_history: Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY to get DFS radar history.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES: Nested attribute to carry
+ *	the list of radar history entries.
+ *	Each entry contains freq, timestamp, and radar signal detect flag.
+ *	The driver shall add an entry when CAC has finished, or radar signal
+ *	has been detected post AP beaconing. The driver shall maintain at least
+ *	8 entries in order to save CAC result for a 160 MHz channel.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ: u32 attribute.
+ *	Channel frequency in MHz.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP: u64 nanoseconds.
+ *	CLOCK_BOOTTIME timestamp when this entry is updated due to CAC
+ *	or radar detection.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED: NLA_FLAG attribute.
+ *	This flag indicates radar signal has been detected.
+ */
+enum qca_wlan_vendor_attr_radar_history {
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_INVALID = 0,
+
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES = 1,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP = 3,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX =
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_mcc_quota_type: MCC channel time quota type
+ *
+ * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR: In the event, it indicates that the
+ *	target exited MCC state and cleared the quota information. In the
+ *	command it clears MCC quota setting and restores adaptive scheduling.
+ * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED: Channel time quota is fixed and
+ *      will not be changed.
+ * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC: Channel time quota is dynamic
+ *      and the target may change the quota based on the data activity.
+ */
+enum qca_wlan_vendor_mcc_quota_type {
+	QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR = 0,
+	QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED = 1,
+	QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mcc_quota: Used by the vendor event
+ * QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA to indicate MCC channel
+ * quota information or as a command to set the required MCC quota for an
+ * interface.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE: u32 attribute.
+ * The type is defined in enum qca_wlan_vendor_mcc_quota_type.
+ * In a command this specifies the MCC quota type to be set for the interface.
+ * In an event this provides the current quota type in force.
+ * This is required in a command and an event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES: Nested attribute to carry
+ * the list of channel quota entries.
+ * In an event each entry contains the frequency and respective time quota for
+ * all the MCC interfaces.
+ * In a command it specifies the interface index and respective time quota.
+ * In a command only one entry (ifindex, quota pair) may be specified.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ: u32 attribute.
+ * Channel frequency in MHz. This is present only in an event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE: u32 attribute.
+ * Channel time quota expressed as percentage.
+ * This is present in an event and a command.
+ * In an command, the user shall specify the quota to be allocated for the
+ * interface represented by %QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX.
+ * In an event this provides the existing quota for the channel.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX: u32 attribute.
+ * Specifies the interface index (netdev) for which the corresponding
+ * configurations are applied. This is required in a command only. Only one
+ * interface index may be specified. If not specified, the configuration is
+ * rejected.
+ */
+enum qca_wlan_vendor_attr_mcc_quota {
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE = 1,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES = 2,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE = 4,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX =
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_supported_radio_cfg - Attributes for
+ * radio configurations present in each radio combination.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND: u32 attribute indicates
+ * the band info in the radio configuration. Uses the enum qca_set_band values.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA: u8 attribute indicates
+ * the number of antennas info in the radio configuration.
+ */
+enum qca_wlan_vendor_attr_supported_radio_cfg {
+	QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND = 1,
+	QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA = 2,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_LAST,
+	QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_MAX =
+	QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_radio_combination - Attributes for
+ * radio combinations supported by the device.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_CFGS: Nested attribute
+ * provides the radio configurations present in the radio combination.
+ * Uses the enum qca_wlan_vendor_attr_supported_radio_cfg attributes.
+ * This attribute provides the values for radio combination matrix.
+ * For standalone config, the number of config values is one and the config
+ * carries the band and antenna information for standalone configuration. For
+ * Dual Band Simultaneous (DBS)/Single Band Simultaneous (SBS) mode
+ * configuration the number of config values is two and the config carries the
+ * band and antenna information for each simultaneous radio.
+ */
+enum qca_wlan_vendor_attr_radio_combination {
+	QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_CFGS = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_LAST,
+	QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_MAX =
+	QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_radio_combination_matrix - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_GET_RADIO_COMBINATION_MATRIX
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_SUPPORTED_CFGS: Nested attribute
+ * provides the radio combinations supported by the device.
+ * Uses the enum qca_wlan_vendor_attr_radio_combination attributes.
+ * For example, in the radio combination matrix for a device which has two
+ * radios, where one radio is capable of 2.4 GHz 2X2 only and another radio is
+ * capable of either 5 GHz or 6 GHz 2X2, the possible number of radio
+ * combinations is 5 and the radio combinations are
+ * {{{2.4 GHz 2X2}}, //Standalone 2.4 GHz
+ * {{5 GHz 2X2}}, //Standalone 5 GHz
+ * {{6 GHz 2X2}}, //Standalone 6 GHz
+ * {{2.4 GHz 2X2}, {5 GHz 2X2}}, //2.4 GHz + 5 GHz DBS
+ * {{2.4 GHz 2X2}, {6 GHz 2X2}}} //2.4 GHz + 6 GHz DBS
+ * The band and antenna info together as nested data provides one radio config.
+ * Standalone configuration has one config with band and antenna nested data.
+ * Dual Band Simultaneous (DBS)/Single Band Simultaneous (SBS) configuration
+ * have two nested band and antenna info data.
+ */
+enum qca_wlan_vendor_attr_radio_combination_matrix {
+	QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_SUPPORTED_CFGS = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_LAST,
+	QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_MAX =
+	QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mdns_offload - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE: Required (flag)
+ * Enable mDNS offload. This attribute is mandatory to enable
+ * mDNS offload feature. If this attribute is not present, mDNS offload
+ * is disabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE: Nested attribute containing
+ * one or more %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY attributes. This
+ * attribute is mandatory when enabling the feature, and not required when
+ * disabling the feature.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY: Nested attribute containing
+ * the following attributes:
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN: Required string attribute.
+ * It consists of a hostname and ".local" as the domain name. The character
+ * set is limited to UTF-8 encoding. The maximum allowed size is 63 bytes.
+ * It is used to compare the domain in the "QU" query. Only 1 FQDN is
+ * supported per vdev.
+ * For example: myphone.local
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT: Required
+ * u16 attribute. It specifies the total number of resource records present
+ * in the answer section of the answer payload. This attribute is needed by the
+ * firmware to populate the mDNS response frame for mDNS queries without having
+ * to parse the answer payload.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD: Required binary blob
+ * attribute sent by the mdnsResponder from userspace. It contains resource
+ * records of various types (e.g., A, AAAA, PTR, TXT) and service list. This
+ * payload is passed down to the firmware and is transmitted in response to
+ * mDNS queries.
+ * The maximum supported size of the answer payload is 512 bytes.
+ */
+enum qca_wlan_vendor_attr_mdns_offload {
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE = 1,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE = 2,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY = 3,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN = 4,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT = 5,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD = 6,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_MAX =
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_vendor_monitor_data_frame_type - Represent the various
+ * Data frame types to be sent over the monitor interface.
+ */
+enum qca_wlan_vendor_monitor_data_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17),
+};
+
+/**
+ * qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various
+ * Management frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the Management Frames.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the Management frames
+ * except the Beacon frame.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected
+ * BSSID Beacon frames. Valid only in the connected state.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents
+ * the Beacon frames obtained during the scan (off channel and connected
+ * channel), when in connected state.
+ */
+enum qca_wlan_vendor_monitor_mgmt_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_MGMT_NO_BEACON = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3),
+};
+
+/**
+ * qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various
+ * Control frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the Control frames
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger frame
+ */
+enum qca_wlan_vendor_monitor_ctrl_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_set_monitor_mode - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the
+ * monitor mode.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL: u32
+ * attribute.
+ * Represents the interval in milliseconds only for the connected Beacon frames,
+ * expecting the connected BSS's Beacon frames to be sent on the monitor
+ * interface at this specific interval.
+ */
+enum qca_wlan_vendor_attr_set_monitor_mode {
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX =
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_roam_scan_state - Roam scan state flags.
+ * Bits will be set to 1 if the corresponding state is enabled.
+ *
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start.
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end.
+ */
+enum qca_wlan_vendor_roam_scan_state {
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_roam_event_type - Roam event type flags.
+ * Bits will be set to 1 if the corresponding event is notified.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event
+ * carries the trigger reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries
+ * the BSSID, RSSI, frequency info of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event
+ * carries the roam fail reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the
+ * BSSID, RSSI, frequency info of the AP to which the roam was attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam
+ * event carries the roam invoke fail reason. When set, it is expected that
+ * the roam event carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event
+ * carries the roam scan state. When set, it is expected that the roam event
+ * carries the respective scan state via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding
+ * frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST.
+ */
+enum qca_wlan_vendor_roam_event_type {
+	QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1),
+	QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2),
+	QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info.
+ * Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address
+ * representing the BSSID of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value
+ * in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is
+ * attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, frequency in MHz
+ * on which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam fail reason for the last failed
+ * roaming attempt by the firmware for the specific BSSID. Different roam
+ * failure reason codes are specified in enum qca_vendor_roam_fail_reasons.
+ */
+enum qca_wlan_vendor_attr_roam_events_candidate_info {
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the
+ * roam events to the driver or notify these events from the driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the
+ * driver/firmware to enable/disable the notification of roam events. It's a
+ * mandatory attribute and used only in the request from the userspace to the
+ * host driver. 1-Enable, 0-Disable.
+ * If the roaming is totally offloaded to the firmware, this request when
+ * enabled shall mandate the firmware to notify all the relevant roam events
+ * represented by the below attributes. If the host is in the suspend mode,
+ * the behavior of the firmware to notify these events is guided by
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get
+ * these events in the suspend state, the firmware is expected to wake up the
+ * host before the respective events are notified. Please note that such a
+ * request to get the events in the suspend state will have a definite power
+ * implication.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents
+ * that the roam events need to be notified in the suspend state too. By
+ * default, these roam events are notified in the resume state. With this flag,
+ * the roam events are notified in both resume and suspend states.
+ * This attribute is used in the request from the userspace to the host driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only.
+ * Represents the different roam event types, signified by the enum
+ * qca_wlan_vendor_roam_event_type.
+ * Each bit of this attribute represents the different roam even types reported
+ * through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. Each bit of this attribute represents the
+ * different roam trigger reason code which are defined in enum
+ * qca_vendor_roam_triggers.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info
+ * for which the roam is attempted. Each entry is a nested attribute defined
+ * by enum qca_wlan_vendor_attr_roam_events_candidate_info.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents
+ * the scan state on which the roam events need to be notified. The values for
+ * this attribute are referred from enum qca_wlan_vendor_roam_scan_state.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of
+ * u32 values. List of frequencies in MHz considered for a roam scan.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ */
+enum qca_wlan_vendor_attr_roam_events {
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST -1,
+};
+
+/**
+ * enum qca_wlan_ratemask_params_type - Rate mask config type
+ *
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM: CCK/OFDM rate mask config
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HT: HT rate mask config
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT: VHT rate mask config
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HE: HE rate mask config
+ */
+enum qca_wlan_ratemask_params_type {
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM = 0,
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_HT = 1,
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT = 2,
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_HE = 3,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ratemask_params - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG.
+ * This is used to set the rate mask value to be used in rate selection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST:
+ * Array of nested containing attributes
+ * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE and
+ * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE: u8, represents
+ * the different PHY types to which the rate mask config is to be applied.
+ * The values for this attribute are referred from enum
+ * qca_wlan_vendor_ratemask_params_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP: binary, rate mask bitmap.
+ * A bit value of 1 represents rate is enabled and a value of 0
+ * represents rate is disabled.
+ * For HE targets, 12 bits correspond to one NSS setting.
+ * b0-13  => NSS1, MCS 0-13
+ * b14-27 => NSS2, MCS 0-13 and so on for other NSS.
+ * For VHT targets, 10 bits correspond to one NSS setting.
+ * b0-9   => NSS1, MCS 0-9
+ * b10-19 => NSS2, MCS 0-9 and so on for other NSS.
+ * For HT targets, 8 bits correspond to one NSS setting.
+ * b0-7  => NSS1, MCS 0-7
+ * b8-15 => NSS2, MCS 0-7 and so on for other NSS.
+ * For OFDM/CCK targets, 8 bits correspond to one NSS setting.
+ */
+enum qca_wlan_vendor_attr_ratemask_params {
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST = 1,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE = 2,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP = 3,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_MAX =
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_audio_data_path - Defines the data path to be used for audio
+ * traffic.
+ *
+ * @QCA_WLAN_AUDIO_DATA_PATH_VIA_HOST_PROCESSOR:
+ * Send audio traffic through the host processor.
+ * @QCA_WLAN_AUDIO_DATA_PATH_VIA_LOW_POWER_DSP:
+ * Send audio traffic using the low power DSP to/from the encoder.
+ */
+enum qca_wlan_audio_data_path {
+	QCA_WLAN_AUDIO_DATA_PATH_VIA_HOST_PROCESSOR = 0,
+	QCA_WLAN_AUDIO_DATA_PATH_VIA_LOW_POWER_DSP = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_pasn_action - Action to authenticate (and generate keys
+ *	for) or drop existing PASN security association for the listed the
+ *	peers. Used by QCA_WLAN_VENDOR_ATTR_PASN_ACTION and sent from the driver
+ *	to userspace.
+ *
+ * @QCA_WLAN_VENDOR_PASN_ACTION_AUTH: Initiate PASN handshake with the peer
+ *	devices indicated with %QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR.
+ * @QCA_WLAN_VENDOR_PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT: Indication from
+ *	the driver to userspace to inform that the existing PASN keys of the
+ *	peer devices specified with %QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR are
+ *	not valid anymore.
+ */
+enum qca_wlan_vendor_pasn_action {
+	QCA_WLAN_VENDOR_PASN_ACTION_AUTH,
+	QCA_WLAN_VENDOR_PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_pasn_peer: Defines the nested attributes used in
+ *	QCA_WLAN_VENDOR_ATTR_PASN_PEERS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR: This attribute is optional in the
+ *	event from the driver to userspace and represents the local MAC address
+ *	to be used for PASN handshake. When this attribute is present, userspace
+ *	shall use the source address specified in this attribute by the driver
+ *	for PASN handshake with peer device.
+ *	This attribute is required in a command response from userspace to the
+ *	driver and represents the MAC address that was used in PASN handshake
+ *	with the peer device.
+ * @QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR: Indicates the MAC address of the
+ *	peer device to which PASN handshake is requested in an event from the
+ *	driver to userspace when QCA_WLAN_VENDOR_ATTR_PASN_ACTION is set to
+ *	QCA_WLAN_VENDOR_PASN_ACTION_AUTH.
+ *	Indicates the MAC address of the peer device for which the keys are to
+ *	be invalidated in an event from the driver to userspace when
+ *	QCA_WLAN_VENDOR_ATTR_PASN_ACTION is set to
+ *	QCA_WLAN_VENDOR_PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT.
+ *	Indicates the MAC address of the peer device for which the status is
+ *	being sent in a status report from userspace to the driver.
+ * @QCA_WLAN_VENDOR_ATTR_PASN_PEER_LTF_KEYSEED_REQUIRED: NLA_FLAG attribute used
+ *	in the event from the driver to userspace. When set, userspace is
+ *	required to derive LTF key seed from KDK and set it to the driver.
+ * @QCA_WLAN_VENDOR_ATTR_PASN_PEER_STATUS_SUCCESS: NLA_FLAG attribute. This
+ *	attribute is used in the command response from userspace to the driver.
+ *	If present, it indicates the successful PASN handshake with the peer. If
+ *	this flag is not present, it indicates that the PASN handshake with the
+ *	peer device failed.
+ */
+enum qca_wlan_vendor_attr_pasn_peer {
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_LTF_KEYSEED_REQUIRED = 3,
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_STATUS_SUCCESS = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAX =
+	QCA_WLAN_VENDOR_ATTR_PASN_PEER_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_pasn: Defines the attributes used in the
+ *	QCA_NL80211_VENDOR_SUBCMD_PASN command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PASN_ACTION: u32 attribute, possible values are
+ *	defined in enum qca_wlan_vendor_pasn_action and used only in an event
+ *	from the driver to userspace.
+ * @QCA_WLAN_VENDOR_ATTR_PASN_PEERS: Nested attribute, used to pass PASN peer
+ *	details for each peer and used in both an event and a command response.
+ *	The nested attributes used inside QCA_WLAN_VENDOR_ATTR_PASN_PEERS are
+ *	defined in enum qca_wlan_vendor_attr_pasn_peer.
+ */
+enum qca_wlan_vendor_attr_pasn {
+	QCA_WLAN_VENDOR_ATTR_PASN_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_PASN_ACTION = 1,
+	QCA_WLAN_VENDOR_ATTR_PASN_PEERS = 2,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_PASN_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_PASN_MAX =
+	QCA_WLAN_VENDOR_ATTR_PASN_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_secure_ranging_ctx_action - Used to add or delete
+ *	the ranging security context derived from PASN for each peer. Used in
+ *	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION.
+ *
+ * @QCA_WLAN_VENDOR_SECURE_RANGING_CTX_ACTION_ADD: Add the secure ranging
+ *	context for the peer.
+ * @QCA_WLAN_VENDOR_SECURE_RANGING_CTX_ACTION_DELETE: Delete the secure ranging
+ *	context for the peer.
+ */
+enum qca_wlan_vendor_secure_ranging_ctx_action {
+	QCA_WLAN_VENDOR_SECURE_RANGING_CTX_ACTION_ADD,
+	QCA_WLAN_VENDOR_SECURE_RANGING_CTX_ACTION_DELETE,
+};
+
+/**
+ * enum qca_wlan_vendor_sha_type - SHA types. Used to configure the SHA type
+ *	used for deriving PASN keys to the driver. Used in
+ *	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE
+ * @QCA_WLAN_VENDOR_SHA_256: SHA-256
+ * @QCA_WLAN_VENDOR_SHA_384: SHA-384
+ */
+enum qca_wlan_vendor_sha_type {
+	QCA_WLAN_VENDOR_SHA_256,
+	QCA_WLAN_VENDOR_SHA_384,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_secure_ranging_ctx: Defines the attributes used
+ *	to set security context for the PASN peer from userspace to the driver.
+ *	Used with QCA_NL80211_VENDOR_SUBCMD_SECURE_RANGING_CONTEXT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION: u32 attribute, possible
+ *	values are defined in enum qca_wlan_vendor_secure_ranging_ctx_action
+ * @QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR: The local MAC address that
+ *	was used during the PASN handshake.
+ * @QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR: The MAC address of
+ *	the peer device for which secure ranging context is being configured.
+ * @QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE: u32 attribute, defines the
+ *	hash algorithm to be used, possible values are defined in enum
+ *	qca_wlan_vendor_sha_type.
+ * @QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK: Variable length attribute, holds
+ *	the temporal key generated from the PASN handshake. The length of this
+ *	attribute is dependent on the value of
+ *	%QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER.
+ * @QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER: cipher suite to use with the
+ *	TK, u32, as defined in IEEE Std 802.11-2020, 9.4.2.24.2 (Cipher suites)
+ *	(e.g., 0x000FAC04).
+ * @QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED: Variable length
+ *	attribute, holds the LTF keyseed derived from KDK of PASN handshake.
+ *	The length of this attribute is dependent on the value of
+ *	%QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE.
+
+ */
+enum qca_wlan_vendor_attr_secure_ranging_ctx {
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION = 1,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR = 3,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE = 4,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK = 5,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER = 6,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED = 7,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_MAX =
+	QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_coap_offload_filter - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_FILTER
+ * nested attribute. The packets that match a filter will be replied with
+ * attributes configured in %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV4:
+ * u32 attribute. Destination IPv4 address in network byte order, the
+ * IPv4 packets with different address will be filtered out.
+ * This attribute is optional.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV4_IS_BC:
+ * Flag attribute. If it's present, indicates that
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV4 is a broadcast
+ * address; while if not, indicates that the address is a unicast/multicast
+ * address.
+ * This attribute is optional.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV6:
+ * NLA_BINARY attribute, length is 16 bytes.
+ * Destination IPv6 address in network byte order, the IPv6 packets
+ * with different destination address will be filtered out.
+ * This attribute is optional.
+ *
+ * At least one of %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV4 and
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV6 must be configured.
+ * Packets on both IPv4 and IPv6 will be processed if both are configured.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_PORT:
+ * u16 attribute. Destination UDP port, the packets with different destination
+ * UDP port will be filtered out.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_MATCH_OFFSET:
+ * u32 attribute. Represents the offset (in UDP payload) of the data
+ * to be matched.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_MATCH_DATA:
+ * NLA_BINARY attribute, the maximum allowed size is 16 bytes.
+ * Binary data that is compared bit-by-bit against the data (specified
+ * by %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_MATCH_OFFSET) in UDP
+ * payload, the packets don't match will be filtered out.
+ * This attribute is mandatory.
+ */
+enum qca_wlan_vendor_attr_coap_offload_filter {
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV4 = 1,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV4_IS_BC = 2,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_IPV6 = 3,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_DEST_PORT = 4,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_MATCH_OFFSET = 5,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_MATCH_DATA = 6,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_MAX =
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_FILTER_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_coap_offload_reply - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_SRC_IPV4:
+ * u32 attribute. Source address (in network byte order) for replying
+ * the matching broadcast/multicast IPv4 packets.
+ * This attribute is optional.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_SRC_IPV6:
+ * NLA_BINARY attribute, length is 16 bytes.
+ * Source address (in network byte order) for replying the matching
+ * multicast IPv6 packets.
+ * This attribute is optional.
+ *
+ * For broadcast/multicast offload reply, one of
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_SRC_IPV4 and
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_SRC_IPV6 or both must be
+ * configured according to version of the IP address(es) configured in
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_FILTER;
+ * while for unicast case, firmware will take the destination IP address
+ * in the received matching packet as the source address for replying.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_FILTER:
+ * Nested attribute. Filter for the received UDP packets, only the matching
+ * packets will be replied and cached.
+ * See enum qca_wlan_vendor_attr_coap_offload_filter for list of supported
+ * attributes.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_MSG:
+ * NLA_BINARY attribute, the maximum allowed size is 1152 bytes.
+ * CoAP message (UDP payload) to be sent upon receiving matching packets.
+ * Firmware is responsible for adding any necessary protocol headers.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_CACHE_EXPTIME:
+ * u32 attribute. Expiration time in milliseconds of the cached CoAP messages.
+ * A cached message will be dropped by firmware if it's expired.
+ * This attribute is optional. A default value of 40000 will be used in the
+ * absence of it.
+ */
+enum qca_wlan_vendor_attr_coap_offload_reply {
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_SRC_IPV4 = 1,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_SRC_IPV6 = 2,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_FILTER = 3,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_MSG = 4,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_CACHE_EXPTIME = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_MAX =
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_coap_offload_tx_ipv4 - Represents parameters for
+ * CoAP message (UDP) transmitting on IPv4.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_SRC_ADDR:
+ * u32 attribute. Source address (in network byte order) for transmitting
+ * packets on IPv4.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_SRC_PORT:
+ * u16 attribute. Source UDP port.
+ * This attribute is optional, a random port is taken if it's not present.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_DEST_ADDR:
+ * u32 attribute. Destination IPv4 address (in network byte order).
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_DEST_IS_BC:
+ * Flag attribute. If it's present, indicates that
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_DEST_ADDR is a broadcast
+ * address; while if not, indicates that the address is unicast/multicast
+ * address.
+ * This attribute is optional.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_DEST_PORT:
+ * u16 attribute. Destination UDP port.
+ * This attribute is mandatory.
+ */
+enum qca_wlan_vendor_attr_coap_offload_tx_ipv4 {
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_SRC_ADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_SRC_PORT = 2,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_DEST_ADDR = 3,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_DEST_IS_BC = 4,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_DEST_PORT = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_MAX =
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV4_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_coap_offload_tx_ipv6 - Represents parameters for
+ * CoAP message (UDP) transmitting on IPv6.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_SRC_ADDR:
+ * NLA_BINARY attribute, length is 16 bytes.
+ * Source address (in network byte order) for transmitting packets on IPv6.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_SRC_PORT:
+ * u16 attribute. Source UDP port.
+ * This attribute is optional, a random port is taken if it's not present.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_DEST_ADDR:
+ * NLA_BINARY attribute, length is 16 bytes.
+ * Destination IPv6 address (in network byte order).
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_DEST_PORT:
+ * u16 attribute. Destination UDP port.
+ * This attribute is mandatory.
+ */
+enum qca_wlan_vendor_attr_coap_offload_tx_ipv6 {
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_SRC_ADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_SRC_PORT = 2,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_DEST_ADDR = 3,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_DEST_PORT = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_MAX =
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_TX_IPV6_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_coap_offload_periodic_tx - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_IPV4:
+ * Nested attribute. The IPv4 source/destination address/port for offload
+ * transmitting. See enum qca_wlan_vendor_attr_coap_offload_tx_ipv4 for the list
+ * of supported attributes.
+ * This attribute is optional.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_IPV6:
+ * Nested attribute. The IPv6 source/destination address/port for offload
+ * transmitting. See enum qca_wlan_vendor_attr_coap_offload_tx_ipv6 for the list
+ * of supported attributes.
+ * This attribute is optional.
+ *
+ * At least one of %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_IPV4 and
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_IPV6 must be configured.
+ * Firmware will transmit the packets on both IPv4 and IPv6 if both are
+ * configured.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_PERIOD:
+ * u32 attribute. Period in milliseconds for the periodic transmitting.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_MSG:
+ * NLA_BINARY attribute, the maximum allowed size is 1152 bytes.
+ * CoAP message (UDP payload) to be periodically transmitted. Firmware
+ * is responsible for adding any necessary protocol headers.
+ * This attribute is mandatory.
+ */
+enum qca_wlan_vendor_attr_coap_offload_periodic_tx {
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_IPV4 = 1,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_IPV6 = 2,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_PERIOD = 3,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_MSG = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_MAX =
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_coap_offload_cache_info - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHES nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_TS:
+ * u64 attribute. Received time (since system booted in microseconds) of
+ * the cached CoAP message.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_SRC_IPV4:
+ * u32 attribute. Source IPv4 address (in network byte order) of the cached
+ * CoAP message.
+ * This attribute is optional.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_SRC_IPV6:
+ * NLA_BINARY attribute, length is 16 bytes.
+ * Source IPv6 address (in network byte order) of the cached CoAP message.
+ * This attribute is optional.
+ *
+ * At most and at least one of
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_SRC_IPV4 and
+ * %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_SRC_IPV6 is given for
+ * an entry.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_MSG:
+ * NLA_BINARY attribute, the maximum allowed size is 1152 bytes.
+ * The cached CoAP message (UDP payload). If the actual message size is
+ * greater than the maximum size, it will be truncated and leaving only
+ * the first 1152 bytes.
+ * This attribute is mandatory.
+ */
+enum qca_wlan_vendor_attr_coap_offload_cache_info {
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_TS = 1,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_SRC_IPV4 = 2,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_SRC_IPV6 = 3,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_MSG = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_coap_offload_action - Actions for
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_COAP_OFFLOAD.
+ *
+ * @QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_ENABLE:
+ * Enable CoAP offload reply.
+ * If it's enabled, firmware will start offload processing on each suspend
+ * and stop on each resume.
+ *
+ * Offload reply on match works as follows:
+ * Reply the packets that match the filter with the given CoAP
+ * message (with necessary protocol headers), increase the CoAP message
+ * ID in the given CoAP message by one for the next use after each successful
+ * transmission, and try to store the information of the received packet,
+ * including the received time, source IP address, and CoAP message (UDP
+ * payload).
+ *
+ * Firmware has a limit to the maximum stored entries, it takes the source IP
+ * address as the key of an entry, and keeps at most one entry for each key.
+ * A packet won't be stored if no entry for the same key is present and the
+ * total number of the existing unexpired entries reaches the maximum value.
+ *
+ * If any configured item is changed, user space should disable offload reply
+ * first and then issue a new enable request.
+ *
+ * @QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_DISABLE:
+ * Disable CoAP offload reply and return information of any cached CoAP
+ * messages.
+ *
+ * @QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_PERIODIC_TX_ENABLE:
+ * Enable CoAP offload periodic transmitting.
+ * If it's enabled, firmware will start offload periodic transmitting on
+ * each suspend and stop on each resume.
+ *
+ * Offload periodic transmitting works as follows:
+ * Send the given CoAP message (with necessary protocol headers) with the given
+ * source/destination IP address/UDP port periodically based on the given
+ * period and increase the CoAP message ID in the given CoAP message by one
+ * for the next use after each successful transmission.
+ *
+ * If any configured item is changed, user space should disable offload
+ * periodic transmitting first and then issue a new enable request.
+ *
+ * @QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_PERIODIC_TX_DISABLE:
+ * Disable CoAP offload periodic transmitting.
+ *
+ * @QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_CACHE_GET:
+ * Get information of the CoAP messages cached during offload reply
+ * processing. The cache is cleared after retrieval.
+ */
+enum qca_wlan_vendor_coap_offload_action {
+	QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_ENABLE = 0,
+	QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_DISABLE = 1,
+	QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_PERIODIC_TX_ENABLE = 2,
+	QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_PERIODIC_TX_DISABLE = 3,
+	QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_CACHE_GET = 4,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_coap_offload - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_COAP_OFFLOAD.
+ * This is used to set parameters for CoAP offload processing, or get
+ * cached CoAP messages from firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_ACTION:
+ * u32 attribute. Action to take in this vendor command.
+ * See enum qca_wlan_vendor_coap_offload_action for supported actions.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REQ_ID:
+ * u32 attribute. Represents the Request ID for the CoAP offload
+ * configuration, which can help to identify the user entity starting
+ * the CoAP offload processing and accordingly stop the respective
+ * ones/get the cached CoAP messages with the matching ID.
+ * This attribute is mandatory.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY:
+ * Nested attribute. Parameters for offload reply.
+ * See enum qca_wlan_vendor_attr_coap_offload_reply for the list of
+ * supported attributes.
+ * This attribute is mandatory if %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_ACTION
+ * is QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_ENABLE, and is ignored
+ * otherwise.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX:
+ * Nested attribute. Parameters for offload periodic transmitting.
+ * See enum qca_wlan_vendor_attr_coap_offload_periodic_tx for the list of
+ * supported attributes.
+ * This attribute is mandatory if %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_ACTION is
+ * QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_PERIODIC_TX_ENABLE, and is ignored
+ * otherwise.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHES:
+ * Array of nested attributes. Information of the cached CoAP messages,
+ * where each entry is taken from
+ * enum qca_wlan_vendor_attr_coap_offload_cache_info.
+ * This attribute is used for reporting the cached CoAP messages
+ * in reply for command in which %QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_ACTION
+ * is QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_CACHE_GET or
+ * QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_DISABLE. It means there is no
+ * cached item if this attribute is not present.
+ */
+enum qca_wlan_vendor_attr_coap_offload {
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_ACTION = 1,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REQ_ID = 2,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_REPLY = 3,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_PERIODIC_TX = 4,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHES = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_MAX =
+	QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_scs_rule_config - Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_SCS_RULE_CONFIG to configure Stream Classification
+ * Service (SCS) rule.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_RULE_ID: Mandatory u32 attribute.
+ * Represents the unique id of SCS rule to be configured.
+
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_REQUEST_TYPE: Mandatory u8 attribute.
+ * Represents the request type: add, remove, or change.
+ * Values as defined in IEEE Std 802.11-2020, Table 9-246 (SCS Request
+ * Type definitions).
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_OUTPUT_TID: Mandatory u8 attribute
+ * in case of add/change request type.
+ * Represents the output traffic identifier (TID) to be assigned to the flow
+ * matching the rule.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_CLASSIFIER_TYPE: Mandatory u8
+ * attribute in case of add/change request type.
+ * Represents type of classifier parameters present in SCS rule.
+ * Refer IEEE Std 802.11-2020 Table 9-164 (Frame classifier type).
+ * Only classifier types 4 and 10 are supported for SCS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_VERSION: Mandatory u8 attribute
+ * in case of add/change request type when classifier type is TCLAS4.
+ * Represents the IP version (4: IPv4, 6: IPv6) of the rule.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_SRC_IPV4_ADDR: Optional
+ * attribute in case of add/change request type when classifier type is TCLAS4
+ * and version attribute is IPv4.
+ * Represents the source IPv4 address in the rule which is to be compared
+ * against the source IP address in the IPv4 header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DST_IPV4_ADDR: Optional
+ * attribute in case of add/change request type when classifier type is TCLAS4
+ * and version attribute is IPv4.
+ * Represents the destination IPv4 address in the rule which is to be compared
+ * against the destination IP address in the IPv4 header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_SRC_IPV6_ADDR: Optional
+ * attribute in case of add/change request type when classifier type is TCLAS4
+ * and version attribute is IPv6.
+ * Represents the source IPv6 address in the rule which is to be compared
+ * against the source IP address in the IPv6 header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DST_IPV6_ADDR: Optional
+ * attribute in case of add/change request type when classifier type is TCLAS4
+ * and version attribute is IPv6.
+ * Represents the destination IPv6 address in the rule which is to be compared
+ * against the destination IP address in the IPv6 header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_SRC_PORT: Optional u16 attribute
+ * in case of add/change request type when classifier type is TCLAS4.
+ * Represents the source port number in the rule which is to be compared against
+ * the source port number in the protocol header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DST_PORT: Optional u16 attribute
+ * in case of add/change request type when classifier type is TCLAS4.
+ * Represents the destination port number in the rule which is to be compared
+ * against the destination port number in the protocol header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DSCP: Optional u8 attribute
+ * in case of add/change request type when classifier type is TCLAS4.
+ * Represents the DSCP value in the rule which is to be compared against the
+ * DSCP field present in the IP header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_NEXT_HEADER: Optional u8
+ * attribute in case of add/change request type when classifier type is TCLAS4.
+ * Represents the protocol/next header in the rule which is to be compared
+ * against the protocol/next header field present in the IPv4/IPv6 header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_FLOW_LABEL: Optional
+ * attribute of size 3 bytes present in case of add/change request type
+ * when classifier type is TCLAS4 and version is IPv6.
+ * Represents the flow label value in the rule which is to be compared against
+ * the flow label field present in the IPv6 header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_PROTOCOL_INSTANCE: Optional u8
+ * attribute in case of add/change request type when classifier type is TCLAS10.
+ * Represents the protocol instance number in the rule.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_NEXT_HEADER: Optional u8
+ * attribute in case of add/change request type when classifier type is TCLAS10.
+ * Represents the protocol/next header in the rule which is to be compared
+ * against the protocol/next header field present in the IPv4/IPv6 header.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_FILTER_MASK: Optional
+ * attribute of variable length present when request type is add/change and
+ * classifier type is TCLAS10.
+ * Represents the mask to be used for masking the header contents of the header
+ * specified by QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_NEXT_HEADER
+ * attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_FILTER_VALUE: Optional
+ * attribute of variable length present when request type is add/change and
+ * classifier type is TCLAS10.
+ * Represents the value to be compared against after masking the header contents
+ * of the header specified by the
+ * QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_NEXT_HEADER attribute with the
+ * filter mask specified by the
+ * QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_FILTER_MASK attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_SERVICE_CLASS_ID: Optional u16
+ * attribute.
+ * Represents the service class id of the configured SCS rule.
+ */
+enum qca_wlan_vendor_attr_scs_rule_config {
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_RULE_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_REQUEST_TYPE = 2,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_OUTPUT_TID = 3,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_CLASSIFIER_TYPE = 4,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_VERSION = 5,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_SRC_IPV4_ADDR = 6,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DST_IPV4_ADDR = 7,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_SRC_IPV6_ADDR = 8,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DST_IPV6_ADDR = 9,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_SRC_PORT = 10,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DST_PORT = 11,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_DSCP = 12,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_NEXT_HEADER = 13,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS4_FLOW_LABEL = 14,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_PROTOCOL_INSTANCE = 15,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_NEXT_HEADER = 16,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_FILTER_MASK = 17,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_TCLAS10_FILTER_VALUE = 18,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_SERVICE_CLASS_ID = 19,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_MAX =
+	QCA_WLAN_VENDOR_ATTR_SCS_RULE_CONFIG_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mlo_links - Definition of attributes used inside
+ * nested attribute QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MLO_LINKS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID: u8 attribute, link ID of this MLO link.
+ * @QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR: Own MAC address of this MLO link.
+ * @QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID: AP link MAC address of this MLO link.
+ */
+enum qca_wlan_vendor_attr_mlo_links {
+	QCA_WLAN_VENDOR_ATTR_MLO_LINK_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID = 3,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_MLO_LINK_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAX =
+	QCA_WLAN_VENDOR_ATTR_MLO_LINK_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_sar_version - This describes the current SAR version
+ * used in the firmware.
+ *
+ * @QCA_WLAN_VENDOR_SAR_VERSION_1: The firmware supports legacy SAR.
+ * In legacy SAR, the firmware supports 5 static and 1 user defined SAR limits.
+ *
+ * @QCA_WLAN_VENDOR_SAR_VERSION_2: The firmware supports SAR version 2,
+ * i.e., SAR Non DBS mode. In SAR version 2, the firmware has 6 SAR tables for
+ * each CTL group. So user can select up to 6 SAR indexes from the current CTL
+ * groups.
+ *
+ * @QCA_WLAN_VENDOR_SAR_VERSION_3: The firmware supports SAR version 3,
+ * i.e., SAR DBS mode. In SAR version 3, the firmware has 6 SAR tables for each
+ * CTL group but user can choose up to 3 SAR set index only, as the top half
+ * of the SAR index (0 to 2) is used for non DBS purpose and the bottom half of
+ * the SAR index (3 to 5) is used for DBS mode.
+ */
+enum qca_wlan_vendor_sar_version {
+	QCA_WLAN_VENDOR_SAR_VERSION_INVALID = 0,
+	QCA_WLAN_VENDOR_SAR_VERSION_1 = 1,
+	QCA_WLAN_VENDOR_SAR_VERSION_2 = 2,
+	QCA_WLAN_VENDOR_SAR_VERSION_3 = 3,
+};
+
+/**
+ * enum qca_wlan_vendor_sar_ctl_group_state - This describes whether
+ * CTL grouping is enabled or disabled in the firmware.
+ *
+ * @QCA_WLAN_VENDOR_SAR_CTL_GROUP_STATE_ENABLED: CTL grouping
+ * is enabled in firmware.
+ *
+ * @QCA_WLAN_VENDOR_SAR_CTL_GROUP_STATE_DISABLED: CTL grouping
+ * is disabled in firmware.
+ *
+ */
+enum qca_wlan_vendor_sar_ctl_group_state {
+	QCA_WLAN_VENDOR_SAR_CTL_GROUP_STATE_INVALID = 0,
+	QCA_WLAN_VENDOR_SAR_CTL_GROUP_STATE_ENABLED = 1,
+	QCA_WLAN_VENDOR_SAR_CTL_GROUP_STATE_DISABLED = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_sar_capability - Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY to get SAR capabilities
+ * supported by the firmware.
+
+ * @QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION:
+ * u32 attribute. This field describes current SAR version supported by the
+ * firmware.
+ * See enum qca_wlan_vendor_sar_version for more information.
+ * This attribute is mandatory.
+
+ * @QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_CTL_GROUP_STATE:
+ * u32 attribute. This field describes whether CTL groups are enabled
+ * or disabled in the firmware.
+ * See enum qca_wlan_vendor_sar_ctl_group_state for more information.
+ * This attribute is optional.
+ */
+
+enum qca_wlan_vendor_attr_sar_capability {
+	QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION = 1,
+	QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_CTL_GROUP_STATE = 2,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX =
+	QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_sr_stats - Attributes for Spatial Reuse statistics.
+ * These statistics are sent from the driver in a response when userspace
+ * queries to get the statistics using the operation
+ * %QCA_WLAN_SR_OPERATION_GET_STATS. These statistics are reset
+ * by the driver when the SR feature is enabled, when the driver receives
+ * %QCA_WLAN_SR_OPERATION_CLEAR_STATS operation, or when disconnected.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_STATS_NON_SRG_TX_OPPORTUNITIES_COUNT: u32 attribute.
+ * Mandatory only when non-SRG is supported by the AP and optional otherwise.
+ * This represents the number of non-SRG TX opportunities.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_STATS_NON_SRG_TX_PPDU_TRIED_COUNT: u32 attribute.
+ * Mandatory only when non-SRG is supported by the AP and optional otherwise.
+ * This represents the number of non-SRG PPDUs tried to transmit.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_STATS_NON_SRG_TX_PPDU_SUCCESS_COUNT: u32 attribute.
+ * Mandatory only when non-SRG is supported by the AP and optional otherwise.
+ * This represents the number of non-SRG PPDUs successfully transmitted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_STATS_SRG_TX_OPPORTUNITIES_COUNT: u32 attribute.
+ * Mandatory only when SRG is supported by the AP and optional otherwise.
+ * This represents the number of SRG TX opportunities.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_STATS_SRG_TX_PPDU_TRIED_COUNT: u32 attribute.
+ * Mandatory only when SRG is supported by the AP and optional otherwise.
+ * This represents the number of SRG PPDUs tried to transmit.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_STATS_SRG_TX_PPDU_SUCCESS_COUNT: u32 attribute.
+ * Mandatory only when SRG is supported by the AP and optional otherwise.
+ * This represents the number of SRG PPDUs successfully transmitted.
+ */
+enum qca_wlan_vendor_attr_sr_stats {
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_NON_SRG_TX_OPPORTUNITIES_COUNT = 1,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_NON_SRG_TX_PPDU_TRIED_COUNT = 2,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_NON_SRG_TX_PPDU_SUCCESS_COUNT = 3,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_SRG_TX_OPPORTUNITIES_COUNT = 4,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_SRG_TX_PPDU_TRIED_COUNT = 5,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_SRG_TX_PPDU_SUCCESS_COUNT = 6,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_SR_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_sr_reason_code - Defines the different reason codes used in
+ * Spatial Reuse feature.
+ *
+ * @QCA_WLAN_SR_REASON_CODE_ROAMING: The SR feature is disabled/enabled due to
+ * roaming to an AP that doesn't support/supports SR feature, respectively.
+ *
+ * @QCA_WLAN_SR_REASON_CODE_CONCURRENCY: The SR feature is disabled/enabled due
+ * to change in concurrent interfaces that are supported by the driver.
+ */
+enum qca_wlan_sr_reason_code {
+	QCA_WLAN_SR_REASON_CODE_ROAMING = 0,
+	QCA_WLAN_SR_REASON_CODE_CONCURRENCY = 1,
+};
+
+/**
+ * enum qca_wlan_sr_operation - Defines the different types of SR operations.
+ * The values are used inside attribute %QCA_WLAN_VENDOR_ATTR_SR_OPERATION.
+ *
+ * @QCA_WLAN_SR_OPERATION_SR_ENABLE: Userspace sends this operation to the
+ * driver to enable the Spatial Reuse feature. Attributes
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_PD_THRESHOLD and
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_PD_THRESHOLD are used with this
+ * operation.
+ *
+ * @QCA_WLAN_SR_OPERATION_SR_DISABLE: Userspace sends this operation to the
+ * driver to disable the Spatial Reuse feature.
+ *
+ * @QCA_WLAN_SR_OPERATION_SR_SUSPEND: The driver uses this operation in an
+ * asynchronous event sent to userspace when the SR feature is disabled.
+ * The disable reason is encoded in QCA_WLAN_VENDOR_ATTR_SR_PARAMS_REASON_CODE
+ * and sent along with the asynchronous event.
+ *
+ * @QCA_WLAN_SR_OPERATION_SR_RESUME: The driver uses this operation in an
+ * asynchronous event when the SR feature is enabled again after the SR feature
+ * was suspended by the driver earlier. The enable reason is
+ * encoded in QCA_WLAN_VENDOR_ATTR_SR_PARAMS_REASON_CODE. Attributes used are
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_PD_THRESHOLD and
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_PD_THRESHOLD.
+ *
+ * @QCA_WLAN_SR_OPERATION_PSR_AND_NON_SRG_OBSS_PD_PROHIBIT: This operation is
+ * used to prohibit PSR-based spatial reuse and non-SRG OBSS PD-based spatial
+ * reuse transmissions. Userspace sends this operation to the driver.
+ * The driver/firmware upon receiving this operation shall prohibit PSR-based
+ * spatial reuse and non-SRG OBSS PD-based spatial reuse transmissions.
+ *
+ * @QCA_WLAN_SR_OPERATION_PSR_AND_NON_SRG_OBSS_PD_ALLOW: This operation is
+ * used to allow PSR-based spatial reuse and non-SRG OBSS PD-based spatial
+ * reuse transmissions. Userspace sends this operation to the driver.
+ * The driver/firmware upon receiving this operation shall allow PSR-based
+ * spatial reuse and non-SRG OBSS PD-based spatial reuse transmissions.
+ *
+ * @QCA_WLAN_SR_OPERATION_GET_STATS: Userspace sends this operation to the
+ * driver to get the SR statistics and the driver sends a synchronous response
+ * with the attributes defined in enum qca_wlan_vendor_attr_sr_stats using the
+ * nested attribute %QCA_WLAN_VENDOR_ATTR_SR_STATS.
+ *
+ * @QCA_WLAN_SR_OPERATION_CLEAR_STATS: Userspace sends this operation to the
+ * driver to clear the SR statistics and upon receiving this operation
+ * the driver/firmware shall clear the SR statistics.
+ *
+ * @QCA_WLAN_SR_OPERATION_GET_PARAMS: Userspace sends this operation to the
+ * driver to get the SR parameters and the driver sends the synchronous response
+ * with the following required attributes:
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MIN_OFFSET,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MAX_OFFSET,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_MAX_OFFSET,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_HESIGA_VAL15_ENABLE,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_DISALLOW.
+ *
+ * @QCA_WLAN_SR_OPERATION_UPDATE_PARAMS: The driver uses this operation in an
+ * asynchronous event to userspace to update any changes in SR parameters.
+ * The following attributes are used with this operation:
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MIN_OFFSET,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MAX_OFFSET,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_MAX_OFFSET,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_HESIGA_VAL15_ENABLE,
+ * %QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_DISALLOW.
+ */
+enum qca_wlan_sr_operation {
+	QCA_WLAN_SR_OPERATION_SR_ENABLE = 0,
+	QCA_WLAN_SR_OPERATION_SR_DISABLE = 1,
+	QCA_WLAN_SR_OPERATION_SR_SUSPEND = 2,
+	QCA_WLAN_SR_OPERATION_SR_RESUME = 3,
+	QCA_WLAN_SR_OPERATION_PSR_AND_NON_SRG_OBSS_PD_PROHIBIT = 4,
+	QCA_WLAN_SR_OPERATION_PSR_AND_NON_SRG_OBSS_PD_ALLOW = 5,
+	QCA_WLAN_SR_OPERATION_GET_STATS = 6,
+	QCA_WLAN_SR_OPERATION_CLEAR_STATS = 7,
+	QCA_WLAN_SR_OPERATION_GET_PARAMS = 8,
+	QCA_WLAN_SR_OPERATION_UPDATE_PARAMS = 9,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_sr_params - Defines attributes for SR configuration
+ * parameters used by attribute %QCA_WLAN_VENDOR_ATTR_SR_PARAMS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_HESIGA_VAL15_ENABLE: Flag attribute.
+ * This attribute is optionally set in response to
+ * %QCA_WLAN_SR_OPERATION_GET_PARAMS and in request when operation is set to
+ * %QCA_WLAN_SR_OPERATION_PSR_AND_NON_SRG_OBSS_PD_PROHIBIT. Refer IEEE Std
+ * 802.11ax-2021 Figure 9-788r-SR Control field format to understand more
+ * about HESIGA_Spatial_reuse_value15_allowed.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_DISALLOW: Flag attribute.
+ * This attribute is used in response to %QCA_WLAN_SR_OPERATION_GET_PARAMS
+ * operation. This indicates whether non-SRG OBSS PD SR transmissions are
+ * allowed or not at non-AP STAs that are associated with the AP. If present
+ * non-SRG OBSS PD SR transmissions are not allowed else are allowed.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MIN_OFFSET: Optional u8
+ * attribute. This attribute is used in response to
+ * %QCA_WLAN_SR_OPERATION_GET_PARAMS operation. This indicates the SRG OBSS PD
+ * Min Offset field which contains an unsigned integer that is added to -82 dBm
+ * to generate the value of the SRG OBSS PD Min parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MAX_OFFSET: Optional u8
+ * attribute. This attribute is used in response to
+ * %QCA_WLAN_SR_OPERATION_GET_PARAMS operation. This indicates the SRG OBSS PD
+ * Max Offset field which contains an unsigned integer that is added to -82 dBm
+ * to generate the value of the SRG OBSS PD Max parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_MAX_OFFSET: Optional u8
+ * attribute. This attribute is used in response to
+ * %QCA_WLAN_SR_OPERATION_GET_PARAMS operation. This indicates the Non-SRG OBSS
+ * PD Max Offset field which contains an unsigned integer that is added to -82
+ * dBm to generate the value of the Non-SRG OBSS PD Max parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_PD_THRESHOLD: s32 attribute (in dBm).
+ * Userspace optionally sends this attribute with
+ * %QCA_WLAN_SR_OPERATION_SR_ENABLE operation to the driver to specify the
+ * preferred SRG PD threshold. The driver shall send this attribute to
+ * userspace in SR resume event to indicate the PD threshold being used for SR.
+ * When there is change in SRG PD threshold (for example, due to roaming, etc.)
+ * the driver shall indicate the userspace the newly configured SRG PD threshold
+ * using an asynchronous event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_PD_THRESHOLD: s32 attribute (in dBm).
+ * Userspace optionally sends this attribute with
+ * %QCA_WLAN_SR_OPERATION_SR_ENABLE operation to the driver to specify the
+ * preferred non-SRG PD threshold. The driver shall send this attribute to
+ * userspace in SR resume event to indicate the PD threshold being used for SR.
+ * When there is change in non-SRG PD threshold (for example, due to roaming,
+ * etc.) the driver shall indicate the userspace the newly configured non-SRG PD
+ * threshold using an asynchronous event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS_REASON_CODE: u32 attribute. The possible
+ * values are defined in enum qca_wlan_sr_reason_code. This
+ * attribute is used with %QCA_WLAN_SR_OPERATION_SR_RESUME and
+ * %QCA_WLAN_SR_OPERATION_SR_SUSPEND operations.
+ */
+enum qca_wlan_vendor_attr_sr_params {
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_HESIGA_VAL15_ENABLE = 1,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_DISALLOW = 2,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MIN_OFFSET = 3,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_OBSS_PD_MAX_OFFSET = 4,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_OBSS_PD_MAX_OFFSET = 5,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_PD_THRESHOLD = 6,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_PD_THRESHOLD = 7,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_REASON_CODE = 8,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_MAX =
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_sr - Defines the attributes used by the vendor
+ * command QCA_NL80211_VENDOR_SUBCMD_SR.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_OPERATION: Mandatory u8 attribute for all requests
+ * from userspace to the driver. Possible values are defined in enum
+ * qca_wlan_sr_operation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_PARAMS: Nested attribute, contains the SR
+ * configuration parameters. The possible attributes inside this attribute are
+ * defined in enum qca_wlan_vendor_attr_sr_params.
+ * This attribute is used when QCA_WLAN_VENDOR_ATTR_SR_OPERATION is set to
+ * %QCA_WLAN_SR_OPERATION_SR_ENABLE in requests from userspace to the driver and
+ * also in response from the driver to userspace when the response is sent for
+ * %QCA_WLAN_SR_OPERATION_GET_PARAMS.
+ * The driver uses this attribute in asynchronous events in which the operation
+ * is set to %QCA_WLAN_SR_OPERATION_SR_RESUME,
+ * %QCA_WLAN_SR_OPERATION_SR_SUSPEND or %QCA_WLAN_SR_OPERATION_UPDATE_PARAMS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SR_STATS: Nested attribute, contains the SR
+ * statistics. These attributes used inside this are defined in enum
+ * qca_wlan_vendor_attr_sr_stats.
+ * This attribute is used in response from the driver to a command in which
+ * %QCA_WLAN_VENDOR_ATTR_SR_OPERATION is set to
+ * %QCA_WLAN_SR_OPERATION_GET_STATS.
+ */
+enum qca_wlan_vendor_attr_sr {
+	QCA_WLAN_VENDOR_ATTR_SR_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SR_OPERATION = 1,
+	QCA_WLAN_VENDOR_ATTR_SR_PARAMS = 2,
+	QCA_WLAN_VENDOR_ATTR_SR_STATS = 3,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_SR_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SR_MAX =
+	QCA_WLAN_VENDOR_ATTR_SR_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mlo_peer_prim_netdev_event - Defines the attributes
+ * used in the QCA_NL80211_VENDOR_SUBCMD_MLO_PEER_PRIM_NETDEV_EVENT subcommand.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_MACADDR: 6 byte MAC address
+ * used by the peer on the link that corresponds to the link used for sending
+ * the event notification.
+ * @QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_MLD_MAC_ADDR: 6 byte
+ * MLD MAC address of the peer.
+ * @QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_PRIM_IFINDEX: u32 attribute,
+ * used to pass ifindex of the primary netdev.
+ */
+enum qca_wlan_vendor_attr_mlo_peer_prim_netdev_event {
+	QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_MACADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_MLD_MAC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_PRIM_IFINDEX = 3,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_MAX =
+	QCA_WLAN_VENDOR_ATTR_MLO_PEER_PRIM_NETDEV_EVENT_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_afc_freq_psd_info: This enum is used with
+ * nested attributes QCA_WLAN_VENDOR_ATTR_AFC_RESP_FREQ_PSD_INFO and
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_FREQ_RANGE_LIST to update the frequency range
+ * and PSD information.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_RANGE_START: Required and type is
+ * u32. This attribute is used to indicate the start of the queried frequency
+ * range in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_RANGE_END: Required and type is u32.
+ * This attribute is used to indicate the end of the queried frequency range
+ * in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_PSD: Required and type is u32.
+ * This attribute will contain the PSD information for a single range as
+ * specified by the QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_RANGE_START and
+ * QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_RANGE_END attributes.
+ *
+ * The PSD power info (dBm/MHz) from user space should be multiplied
+ * by a factor of 100 when sending to the driver to preserve granularity
+ * up to 2 decimal places.
+ * Example:
+ *     PSD power value: 10.21 dBm/MHz
+ *     Value to be updated in QCA_WLAN_VENDOR_ATTR_AFC_PSD_INFO: 1021.
+ *
+ * Note: QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_PSD attribute will be used only
+ * with nested attribute QCA_WLAN_VENDOR_ATTR_AFC_RESP_FREQ_PSD_INFO and with
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_FREQ_RANGE_LIST when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE.
+ *
+ * The following set of attributes will be used to exchange frequency and
+ * corresponding PSD information for AFC between the user space and the driver.
+ */
+enum qca_wlan_vendor_attr_afc_freq_psd_info {
+	QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_RANGE_START = 1,
+	QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_RANGE_END = 2,
+	QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_PSD = 3,
+
+	QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_AFC_FREQ_PSD_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_afc_chan_eirp_info: This enum is used with
+ * nested attribute QCA_WLAN_VENDOR_ATTR_AFC_CHAN_LIST_INFO to update the
+ * channel list and corresponding EIRP information.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM: Required and type is u8.
+ * This attribute is used to indicate queried channel from
+ * the operating class indicated in QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_EIRP: Optional and type is u32.
+ * This attribute is used to configure the EIRP power info corresponding
+ * to the channel number indicated in QCA_WLAN_VENDOR_ATTR_AFC_CHAN_NUM.
+ * The EIRP power info(dBm) from user space should be multiplied
+ * by a factor of 100 when sending to Driver to preserve granularity up to
+ * 2 decimal places.
+ * Example:
+ *     EIRP power value: 34.23 dBm
+ *     Value to be updated in QCA_WLAN_VENDOR_ATTR_AFC_EIRP_INFO: 3423.
+ *
+ * Note: QCA_WLAN_VENDOR_ATTR_AFC_EIRP_INFO attribute will only be used with
+ * nested attribute QCA_WLAN_VENDOR_ATTR_AFC_RESP_OPCLASS_CHAN_EIRP_INFO and
+ * with QCA_WLAN_VENDOR_ATTR_AFC_EVENT_OPCLASS_CHAN_LIST when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE:
+ *
+ * The following set of attributes will be used to exchange Channel and
+ * corresponding EIRP information for AFC between the user space and Driver.
+ */
+enum qca_wlan_vendor_attr_afc_chan_eirp_info {
+	QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM = 1,
+	QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_EIRP = 2,
+
+	QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_afc_opclass_info: This enum is used with nested
+ * attributes QCA_WLAN_VENDOR_ATTR_AFC_RESP_OPCLASS_CHAN_EIRP_INFO and
+ * QCA_WLAN_VENDOR_ATTR_AFC_REQ_OPCLASS_CHAN_INFO to update the operating class,
+ * channel, and EIRP related information.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_OPCLASS: Required and type is u8.
+ * This attribute is used to indicate the operating class, as listed under
+ * IEEE Std 802.11-2020 Annex E Table E-4, for the queried channel list.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_CHAN_LIST: Array of nested attributes
+ * for updating the channel number and EIRP power information.
+ * It uses the attributes defined in
+ * enum qca_wlan_vendor_attr_afc_chan_eirp_info.
+ *
+ * Operating class information packing format for
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_OPCLASS_CHAN_INFO when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE_EXPIRY.
+ *
+ * m - Total number of operating classes.
+ * n, j - Number of queried channels for the corresponding operating class.
+ *
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_OPCLASS[0]
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_CHAN_LIST[0]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[0]
+ *      .....
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[n - 1]
+ *  ....
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_OPCLASS[m]
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_CHAN_LIST[m]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[0]
+ *      ....
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[j - 1]
+ *
+ * Operating class information packing format for
+ * QCA_WLAN_VENDOR_ATTR_AFC_RESP_OPCLASS_CHAN_EIRP_INFO and
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_OPCLASS_CHAN_INFO when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE.
+ *
+ * m - Total number of operating classes.
+ * n, j - Number of channels for the corresponding operating class.
+ *
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_OPCLASS[0]
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_CHAN_LIST[0]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[0]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_EIRP[0]
+ *      .....
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[n - 1]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_EIRP[n - 1]
+ *  ....
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_OPCLASS[m]
+ *  QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_CHAN_LIST[m]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[0]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_EIRP[0]
+ *      ....
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_CHAN_NUM[j - 1]
+ *      QCA_WLAN_VENDOR_ATTR_AFC_CHAN_EIRP_INFO_EIRP[j - 1]
+ *
+ * The following set of attributes will be used to exchange operating class
+ * information for AFC between the user space and the driver.
+ */
+enum qca_wlan_vendor_attr_afc_opclass_info {
+	QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_OPCLASS = 1,
+	QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_CHAN_LIST = 2,
+
+	QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_AFC_OPCLASS_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_afc_event_type: Defines values for AFC event type.
+ * Attribute used by QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE attribute.
+ *
+ * @QCA_WLAN_VENDOR_AFC_EVENT_TYPE_EXPIRY: AFC expiry event sent from the
+ * driver to userspace in order to query the new AFC power values.
+ *
+ * @QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE: Power update
+ * complete event will be sent from the driver to userspace to indicate
+ * processing of the AFC response.
+ *
+ * @QCA_WLAN_VENDOR_AFC_EVENT_TYPE_PAYLOAD_RESET: AFC payload reset event
+ * will be sent from the driver to userspace to indicate last received
+ * AFC response data has been cleared on the AP due to invalid data
+ * in the QCA_NL80211_VENDOR_SUBCMD_AFC_RESPONSE.
+ *
+ * The following enum defines the different event types that will be
+ * used by the driver to help trigger corresponding AFC functionality in user
+ * space.
+ */
+enum qca_wlan_vendor_afc_event_type {
+	QCA_WLAN_VENDOR_AFC_EVENT_TYPE_EXPIRY = 0,
+	QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE = 1,
+	QCA_WLAN_VENDOR_AFC_EVENT_TYPE_PAYLOAD_RESET = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_afc_ap_deployment_type: Defines values for AP
+ * deployment type.
+ * Attribute used by QCA_WLAN_VENDOR_ATTR_AFC_EVENT_AP_DEPLOYMENT attribute.
+ *
+ * @QCA_WLAN_VENDOR_AFC_AP_DEPLOYMENT_TYPE_UNKNOWN: Unknown AP deployment.
+ *
+ * @QCA_WLAN_VENDOR_AFC_AP_DEPLOYMENT_TYPE_INDOOR: Indoor AP deployment.
+ *
+ * @QCA_WLAN_VENDOR_AFC_AP_DEPLOYMENT_TYPE_OUTDOOR: Outdoor AP deployment.
+ *
+ * The following enum defines different deployment modes that the AP might
+ * come up in. This information will be essential to retrieve deployment-type
+ * specific SP power values for AFC operation.
+ */
+enum qca_wlan_vendor_afc_ap_deployment_type {
+	QCA_WLAN_VENDOR_AFC_AP_DEPLOYMENT_TYPE_UNKNOWN = 0,
+	QCA_WLAN_VENDOR_AFC_AP_DEPLOYMENT_TYPE_INDOOR = 1,
+	QCA_WLAN_VENDOR_AFC_AP_DEPLOYMENT_TYPE_OUTDOOR = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_afc_evt_status_code: Defines values AP will use to
+ * indicate AFC response status.
+ * Enum used by QCA_WLAN_VENDOR_ATTR_AFC_EVENT_STATUS_CODE attribute.
+ *
+ * @QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_SUCCESS: Success
+ *
+ * @QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_TIMEOUT: Indicates AFC indication
+ * command was not received within the expected time of the AFC expiry event
+ * being triggered.
+ *
+ * @QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_PARSING_ERROR: Indicates AFC data
+ * parsing error by the driver.
+ *
+ * @QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_LOCAL_ERROR: Indicates any other local
+ * error.
+ *
+ * The following enum defines the status codes that the driver will use to
+ * indicate whether the AFC data is valid or not.
+ */
+enum qca_wlan_vendor_afc_evt_status_code {
+	QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_SUCCESS = 0,
+	QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_TIMEOUT = 1,
+	QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_PARSING_ERROR = 2,
+	QCA_WLAN_VENDOR_AFC_EVT_STATUS_CODE_LOCAL_ERROR = 3,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_afc_event: Defines attributes to be used with
+ * vendor event QCA_NL80211_VENDOR_SUBCMD_AFC_EVENT. These attributes will
+ * support sending only a single request to the user space at a time.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE: Required u8 attribute.
+ * Used with event to notify the type of AFC event received.
+ * Valid values are defined in enum qca_wlan_vendor_afc_event_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_AP_DEPLOYMENT: u8 attribute. Required when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is QCA_WLAN_VENDOR_AFC_EVENT_TYPE_EXPIRY,
+ * otherwise unused.
+ *
+ * This attribute is used to indicate the AP deployment type in the AFC request.
+ * Valid values are defined in enum qca_wlan_vendor_afc_ap_deployment_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_REQ_ID: Required u32 attribute.
+ * Unique request identifier generated by the AFC client for every
+ * AFC expiry event trigger. See also QCA_WLAN_VENDOR_ATTR_AFC_RESP_REQ_ID.
+ * The user space application is responsible for ensuring no duplicate values
+ * are in-flight with the server, e.g., by delaying a request, should the same
+ * value be received from different radios in parallel.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_AFC_WFA_VERSION: u32 attribute. Optional.
+ * It is used when the QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_EXPIRY, otherwise unused.
+ *
+ * This attribute indicates the AFC spec version information. This will
+ * indicate the AFC version AFC client must use to query the AFC data.
+ * Bits 15:0  - Minor version
+ * Bits 31:16 - Major version
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_MIN_DES_POWER: u16 attribute. Required when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is QCA_WLAN_VENDOR_AFC_EVENT_TYPE_EXPIRY,
+ * otherwise unused.
+ * This attribute indicates the minimum desired power (in dBm) for
+ * the queried spectrum.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_STATUS_CODE: u8 attribute. Required when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE, otherwise unused.
+ *
+ * Valid values are defined in enum qca_wlan_vendor_afc_evt_status_code.
+ * This attribute is used to indicate if there were any errors parsing the
+ * AFC response.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_SERVER_RESP_CODE: s32 attribute. Required
+ * when QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE, otherwise unused.
+ *
+ * This attribute indicates the AFC response code. The AFC response codes are
+ * in the following categories:
+ * -1: General Failure.
+ * 0: Success.
+ * 100 - 199: General errors related to protocol.
+ * 300 - 399: Error events specific to message exchange
+ *            for the Available Spectrum Inquiry.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_EXP_DATE: u32 attribute. Required when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE, otherwise unused.
+ *
+ * This attribute indicates the date until which the current response is
+ * valid for in UTC format.
+ * Date format: bits 7:0   - DD (Day 1-31)
+ *              bits 15:8  - MM (Month 1-12)
+ *              bits 31:16 - YYYY (Year)
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_EXP_TIME: u32 attribute. Required when
+ * QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE, otherwise unused.
+ *
+ * This attribute indicates the time until which the current response is
+ * valid for in UTC format.
+ * Time format: bits 7:0   - SS (Seconds 0-59)
+ *              bits 15:8  - MM (Minutes 0-59)
+ *              bits 23:16 - HH (Hours 0-23)
+ *              bits 31:24 - Reserved
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_FREQ_RANGE_LIST: Array of nested attributes
+ * for updating the list of frequency ranges to be queried.
+ * Required when QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_EXPIRY or
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE, otherwise unused.
+ * It uses the attributes defined in
+ * enum qca_wlan_vendor_attr_afc_freq_psd_info.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_EVENT_OPCLASS_CHAN_LIST: Array of nested attributes
+ * for updating the list of operating classes and corresponding channels to be
+ * queried.
+ * Required when QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE is
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_EXPIRY or
+ * QCA_WLAN_VENDOR_AFC_EVENT_TYPE_POWER_UPDATE_COMPLETE, otherwise unused.
+ * It uses the attributes defined in enum qca_wlan_vendor_attr_afc_opclass_info.
+ */
+enum qca_wlan_vendor_attr_afc_event {
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_TYPE = 1,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_AP_DEPLOYMENT = 2,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_REQ_ID = 3,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_AFC_WFA_VERSION = 4,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_MIN_DES_POWER = 5,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_STATUS_CODE = 6,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_SERVER_RESP_CODE = 7,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_EXP_DATE = 8,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_EXP_TIME = 9,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_FREQ_RANGE_LIST = 10,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_OPCLASS_CHAN_LIST = 11,
+
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_MAX =
+	QCA_WLAN_VENDOR_ATTR_AFC_EVENT_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_afc_response: Defines attributes to be used
+ * with vendor command QCA_NL80211_VENDOR_SUBCMD_AFC_RESPONSE. These attributes
+ * will support sending only a single AFC response to the driver at a time.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_DATA: Type is NLA_STRING. Required attribute.
+ * This attribute will be used to send a single Spectrum Inquiry response object
+ * from the 'availableSpectrumInquiryResponses' array object from the response
+ * JSON.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_TIME_TO_LIVE: Required u32 attribute.
+ *
+ * This attribute indicates the period (in seconds) for which the response
+ * data received is valid for.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_REQ_ID: Required u32 attribute.
+ *
+ * This attribute indicates the request ID for which the corresponding
+ * response is being sent for. See also QCA_WLAN_VENDOR_ATTR_AFC_EVENT_REQ_ID.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_EXP_DATE: Required u32 attribute.
+ *
+ * This attribute indicates the date until which the current response is
+ * valid for in UTC format.
+ * Date format: bits 7:0   - DD (Day 1-31)
+ *              bits 15:8  - MM (Month 1-12)
+ *              bits 31:16 - YYYY (Year)
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_EXP_TIME: Required u32 attribute.
+ *
+ * This attribute indicates the time until which the current response is
+ * valid for in UTC format.
+ * Time format: bits 7:0   - SS (Seconds 0-59)
+ *              bits 15:8  - MM (Minutes 0-59)
+ *              bits 23:16 - HH (Hours 0-23)
+ *              bits 31:24 - Reserved
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_AFC_SERVER_RESP_CODE: Required s32 attribute.
+ *
+ * This attribute indicates the AFC response code. The AFC response codes are
+ * in the following categories:
+ * -1: General Failure.
+ * 0: Success.
+ * 100 - 199: General errors related to protocol.
+ * 300 - 399: Error events specific to message exchange
+ *            for the Available Spectrum Inquiry.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_FREQ_PSD_INFO: Array of nested attributes
+ * for PSD info of all the queried frequency ranges. It uses the attributes
+ * defined in enum qca_wlan_vendor_attr_afc_freq_psd_info. Required attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AFC_RESP_OPCLASS_CHAN_EIRP_INFO: Array of nested
+ * attributes for EIRP info of all queried operating class/channels. It uses
+ * the attributes defined in enum qca_wlan_vendor_attr_afc_opclass_info and
+ * enum qca_wlan_vendor_attr_afc_chan_eirp_info. Required attribute.
+ *
+ */
+enum qca_wlan_vendor_attr_afc_response {
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_DATA = 1,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_TIME_TO_LIVE = 2,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_REQ_ID = 3,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_EXP_DATE = 4,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_EXP_TIME = 5,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_AFC_SERVER_RESP_CODE = 6,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_FREQ_PSD_INFO = 7,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_OPCLASS_CHAN_EIRP_INFO = 8,
+
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_MAX =
+	QCA_WLAN_VENDOR_ATTR_AFC_RESP_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_dozed_ap_state - Doze states for AP interface
+ *
+ * @QCA_WLAN_DOZED_AP_DISABLE: Disable doze state on the AP interface.
+ *
+ * @QCA_WLAN_DOZED_AP_ENABLE: Enable doze state on the AP interface. AP starts
+ * beaconing at higher beacon interval with Rx disabled.
+ */
+enum qca_wlan_dozed_ap_state {
+	QCA_WLAN_DOZED_AP_DISABLE = 0,
+	QCA_WLAN_DOZED_AP_ENABLE = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_dozed_ap - Used by the vendor command
+ * @QCA_NL80211_VENDOR_SUBCMD_DOZED_AP to configure or receive dozed AP mode
+ * configuration.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_DOZED_AP_STATE: u8 attribute.
+ * Configures the doze state for an AP interface. Possible values are defined
+ * in enum qca_wlan_dozed_ap_state. @QCA_NL80211_VENDOR_SUBCMD_DOZED_AP event
+ * gets triggered asynchronously to provide updated AP interface configuration.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_DOZED_AP_COOKIE: Unsigned 64-bit cookie provided by
+ * the driver in the response to specific @QCA_NL80211_VENDOR_SUBCMD_DOZED_AP
+ * command, which is used later to maintain synchronization between commands
+ * and asynchronous events.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_DOZED_AP_NEXT_TSF: u64 attribute.
+ * Used in event to indicate the next TBTT TSF timer value after applying the
+ * doze mode configuration. Next TBTT TSF is the time at which the AP sends
+ * the first beacon after entering or exiting dozed mode.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_DOZED_AP_BI_MULTIPLIER: u16 attribute.
+ * Used with event to inform the periodicity of beacon transmission that would
+ * be skipped at all TBTTs in between.
+ */
+enum qca_wlan_vendor_attr_dozed_ap {
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_STATE = 1,
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_COOKIE = 2,
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_NEXT_TSF = 3,
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_BI_MULTIPLIER = 4,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_MAX =
+	QCA_WLAN_VENDOR_ATTR_DOZED_AP_AFTER_LAST - 1,
+};
+
 #endif /* QCA_VENDOR_H */
diff --git a/wcn6740/qcwcn/wifi_hal/radio_mode.cpp b/wcn6740/qcwcn/wifi_hal/radio_mode.cpp
new file mode 100644
index 0000000..267d3f4
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/radio_mode.cpp
@@ -0,0 +1,321 @@
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ *  Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *  SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "radio_mode.h"
+#include "vendor_definitions.h"
+#include <netlink/genl/genl.h>
+#include <string.h>
+#include <net/if.h>
+
+/* Used to handle radio command events from driver/firmware. */
+typedef struct radio_event_handler_s {
+    RADIOModeCommand* mRADIOModeCommandInstance;
+} radio_event_handlers;
+
+wifi_error initializeRadioHandler(hal_info *info)
+{
+    info->radio_handlers = (radio_event_handlers *)malloc(
+            sizeof(radio_event_handlers));
+    if (info->radio_handlers) {
+        memset(info->radio_handlers, 0, sizeof(radio_event_handlers));
+    } else {
+        ALOGE("%s: Allocation of radio event handlers failed",
+                __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return WIFI_SUCCESS;
+}
+
+wifi_error cleanupRadioHandler(hal_info *info) {
+    radio_event_handlers* event_handlers;
+    if (info && info->radio_handlers) {
+        event_handlers = (radio_event_handlers*) info->radio_handlers;
+        if (event_handlers->mRADIOModeCommandInstance) {
+            delete event_handlers->mRADIOModeCommandInstance;
+        }
+        memset(event_handlers, 0, sizeof(radio_event_handlers));
+        free(info->radio_handlers);
+        info->radio_handlers = NULL;
+        return WIFI_SUCCESS;
+    }
+    ALOGE ("%s: info or info->radio_handlers NULL", __FUNCTION__);
+    return WIFI_ERROR_UNKNOWN;
+}
+
+/* Used to handle radio mode command events from driver/firmware.*/
+void RADIOModeCommand::setCallbackHandler(wifi_radio_mode_change_handler handler)
+{
+    mHandler = handler;
+}
+
+void RADIOModeCommand::setReqId(wifi_request_id id)
+{
+    mreqId =  id;
+}
+
+RADIOModeCommand::RADIOModeCommand(wifi_handle handle, int id,
+                                   u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    memset(&mHandler, 0, sizeof(mHandler));
+    if (registerVendorHandler(vendor_id, subcmd)) {
+        /* Error case should not happen print log */
+        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
+              __FUNCTION__, vendor_id, subcmd);
+    }
+}
+
+RADIOModeCommand::~RADIOModeCommand()
+{
+    unregisterVendorHandler(mVendor_id, mSubcmd);
+}
+
+
+RADIOModeCommand* RADIOModeCommand::instance(wifi_handle handle,
+                                             wifi_request_id id)
+{
+    if (handle == NULL) {
+        ALOGE("Interface Handle is invalid");
+        return NULL;
+    }
+    hal_info *info = getHalInfo(handle);
+    if (!info) {
+        ALOGE("hal_info is invalid");
+        return NULL;
+    }
+    RADIOModeCommand* instance = info->radio_handlers->mRADIOModeCommandInstance;
+    if (instance) {
+        if (handle != getWifiHandle(instance->mInfo)) {
+            ALOGV("%s - Handle different, update the handle", __FUNCTION__);
+            instance->mInfo = (hal_info *)handle;
+        }
+        instance->setReqId(id);
+    } else {
+        info->radio_handlers->mRADIOModeCommandInstance =
+            new RADIOModeCommand(handle, id, OUI_QCA,
+                QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO);
+        instance = info->radio_handlers->mRADIOModeCommandInstance;
+    }
+    return instance;
+}
+
+/* This function will be the main handler for incoming event.
+ * Call the appropriate callback handler after parsing the vendor data.
+ */
+int RADIOModeCommand::handleEvent(WifiEvent &event)
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    int num_of_mac = 0;
+    wifi_mac_info mode_info;
+    memset(&mode_info, 0, sizeof(mode_info));
+
+    WifiVendorCommand::handleEvent(event);
+
+    /* Parse the vendordata and get the attribute */
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO:
+        {
+            struct nlattr *mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_MAX + 1];
+            struct nlattr *modeInfo;
+            int rem;
+
+            nla_parse(mtb_vendor, QCA_WLAN_VENDOR_ATTR_MAC_MAX,
+                      (struct nlattr *)mVendorData,
+                      mDataLen, NULL);
+
+            if (mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_INFO])
+            {
+                for (modeInfo = (struct nlattr *) nla_data(mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_INFO]),
+                     rem = nla_len(mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_INFO]);
+                     nla_ok(modeInfo, rem);modeInfo = nla_next(modeInfo, &(rem))) {
+
+                     struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAX+ 1];
+                     nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAX,
+                                (struct nlattr *) nla_data(modeInfo), nla_len(modeInfo), NULL);
+                     if (!tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID])
+                     {
+                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID"
+                               " not found", __FUNCTION__);
+                        ret = WIFI_ERROR_INVALID_ARGS;
+                        goto cleanup;
+                     }
+                     mode_info.wlan_mac_id = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID]);
+                     ALOGV("mac_id[%d]: %d ", num_of_mac, mode_info.wlan_mac_id);
+
+                     if (!tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND])
+                     {
+                         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND"
+                               " NOT FOUND", __FUNCTION__);
+                         ret = WIFI_ERROR_INVALID_ARGS;
+                         goto cleanup;
+                     }
+                     mode_info.mac_band = (wlan_mac_band) nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND]);
+                     ALOGV("mac_band[%d]: %d ", num_of_mac, mode_info.mac_band);
+
+                     if (tb2[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO])
+                     {
+                       int num_of_iface = 0;
+                       struct nlattr *tb_iface;
+                       int rem_info;
+
+                       for (tb_iface = (struct nlattr *) nla_data(tb2[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO]),
+                            rem_info = nla_len(tb2[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO]);
+                            nla_ok(tb_iface, rem_info);tb_iface = nla_next(tb_iface, &(rem_info))) {
+
+                            struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_MAX+ 1];
+                            wifi_iface_info miface_info;
+
+                            nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_MAX,
+                                      (struct nlattr *) nla_data(tb_iface), nla_len(tb_iface), NULL);
+
+                            if (!tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX])
+                            {
+                                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX"
+                                      " NOT FOUND", __FUNCTION__);
+                                ret = WIFI_ERROR_INVALID_ARGS;
+                                goto cleanup;
+                            }
+                            if (if_indextoname(nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX]),
+                                               miface_info.iface_name) == NULL)
+                            {
+                                ALOGE("%s: Failed to convert %d IFINDEX to IFNAME", __FUNCTION__,
+                                      nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX]));
+                            }
+                            ALOGV("ifname[%d]: %s ", num_of_iface, miface_info.iface_name);
+
+                            if (!tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ])
+                            {
+                                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ"
+                                      " NOT FOUND", __FUNCTION__);
+                                ret = WIFI_ERROR_INVALID_ARGS;
+                                goto cleanup;
+                            }
+                            miface_info.channel = nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ]);
+                            ALOGV("channel[%d]: %d ", num_of_iface, miface_info.channel);
+
+                            if (!num_of_iface)
+                               mode_info.iface_info = (wifi_iface_info *)
+                                         malloc(sizeof(wifi_iface_info));
+                            else
+                               mode_info.iface_info = (wifi_iface_info *)
+                                         realloc(mode_info.iface_info, (num_of_iface + 1) * sizeof(wifi_iface_info));
+
+                            if (mode_info.iface_info != NULL) {
+                                memcpy(&mode_info.iface_info[num_of_iface], &miface_info, sizeof(wifi_iface_info));
+                                num_of_iface++;
+                                mode_info.num_iface = num_of_iface;
+                            }
+                       }
+                    }
+                    if (!num_of_mac)
+                       mwifi_iface_mac_info = (wifi_mac_info *)
+                          malloc(sizeof(wifi_mac_info));
+                    else
+                       mwifi_iface_mac_info = (wifi_mac_info *)
+                          realloc(mwifi_iface_mac_info, (num_of_mac + 1) * (sizeof(wifi_mac_info)));
+
+                    if (mwifi_iface_mac_info != NULL) {
+                        memcpy(&mwifi_iface_mac_info[num_of_mac], &mode_info, sizeof(wifi_mac_info));
+                        num_of_mac++;
+                    }
+                }
+            }
+
+            if (mHandler.on_radio_mode_change && num_of_mac) {
+                (*mHandler.on_radio_mode_change)(mreqId, num_of_mac, mwifi_iface_mac_info);
+            }
+            else {
+                  ALOGE("No Callback registered: on radio mode change");
+                  ret = WIFI_ERROR_UNKNOWN;
+                  goto cleanup;
+            }
+            ret = WIFI_SUCCESS;
+        }
+        break;
+
+        default:
+            /* Error case should not happen print log */
+            ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd);
+    }
+
+cleanup:
+    if (mode_info.iface_info != NULL) {
+       free(mode_info.iface_info);
+       mode_info.iface_info = NULL;
+    }
+    if (mwifi_iface_mac_info != NULL) {
+       free(mwifi_iface_mac_info);
+       mwifi_iface_mac_info = NULL;
+    }
+
+    return ret;
+}
+
+wifi_error wifi_set_radio_mode_change_handler(wifi_request_id id,
+                                      wifi_interface_handle iface,
+                                      wifi_radio_mode_change_handler eh)
+{
+    wifi_error ret;
+    WifiVendorCommand *vCommand = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    RADIOModeCommand *radiomodeCommand;
+
+    ret = initialize_vendor_cmd(iface, id,
+                                QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO,
+                                &vCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        return ret;
+    }
+
+    radiomodeCommand = RADIOModeCommand::instance(wifiHandle, id);
+    if (radiomodeCommand == NULL) {
+        ALOGE("%s: Error RadioModeCommand NULL", __FUNCTION__);
+        ret = WIFI_ERROR_OUT_OF_MEMORY;
+        goto cleanup;
+    }
+    radiomodeCommand->setCallbackHandler(eh);
+    radiomodeCommand->setReqId(id);
+
+cleanup:
+    delete vCommand;
+    return mapKernelErrortoWifiHalError(ret);
+}
diff --git a/wcn6740/qcwcn/wifi_hal/radio_mode.h b/wcn6740/qcwcn/wifi_hal/radio_mode.h
new file mode 100644
index 0000000..d6a4e92
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/radio_mode.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_RADIO_MODE_COMMAND_H__
+#define __WIFI_HAL_RADIO_MODE_COMMAND_H__
+
+#include "cpp_bindings.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+class RADIOModeCommand: public WifiVendorCommand
+{
+private:
+    static RADIOModeCommand *mRADIOModeCommandInstance;
+    wifi_radio_mode_change_handler mHandler;
+    wifi_request_id mreqId;
+    wifi_mac_info *mwifi_iface_mac_info;
+    RADIOModeCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+
+public:
+    virtual ~RADIOModeCommand();
+    static RADIOModeCommand* instance(wifi_handle handle, wifi_request_id id);
+    virtual int handleEvent(WifiEvent &event);
+    virtual void setReqId(wifi_request_id reqid);
+    virtual void setCallbackHandler(wifi_radio_mode_change_handler nHandler);
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/qcwcn/wifi_hal/rb_wrapper.cpp b/wcn6740/qcwcn/wifi_hal/rb_wrapper.cpp
similarity index 96%
copy from qcwcn/wifi_hal/rb_wrapper.cpp
copy to wcn6740/qcwcn/wifi_hal/rb_wrapper.cpp
index 4c9e475..9083725 100644
--- a/qcwcn/wifi_hal/rb_wrapper.cpp
+++ b/wcn6740/qcwcn/wifi_hal/rb_wrapper.cpp
@@ -106,7 +106,11 @@
         return WIFI_ERROR_UNKNOWN;
     }
 
-    rb_info->written_records += no_of_records;
+    if (rb_info->written_records < (UINT_MAX - 1))
+        rb_info->written_records += no_of_records;
+    else
+        rb_info->written_records = 0;
+
     return WIFI_SUCCESS;
 }
 
@@ -117,7 +121,7 @@
     wifi_ring_buffer_status rbs;
     wifi_ring_buffer_data_handler handler;
 
-    while (1) {
+    while (info && !info->clean_up) {
         size_t length = 0;
         u8 *buf;
 
diff --git a/qcwcn/wifi_hal/rb_wrapper.h b/wcn6740/qcwcn/wifi_hal/rb_wrapper.h
similarity index 100%
copy from qcwcn/wifi_hal/rb_wrapper.h
copy to wcn6740/qcwcn/wifi_hal/rb_wrapper.h
diff --git a/qcwcn/wifi_hal/ring_buffer.cpp b/wcn6740/qcwcn/wifi_hal/ring_buffer.cpp
similarity index 90%
copy from qcwcn/wifi_hal/ring_buffer.cpp
copy to wcn6740/qcwcn/wifi_hal/ring_buffer.cpp
index d78bd62..5918923 100644
--- a/qcwcn/wifi_hal/ring_buffer.cpp
+++ b/wcn6740/qcwcn/wifi_hal/ring_buffer.cpp
@@ -70,9 +70,9 @@
     void (*threshold_cb)(void *);
     void *cb_ctx;
 
-    u32 total_bytes_written;
-    u32 total_bytes_read;
-    u32 total_bytes_overwritten;
+    u64 total_bytes_written;
+    u64 total_bytes_read;
+    u64 total_bytes_overwritten;
     u32 cur_valid_bytes;
     enum rb_bool threshold_reached;
 } rbc_t;
@@ -160,7 +160,7 @@
                                      // write in current buffer
     unsigned int total_push_in_rd_ptr = 0; // Total amount of push in read pointer in this write
 
-    if (record_length > rbc->each_buf_size) {
+    if (record_length > rbc->each_buf_size || length > rbc->each_buf_size) {
         return RB_FAILURE;
     }
 
@@ -279,6 +279,17 @@
             }
         }
         rb_unlock(&rbc->rb_rw_lock);
+        if(rbc->bufs[rbc->wr_buf_no].data == NULL || (rbc->bufs[rbc->wr_buf_no].data + rbc->cur_wr_buf_idx) == NULL ||
+                buf == NULL || buf + bytes_written == NULL) {
+            ALOGE("The read or Write buffer is null");
+            return RB_FAILURE;
+        }
+        if (((bytes_written + cur_copy_len) > length
+                || (rbc->cur_wr_buf_idx + cur_copy_len) > rbc->each_buf_size)) {
+            ALOGE("LOG_RB rb_write overflow - cur_copy_len=%d wr_buf[max=%zu no=%d idx=%d] buf[max=%zu accessed=%d]",
+              cur_copy_len, rbc->each_buf_size, rbc->wr_buf_no, rbc->cur_wr_buf_idx, length, bytes_written + cur_copy_len);
+            return RB_FAILURE;
+        }
 
         /* don't use lock while doing memcpy, so that we don't block the read
          * context for too long. There is no harm while writing the memory if
@@ -476,15 +487,33 @@
             cur_read_len = rbc->cur_wr_buf_idx - rbc->cur_rd_buf_idx;
         } else {
             /* write is rolled over and just behind the read */
-            cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+            if (rbc->bufs[rbc->rd_buf_no].last_wr_index >= rbc->cur_rd_buf_idx) {
+                cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+            } else {
+                ALOGE("Alert: cur_read_len=%u invalid, rd_buf[no=%d rd_idx=%d wr_index=%d]",cur_read_len, rbc->rd_buf_no, rbc->cur_rd_buf_idx, rbc->bufs[rbc->rd_buf_no].last_wr_index);
+                rb_unlock(&rbc->rb_rw_lock);
+                return NULL;
+            }
         }
     } else {
         if (rbc->cur_rd_buf_idx == 0) {
             /* The complete buffer can be read out */
             cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index;
         } else {
-            /* Read the remaining bytes in this buffer */
-            cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+            if ( rbc->bufs[rbc->rd_buf_no].last_wr_index >= rbc->cur_rd_buf_idx) {
+                /* Read the remaining bytes in this buffer */
+                cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+            }
+            else {
+                ALOGE("Alert: cur_read_len invalid cur_read_len = %u, cur_rd_buf_idx = %u, last_write_index = %u, read_buf_no = %u, max_num_bufs = %u", cur_read_len, rbc->cur_rd_buf_idx, rbc->bufs[rbc->rd_buf_no].last_wr_index, rbc->rd_buf_no,rbc->max_num_bufs);
+                /* Move to the next buffer */
+                rbc->bufs[rbc->rd_buf_no].full = 0;
+                rbc->rd_buf_no++;
+                if (rbc->rd_buf_no == rbc->max_num_bufs) {
+                    ALOGV("Read rolling over to the start of ring buffer");
+                    rbc->rd_buf_no = 0;
+                }
+            }
         }
     }
 
diff --git a/qcwcn/wifi_hal/ring_buffer.h b/wcn6740/qcwcn/wifi_hal/ring_buffer.h
similarity index 100%
copy from qcwcn/wifi_hal/ring_buffer.h
copy to wcn6740/qcwcn/wifi_hal/ring_buffer.h
diff --git a/wcn6740/qcwcn/wifi_hal/roam.cpp b/wcn6740/qcwcn/wifi_hal/roam.cpp
new file mode 100644
index 0000000..bd93c3d
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/roam.cpp
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include <errno.h>
+
+#include "common.h"
+#include "roamcommand.h"
+
+#define WLAN_ROAM_MAX_NUM_WHITE_LIST 8
+#define WLAN_ROAM_MAX_NUM_BLACK_LIST 16
+
+RoamCommand::RoamCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+}
+
+RoamCommand::~RoamCommand()
+{
+}
+
+/* This function implements creation of Vendor command */
+wifi_error RoamCommand::create() {
+    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    /* Insert the oui in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+    /* Insert the subcmd in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+     ALOGV("%s: mVendor_id = %d, Subcmd = %d.",
+        __FUNCTION__, mVendor_id, mSubcmd);
+    return ret;
+}
+
+wifi_error RoamCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+wifi_error wifi_set_bssid_blacklist(wifi_request_id id,
+                                    wifi_interface_handle iface,
+                                    wifi_bssid_params params)
+{
+    wifi_error ret;
+    int i;
+    RoamCommand *roamCommand;
+    struct nlattr *nlData, *nlBssids;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_CONTROL_ROAMING)) {
+        ALOGE("%s: Roaming is not supported by driver",
+            __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    for (i = 0; i < params.num_bssid; i++) {
+        ALOGV("BSSID: %d : %02x:%02x:%02x:%02x:%02x:%02x", i,
+                params.bssids[i][0], params.bssids[i][1],
+                params.bssids[i][2], params.bssids[i][3],
+                params.bssids[i][4], params.bssids[i][5]);
+    }
+
+    roamCommand =
+         new RoamCommand(wifiHandle,
+                          id,
+                          OUI_QCA,
+                          QCA_NL80211_VENDOR_SUBCMD_ROAM);
+    if (roamCommand == NULL) {
+        ALOGE("%s: Error roamCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = roamCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = roamCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
+                          QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = roamCommand->put_u32( QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID, id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = roamCommand->put_u32(
+                  QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID,
+                  params.num_bssid);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    nlBssids = roamCommand->attr_start(
+            QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS);
+    for (i = 0; i < params.num_bssid; i++) {
+        struct nlattr *nl_ssid = roamCommand->attr_start(i);
+
+        ret = roamCommand->put_addr(
+                      QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID,
+                      (u8 *)params.bssids[i]);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+
+        roamCommand->attr_end(nl_ssid);
+    }
+    roamCommand->attr_end(nlBssids);
+
+    roamCommand->attr_end(nlData);
+
+    ret = roamCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("wifi_set_bssid_blacklist(): requestResponse Error:%d", ret);
+
+cleanup:
+    delete roamCommand;
+    return ret;
+
+}
+
+wifi_error wifi_set_ssid_white_list(wifi_request_id id, wifi_interface_handle iface,
+                                    int num_networks, ssid_t *ssid_list)
+{
+    wifi_error ret;
+    int i;
+    RoamCommand *roamCommand;
+    struct nlattr *nlData, *nlSsids;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    char ssid[MAX_SSID_LENGTH + 1];
+
+    ALOGV("%s: Number of SSIDs : %d", __FUNCTION__, num_networks);
+
+    roamCommand = new RoamCommand(
+                                wifiHandle,
+                                id,
+                                OUI_QCA,
+                                QCA_NL80211_VENDOR_SUBCMD_ROAM);
+    if (roamCommand == NULL) {
+        ALOGE("%s: Failed to create object of RoamCommand class", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = roamCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to create NL message,  Error: %d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = roamCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to set interface Id of message, Error: %d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
+                              QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID, id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS,
+                               num_networks);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    nlSsids = roamCommand->attr_start(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST);
+    for (i = 0; i < num_networks; i++) {
+        struct nlattr *nl_ssid = roamCommand->attr_start(i);
+
+        memcpy(ssid, ssid_list[i].ssid_str, ssid_list[i].length);
+        ssid[ssid_list[i].length] = '\0';
+        ALOGV("ssid[%d] : %s", i, ssid);
+
+        ret = roamCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID,
+                                     ssid, (ssid_list[i].length + 1));
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: Failed to add ssid atribute, Error: %d", __FUNCTION__, ret);
+            goto cleanup;
+        }
+
+        roamCommand->attr_end(nl_ssid);
+    }
+    roamCommand->attr_end(nlSsids);
+
+    roamCommand->attr_end(nlData);
+
+    ret = roamCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete roamCommand;
+    return ret;
+}
+
+wifi_error wifi_get_roaming_capabilities(wifi_interface_handle iface,
+                                         wifi_roaming_capabilities *caps)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (!caps) {
+        ALOGE("%s: Invalid Buffer provided. Exit", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (!info) {
+        ALOGE("%s: hal_info is NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    // Per WiFi HAL design, roaming feature should have nothing to do with Gscan
+    // But for current driver impl, roaming_capa is provided as part of
+    // GSCAN_GET_CAPABILITY query, so if Gscan is not supported, roaming_capa
+    // is not set (uses initial value 0).
+    // To de-couple roaming with Gscan, set default values for roaming_capa
+    // if Gscan is not supported.
+    // TODO: removes below if driver has new API to get roaming_capa.
+    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
+        info->capa.roaming_capa.max_whitelist_size = WLAN_ROAM_MAX_NUM_WHITE_LIST;
+        info->capa.roaming_capa.max_blacklist_size = WLAN_ROAM_MAX_NUM_BLACK_LIST;
+    }
+    memcpy(caps, &info->capa.roaming_capa, sizeof(wifi_roaming_capabilities));
+
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_configure_roaming(wifi_interface_handle iface, wifi_roaming_config *roaming_config)
+{
+    wifi_error ret;
+    int requestId;
+    wifi_bssid_params bssid_params;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (!roaming_config) {
+        ALOGE("%s: Invalid Buffer provided. Exit", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate it randomly.
+     */
+    requestId = get_requestid();
+
+    /* Set bssid blacklist */
+    if (roaming_config->num_blacklist_bssid > info->capa.roaming_capa.max_blacklist_size) {
+        ALOGE("%s: Number of blacklist bssids(%d) provided is more than maximum blacklist bssids(%d)"
+              " supported", __FUNCTION__, roaming_config->num_blacklist_bssid,
+              info->capa.roaming_capa.max_blacklist_size);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+    bssid_params.num_bssid = roaming_config->num_blacklist_bssid;
+
+    memcpy(bssid_params.bssids, roaming_config->blacklist_bssid,
+           (bssid_params.num_bssid * sizeof(mac_addr)));
+
+    ret = wifi_set_bssid_blacklist(requestId, iface, bssid_params);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to configure blacklist bssids", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Set ssid whitelist */
+    if (roaming_config->num_whitelist_ssid > info->capa.roaming_capa.max_whitelist_size) {
+        ALOGE("%s: Number of whitelist ssid(%d) provided is more than maximum whitelist ssids(%d) "
+              "supported", __FUNCTION__, roaming_config->num_whitelist_ssid,
+              info->capa.roaming_capa.max_whitelist_size);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    // Framework is always sending SSID length as 32 though null terminated lengths
+    // are lesser. Thus update correct lengths before sending to driver.
+    for (int i = 0; i < roaming_config->num_whitelist_ssid; i++) {
+        int j;
+
+        for (j = 0; j < roaming_config->whitelist_ssid[i].length; j++) {
+            if (roaming_config->whitelist_ssid[i].ssid_str[j] == '\0')
+                break;
+        }
+
+        if (roaming_config->whitelist_ssid[i].length == j)
+            continue;
+
+        ALOGI("%s: ssid_str %s reported length = %d , null terminated length = %d", __FUNCTION__,
+              roaming_config->whitelist_ssid[i].ssid_str,
+              roaming_config->whitelist_ssid[i].length, j);
+        roaming_config->whitelist_ssid[i].length = j;
+    }
+
+    ret = wifi_set_ssid_white_list(requestId, iface, roaming_config->num_whitelist_ssid,
+                                   roaming_config->whitelist_ssid);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Failed to configure whitelist ssids", __FUNCTION__);
+
+    return ret;
+}
+
+/* Enable/disable firmware roaming */
+wifi_error wifi_enable_firmware_roaming(wifi_interface_handle iface, fw_roaming_state_t state)
+{
+    int requestId;
+    wifi_error ret;
+    RoamCommand *roamCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    qca_roaming_policy policy;
+
+    ALOGV("%s: set firmware roam state : %d", __FUNCTION__, state);
+
+    if (state == ROAMING_ENABLE) {
+        policy = QCA_ROAMING_ALLOWED_WITHIN_ESS;
+    } else if(state == ROAMING_DISABLE) {
+        policy = QCA_ROAMING_NOT_ALLOWED;
+    } else {
+        ALOGE("%s: Invalid state provided: %d. Exit \n", __FUNCTION__, state);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate it randomly.
+     */
+    requestId = get_requestid();
+
+    roamCommand =
+         new RoamCommand(wifiHandle,
+                          requestId,
+                          OUI_QCA,
+                          QCA_NL80211_VENDOR_SUBCMD_ROAMING);
+    if (roamCommand == NULL) {
+        ALOGE("%s: Failed to create object of RoamCommand class", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = roamCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to create NL message,  Error: %d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = roamCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to set interface Id of message, Error: %d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY, policy);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to add roaming policy atribute, Error: %d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    roamCommand->attr_end(nlData);
+
+    ret = roamCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete roamCommand;
+    return ret;
+}
diff --git a/qcwcn/wifi_hal/roamcommand.h b/wcn6740/qcwcn/wifi_hal/roamcommand.h
similarity index 100%
copy from qcwcn/wifi_hal/roamcommand.h
copy to wcn6740/qcwcn/wifi_hal/roamcommand.h
diff --git a/wcn6740/qcwcn/wifi_hal/rssi_monitor.cpp b/wcn6740/qcwcn/wifi_hal/rssi_monitor.cpp
new file mode 100644
index 0000000..a2038f8
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/rssi_monitor.cpp
@@ -0,0 +1,380 @@
+/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "rssi_monitor.h"
+
+/* Used to handle rssi command events from driver/firmware.*/
+typedef struct rssi_monitor_event_handler_s {
+    RSSIMonitorCommand* mRSSIMonitorCommandInstance;
+} rssi_monitor_event_handlers;
+
+wifi_error initializeRSSIMonitorHandler(hal_info *info)
+{
+    info->rssi_handlers = (rssi_monitor_event_handlers *)malloc(sizeof(
+                              rssi_monitor_event_handlers));
+    if (info->rssi_handlers) {
+        memset(info->rssi_handlers, 0, sizeof(rssi_monitor_event_handlers));
+    }
+    else {
+        ALOGE("%s: Allocation of RSSI event handlers failed",
+              __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return WIFI_SUCCESS;
+}
+
+wifi_error cleanupRSSIMonitorHandler(hal_info *info)
+{
+    rssi_monitor_event_handlers* event_handlers;
+    if (info && info->rssi_handlers) {
+        event_handlers = (rssi_monitor_event_handlers*) info->rssi_handlers;
+        if (event_handlers->mRSSIMonitorCommandInstance) {
+            delete event_handlers->mRSSIMonitorCommandInstance;
+        }
+        memset(event_handlers, 0, sizeof(rssi_monitor_event_handlers));
+        free(info->rssi_handlers);
+        info->rssi_handlers = NULL;
+        return WIFI_SUCCESS;
+    }
+    ALOGE ("%s: info or info->rssi_handlers NULL", __FUNCTION__);
+    return WIFI_ERROR_UNKNOWN;
+}
+
+void RSSIMonitorCommand::enableEventHandling()
+{
+    pthread_mutex_lock(&rm_lock);
+    mEventHandlingEnabled = true;
+    pthread_mutex_unlock(&rm_lock);
+}
+
+void RSSIMonitorCommand::disableEventHandling()
+{
+    pthread_mutex_lock(&rm_lock);
+    mEventHandlingEnabled = false;
+    pthread_mutex_unlock(&rm_lock);
+}
+
+bool RSSIMonitorCommand::isEventHandlingEnabled()
+{
+    bool eventHandlingEnabled;
+    pthread_mutex_lock(&rm_lock);
+    eventHandlingEnabled = mEventHandlingEnabled;
+    pthread_mutex_unlock(&rm_lock);
+
+    return eventHandlingEnabled;
+}
+
+void RSSIMonitorCommand::setCallbackHandler(wifi_rssi_event_handler handler)
+{
+    mHandler = handler;
+}
+
+RSSIMonitorCommand::RSSIMonitorCommand(wifi_handle handle, int id,
+                                       u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    memset(&mHandler, 0, sizeof(mHandler));
+    if (registerVendorHandler(vendor_id, subcmd)) {
+        /* Error case should not happen print log */
+        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
+              __FUNCTION__, vendor_id, subcmd);
+    }
+    pthread_mutex_init(&rm_lock, NULL);
+    disableEventHandling();
+}
+
+RSSIMonitorCommand::~RSSIMonitorCommand()
+{
+    unregisterVendorHandler(mVendor_id, mSubcmd);
+    pthread_mutex_destroy(&rm_lock);
+}
+
+void RSSIMonitorCommand::setReqId(wifi_request_id reqid)
+{
+    mId = reqid;
+}
+
+RSSIMonitorCommand* RSSIMonitorCommand::instance(wifi_handle handle,
+                                                 wifi_request_id id)
+{
+    if (handle == NULL) {
+        ALOGE("Interface Handle is invalid");
+        return NULL;
+    }
+    hal_info *info = getHalInfo(handle);
+    if (!info || !info->rssi_handlers) {
+        ALOGE("rssi_handlers is invalid");
+        return NULL;
+    }
+
+    RSSIMonitorCommand* mRSSIMonitorCommandInstance =
+        info->rssi_handlers->mRSSIMonitorCommandInstance;
+
+    if (mRSSIMonitorCommandInstance == NULL) {
+        mRSSIMonitorCommandInstance = new RSSIMonitorCommand(handle, id,
+                OUI_QCA,
+                QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI);
+        info->rssi_handlers->mRSSIMonitorCommandInstance = mRSSIMonitorCommandInstance;
+        return mRSSIMonitorCommandInstance;
+    }
+    else
+    {
+        if (handle != getWifiHandle(mRSSIMonitorCommandInstance->mInfo))
+        {
+            /* upper layer must have cleaned up the handle and reinitialized,
+               so we need to update the same */
+            ALOGV("Handle different, update the handle");
+            mRSSIMonitorCommandInstance->mInfo = (hal_info *)handle;
+        }
+        mRSSIMonitorCommandInstance->setReqId(id);
+    }
+    return mRSSIMonitorCommandInstance;
+}
+
+/* This function will be the main handler for incoming event.
+ * Call the appropriate callback handler after parsing the vendor data.
+ */
+int RSSIMonitorCommand::handleEvent(WifiEvent &event)
+{
+    int ret = WIFI_SUCCESS;
+
+    if (isEventHandlingEnabled() == false) {
+        ALOGE("%s: RSSI monitor isn't running or already stopped. "
+              "Nothing to do. Exit", __FUNCTION__);
+        return ret;
+    }
+
+    WifiVendorCommand::handleEvent(event);
+
+    /* Parse the vendordata and get the attribute */
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI:
+        {
+            mac_addr addr;
+            s8 rssi;
+            wifi_request_id reqId;
+            struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
+                                     + 1];
+            nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX,
+                    (struct nlattr *)mVendorData,
+                    mDataLen, NULL);
+
+            memset(addr, 0, sizeof(mac_addr));
+
+            if (!tb_vendor[
+                QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID])
+            {
+                ALOGE("%s: ATTR_RSSI_MONITORING_REQUEST_ID not found. Exit.",
+                    __FUNCTION__);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                break;
+            }
+            reqId = nla_get_u32(
+                    tb_vendor[QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID]
+                    );
+            /* If event has a different request_id, ignore that and use the
+             *  request_id value which we're maintaining.
+             */
+            if (reqId != id()) {
+                ALOGV("%s: Event has Req. ID:%d <> Ours:%d, continue...",
+                    __FUNCTION__, reqId, id());
+                reqId = id();
+            }
+            ret = get_mac_addr(tb_vendor,
+                    QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
+                    addr);
+            if (ret != WIFI_SUCCESS) {
+                return ret;
+            }
+            ALOGV(MAC_ADDR_STR, MAC_ADDR_ARRAY(addr));
+
+            if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI])
+            {
+                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI"
+                      " not found", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            rssi = get_s8(tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI]);
+            ALOGV("Current RSSI : %d ", rssi);
+
+            if (mHandler.on_rssi_threshold_breached)
+                (*mHandler.on_rssi_threshold_breached)(reqId, addr, rssi);
+            else
+                ALOGE("RSSI Monitoring: No Callback registered: ");
+        }
+        break;
+
+        default:
+            /* Error case should not happen print log */
+            ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd);
+    }
+
+    return ret;
+}
+
+wifi_error wifi_start_rssi_monitoring(wifi_request_id id,
+                                      wifi_interface_handle iface,
+                                      s8 max_rssi,
+                                      s8 min_rssi,
+                                      wifi_rssi_event_handler eh)
+{
+    wifi_error ret;
+    struct nlattr *nlData;
+    WifiVendorCommand *vCommand = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    RSSIMonitorCommand *rssiCommand;
+
+    ret = initialize_vendor_cmd(iface, id,
+                                QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
+                                &vCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        return ret;
+    }
+
+    ALOGV("%s: Max RSSI:%d Min RSSI:%d", __FUNCTION__,
+          max_rssi, min_rssi);
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL,
+                             QCA_WLAN_RSSI_MONITORING_START);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
+                            id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ret = vCommand->put_s8(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI,
+                           max_rssi);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ret = vCommand->put_s8(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI,
+                           min_rssi);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    vCommand->attr_end(nlData);
+
+    rssiCommand = RSSIMonitorCommand::instance(wifiHandle, id);
+    if (rssiCommand == NULL) {
+        ALOGE("%s: Error rssiCommand NULL", __FUNCTION__);
+        ret = WIFI_ERROR_OUT_OF_MEMORY;
+        goto cleanup;
+    }
+
+    rssiCommand->setCallbackHandler(eh);
+
+    ret = vCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    rssiCommand->enableEventHandling();
+
+cleanup:
+    delete vCommand;
+    return ret;
+}
+
+wifi_error wifi_stop_rssi_monitoring(wifi_request_id id,
+                                     wifi_interface_handle iface)
+{
+    wifi_error ret;
+    struct nlattr *nlData;
+    WifiVendorCommand *vCommand = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    RSSIMonitorCommand *rssiCommand;
+    rssi_monitor_event_handlers* event_handlers;
+    hal_info *info = getHalInfo(wifiHandle);
+
+    event_handlers = info->rssi_handlers;
+    rssiCommand = event_handlers->mRSSIMonitorCommandInstance;
+
+    if (rssiCommand == NULL ||
+        rssiCommand->isEventHandlingEnabled() == false) {
+        ALOGE("%s: RSSI monitor isn't running or already stopped. "
+            "Nothing to do. Exit", __FUNCTION__);
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    ret = initialize_vendor_cmd(iface, id,
+                                QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
+                                &vCommand);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __FUNCTION__);
+        return ret;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL,
+                            QCA_WLAN_RSSI_MONITORING_STOP);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
+                            id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    vCommand->attr_end(nlData);
+
+    ret = vCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    rssiCommand->disableEventHandling();
+
+cleanup:
+    delete vCommand;
+    return ret;
+}
diff --git a/qcwcn/wifi_hal/rssi_monitor.h b/wcn6740/qcwcn/wifi_hal/rssi_monitor.h
similarity index 100%
copy from qcwcn/wifi_hal/rssi_monitor.h
copy to wcn6740/qcwcn/wifi_hal/rssi_monitor.h
diff --git a/wcn6740/qcwcn/wifi_hal/rtt.cpp b/wcn6740/qcwcn/wifi_hal/rtt.cpp
new file mode 100644
index 0000000..785af6d
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/rtt.cpp
@@ -0,0 +1,383 @@
+/* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG  "WifiHAL"
+#include <cutils/sched_policy.h>
+#include <unistd.h>
+
+#include <utils/Log.h>
+#include <time.h>
+
+#include "common.h"
+#include "cpp_bindings.h"
+#include "rtt.h"
+#include "wifi_hal.h"
+#include "wifihal_internal.h"
+
+/* Implementation of the API functions exposed in rtt.h */
+wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
+                                     wifi_rtt_capabilities *capabilities)
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+
+    if (iface == NULL) {
+        ALOGE("wifi_get_rtt_capabilities: NULL iface pointer provided."
+            " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (capabilities == NULL) {
+        ALOGE("wifi_get_rtt_capabilities: NULL capabilities pointer provided."
+            " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* RTT commands are diverted through LOWI interface. */
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
+     * LOWI if it isn't up yet.
+     */
+    lowiWifiHalApi = getLowiCallbackTable(
+                ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->get_rtt_capabilities == NULL) {
+        ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.");
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = (wifi_error)lowiWifiHalApi->get_rtt_capabilities(iface, capabilities);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("wifi_get_rtt_capabilities: lowi_wifihal_get_rtt_capabilities "
+            "returned error:%d. Exit.", ret);
+
+    return ret;
+}
+
+/* API to request RTT measurement */
+wifi_error wifi_rtt_range_request(wifi_request_id id,
+                                    wifi_interface_handle iface,
+                                    unsigned num_rtt_config,
+                                    wifi_rtt_config rtt_config[],
+                                    wifi_rtt_event_handler handler)
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+    hal_info *info = NULL;
+
+    if (iface == NULL) {
+        ALOGE("wifi_rtt_range_request: NULL iface pointer provided."
+            " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    info = getHalInfo(wifiHandle);
+    if (!info)
+    {
+        ALOGE("%s: hal_info is null ", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_D2AP_RTT)) {
+        ALOGE("%s: RTT is not supported by driver", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if (rtt_config == NULL) {
+        ALOGE("wifi_rtt_range_request: NULL rtt_config pointer provided."
+            " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (num_rtt_config <= 0) {
+        ALOGE("wifi_rtt_range_request: number of destination BSSIDs to "
+            "measure RTT on = 0. Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (handler.on_rtt_results == NULL) {
+        ALOGE("wifi_rtt_range_request: NULL capabilities pointer provided."
+            " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* RTT commands are diverted through LOWI interface. */
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
+     * LOWI if it isn't up yet.
+     */
+    lowiWifiHalApi = getLowiCallbackTable(
+                    ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->rtt_range_request == NULL) {
+        ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.");
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = (wifi_error)lowiWifiHalApi->rtt_range_request(id, iface,
+                                                        num_rtt_config,
+                                                        rtt_config, handler);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("wifi_rtt_range_request: lowi_wifihal_rtt_range_request "
+            "returned error:%d. Exit.", ret);
+
+    return ret;
+}
+
+/* API to cancel RTT measurements */
+wifi_error wifi_rtt_range_cancel(wifi_request_id id,
+                                   wifi_interface_handle iface,
+                                   unsigned num_devices,
+                                   mac_addr addr[])
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+
+    if (iface == NULL) {
+        ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided."
+            " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (addr == NULL) {
+        ALOGE("wifi_rtt_range_cancel: NULL addr pointer provided."
+            " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (num_devices <= 0) {
+        ALOGE("wifi_rtt_range_cancel: number of destination BSSIDs to "
+            "measure RTT on = 0. Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* RTT commands are diverted through LOWI interface. */
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
+     * LOWI if it isn't up yet.
+     */
+    lowiWifiHalApi = getLowiCallbackTable(
+                    ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->rtt_range_cancel == NULL) {
+        ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.");
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = (wifi_error)lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel "
+            "returned error:%d. Exit.", ret);
+
+    return ret;
+}
+
+// API to configure the LCI. Used in RTT Responder mode only
+wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface,
+                        wifi_lci_information *lci)
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+
+    if (iface == NULL) {
+        ALOGE("%s: NULL iface pointer provided."
+            " Exit.", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (lci == NULL) {
+        ALOGE("%s: NULL lci pointer provided."
+            " Exit.", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* RTT commands are diverted through LOWI interface. */
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
+     * LOWI if it isn't up yet.
+     */
+    lowiWifiHalApi = getLowiCallbackTable(
+                    ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->rtt_set_lci == NULL) {
+        ALOGE("%s: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
+
+    return ret;
+}
+
+// API to configure the LCR. Used in RTT Responder mode only.
+wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface,
+                        wifi_lcr_information *lcr)
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+
+    if (iface == NULL) {
+        ALOGE("%s: NULL iface pointer provided."
+            " Exit.", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if (lcr == NULL) {
+        ALOGE("%s: NULL lcr pointer provided."
+            " Exit.", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* RTT commands are diverted through LOWI interface. */
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
+     * LOWI if it isn't up yet.
+     */
+    lowiWifiHalApi = getLowiCallbackTable(
+                    ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->rtt_set_lcr == NULL) {
+        ALOGE("%s: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
+
+    return ret;
+}
+
+/*
+ * Get RTT responder information e.g. WiFi channel to enable responder on.
+ */
+wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
+                                      wifi_rtt_responder *responder_info)
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+
+    if (iface == NULL || responder_info == NULL) {
+        ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface,
+               responder_info);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
+    lowiWifiHalApi = getLowiCallbackTable(
+                    ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->rtt_get_responder_info == NULL) {
+        ALOGE("%s: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = lowiWifiHalApi->rtt_get_responder_info(iface, responder_info);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
+
+    return ret;
+}
+
+/**
+ * Enable RTT responder mode.
+ * channel_hint - hint of the channel information where RTT responder should
+ *                be enabled on.
+ * max_duration_seconds - timeout of responder mode.
+ * responder_info - responder information e.g. channel used for RTT responder,
+ *                  NULL if responder is not enabled.
+ */
+wifi_error wifi_enable_responder(wifi_request_id id,
+                                 wifi_interface_handle iface,
+                                 wifi_channel_info channel_hint,
+                                 unsigned max_duration_seconds,
+                                 wifi_rtt_responder *responder_info)
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+
+    if (iface == NULL || responder_info == NULL) {
+        ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface, responder_info);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
+    lowiWifiHalApi = getLowiCallbackTable(
+                    ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->enable_responder == NULL) {
+        ALOGE("%s: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = lowiWifiHalApi->enable_responder(id, iface, channel_hint,
+                                           max_duration_seconds,
+                                           responder_info);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
+
+    return ret;
+}
+
+
+/**
+ * Disable RTT responder mode.
+ */
+wifi_error wifi_disable_responder(wifi_request_id id,
+                                  wifi_interface_handle iface)
+
+{
+    wifi_error ret;
+    lowi_cb_table_t *lowiWifiHalApi = NULL;
+
+    if (iface == NULL) {
+        ALOGE("%s: iface : %p", __FUNCTION__, iface);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
+    lowiWifiHalApi = getLowiCallbackTable(
+                    ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
+    if (lowiWifiHalApi == NULL ||
+        lowiWifiHalApi->disable_responder == NULL) {
+        ALOGE("%s: getLowiCallbackTable returned NULL or "
+            "the function pointer is NULL. Exit.", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = lowiWifiHalApi->disable_responder(id, iface);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
+
+    return ret;
+}
diff --git a/qcwcn/wifi_hal/sync.h b/wcn6740/qcwcn/wifi_hal/sync.h
similarity index 100%
copy from qcwcn/wifi_hal/sync.h
copy to wcn6740/qcwcn/wifi_hal/sync.h
diff --git a/wcn6740/qcwcn/wifi_hal/tcp_params_update.cpp b/wcn6740/qcwcn/wifi_hal/tcp_params_update.cpp
new file mode 100644
index 0000000..c2c21e9
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/tcp_params_update.cpp
@@ -0,0 +1,374 @@
+/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "vendor_definitions.h"
+#include <netlink/genl/genl.h>
+#include <string.h>
+#include <net/if.h>
+#include "tcp_params_update.h"
+
+TCPParamCommand::TCPParamCommand(wifi_handle handle, int id,
+                    u32 vendor_id, u32 subcmd)
+    : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    if (registerVendorHandler(vendor_id, subcmd)) {
+        /* Error case should not happen print log */
+        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
+                        __FUNCTION__, vendor_id, subcmd);
+    }
+    memset(def_tcp_limit_output_bytes, 0, SIZE_TCP_PARAM);
+    memset(def_tcp_adv_win_scale, 0, SIZE_TCP_PARAM);
+    def_tcp_limit_output_bytes_valid = false;
+    def_tcp_adv_win_scale_valid = false;
+}
+
+TCPParamCommand::~TCPParamCommand()
+{
+    unregisterVendorHandler(OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT);
+}
+
+TCPParamCommand *TCPParamCommand::instance(wifi_handle handle, wifi_request_id id)
+{
+    TCPParamCommand* mTCPParamCommandInstance;
+
+    mTCPParamCommandInstance = new TCPParamCommand(handle, id, OUI_QCA,
+                        QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT);
+    return mTCPParamCommandInstance;
+}
+
+/* This function will be the main handler for incoming event.
+ * Call the appropriate callback handler after parsing the vendor data.
+ */
+int TCPParamCommand::handleEvent(WifiEvent &event)
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    WifiVendorCommand::handleEvent(event);
+
+    u8 tpDirection, tpLevel;
+    u32 tcpLimitOutputBytes;
+    u8 tcpLimitOutputBytesFlag = 0;
+    s8 tcpAdvWinScale;
+    u8 tcpAdvWinScaleFlag = 0;
+    u32 tcpDelackSeg;
+    u8 tcpDelackSegFlag = 0;
+    char value_to_str[100];
+    int ret_val = 0;
+
+    /* Parse the vendordata and get the attribute */
+    switch(mSubcmd) {
+    case QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT:
+    {
+        struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_MAX + 1];
+
+        nla_parse(tb, QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_MAX,
+                    (struct nlattr *)mVendorData, mDataLen, NULL);
+
+        if (!tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION] ||
+            !tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL]) {
+            ALOGE("Invalid event, didn't receive mandatory attributes");
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        tpDirection = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION]);
+        tpLevel = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL]);
+
+        if (tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES]) {
+            tcpLimitOutputBytes = nla_get_u32(tb[
+            QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES]);
+            tcpLimitOutputBytesFlag = 1;
+        }
+
+        if (tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE]) {
+            tcpAdvWinScale = *(s8 *)nla_data(tb[
+            QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE]);
+            tcpAdvWinScaleFlag = 1;
+        }
+
+        if (tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG]) {
+            tcpDelackSeg = nla_get_u32(tb[
+            QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG]);
+            tcpDelackSegFlag = 1;
+        }
+        if (tpDirection == TP_CHANGE_RX) {
+            switch(tpLevel) {
+            case QCA_WLAN_THROUGHPUT_LEVEL_LOW:
+            {
+                if (def_tcp_adv_win_scale_valid)
+                    wlan_service_set_tcp_adv_win_scale(def_tcp_adv_win_scale);
+                wlan_service_set_tcp_use_userconfig("0");
+            }
+            break;
+            case QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM:
+            case QCA_WLAN_THROUGHPUT_LEVEL_HIGH:
+            {
+                if (tcpAdvWinScaleFlag) {
+                    ret_val = snprintf(value_to_str, sizeof(value_to_str), "%d",
+                                            tcpAdvWinScale);
+                    if (ret_val < 0 || ret_val >= (int)sizeof(value_to_str)) {
+                        ALOGE("Error in converting value to string: %d", ret_val);
+                        ret = WIFI_ERROR_UNKNOWN;
+                        goto cleanup;
+                    }
+                    wlan_service_set_tcp_adv_win_scale(value_to_str);
+                }
+                if (tcpDelackSegFlag && wlan_service_set_tcp_use_userconfig("1") == 0) {
+                    ret_val = snprintf(value_to_str, sizeof(value_to_str), "%d",
+                                            tcpDelackSeg);
+                    if (ret_val < 0 || ret_val >= (int)sizeof(value_to_str)) {
+                        ALOGE("Error in converting value to string: %d", ret_val);
+                        ret = WIFI_ERROR_UNKNOWN;
+                        goto cleanup;
+                    }
+                    wlan_service_set_tcp_delack_seg(value_to_str);
+                 }
+            }
+            break;
+            default:
+            {
+                /* Error case should not happen print log */
+                ALOGE("%s: Invalid throughput level value", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            }
+        } else if (tpDirection == TP_CHANGE_TX) {
+            switch(tpLevel) {
+            case QCA_WLAN_THROUGHPUT_LEVEL_LOW:
+            {
+                if (def_tcp_limit_output_bytes_valid)
+                    wlan_service_set_tcp_limit_output_bytes(
+                                    def_tcp_limit_output_bytes);
+            }
+            break;
+            case QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM:
+            case QCA_WLAN_THROUGHPUT_LEVEL_HIGH:
+            {
+                if (tcpLimitOutputBytesFlag) {
+                    ret_val = snprintf(value_to_str, sizeof(value_to_str), "%d",
+                                            tcpLimitOutputBytes);
+                    if (ret_val < 0 || ret_val >= (int)sizeof(value_to_str)) {
+                        ALOGE("Error in converting value to string: %d", ret_val);
+                        ret = WIFI_ERROR_UNKNOWN;
+                        goto cleanup;
+                    }
+                    wlan_service_set_tcp_limit_output_bytes(value_to_str);
+                }
+            }
+            break;
+            default:
+            {
+                /* Error case should not happen print log */
+                ALOGE("%s: Invalid throughput level value", __FUNCTION__);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            }
+        } else {
+            /* Error case should not happen print log */
+            ALOGE("%s: Invalid throughput change direction", __FUNCTION__);
+            return ret;
+        }
+        ret = WIFI_SUCCESS;
+    }
+    break;
+    default:
+        /* Error case should not happen print log */
+        ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd);
+        break;
+    }
+
+    return ret;
+
+cleanup:
+    return ret;
+}
+
+wifi_error wifi_init_tcp_param_change_event_handler(wifi_interface_handle iface)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    TCPParamCommand *tcpParamCommand;
+
+    if (wifiHandle == NULL) {
+        ALOGE("%s: Interface Handle is invalid", __func__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    hal_info *info = getHalInfo(wifiHandle);
+    if (!info)
+        return WIFI_ERROR_UNKNOWN;
+
+    tcpParamCommand = TCPParamCommand::instance(wifiHandle, 0);
+    if (tcpParamCommand == NULL) {
+        ALOGE("%s: Error TcpParamCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    info->tcp_param_handler = (tcp_param_cmd_handler *)malloc(sizeof(tcp_param_cmd_handler));
+    if (info->tcp_param_handler == NULL) {
+        ALOGE("%s: Allocation of tcp handler failed",__FUNCTION__);
+        delete tcpParamCommand;
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    info->tcp_param_handler->tcpParamCommand = tcpParamCommand;
+
+    if (wlan_service_read_sys_param("/proc/sys/net/ipv4/tcp_limit_output_bytes",
+                    tcpParamCommand->def_tcp_limit_output_bytes,
+                    SIZE_TCP_PARAM) == 0) {
+        tcpParamCommand->def_tcp_limit_output_bytes_valid = true;
+    }
+
+    if (wlan_service_read_sys_param("/proc/sys/net/ipv4/tcp_adv_win_scale",
+                    tcpParamCommand->def_tcp_adv_win_scale,
+                    SIZE_TCP_PARAM) == 0) {
+        tcpParamCommand->def_tcp_adv_win_scale_valid = true;
+    }
+
+    return WIFI_SUCCESS;
+}
+
+void cleanupTCPParamCommand(hal_info *info) {
+
+    TCPParamCommand *tcpParamCommand;
+
+    if (info == NULL || info->tcp_param_handler == NULL)
+        return;
+
+    tcpParamCommand = info->tcp_param_handler->tcpParamCommand;
+
+    if (tcpParamCommand) {
+        if (tcpParamCommand->def_tcp_limit_output_bytes_valid)
+            wlan_service_update_sys_param("/proc/sys/net/ipv4/tcp_limit_output_bytes",
+                              tcpParamCommand->def_tcp_limit_output_bytes);
+        wlan_service_update_sys_param("/proc/sys/net/ipv4/tcp_use_userconfig", "0");
+        if (tcpParamCommand->def_tcp_adv_win_scale_valid)
+            wlan_service_update_sys_param("/proc/sys/net/ipv4/tcp_adv_win_scale",
+                              tcpParamCommand->def_tcp_adv_win_scale);
+        delete tcpParamCommand;
+    }
+
+    free(info->tcp_param_handler);
+
+    return;
+}
+
+/**
+ * wlan_service_update_sys_param()
+ * @path: path on the file system to be modified
+ * @str:  value to be written to the path
+ *
+ * Generic function to update a system parameter
+ * Return: WIFI_SUCCESS code if read is successful
+ *         Eror code if read is failure
+ */
+wifi_error wlan_service_update_sys_param(const char *path, const char *str)
+{
+    int ret;
+    FILE *fp;
+    fp = fopen(path, "w");
+
+    if (fp == NULL) {
+        ALOGE("%s: unable to open %s", __FUNCTION__, path);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ALOGD("%s: %s %s", __FUNCTION__,  path, str);
+
+    ret = fputs(str, fp);
+    fclose(fp);
+
+    if (ret < 0) {
+        ALOGE("%s: failed to write %s to %s with err %d", __FUNCTION__, str, path, ret);
+        return mapKernelErrortoWifiHalError(ret);
+    }
+
+    return WIFI_SUCCESS;
+}
+
+/**
+ * wlan_service_read_sys_param()
+ * @path: path on the file system to be read
+ * @str:  value read from the path
+ *
+ * Generic function to read a system parameter
+ * Return: WIFI_SUCCESS code if read is successful
+ *         Eror code if read is failure
+ */
+wifi_error wlan_service_read_sys_param(const char *path, char *str, size_t max_size)
+{
+    size_t ret_len;
+    FILE *fp = fopen(path, "r");
+
+    if (fp == NULL) {
+        ALOGE("%s: unable to open %s", __FUNCTION__, path);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret_len = fread(str, 1, max_size, fp);
+    fclose(fp);
+
+    if (ret_len == 0 || ret_len == max_size) {
+        ALOGE("Faild to read %s, ret_len = %zu", path, ret_len);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ALOGD("%s: %s %s", __FUNCTION__,  path, str);
+    return WIFI_SUCCESS;
+}
+
+int TCPParamCommand::wlan_service_set_tcp_adv_win_scale(char *str)
+{
+    return wlan_service_update_sys_param(
+        "/proc/sys/net/ipv4/tcp_adv_win_scale", str);
+}
+
+int TCPParamCommand::wlan_service_set_tcp_use_userconfig(const char *str)
+{
+    return wlan_service_update_sys_param(
+        "/proc/sys/net/ipv4/tcp_use_userconfig", str);
+}
+
+int TCPParamCommand::wlan_service_set_tcp_delack_seg(char *str)
+{
+    return wlan_service_update_sys_param(
+        "/proc/sys/net/ipv4/tcp_delack_seg", str);
+}
+
+int TCPParamCommand::wlan_service_set_tcp_limit_output_bytes(char *str)
+{
+    return wlan_service_update_sys_param (
+        "/proc/sys/net/ipv4/tcp_limit_output_bytes", str);
+}
diff --git a/wcn6740/qcwcn/wifi_hal/tcp_params_update.h b/wcn6740/qcwcn/wifi_hal/tcp_params_update.h
new file mode 100644
index 0000000..184372d
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/tcp_params_update.h
@@ -0,0 +1,81 @@
+/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_TCP_PARAM_UPDATE_COMMAND_H__
+#define __WIFI_HAL_TCP_PARAM_UPDATE_COMMAND_H__
+
+#include "cpp_bindings.h"
+#include "common.h"
+#include <errno.h>
+
+#define SIZE_TCP_PARAM	100
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* Indicates the direction of throughput in which the change is being
+ * reported. u8 attribute. Value is 0 for TX and 1 for RX.
+ */
+typedef enum {
+	TP_CHANGE_TX = 0,
+	TP_CHANGE_RX = 1
+} TpChangeDirection;
+
+wifi_error wlan_service_update_sys_param(const char *path, const char *str);
+wifi_error wlan_service_read_sys_param(const char *path, char *str, size_t max_size);
+void cleanupTCPParamCommand(hal_info *info);
+
+class TCPParamCommand: public WifiVendorCommand
+{
+private:
+	TCPParamCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+	int wlan_service_set_tcp_adv_win_scale(char *str);
+	int wlan_service_set_tcp_use_userconfig(const char *str);
+	int wlan_service_set_tcp_delack_seg(char *str);
+	int wlan_service_set_tcp_limit_output_bytes(char *str);
+
+public:
+	virtual ~TCPParamCommand();
+	static TCPParamCommand *instance(wifi_handle handle,
+					 wifi_request_id id);
+	virtual int handleEvent(WifiEvent &event);
+	char def_tcp_limit_output_bytes[SIZE_TCP_PARAM];
+	bool def_tcp_limit_output_bytes_valid;
+	char def_tcp_adv_win_scale[SIZE_TCP_PARAM];
+	bool def_tcp_adv_win_scale_valid;
+};
+
+/* Used to clean TCPParam object*/
+typedef struct tcp_param_cmd_handler_s {
+	TCPParamCommand *tcpParamCommand;
+} tcp_param_cmd_handler;
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/wcn6740/qcwcn/wifi_hal/tdls.cpp b/wcn6740/qcwcn/wifi_hal/tdls.cpp
new file mode 100644
index 0000000..2082fef
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/tdls.cpp
@@ -0,0 +1,583 @@
+/* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "tdlsCommand.h"
+#include "vendor_definitions.h"
+
+/* Singleton Static Instance */
+TdlsCommand* TdlsCommand::mTdlsCommandInstance  = NULL;
+TdlsCommand::TdlsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    memset(&mHandler, 0, sizeof(mHandler));
+    memset(&mTDLSgetStatusRspParams, 0, sizeof(wifi_tdls_status));
+    mRequestId = 0;
+}
+
+TdlsCommand::~TdlsCommand()
+{
+    mTdlsCommandInstance = NULL;
+    unregisterVendorHandler(mVendor_id, mSubcmd);
+}
+
+TdlsCommand* TdlsCommand::instance(wifi_handle handle)
+{
+    if (handle == NULL) {
+        ALOGE("Interface Handle is invalid");
+        return NULL;
+    }
+    if (mTdlsCommandInstance == NULL) {
+        mTdlsCommandInstance = new TdlsCommand(handle, 0,
+                OUI_QCA,
+                QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE);
+        ALOGV("TdlsCommand %p created", mTdlsCommandInstance);
+        return mTdlsCommandInstance;
+    }
+    else
+    {
+        if (handle != getWifiHandle(mTdlsCommandInstance->mInfo))
+        {
+            /* upper layer must have cleaned up the handle and reinitialized,
+               so we need to update the same */
+            ALOGV("Handle different, update the handle");
+            mTdlsCommandInstance->mInfo = (hal_info *)handle;
+        }
+    }
+    ALOGV("TdlsCommand %p created already", mTdlsCommandInstance);
+    return mTdlsCommandInstance;
+}
+
+void TdlsCommand::setSubCmd(u32 subcmd)
+{
+    mSubcmd = subcmd;
+}
+
+/* This function will be the main handler for incoming event SUBCMD_TDLS
+ * Call the appropriate callback handler after parsing the vendor data.
+ */
+int TdlsCommand::handleEvent(WifiEvent &event)
+{
+    ALOGV("Got a TDLS message from Driver");
+    WifiVendorCommand::handleEvent(event);
+
+    /* Parse the vendordata and get the attribute */
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE:
+            {
+                struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX
+                    + 1];
+                mac_addr addr;
+                wifi_tdls_status status;
+
+                memset(&addr, 0, sizeof(mac_addr));
+                memset(&status, 0, sizeof(wifi_tdls_status));
+                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX,
+                        (struct nlattr *)mVendorData,
+                        mDataLen, NULL);
+
+                ALOGV("QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE Received");
+                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR not found",
+                            __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                memcpy(addr,
+                  (u8 *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]),
+                  nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]));
+
+                ALOGV(MAC_ADDR_STR, MAC_ADDR_ARRAY(addr));
+
+                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_STATE not found",
+                            __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                status.state = (wifi_tdls_state)
+                    get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE]);
+                ALOGV("TDLS: State New : %d ", status.state);
+
+                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_REASON])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_REASON not found",
+                            __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                status.reason = (wifi_tdls_reason)
+                    get_s32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_REASON]);
+                ALOGV("TDLS: Reason : %d ", status.reason);
+
+                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL not found",
+                            __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                status.channel =
+                    get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL]);
+                ALOGV("TDLS: channel : %d ", status.channel);
+
+                if (!tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS"
+                            " not found", __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                status.global_operating_class = get_u32(
+                   tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS]);
+                ALOGV("TDLS: global_operating_class: %d ",
+                        status.global_operating_class);
+
+                if (mHandler.on_tdls_state_changed)
+                    (*mHandler.on_tdls_state_changed)(addr, status);
+                else
+                    ALOGE("TDLS: No Callback registered: ");
+            }
+            break;
+
+        default:
+            /* Error case should not happen print log */
+            ALOGE("%s: Wrong TDLS subcmd received %d", __FUNCTION__, mSubcmd);
+    }
+
+    return NL_SKIP;
+}
+
+int TdlsCommand::handleResponse(WifiEvent &reply)
+{
+    WifiVendorCommand::handleResponse(reply);
+
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS:
+            {
+                struct nlattr *tb_vendor[
+                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
+                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
+                        (struct nlattr *)mVendorData,
+                        mDataLen, NULL);
+
+                ALOGV("QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS Received");
+                memset(&mTDLSgetStatusRspParams, 0, sizeof(wifi_tdls_status));
+
+                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE"
+                            " not found", __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                mTDLSgetStatusRspParams.state = (wifi_tdls_state)get_u32(
+                        tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE]);
+                ALOGV("TDLS: State : %u ", mTDLSgetStatusRspParams.state);
+
+                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON"
+                            " not found", __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                mTDLSgetStatusRspParams.reason = (wifi_tdls_reason)get_s32(
+                        tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON]);
+                ALOGV("TDLS: Reason : %d ", mTDLSgetStatusRspParams.reason);
+
+                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL"
+                            " not found", __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                mTDLSgetStatusRspParams.channel = get_u32(tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL]);
+                ALOGV("TDLS: channel : %d ", mTDLSgetStatusRspParams.channel);
+
+                if (!tb_vendor[
+                  QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS])
+                {
+                    ALOGE("%s:"
+                   "QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS"
+                    " not found", __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                mTDLSgetStatusRspParams.global_operating_class =
+                  get_u32(tb_vendor[
+                  QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]);
+                ALOGV("TDLS: global_operating_class: %d ",
+                        mTDLSgetStatusRspParams.global_operating_class);
+            }
+            break;
+        case QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES:
+            {
+                struct nlattr *tb_vendor[
+                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX + 1];
+                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX,
+                        (struct nlattr *)mVendorData,
+                        mDataLen, NULL);
+
+                memset(&mTDLSgetCaps, 0, sizeof(wifiTdlsCapabilities));
+
+                if (!tb_vendor[
+                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS]
+                   )
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_"
+                          "MAX_CONC_SESSIONS not found", __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                mTDLSgetCaps.maxConcurrentTdlsSessionNum = get_u32(tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS]);
+
+                if (!tb_vendor[
+                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED])
+                {
+                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_"
+                          "FEATURES_SUPPORTED not found", __FUNCTION__);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+                mTDLSgetCaps.tdlsSupportedFeatures = get_u32(tb_vendor[
+                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED]);
+            }
+            break;
+        default :
+            ALOGE("%s: Wrong TDLS subcmd response received %d",
+                __FUNCTION__, mSubcmd);
+    }
+    return NL_SKIP;
+}
+
+
+wifi_error TdlsCommand::setCallbackHandler(wifi_tdls_handler nHandler, u32 event)
+{
+    wifi_error res;
+    mHandler = nHandler;
+
+    res = registerVendorHandler(mVendor_id, event);
+    if (res != WIFI_SUCCESS) {
+        /* Error case should not happen print log */
+        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
+              __FUNCTION__, mVendor_id, mSubcmd);
+    }
+    return res;
+}
+
+void TdlsCommand::unregisterHandler(u32 subCmd)
+{
+    unregisterVendorHandler(mVendor_id, subCmd);
+}
+
+void TdlsCommand::getStatusRspParams(wifi_tdls_status *status)
+{
+    status->channel = mTDLSgetStatusRspParams.channel;
+    status->global_operating_class =
+        mTDLSgetStatusRspParams.global_operating_class;
+    status->state = mTDLSgetStatusRspParams.state;
+    status->reason = mTDLSgetStatusRspParams.reason;
+}
+
+wifi_error TdlsCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+void TdlsCommand::getCapsRspParams(wifi_tdls_capabilities *caps)
+{
+    caps->max_concurrent_tdls_session_num =
+        mTDLSgetCaps.maxConcurrentTdlsSessionNum;
+    caps->is_global_tdls_supported =
+        !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_GLOBAL_TDLS_SUPPORTED);
+    caps->is_per_mac_tdls_supported =
+        !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_PER_MAC_TDLS_SUPPORTED);
+    caps->is_off_channel_tdls_supported =
+        !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_OFF_CHANNEL_TDLS_SUPPORTED);
+    ALOGV("TDLS capabilities:");
+    ALOGV("max_concurrent_tdls_session_numChannel : %d\n",
+            caps->max_concurrent_tdls_session_num);
+    ALOGV("is_global_tdls_supported : %d\n",
+            caps->is_global_tdls_supported);
+    ALOGV("is_per_mac_tdls_supported : %d\n",
+            caps->is_per_mac_tdls_supported);
+    ALOGV("is_off_channel_tdls_supported : %d \n",
+            caps->is_off_channel_tdls_supported);
+}
+
+/* wifi_enable_tdls - enables TDLS-auto mode for a specific route
+ *
+ * params specifies hints, which provide more information about
+ * why TDLS is being sought. The firmware should do its best to
+ * honor the hints before downgrading regular AP link
+ *
+ * On successful completion, must fire on_tdls_state_changed event
+ * to indicate the status of TDLS operation.
+ */
+wifi_error wifi_enable_tdls(wifi_interface_handle iface,
+                            mac_addr addr,
+                            wifi_tdls_params *params,
+                            wifi_tdls_handler handler)
+{
+    wifi_error ret;
+    TdlsCommand *pTdlsCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    pTdlsCommand = TdlsCommand::instance(handle);
+
+    if (pTdlsCommand == NULL) {
+        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE);
+
+    /* Create the message */
+    ret = pTdlsCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = pTdlsCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the attributes */
+    nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    ALOGV("%s: MAC_ADDR: " MAC_ADDR_STR, __FUNCTION__, MAC_ADDR_ARRAY(addr));
+    ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR,
+                                  (char *)addr, 6);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    if (params != NULL) {
+        ALOGV("%s: Channel: %d, Global operating class: %d, "
+            "Max Latency: %dms, Min Bandwidth: %dKbps",
+            __FUNCTION__, params->channel, params->global_operating_class,
+            params->max_latency_ms, params->min_bandwidth_kbps);
+        ret = pTdlsCommand->put_u32(
+                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL,
+                            params->channel);
+        if (ret != WIFI_SUCCESS)
+                goto cleanup;
+        ret = pTdlsCommand->put_u32(
+                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS,
+                            params->global_operating_class);
+        if (ret != WIFI_SUCCESS)
+                goto cleanup;
+        ret = pTdlsCommand->put_u32(
+                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS,
+                            params->max_latency_ms);
+        if (ret != WIFI_SUCCESS)
+                goto cleanup;
+        ret = pTdlsCommand->put_u32(
+                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS,
+                            params->min_bandwidth_kbps);
+        if (ret != WIFI_SUCCESS)
+                goto cleanup;
+    }
+
+    pTdlsCommand->attr_end(nl_data);
+
+    ret = pTdlsCommand->setCallbackHandler(handler,
+                        QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = pTdlsCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    return ret;
+}
+
+/* wifi_disable_tdls - disables TDLS-auto mode for a specific route
+ *
+ * This terminates any existing TDLS with addr device, and frees the
+ * device resources to make TDLS connections on new routes.
+ *
+ * DON'T fire any more events on 'handler' specified in earlier call to
+ * wifi_enable_tdls after this action.
+ */
+wifi_error wifi_disable_tdls(wifi_interface_handle iface, mac_addr addr)
+{
+    wifi_error ret;
+    TdlsCommand *pTdlsCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    pTdlsCommand = TdlsCommand::instance(handle);
+
+    if (pTdlsCommand == NULL) {
+        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE);
+
+    /* Create the message */
+    ret = pTdlsCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = pTdlsCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ALOGV("%s: ifindex obtained:%d", __FUNCTION__, ret);
+    ALOGV("%s: MAC_ADDR: " MAC_ADDR_STR, __FUNCTION__, MAC_ADDR_ARRAY(addr));
+
+    /* Add the attributes */
+    nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR,
+                                  (char *)addr, 6);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    pTdlsCommand->attr_end(nl_data);
+
+    ret = pTdlsCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
+
+cleanup:
+    delete pTdlsCommand;
+    return ret;
+}
+
+/* wifi_get_tdls_status - allows getting the status of TDLS for a specific
+ * route
+ */
+wifi_error wifi_get_tdls_status(wifi_interface_handle iface, mac_addr addr,
+                                wifi_tdls_status *status)
+{
+    wifi_error ret;
+    TdlsCommand *pTdlsCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    pTdlsCommand = TdlsCommand::instance(handle);
+
+    if (pTdlsCommand == NULL) {
+        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS);
+
+    /* Create the message */
+    ret = pTdlsCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = pTdlsCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    ALOGV("%s: ifindex obtained:%d", __FUNCTION__, ret);
+
+    /* Add the attributes */
+    nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR,
+                                  (char *)addr, 6);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    pTdlsCommand->attr_end(nl_data);
+
+    ret = pTdlsCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
+
+    pTdlsCommand->getStatusRspParams(status);
+
+cleanup:
+    return ret;
+}
+
+/* return the current HW + Firmware combination's TDLS capabilities */
+wifi_error wifi_get_tdls_capabilities(wifi_interface_handle iface,
+                                      wifi_tdls_capabilities *capabilities)
+{
+    wifi_error ret;
+    TdlsCommand *pTdlsCommand;
+
+    if (capabilities == NULL) {
+        ALOGE("%s: capabilities is NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    pTdlsCommand = TdlsCommand::instance(handle);
+
+    if (pTdlsCommand == NULL) {
+        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES);
+
+    /* Create the message */
+    ret = pTdlsCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = pTdlsCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = pTdlsCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+    pTdlsCommand->getCapsRspParams(capabilities);
+
+cleanup:
+    if (ret != WIFI_SUCCESS)
+        memset(capabilities, 0, sizeof(wifi_tdls_capabilities));
+    delete pTdlsCommand;
+    return ret;
+}
diff --git a/qcwcn/wifi_hal/tdlsCommand.h b/wcn6740/qcwcn/wifi_hal/tdlsCommand.h
old mode 100755
new mode 100644
similarity index 100%
copy from qcwcn/wifi_hal/tdlsCommand.h
copy to wcn6740/qcwcn/wifi_hal/tdlsCommand.h
diff --git a/qcwcn/wifi_hal/vendor_definitions.h b/wcn6740/qcwcn/wifi_hal/vendor_definitions.h
similarity index 100%
copy from qcwcn/wifi_hal/vendor_definitions.h
copy to wcn6740/qcwcn/wifi_hal/vendor_definitions.h
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp
similarity index 75%
copy from qcwcn/wifi_hal/wifi_hal.cpp
copy to wcn6740/qcwcn/wifi_hal/wifi_hal.cpp
index 372d9e1..73e102a 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp
@@ -12,6 +12,40 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <stdint.h>
@@ -25,7 +59,7 @@
 #include <netpacket/packet.h>
 #include <linux/filter.h>
 #include <linux/errqueue.h>
-
+#include <linux-private/linux/fib_rules.h>
 #include <linux/pkt_sched.h>
 #include <netlink/object-api.h>
 #include <netlink/netlink.h>
@@ -54,6 +88,7 @@
 #include "cpp_bindings.h"
 #include "ifaceeventhandler.h"
 #include "wifiloggercmd.h"
+#include "tcp_params_update.h"
 
 /*
  BUGBUG: normally, libnl allocates ports for all connections it makes; but
@@ -106,6 +141,12 @@
                                             u8 enable);
 wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
                              WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
+static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle handle);
+
+wifi_error
+    wifi_init_tcp_param_change_event_handler(wifi_interface_handle iface);
+
+wifi_error wifi_set_voip_mode(wifi_interface_handle iface, wifi_voip_mode mode);
 
 /* Initialize/Cleanup */
 
@@ -376,6 +417,28 @@
     return ret;
 }
 
+static wifi_error wifi_get_sar_version(wifi_interface_handle handle)
+{
+    wifi_error ret;
+    wifi_handle wifiHandle = getWifiHandle(handle);
+
+    WifihalGeneric *sarVersion = new WifihalGeneric(
+                            wifiHandle,
+                            0,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY);
+    if (!sarVersion) {
+        ALOGE("%s: Failed to create object of WifihalGeneric class", __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+
+    ret = sarVersion->getSarVersion(handle);
+
+    delete sarVersion;
+    return ret;
+}
+
 static wifi_error get_firmware_bus_max_size_supported(
                                                 wifi_interface_handle iface)
 {
@@ -473,6 +536,256 @@
     return WIFI_SUCCESS;
 }
 
+static uint32_t get_frequency_from_channel(uint32_t channel, wlan_mac_band band)
+{
+  uint32_t freq = 0;
+
+  switch (band)
+  {
+    case WLAN_MAC_2_4_BAND:
+      if (!(channel >= 1 && channel <= 14))
+        goto failure;
+      //special handling for channel 14 by filling freq here
+      if (channel == 14)
+        freq = 2484;
+      else
+        freq = 2407 + (channel * 5);
+      break;
+    case WLAN_MAC_5_0_BAND:
+      if (!((channel >= 34 && channel < 65) ||
+          (channel > 99 && channel <= 196)))
+        goto failure;
+      freq = 5000 + (channel * 5);
+      break;
+    case WLAN_MAC_6_0_BAND:
+      if (!(channel >= 1 && channel <= 233))
+        goto failure;
+      freq = 5950 + (channel * 5);
+      break;
+    default:
+      break;
+  }
+
+failure:
+  return freq;
+}
+
+static u32 get_nl_ifmask_from_coex_restriction_mask(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (!in_mask)
+       return op_mask;
+    if (in_mask & SOFTAP)
+         op_mask |= BIT(NL80211_IFTYPE_AP);
+    if (in_mask & WIFI_DIRECT)
+         op_mask |= BIT(NL80211_IFTYPE_P2P_GO);
+    if (in_mask & WIFI_AWARE)
+         op_mask |= BIT(NL80211_IFTYPE_NAN);
+
+    return op_mask;
+}
+
+wifi_error wifi_set_coex_unsafe_channels(wifi_handle handle, u32 num_channels,
+                                         wifi_coex_unsafe_channel *unsafeChannels,
+                                         u32 restrictions)
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    WifihalGeneric *cmd = NULL;
+    struct nlattr *nl_data = NULL;
+    struct nlattr *nl_attr_unsafe_chan = NULL;
+    struct nlattr *unsafe_channels_attr = NULL;
+    hal_info *info = NULL;
+    int freq_cnt = 0;
+    u32 *freq = (u32 *) malloc(sizeof(u32) * num_channels);
+    u32 *power_cap_dbm = (u32 *) malloc(sizeof(u32) * num_channels);
+
+    if (!freq || !power_cap_dbm) {
+        ALOGE("%s: Failed to allocate memory", __FUNCTION__);
+        ret = WIFI_ERROR_OUT_OF_MEMORY;
+        goto cleanup;
+    }
+
+    if (!handle) {
+         ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
+         goto cleanup;
+    }
+
+    info = getHalInfo(handle);
+    if (!info || info->num_interfaces < 1) {
+         ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present",
+               __FUNCTION__);
+         goto cleanup;
+    }
+
+    cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA,
+                             QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT);
+    if (cmd == NULL) {
+         ALOGE("%s: Error, created command NULL", __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    /* Create the NL message. */
+    ret = cmd->create();
+    if (ret < 0) {
+         ALOGE("%s: failed to create NL msg due to error: (%d)",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data) {
+         ALOGE("%s: failed attr_start for NL80211_ATTR_VENDOR_DATA",
+               __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    nl_attr_unsafe_chan = cmd->attr_start(
+        QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE);
+    if (!nl_attr_unsafe_chan) {
+         ALOGE("%s: failed attr_start for"
+               " QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE", __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+    ALOGD("%s: num_channels:%d, restrictions:%x", __FUNCTION__, num_channels,
+          restrictions);
+    for (int i = 0; i < num_channels; i++)
+    {
+        u32 frequency = get_frequency_from_channel(unsafeChannels[i].channel,
+                unsafeChannels[i].band);
+        if (frequency != 0)
+        {
+          freq[freq_cnt] = frequency;
+          power_cap_dbm[freq_cnt] = unsafeChannels[i].power_cap_dbm;
+          freq_cnt++;
+          ALOGV("%s: channel:%d, freq:%d, power_cap_dbm:%d, band:%d",
+               __FUNCTION__, unsafeChannels[i].channel, frequency,
+               unsafeChannels[i].power_cap_dbm, unsafeChannels[i].band);
+        }
+        else {
+            ALOGV("%s: Invalid channel found, channel:%d, power_cap_dbm:%d, band:%d",
+               __FUNCTION__, unsafeChannels[i].channel,
+               unsafeChannels[i].power_cap_dbm, unsafeChannels[i].band);
+        }
+    }
+    if (num_channels == 0) {
+         unsafe_channels_attr = cmd->attr_start(0);
+         if (!unsafe_channels_attr) {
+              ALOGE("%s: failed attr_start for unsafe_channels_attr when"
+                    " trying to clear usafe channels clear", __FUNCTION__);
+              ret = WIFI_ERROR_OUT_OF_MEMORY;
+              goto cleanup;
+         }
+         ret = cmd->put_u32(
+               QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, 0);
+         if (ret != WIFI_SUCCESS) {
+              ALOGE("%s: Failed to put frequency start, ret:%d",
+                    __FUNCTION__, ret);
+              goto cleanup;
+         }
+         ret = cmd->put_u32(
+               QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, 0);
+         if (ret != WIFI_SUCCESS) {
+              ALOGE("%s: Failed to put frequency end, ret:%d",
+                    __FUNCTION__, ret);
+              goto cleanup;
+         }
+         cmd->attr_end(unsafe_channels_attr);
+    }
+    else {
+        if (!unsafeChannels) {
+            ALOGE("%s: unsafe channels buffer should not be NULL when"
+                  " there are unsafe channels", __FUNCTION__);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto cleanup;
+        }
+
+        if(freq_cnt == 0)
+        {
+            ALOGE("%s: No valid frequency, ignore channel list", __FUNCTION__);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto cleanup;
+        }
+        for (int i = 0; i < freq_cnt; i++) {
+            unsafe_channels_attr = cmd->attr_start(i);
+            if (!unsafe_channels_attr) {
+                ALOGE("%s: failed attr_start for unsafe_channels_attr of"
+                    " index:%d", __FUNCTION__, i);
+                ret = WIFI_ERROR_OUT_OF_MEMORY;
+                goto cleanup;
+            }
+
+            ret = cmd->put_u32(
+                  QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, freq[i]);
+            if (ret != WIFI_SUCCESS) {
+                ALOGE("%s: Failed to put frequency start, ret:%d",
+                      __FUNCTION__, ret);
+                goto cleanup;
+            }
+            ret = cmd->put_u32(
+                QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, freq[i]);
+            if (ret != WIFI_SUCCESS) {
+                ALOGE("%s: Failed to put frequency end, ret:%d",
+                    __FUNCTION__, ret);
+                goto cleanup;
+            }
+            /**
+             * WIFI_COEX_NO_POWER_CAP (0x7FFFFFF) is specific to android
+             * framework, this value denotes that framework/wifihal is not
+             * providing any power cap and allow driver/firmware to operate on
+             * current power cap dbm. As driver is supposed to work on with
+             * LA/LE etc, we are skipping to send 0x7FFFFFF down to driver,
+             * hence driver will be operating as per current power cap calculated
+             * based on regulatory or other constraints.
+             */
+            if (power_cap_dbm[i] != WIFI_COEX_NO_POWER_CAP) {
+                ret = cmd->put_s32(
+                      QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM,
+                      power_cap_dbm[i]);
+                if (ret != WIFI_SUCCESS) {
+                    ALOGE("%s: Failed to put power_cap_dbm, ret:%d",
+                          __FUNCTION__, ret);
+                    goto cleanup;
+                }
+            }
+            ALOGD("%s: freq:%d, power_cap_dbm:%d",
+                   __FUNCTION__, freq[i], power_cap_dbm[i]);
+            cmd->attr_end(unsafe_channels_attr);
+        }
+    }
+    cmd->attr_end(nl_attr_unsafe_chan);
+    if (num_channels > 0) {
+        ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK,
+                       get_nl_ifmask_from_coex_restriction_mask(restrictions));
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: Failed to put restrictions mask, ret:%d",
+                  __FUNCTION__, ret);
+            goto cleanup;
+        }
+    }
+    cmd->attr_end(nl_data);
+
+    /* Send the msg and wait for a response. */
+    ret = cmd->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+cleanup:
+    if (cmd)
+        delete cmd;
+    if (freq)
+        free (freq);
+    if (power_cap_dbm)
+        free (power_cap_dbm);
+    return ret;
+}
+
 wifi_error wifi_set_dtim_config(wifi_interface_handle handle, u32 multiplier)
 {
     wifi_error ret = WIFI_ERROR_INVALID_ARGS;
@@ -543,6 +856,161 @@
     return ret;
 }
 
+static u32 get_nl_band_mask(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & WLAN_MAC_2_4_BAND)
+         op_mask |= BIT(NL80211_BAND_2GHZ);
+    if (in_mask & WLAN_MAC_5_0_BAND)
+         op_mask |= BIT(NL80211_BAND_5GHZ);
+    if (in_mask & WLAN_MAC_6_0_BAND)
+         op_mask |= BIT(NL80211_BAND_6GHZ);
+    if (in_mask & WLAN_MAC_60_0_BAND)
+         op_mask |= BIT(NL80211_BAND_60GHZ);
+
+    return op_mask;
+}
+
+static u32 get_nl_iftype_mode_masks(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & BIT(WIFI_INTERFACE_STA) ||
+        in_mask & BIT(WIFI_INTERFACE_TDLS))
+         op_mask |= BIT(NL80211_IFTYPE_STATION);
+    if (in_mask & BIT(WIFI_INTERFACE_SOFTAP))
+         op_mask |= BIT(NL80211_IFTYPE_AP);
+    if (in_mask & BIT(WIFI_INTERFACE_P2P_CLIENT))
+         op_mask |= BIT(NL80211_IFTYPE_P2P_CLIENT);
+    if (in_mask & BIT(WIFI_INTERFACE_P2P_GO))
+         op_mask |= BIT(NL80211_IFTYPE_P2P_GO);
+    if (in_mask & BIT(WIFI_INTERFACE_NAN))
+         op_mask |= BIT(NL80211_IFTYPE_NAN);
+
+    return op_mask;
+}
+
+static u32 get_vendor_filter_mask(u32 in_mask)
+{
+    u32 op_mask = 0;
+
+    if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE)
+         op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX);
+    if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY)
+         op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY);
+
+    return op_mask;
+}
+
+wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask,
+                                    u32 iface_mode_mask, u32 filter_mask,
+                                    u32 max_size, u32* size,
+                                    wifi_usable_channel* channels)
+{
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
+    WifihalGeneric *cmd = NULL;
+    struct nlattr *nl_data = NULL;
+    hal_info *info = NULL;
+    u32 band = 0, iface_mask = 0, filter = 0;
+
+    if (!handle) {
+         ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
+         goto cleanup;
+    }
+
+    info = getHalInfo(handle);
+    if (!info || info->num_interfaces < 1) {
+         ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present",
+               __FUNCTION__);
+         goto cleanup;
+    }
+
+    if (!max_size) {
+         ALOGE("%s: max channel size is zero", __FUNCTION__);
+         ret = WIFI_ERROR_INVALID_ARGS;
+         goto cleanup;
+    }
+
+    if (!channels) {
+         ALOGE("%s: user input channel buffer NULL", __FUNCTION__);
+         ret = WIFI_ERROR_INVALID_ARGS;
+         goto cleanup;
+    }
+
+    cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA,
+                             QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS);
+    if (cmd == NULL) {
+         ALOGE("%s: Error, created command NULL", __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    /* Create the NL message. */
+    ret = cmd->create();
+    if (ret < 0) {
+         ALOGE("%s: failed to create NL msg due to error: (%d)",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data) {
+         ALOGE("%s: failed attr_start for VENDOR_DATA due to error",
+               __FUNCTION__);
+         ret = WIFI_ERROR_OUT_OF_MEMORY;
+         goto cleanup;
+    }
+
+    band = get_nl_band_mask(band_mask);
+    ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK,
+                       band);
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: failed to put vendor data due to error:%d",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    iface_mask = get_nl_iftype_mode_masks(iface_mode_mask);
+    ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK,
+                       iface_mask);
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: failed to put vendor data due to error:%d",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    filter = get_vendor_filter_mask(filter_mask);
+    ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK,
+                       filter);
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: failed to put vendor data due to error:%d",
+               __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    cmd->attr_end(nl_data);
+
+    /* Populate the input received from caller/framework. */
+    cmd->setMaxSetSize(max_size);
+    cmd->set_channels_buff(channels);
+
+    /* Send the msg and wait for a response. */
+    ret = cmd->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+         ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret);
+         goto cleanup;
+    }
+
+    *size = cmd->get_results_size();
+
+cleanup:
+    if (cmd)
+        delete cmd;
+    return ret;
+}
+
 /*initialize function pointer table with Qualcomm HAL API*/
 wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
     if (fn == NULL) {
@@ -640,11 +1108,18 @@
     fn->wifi_select_tx_power_scenario = wifi_select_tx_power_scenario;
     fn->wifi_reset_tx_power_scenario = wifi_reset_tx_power_scenario;
     fn->wifi_set_radio_mode_change_handler = wifi_set_radio_mode_change_handler;
+    /* Customers will uncomment when they want to set qpower*/
+    //fn->wifi_set_qpower = wifi_set_qpower;
     fn->wifi_virtual_interface_create = wifi_virtual_interface_create;
     fn->wifi_virtual_interface_delete = wifi_virtual_interface_delete;
     fn->wifi_set_latency_mode = wifi_set_latency_mode;
     fn->wifi_set_thermal_mitigation_mode = wifi_set_thermal_mitigation_mode;
+    fn->wifi_multi_sta_set_primary_connection = wifi_multi_sta_set_primary_connection;
+    fn->wifi_multi_sta_set_use_case = wifi_multi_sta_set_use_case;
+    fn->wifi_set_coex_unsafe_channels = wifi_set_coex_unsafe_channels;
     fn->wifi_set_dtim_config = wifi_set_dtim_config;
+    fn->wifi_set_voip_mode = wifi_set_voip_mode;
+    fn->wifi_get_usable_channels = wifi_get_usable_channels;
 
     return WIFI_SUCCESS;
 }
@@ -675,7 +1150,7 @@
 
 wifi_error wifi_initialize(wifi_handle *handle)
 {
-    wifi_error ret = WIFI_SUCCESS;
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
     wifi_interface_handle iface_handle;
     struct nl_sock *cmd_sock = NULL;
     struct nl_sock *event_sock = NULL;
@@ -850,6 +1325,7 @@
             free(info->interfaces[i]);
         }
         ALOGE("%s no iface with wlan0", __func__);
+        ret = WIFI_ERROR_UNKNOWN;
         goto unload;
     }
     iface_handle = (wifi_interface_handle)info->interfaces[index];
@@ -952,8 +1428,35 @@
         goto unload;
     }
 
+    ret = initializeRadioHandler(info);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Initializing Radio Event handler Failed");
+        goto unload;
+    }
+
+    ret = wifi_init_tcp_param_change_event_handler(iface_handle);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Initializing TCP param change event Handler Failed");
+        goto unload;
+    }
+
     ALOGV("Initialized Wifi HAL Successfully; vendor cmd = %d Supported"
-            " features : 0x%" PRIx64, NL80211_CMD_VENDOR, info->supported_feature_set);
+            " features : %" PRIx64, NL80211_CMD_VENDOR, info->supported_feature_set);
+
+    if (wifi_is_nan_ext_cmd_supported(iface_handle))
+        info->support_nan_ext_cmd = true;
+    else
+        info->support_nan_ext_cmd = false;
+
+    ALOGV("support_nan_ext_cmd is %d",
+          info->support_nan_ext_cmd);
+
+    ret = wifi_get_sar_version(iface_handle);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to  get  SAR Version, Setting it to default.");
+        info->sar_version = QCA_WLAN_VENDOR_SAR_VERSION_1;
+        ret = WIFI_SUCCESS;
+    }
 
 cld80211_cleanup:
     if (status != 0 || ret != WIFI_SUCCESS) {
@@ -974,9 +1477,12 @@
             }
             if (info->pkt_stats) free(info->pkt_stats);
             if (info->rx_aggr_pkts) free(info->rx_aggr_pkts);
+            if (info->wifihal_ctrl_sock.s) close(info->wifihal_ctrl_sock.s);
             wifi_logger_ring_buffers_deinit(info);
             cleanupGscanHandlers(info);
             cleanupRSSIMonitorHandler(info);
+            cleanupRadioHandler(info);
+            cleanupTCPParamCommand(info);
             free(info->event_cb);
             if (info->driver_supported_features.flags) {
                 free(info->driver_supported_features.flags);
@@ -995,7 +1501,6 @@
     int len, fd, ret = 0, count = 5;
     ts.tv_sec = 0;
     ts.tv_nsec = 200 * 1000000L;
-
     do {
         if (access(WIFI_DRIVER_STATE_CTRL_PARAM, W_OK) == 0)
             break;
@@ -1006,21 +1511,20 @@
               strerror(errno), errno, WIFI_DRIVER_STATE_CTRL_PARAM);
         return -1;
     }
-
     fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_STATE_CTRL_PARAM, O_WRONLY));
     if (fd < 0) {
         ALOGE("Failed to open driver state control param at %s",
               WIFI_DRIVER_STATE_CTRL_PARAM);
+        close(fd);
         return -1;
     }
-
     len = strlen(state) + 1;
     if (TEMP_FAILURE_RETRY(write(fd, state, len)) != len) {
         ALOGE("Failed to write driver state control param at %s",
               WIFI_DRIVER_STATE_CTRL_PARAM);
+        close(fd);
         ret = -1;
     }
-
     close(fd);
     return ret;
 }
@@ -1090,9 +1594,7 @@
 
    list_for_each_entry_safe(reg, tmp, &info->monitor_sockets, list) {
         del_from_list(&reg->list);
-        if(reg) {
-           free(reg);
-        }
+        free(reg);
     }
 
     if (info->interfaces) {
@@ -1115,6 +1617,8 @@
     wifi_logger_ring_buffers_deinit(info);
     cleanupGscanHandlers(info);
     cleanupRSSIMonitorHandler(info);
+    cleanupRadioHandler(info);
+    cleanupTCPParamCommand(info);
 
     if (info->num_event_cb)
         ALOGE("%d events were leftover without being freed",
@@ -1156,12 +1660,13 @@
 
     hal_info *info = getHalInfo(handle);
     info->cleaned_up_handler = handler;
-    info->clean_up = true;
     // Remove the dynamically created interface during wifi cleanup.
     wifi_cleanup_dynamic_ifaces(handle);
 
-
     TEMP_FAILURE_RETRY(write(info->exit_sockets[0], "E", 1));
+
+    // Ensure wifi_event_loop() exits by setting clean_up to true.
+    info->clean_up = true;
     ALOGI("Sent msg on exit sock to unblock poll()");
 }
 
@@ -1263,7 +1768,7 @@
        ALOGE("%s: nl_send_auto_complete - failed : %d \n", __FUNCTION__, retval);
        goto nl_out;
      }
-
+     ALOGI("%s: sent gennl msg of len: %d to driver\n", __FUNCTION__, ctrl_msg->data_len);
      retval = internal_pollin_handler(handle, info->event_sock);
   }
   else if (ctrl_msg->family_name == CLD80211_FAMILY)
@@ -1282,7 +1787,7 @@
         ALOGE("%s: send cld80211 message - failed\n", __FUNCTION__);
         goto nl_out;
       }
-      ALOGD("%s: sent cld80211 message for pid %d\n", __FUNCTION__, getpid());
+      ALOGI("%s: sent cld80211 msg of len: %d to driver\n", __FUNCTION__, ctrl_msg->data_len);
     }
     else
     {
@@ -1354,9 +1859,6 @@
 
          list_for_each_entry(reg, &info->monitor_sockets, list) {
 
-           if(reg == NULL)
-              break;
-
            int mlen = min(match_len, reg->match_len);
 
            if (reg->match_len == 0)
@@ -1405,8 +1907,6 @@
          //! if sock is not present, return error -2.
          //! if sock is present,  and cmd_id does not match, return error -2.
          //! if sock is present, and cmd_id matches, delete entry and return 0.
-         if(reg == NULL)
-            break;
 
          if (ctrl_msg->monsock_len != reg->monsock_len)
              continue;
@@ -1584,6 +2084,19 @@
     }
 }
 
+static bool exit_event_handler(int fd) {
+    char buf[4];
+    memset(buf, 0, sizeof(buf));
+
+    TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf)));
+    ALOGI("exit_event_handler, buf=%s", buf);
+    if (strncmp(buf, "E", 1) == 0) {
+       return true;
+    }
+
+    return false;
+}
+
 /* Run event handler */
 void wifi_event_loop(wifi_handle handle)
 {
@@ -1631,10 +2144,16 @@
             if ((info->wifihal_ctrl_sock.s > 0) && (pfd[3].revents & (POLLIN | POLLHUP | POLLERR))) {
                 internal_event_handler_app(handle, pfd[3].revents, &info->wifihal_ctrl_sock);
             }
+            if (pfd[2].revents & POLLIN) {
+                if (exit_event_handler(pfd[2].fd)) {
+                    break;
+                }
+            }
         }
         rb_timerhandler(info);
     } while (!info->clean_up);
     internal_cleaned_up_handler(handle);
+    ALOGI("wifi_event_loop() exits success");
 }
 
 static int user_sock_message_handler(nl_msg *msg, void *arg)
@@ -1709,14 +2228,12 @@
 
        list_for_each_entry(reg, &info->monitor_sockets, list) {
 
-                 if(reg == NULL)
-                    break;
-
                  if (memcmp(reg->match, buff, reg->match_len))
                      continue;
 
                  /* found match! */
                  /* Indicate the received Action frame to respective client */
+                 ALOGI("send gennl msg of len : %d to apps", ctrl_evt->data_len);
                  if (sendto(info->wifihal_ctrl_sock.s, (char *)ctrl_evt,
                             sizeof(*ctrl_evt) + ctrl_evt->data_len,
                             0, (struct sockaddr *)&reg->monsock, reg->monsock_len) < 0)
@@ -1863,8 +2380,14 @@
 
 static bool is_wifi_interface(const char *name)
 {
+    // filter out bridge interface
+    if (strstr(name, "br") != NULL) {
+        return false;
+    }
+
     if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "p2p", 3) != 0
-        && strncmp(name, "wifi", 4) != 0) {
+        && strncmp(name, "wifi", 4) != 0
+        && strncmp(name, "swlan", 5) != 0) {
         /* not a wifi interface; ignore it */
         return false;
     } else {
@@ -1957,8 +2480,6 @@
         for (int i = 0; i < info->num_interfaces; i++)
             free(info->interfaces[i]);
         free(info->interfaces);
-        info->interfaces = NULL;
-        info->num_interfaces = 0;
     }
 
     wifi_error ret = wifi_init_interfaces(handle);
@@ -1993,10 +2514,10 @@
     ret = acquire_supported_features(iface, set);
     if (ret != WIFI_SUCCESS) {
         *set = info->supported_feature_set;
-        ALOGV("Supported feature set acquired at initialization : 0x%" PRIx64, *set);
+        ALOGV("Supported feature set acquired at initialization : %" PRIx64, *set);
     } else {
         info->supported_feature_set = *set;
-        ALOGV("Supported feature set acquired : 0x%" PRIx64, *set);
+        ALOGV("Supported feature set acquired : %" PRIx64, *set);
     }
     return WIFI_SUCCESS;
 }
@@ -2036,8 +2557,10 @@
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-    if (!nlData)
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
+    }
 
     ret = vCommand->put_u32(
           QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX,
@@ -2091,8 +2614,10 @@
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-    if (!nlData)
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
+    }
 
     /* Add the fixed part of the mac_oui to the nl command */
     ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG, nodfs);
@@ -2139,8 +2664,10 @@
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-    if (!nlData)
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
+    }
 
     ret = vCommand->put_u32(
             QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL,
@@ -2212,8 +2739,10 @@
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-    if (!nlData)
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
+    }
 
     ret = vCommand->put_u32(
             QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL,
@@ -2268,8 +2797,10 @@
 
         /* Add the vendor specific attributes for the NL command. */
         nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-        if (!nlData)
+        if (!nlData){
+            ret = WIFI_ERROR_UNKNOWN;
             goto cleanup;
+        }
 
         ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
                                 QCA_WLAN_SET_PACKET_FILTER);
@@ -2358,8 +2889,10 @@
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-    if (!nlData)
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
+    }
 
     ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
                             QCA_WLAN_GET_PACKET_FILTER);
@@ -2410,8 +2943,10 @@
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-    if (!nlData)
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
+    }
 
     ret = vCommand->put_u8(QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG, enable);
     if (ret != WIFI_SUCCESS)
@@ -2479,8 +3014,10 @@
 
         /* Add the vendor specific attributes for the NL command. */
         nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-        if (!nlData)
+        if (!nlData){
+             ret = WIFI_ERROR_UNKNOWN;
              goto cleanup;
+        }
 
         ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
                                  QCA_WLAN_WRITE_PACKET_FILTER);
@@ -2518,7 +3055,7 @@
         vCommand->attr_end(nlData);
 
         ret = vCommand->requestResponse();
-       if (ret != WIFI_SUCCESS) {
+        if (ret != WIFI_SUCCESS) {
             ALOGE("%s: requestResponse Error:%d",__func__, ret);
             goto cleanup;
         }
@@ -2557,8 +3094,10 @@
     }
     /* Add the vendor specific attributes for the NL command. */
     nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
-    if (!nlData)
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
+    }
 
     subcmd = enable ? QCA_WLAN_ENABLE_PACKET_FILTER :
                       QCA_WLAN_DISABLE_PACKET_FILTER;
@@ -2578,8 +3117,7 @@
     info->apf_enabled = !!enable;
 
 cleanup:
-    if (vCommand)
-        delete vCommand;
+    delete vCommand;
     return ret;
 
 }
@@ -2605,7 +3143,7 @@
 static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
                                           u32 src_offset, u8 *host_dst, u32 length)
 {
-    wifi_error ret = WIFI_SUCCESS;
+    wifi_error ret = WIFI_ERROR_UNKNOWN;
     struct nlattr *nlData;
     WifihalGeneric *vCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(handle);
@@ -2711,3 +3249,270 @@
     delete vCommand;
     return ret;
 }
+
+class GetSupportedVendorCmd : public WifiCommand
+{
+private:
+    u32 mVendorCmds[256];
+    int mNumOfVendorCmds;
+
+public:
+    GetSupportedVendorCmd(wifi_handle handle) : WifiCommand(handle, 0)
+    {
+        mNumOfVendorCmds = 0;
+        memset(mVendorCmds, 0, 256);
+    }
+
+    virtual wifi_error create() {
+        int nl80211_id = genl_ctrl_resolve(mInfo->cmd_sock, "nl80211");
+        wifi_error ret = mMsg.create(nl80211_id, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, 0);
+        mMsg.put_flag(NL80211_ATTR_SPLIT_WIPHY_DUMP);
+
+        return ret;
+    }
+
+    virtual wifi_error requestResponse() {
+        return WifiCommand::requestResponse(mMsg);
+    }
+    virtual wifi_error set_iface_id(const char* name) {
+        unsigned ifindex = if_nametoindex(name);
+        return mMsg.set_iface_id(ifindex);
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        struct nlattr **tb = reply.attributes();
+
+        if (tb[NL80211_ATTR_VENDOR_DATA]) {
+            struct nlattr *nl;
+            int rem, i = 0;
+
+            for_each_attr(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
+                struct nl80211_vendor_cmd_info *vinfo;
+                if (nla_len(nl) != sizeof(*vinfo)) {
+                    ALOGE("Unexpected vendor data info found in attribute");
+                    continue;
+                }
+                vinfo = (struct nl80211_vendor_cmd_info *)nla_data(nl);
+                if (vinfo->vendor_id == OUI_QCA) {
+                    mVendorCmds[i] = vinfo->subcmd;
+                    i++;
+                }
+            }
+            mNumOfVendorCmds = i;
+        }
+        return NL_SKIP;
+    }
+
+    int isVendorCmdSupported(u32 cmdId) {
+        int i, ret;
+
+        ret = 0;
+        for (i = 0; i < mNumOfVendorCmds; i++) {
+            if (cmdId == mVendorCmds[i]) {
+                ret = 1;
+                break;
+            }
+        }
+
+        return ret;
+    }
+};
+
+static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle iface_handle)
+{
+    wifi_error ret;
+    wifi_handle handle = getWifiHandle(iface_handle);
+    interface_info *info = getIfaceInfo(iface_handle);
+    GetSupportedVendorCmd cmd(handle);
+
+    ret = cmd.create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: create command failed", __func__);
+        return 0;
+    }
+
+    ret = cmd.set_iface_id(info->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: set iface id failed", __func__);
+        return 0;
+    }
+
+    ret = cmd.requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to query nan_ext command support, ret=%d", ret);
+        return 0;
+    } else {
+        return cmd.isVendorCmdSupported(QCA_NL80211_VENDOR_SUBCMD_NAN_EXT);
+    }
+}
+
+wifi_error wifi_get_radar_history(wifi_interface_handle handle,
+       radar_history_result *resultBuf, int resultBufSize, int *numResults)
+{
+    wifi_error ret;
+    struct nlattr *nlData;
+    WifihalGeneric *vCommand = NULL;
+    interface_info *ifaceInfo = NULL;
+    wifi_handle wifiHandle = NULL;
+
+    ALOGI("%s: enter", __FUNCTION__);
+
+    if (!handle) {
+        ALOGE("%s: Error, wifi_interface_handle NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ifaceInfo = getIfaceInfo(handle);
+    if (!ifaceInfo) {
+        ALOGE("%s: Error, interface_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    wifiHandle = getWifiHandle(handle);
+    if (!wifiHandle) {
+        ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    if (resultBuf == NULL || numResults == NULL) {
+        ALOGE("%s: Error, resultsBuf/numResults NULL pointer", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    vCommand = new WifihalGeneric(wifiHandle, 0,
+            OUI_QCA,
+            QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY);
+    if (vCommand == NULL) {
+        ALOGE("%s: Error vCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    /* Create the message */
+    ret = vCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = vCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    vCommand->attr_end(nlData);
+
+    ret = vCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* No more data, copy the parsed results into the caller's results buffer */
+    ret = vCommand->copyCachedRadarHistory(
+            resultBuf, resultBufSize, numResults);
+
+cleanup:
+    vCommand->freeCachedRadarHistory();
+    delete vCommand;
+    return ret;
+}
+
+#define SIZEOF_TLV_HDR 4
+#define OEM_DATA_TLV_TYPE_HEADER 1
+#define OEM_DATA_CMD_SET_SKIP_CAC   18
+
+struct oem_data_header {
+    u16 cmd_id;
+    u16 request_idx;
+};
+
+static int wifi_add_oem_data_head(int cmd_id, u8* oem_buf, size_t max)
+{
+    struct oem_data_header oem_hdr;
+    oem_hdr.cmd_id = cmd_id;
+    oem_hdr.request_idx = 0;
+
+    if ((SIZEOF_TLV_HDR + sizeof(oem_hdr)) > max) {
+        return 0;
+    }
+
+    wifi_put_le16(oem_buf, OEM_DATA_TLV_TYPE_HEADER);
+    oem_buf += 2;
+    wifi_put_le16(oem_buf, sizeof(oem_hdr));
+    oem_buf += 2;
+    memcpy(oem_buf, (u8 *)&oem_hdr, sizeof(oem_hdr));
+    oem_buf += sizeof(oem_hdr);
+
+    return (SIZEOF_TLV_HDR + sizeof(oem_hdr));
+}
+
+
+/**
+ * This cmd takes effect on the interface the cmd is sent to.
+ * This cmd loses effect when interface is down. (i.e. set mac addr)
+ */
+wifi_error wifi_disable_next_cac(wifi_interface_handle handle) {
+    wifi_error ret;
+    interface_info *ifaceInfo = NULL;
+    struct nlattr *nlData;
+    WifiVendorCommand *vCommand = NULL;
+    u8 oem_buf[16];
+    int oem_buf_len = 0;
+
+    if (!handle) {
+        ALOGE("%s: Error, wifi_interface_handle NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ifaceInfo = getIfaceInfo(handle);
+    if (!ifaceInfo) {
+        ALOGE("%s: Error, interface_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ALOGI("%s: enter - iface=%s", __FUNCTION__, ifaceInfo->name);
+    oem_buf_len = wifi_add_oem_data_head(
+            OEM_DATA_CMD_SET_SKIP_CAC, oem_buf, sizeof(oem_buf));
+    if (oem_buf_len <= 0) {
+        ALOGE("%s: fill oem data head failed, cmd=%d", __func__,
+                OEM_DATA_CMD_SET_SKIP_CAC);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ret = initialize_vendor_cmd(handle, get_requestid(),
+                                QCA_NL80211_VENDOR_SUBCMD_OEM_DATA,
+                                &vCommand);
+
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Initialization failed", __func__);
+        return ret;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_OUT_OF_MEMORY;
+        goto cleanup;
+    }
+
+    ret = vCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA,
+                              (char *)oem_buf, oem_buf_len);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    vCommand->attr_end(nlData);
+    ret = vCommand->requestResponse();
+
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete vCommand;
+    return ret;
+}
diff --git a/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
new file mode 100644
index 0000000..2ad9c38
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * wpa_supplicant/hostapd control interface library
+ * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "wifi_hal_ctrl.h"
+
+struct wifihal_ctrl * wifihal_ctrl_open2(const char *ctrl_path,
+                                         const char *cli_path)
+{
+    struct wifihal_ctrl *ctrl;
+    static int counter = 0;
+    int retval;
+    size_t res;
+    int tries = 0;
+    int flags;
+#ifdef ANDROID
+    struct group *grp_wifi;
+    gid_t gid_wifi;
+    struct passwd *pwd_system;
+    uid_t uid_system;
+#endif
+
+    if (ctrl_path == NULL)
+        return NULL;
+
+    ctrl = malloc(sizeof(*ctrl));
+    if (ctrl == NULL) {
+        return NULL;
+    }
+
+    memset(ctrl, 0, sizeof(*ctrl));
+    ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
+    if (ctrl->s < 0) {
+         free(ctrl);
+         return NULL;
+    }
+
+    ctrl->local.sun_family = AF_UNIX;
+
+try_again:
+    if (cli_path && cli_path[0] == '/') {
+       res = strlcpy(ctrl->local.sun_path, cli_path,
+                     sizeof(ctrl->local.sun_path));
+
+       if (res >= sizeof(ctrl->local.sun_path)) {
+             close(ctrl->s);
+             free(ctrl);
+             return NULL;
+         }
+
+    } else {
+       counter++;
+       retval = snprintf(ctrl->local.sun_path,
+                      sizeof(ctrl->local.sun_path),
+                      CONFIG_CTRL_IFACE_CLIENT_DIR "/"
+                      CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d",
+                      (int) getpid(), counter);
+    }
+    tries++;
+    if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
+             sizeof(ctrl->local)) < 0) {
+       if (errno == EADDRINUSE && tries < 2) {
+           /*
+            * getpid() returns unique identifier for this instance
+            * of wifihal_ctrl, so the existing socket file must have
+            * been left by unclean termination of an earlier run.
+            * Remove the file and try again.
+            */
+           unlink(ctrl->local.sun_path);
+           goto try_again;
+        }
+       close(ctrl->s);
+       free(ctrl);
+       return NULL;
+    }
+
+#ifdef ANDROID
+    chmod(ctrl->local.sun_path, S_IRWXU | S_IRWXG );
+
+    /* Set group even if we do not have privileges to change owner */
+    grp_wifi = getgrnam("wifi");
+    gid_wifi = grp_wifi ? grp_wifi->gr_gid : 0;
+    pwd_system = getpwnam("system");
+    uid_system = pwd_system ? pwd_system->pw_uid : 0;
+    if (!gid_wifi || !uid_system) {
+        wifihal_ctrl_close(ctrl);
+        return NULL;
+    }
+    chown(ctrl->local.sun_path, -1, gid_wifi);
+    chown(ctrl->local.sun_path, uid_system, gid_wifi);
+
+
+    if (*ctrl_path != '/') {
+            wifihal_ctrl_close(ctrl);
+            return NULL;
+           }
+#endif /* ANDROID */
+
+       ctrl->dest.sun_family = AF_UNIX;
+       res = strlcpy(ctrl->dest.sun_path, ctrl_path,
+                     sizeof(ctrl->dest.sun_path));
+       if (res >= sizeof(ctrl->dest.sun_path)) {
+           wifihal_ctrl_close(ctrl);
+           return NULL;
+       }
+       if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
+            sizeof(ctrl->dest)) < 0) {
+        wifihal_ctrl_close(ctrl);
+        return NULL;
+       }
+       /*
+        * Make socket non-blocking so that we don't hang forever if
+        * target dies unexpectedly.
+        */
+       flags = fcntl(ctrl->s, F_GETFL);
+       if (flags >= 0) {
+        flags |= O_NONBLOCK;
+        if (fcntl(ctrl->s, F_SETFL, flags) < 0) {
+             perror("fcntl(ctrl->s, O_NONBLOCK)");
+             /* Not fatal, continue on.*/
+        }
+       }
+       return ctrl;
+}
+
+struct wifihal_ctrl * wifihal_ctrl_open(const char *ctrl_path)
+{
+    return wifihal_ctrl_open2(ctrl_path, NULL);
+}
+
+void wifihal_ctrl_close(struct wifihal_ctrl *ctrl)
+{
+    if (ctrl == NULL)
+        return;
+    unlink(ctrl->local.sun_path);
+    if (ctrl->s >= 0)
+        close(ctrl->s);
+    free(ctrl);
+}
+
+int wifihal_ctrl_request2(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len,
+                         char *reply, size_t *reply_len, time_t sec, suseconds_t usec)
+{
+    struct timeval tv;
+    int counter = 0, res;
+    fd_set rfds;
+    const char *_cmd;
+    size_t _cmd_len;
+    char *cmd_buf = NULL;
+
+    _cmd = cmd;
+    _cmd_len = cmd_len;
+
+    errno = 0;
+retry_send:
+    if (sendto(ctrl->s, _cmd, _cmd_len, 0, (struct sockaddr *)&ctrl->dest, sizeof(ctrl->dest)) < 0) {
+        if (errno == EAGAIN || errno == EBUSY || errno == EWOULDBLOCK)
+        {
+          /*
+           * Must be a non-blocking socket... Try for a bit
+           * longer before giving up.
+           */
+              if(counter == 5) {
+                 goto send_err;
+                } else {
+                 counter++;
+                }
+                sleep(1);
+                goto retry_send;
+         }
+         send_err:
+         free(cmd_buf);
+         return -1;
+     }
+     free(cmd_buf);
+
+     for (;;) {
+        tv.tv_sec = sec;
+        tv.tv_usec = usec;
+        FD_ZERO(&rfds);
+        FD_SET(ctrl->s, &rfds);
+        res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
+        if (res < 0 && errno == EINTR)
+            continue;
+        if (res < 0)
+            return res;
+        if (FD_ISSET(ctrl->s, &rfds)) {
+                res = recv(ctrl->s, reply, *reply_len, 0);
+                if (res < 0)
+                    return res;
+                *reply_len = res;
+                break;
+        } else {
+           return -2;
+        }
+     }
+     return 0;
+}
+
+
+int wifihal_ctrl_request(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len,
+                         char *reply, size_t *reply_len)
+{
+    return wifihal_ctrl_request2(ctrl, cmd, cmd_len, reply, reply_len, 1, 0);
+}
diff --git a/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h
new file mode 100644
index 0000000..f0cdaa3
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * wpa_supplicant/hostapd control interface library
+ * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WIFIHAL_CTRL_H
+#define WIFIHAL_CTRL_H
+
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "stdlib.h"
+
+#ifdef ANDROID
+#include <dirent.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <cutils/sockets.h>
+#endif /* ANDROID */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * struct wifihal_ctrl - Internal structure for control interface library
+ *
+ * This structure is used by the clients to interface with WiFi Hal
+ * library to store internal data. Programs using the library should not touch
+ * this data directly. They can only use the pointer to the data structure as
+ * an identifier for the control interface connection and use this as one of
+ * the arguments for most of the control interface library functions.
+ */
+
+struct wifihal_ctrl {
+    int s;
+    struct sockaddr_un local;
+    struct sockaddr_un dest;
+};
+
+#ifndef CONFIG_CTRL_IFACE_CLIENT_DIR
+#define CONFIG_CTRL_IFACE_CLIENT_DIR "/dev/socket/wifihal"
+#endif /* CONFIG_CTRL_IFACE_CLIENT_DIR */
+#ifndef CONFIG_CTRL_IFACE_CLIENT_PREFIX
+#define CONFIG_CTRL_IFACE_CLIENT_PREFIX "wifihal_ctrl_cli_"
+#endif /* CONFIG_CTRL_IFACE_CLIENT_PREFIX */
+
+#define DEFAULT_PAGE_SIZE         4096
+
+enum nl_family_type
+{
+  //! gen netlink family
+  GENERIC_NL_FAMILY = 1,
+  //! Cld80211 family
+  CLD80211_FAMILY
+};
+
+
+enum wifihal_ctrl_cmd
+{
+    /** attach monitor sock */
+    WIFIHAL_CTRL_MONITOR_ATTACH,
+    /** dettach monitor sock */
+    WIFIHAL_CTRL_MONITOR_DETTACH,
+    /** Send data over Netlink Sock */
+    WIFIHAL_CTRL_SEND_NL_DATA,
+};
+
+//! WIFIHAL Control Request
+typedef struct wifihal_ctrl_req_s {
+    //! ctrl command
+    uint32_t ctrl_cmd;
+    //! Family name
+    uint32_t family_name;
+    //! command ID
+    uint32_t cmd_id;
+    //! monitor sock len
+    uint32_t monsock_len;
+    //! monitor sock
+    struct sockaddr_un monsock;
+    //! data buff length
+    uint32_t data_len;
+    //! reserved
+    uint32_t reserved[4];
+    //! data
+    char data[0];
+}wifihal_ctrl_req_t;
+
+
+//! WIFIHAL Sync Response
+typedef struct wifihal_ctrl_sync_rsp_s {
+    //! ctrl command
+    uint32_t ctrl_cmd;
+    //! Family name
+    uint32_t family_name;
+    //! command ID
+    uint32_t cmd_id;
+    //! status for the request
+    int status;
+    //! reserved
+    uint32_t reserved[4];
+}wifihal_ctrl_sync_rsp_t;
+
+//! WIFIHAL Async Response
+typedef struct wifihal_ctrl_event_s {
+    //! Family name
+    uint32_t family_name;
+    //! command ID
+    uint32_t cmd_id;
+    //! data buff length
+    uint32_t data_len;
+    //! reserved
+    uint32_t reserved;
+    //! data
+    char data[0];
+}wifihal_ctrl_event_t;
+
+/* WiFi Hal control interface access */
+
+/**
+ * wifihal_ctrl_open - Open a control interface to WiFi-Hal
+ * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
+ * Returns: Pointer to abstract control interface data or %NULL on failure
+ *
+ * This function is used to open a control interface to WiFi-Hal.
+ * ctrl_path is usually /var/run/wifihal. This path
+ * is configured in WiFi-Hal and other programs using the control
+ * interface need to use matching path configuration.
+ */
+struct wifihal_ctrl * wifihal_ctrl_open(const char *ctrl_path);
+
+/**
+ * wifihal_ctrl_open2 - Open a control interface to wifihal
+ * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
+ * @cli_path: Path for client UNIX domain sockets; ignored if UDP socket
+ *            is used.
+ * Returns: Pointer to abstract control interface data or %NULL on failure
+ *
+ * This function is used to open a control interface to wifihal
+ * when the socket path for client need to be specified explicitly. Default
+ * ctrl_path is usually /var/run/wifihal and client
+ * socket path is /tmp.
+ */
+struct wifihal_ctrl * wifihal_ctrl_open2(const char *ctrl_path, const char *cli_path);
+
+
+/**
+ * wifihal_ctrl_close - Close a control interface to wifihal
+ * @ctrl: Control interface data from wifihal_ctrl_open()
+ *
+ * This function is used to close a control interface.
+ */
+void wifihal_ctrl_close(struct wifihal_ctrl *ctrl);
+
+
+/**
+ * wifihal_ctrl_request2 - Send a command to wifihal
+ * @ctrl: Control interface data from wifihal_ctrl_open()
+ * @cmd: Command; usually, hexadecimal data
+ * @cmd_len: Length of the cmd in bytes
+ * @reply: Buffer for the response
+ * @reply_len: Reply buffer length
+ * @sec: time in secs
+ * @usec: time in micro secs
+ * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
+ *
+ * This function is used to send commands to wifihal. Received
+ * response will be written to reply and reply_len is set to the actual length
+ * of the reply. This function will block for up to two seconds while waiting
+ * for the reply. If unsolicited messages are received, the blocking time may
+ * be longer.
+ *
+ */
+int wifihal_ctrl_request2(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len,
+                         char *reply, size_t *reply_len, time_t sec, suseconds_t usec);
+
+/**
+ * wifihal_ctrl_request - Send a command to wifihal
+ * @ctrl: Control interface data from wifihal_ctrl_open()
+ * @cmd: Command; usually, hexadecimal data
+ * @cmd_len: Length of the cmd in bytes
+ * @reply: Buffer for the response
+ * @reply_len: Reply buffer length
+ * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
+ *
+ * This function is used to send commands to wifihal. Received
+ * response will be written to reply and reply_len is set to the actual length
+ * of the reply. This function will block for up to two seconds while waiting
+ * for the reply. If unsolicited messages are received, the blocking time may
+ * be longer.
+ *
+ */
+int wifihal_ctrl_request(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len,
+                         char *reply, size_t *reply_len);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/wcn6740/qcwcn/wifi_hal/wificonfig.cpp b/wcn6740/qcwcn/wifi_hal/wificonfig.cpp
new file mode 100644
index 0000000..5aec138
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wificonfig.cpp
@@ -0,0 +1,1530 @@
+/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+#define LOG_TAG  "WifiHAL"
+#include <utils/Log.h>
+#include <time.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string>
+#include <net/if.h>
+#include <vector>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <sys/socket.h>
+#include "wificonfigcommand.h"
+#include "ifaceeventhandler.h"
+
+#define NUM_OF_SAR_LIMITS_SPECS 2
+#define NUM_OF_SPEC_CHAINS 2
+
+/* Implementation of the API functions exposed in wifi_config.h */
+wifi_error wifi_extended_dtim_config_set(wifi_request_id id,
+                                         wifi_interface_handle iface,
+                                         int extended_dtim)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    ALOGV("%s: extended_dtim:%d", __FUNCTION__, extended_dtim);
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            id,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_extended_dtim_config_set: failed to create NL msg. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_extended_dtim_config_set: failed to set iface id. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_extended_dtim_config_set: failed attr_start for "
+            "VENDOR_DATA. Error:%d", ret);
+        goto cleanup;
+    }
+
+    ret = wifiConfigCommand->put_u32(
+                  QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM, extended_dtim);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_extended_dtim_config_set(): failed to put vendor data. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_extended_dtim_config_set(): requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+int check_feature(enum qca_wlan_vendor_features feature, features_info *info)
+{
+    size_t idx = feature / 8;
+
+    return (idx < info->flags_len) &&
+            (info->flags[idx] & BIT(feature % 8));
+}
+
+/* Set the country code to driver. */
+wifi_error wifi_set_country_code(wifi_interface_handle iface,
+                                 const char* country_code)
+{
+    int requestId;
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    ALOGV("%s: %s", __FUNCTION__, country_code);
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate it randomly.
+     */
+    requestId = get_requestid();
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message with NL80211_CMD_REQ_SET_REG NL cmd. */
+    ret = wifiConfigCommand->create_generic(NL80211_CMD_REQ_SET_REG);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_country_code: failed to create NL msg. Error:%d", ret);
+        goto cleanup;
+    }
+
+    ret = wifiConfigCommand->put_string(NL80211_ATTR_REG_ALPHA2, country_code);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_country_code: put country code failed. Error:%d", ret);
+        goto cleanup;
+    }
+
+    if (check_feature(QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY,
+                      &info->driver_supported_features)) {
+        ret = wifiConfigCommand->put_u32(NL80211_ATTR_USER_REG_HINT_TYPE,
+                                         NL80211_USER_REG_HINT_CELL_BASE);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("wifi_set_country_code: put reg hint type failed. Error:%d",
+                  ret);
+            goto cleanup;
+        }
+    }
+
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_country_code(): requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+    usleep(WAIT_TIME_FOR_SET_REG_DOMAIN);
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+/*
+ * Set the powersave to driver.
+ */
+wifi_error wifi_set_qpower(wifi_interface_handle iface,
+                                 u8 powersave)
+{
+    int requestId, ret = 0;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    //hal_info *info = getHalInfo(wifiHandle);
+
+    ALOGD("%s: %d", __FUNCTION__, powersave);
+
+    requestId = get_requestid();
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret < 0) {
+        ALOGE("wifi_set_qpower: failed to create NL msg. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret < 0) {
+        ALOGE("wifi_set_qpower: failed to set iface id. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_set_qpower: failed attr_start for "
+            "VENDOR_DATA. Error:%d", ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u8(
+        QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER, powersave)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_set_qpower(): failed to put vendor data. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != 0) {
+        ALOGE("wifi_set_qpower(): requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return (wifi_error)ret;
+
+}
+
+wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor(
+                                                wifi_request_id id,
+                                                wifi_interface_handle iface,
+                                                u16 factor)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    ALOGV("%s factor:%u", __FUNCTION__, factor);
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            id,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
+            "create NL msg. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
+            "set iface id. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed "
+            "attr_start for VENDOR_DATA. Error:%d", ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+        QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR, factor)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): failed to "
+            "put vendor data. Error:%d", ret);
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): "
+            "requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+wifi_error wifi_set_guard_time(wifi_request_id id,
+                               wifi_interface_handle iface,
+                               u32 guard_time)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    ALOGV("%s : guard_time:%u", __FUNCTION__, guard_time);
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            id,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_guard_time: failed to create NL msg. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_guard_time: failed to set iface id. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_set_guard_time: failed attr_start for VENDOR_DATA. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+        QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME, guard_time)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_set_guard_time: failed to add vendor data.");
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_set_guard_time(): requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+wifi_error wifi_select_SARv01_tx_power_scenario(wifi_interface_handle handle,
+                                         wifi_power_scenario scenario)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(handle);
+    wifi_handle wifiHandle = getWifiHandle(handle);
+    u32 bdf_file = 0;
+
+    ALOGV("%s : power scenario:%d", __FUNCTION__, scenario);
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            1,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_select_tx_power_scenario: failed to create NL msg. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_select_tx_power_scenario: failed to set iface id. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_select_tx_power_scenario: failed attr_start for VENDOR_DATA. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+
+    switch (scenario) {
+        /* WIFI_POWER_SCENARIO_VOICE_CALL is used by VTS test to check this API.
+         * We should not remove this scenario even we don't use it in new projects.
+         */
+        case WIFI_POWER_SCENARIO_VOICE_CALL:
+        case WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON:
+        case WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT:
+        case WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT:
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT:
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW:
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_CELL_ON:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF:
+        case WIFI_POWER_SCENARIO_ON_BODY_BT:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4;
+            break;
+
+        default:
+            ALOGE("wifi_select_tx_power_scenario: invalid scenario %d", scenario);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+                      QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
+                      bdf_file)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("failed to put SAR_ENABLE");
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_select_tx_power_scenario(): requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+wifi_error wifi_select_SARv02_tx_power_scenario(wifi_interface_handle handle,
+                                         wifi_power_scenario scenario)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData, *nlSpecList, *nlSpec;
+    interface_info *ifaceInfo = getIfaceInfo(handle);
+    wifi_handle wifiHandle = getWifiHandle(handle);
+    u32 power_lim_idx = 0;
+
+    ALOGV("%s : power scenario SARV2:%d", __FUNCTION__, scenario);
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            1,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_select_tx_power_scenario: failed to create NL msg. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_select_tx_power_scenario: failed to set iface id. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_select_tx_power_scenario: failed attr_start for VENDOR_DATA.");
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+                  QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
+                  QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("failed to put SAR_ENABLE");
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+                  QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS,
+                  NUM_OF_SAR_LIMITS_SPECS)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("failed to put SAR_LIMITS_NUM_SPECS");
+        goto cleanup;
+    }
+
+    switch (scenario) {
+        case WIFI_POWER_SCENARIO_VOICE_CALL:
+        case WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON:
+        case WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT:
+        case WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW:
+
+            power_lim_idx = 0;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF:
+            power_lim_idx = 1;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT:
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT:
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW:
+        case WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW:
+            power_lim_idx = 2;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_CELL_ON:
+            power_lim_idx = 3;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT:
+            power_lim_idx = 4;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF:
+        case WIFI_POWER_SCENARIO_ON_BODY_BT:
+            power_lim_idx = 5;
+            break;
+        default:
+            ALOGE("wifi_select_tx_power_scenario: invalid scenario %d", scenario);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto cleanup;
+    }
+
+
+    nlSpecList = wifiConfigCommand->attr_start(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC);
+    if (!nlSpecList)
+    {
+        ALOGE("Cannot create spec list");
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+
+    for (int i = 0; i < NUM_OF_SPEC_CHAINS; i++) {
+        nlSpec = wifiConfigCommand->attr_start(0);
+        if (!nlSpec) {
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+        if (wifiConfigCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN,
+            i))
+        {
+            ALOGE("Failed to put: QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN");
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+
+        if (wifiConfigCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX,
+            power_lim_idx))
+        {
+            ALOGE("Failed to put: QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX");
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+        }
+
+        wifiConfigCommand->attr_end(nlSpec);
+    }
+
+
+
+    wifiConfigCommand->attr_end(nlSpecList);
+
+    wifiConfigCommand->attr_end(nlData);
+    ALOGV("wifi_select_tx_power_scenario %u selected", power_lim_idx);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_select_tx_power_scenario(): requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+
+wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle,
+                                         wifi_power_scenario scenario)
+{
+
+    wifi_handle wifiHandle = getWifiHandle(handle);
+    hal_info *info = getHalInfo(wifiHandle);
+    if (info == NULL) {
+        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    ALOGV("wifi_select_tx_power_scenario: sarVer%u", (u32)info->sar_version);
+    if  (info->sar_version == QCA_WLAN_VENDOR_SAR_VERSION_1)
+        return wifi_select_SARv01_tx_power_scenario(handle,scenario);
+    else if (info->sar_version == QCA_WLAN_VENDOR_SAR_VERSION_2)
+        return wifi_select_SARv02_tx_power_scenario(handle,scenario);
+    else {
+        ALOGE("wifi_select_tx_power_scenario %u invalid or not supported", (u32)info->sar_version);
+        return WIFI_ERROR_UNKNOWN;
+    }
+}
+
+
+wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(handle);
+    wifi_handle wifiHandle = getWifiHandle(handle);
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            1,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_reset_tx_power_scenario: failed to create NL msg. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_reset_tx_power_scenario: failed to set iface id. Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("wifi_reset_tx_power_scenario: failed attr_start for VENDOR_DATA. "
+            "Error:%d", ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
+                               QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("failed to put SAR_ENABLE or NUM_SPECS");
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("wifi_reset_tx_power_scenario(): requestEvent Error:%d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
+                                            wifi_thermal_mode mode,
+                                            u32 completion_window)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    u32 qca_vendor_thermal_level;
+    hal_info *info = getHalInfo(handle);
+
+    if (!info || info->num_interfaces < 1) {
+         ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
+               __FUNCTION__);
+         return WIFI_ERROR_UNKNOWN;
+    }
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            handle,
+                            1,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error, Failed to create wifiConfigCommand", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to create thermal vendor command, Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    if (wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
+                                   info->interfaces[0]->id)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to put iface id", __FUNCTION__);
+        goto cleanup;
+    }
+
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed in attr_start for VENDOR_DATA, Error:%d",
+              __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE,
+                             QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("Failed to put THERMAL_LEVEL command type");
+        goto cleanup;
+    }
+
+    switch(mode) {
+        case WIFI_MITIGATION_NONE:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE;
+            break;
+        case WIFI_MITIGATION_LIGHT:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT;
+            break;
+        case WIFI_MITIGATION_MODERATE:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE;
+            break;
+        case WIFI_MITIGATION_SEVERE:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE;
+            break;
+        case WIFI_MITIGATION_CRITICAL:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL;
+            break;
+        case WIFI_MITIGATION_EMERGENCY:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY;
+            break;
+        default:
+            ALOGE("Unknown thermal mitigation level %d", mode);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+                             QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL,
+                             qca_vendor_thermal_level)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("Failed to put thermal level");
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+                             QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW,
+                             completion_window)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("Failed to put thermal completion window");
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to set thermal level with Error: %d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle,
+                                     int id, u32 vendor_id,
+                                     u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    /* Initialize the member data variables here */
+    mWaitforRsp = false;
+    mRequestId = id;
+}
+
+WiFiConfigCommand::~WiFiConfigCommand()
+{
+    unregisterVendorHandler(mVendor_id, mSubcmd);
+}
+
+/* This function implements creation of Vendor command */
+wifi_error WiFiConfigCommand::create()
+{
+    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    /* Insert the oui in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+    /* Insert the subcmd in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+
+    return ret;
+}
+
+/* This function implements creation of generic NL command */
+wifi_error WiFiConfigCommand::create_generic(u8 cmdId)
+{
+    wifi_error ret = mMsg.create(cmdId, 0, 0);
+    return ret;
+}
+
+void WiFiConfigCommand::waitForRsp(bool wait)
+{
+    mWaitforRsp = wait;
+}
+
+/* Callback handlers registered for nl message send */
+static int error_handler_wifi_config(struct sockaddr_nl *nla,
+                                     struct nlmsgerr *err,
+                                     void *arg)
+{
+    struct sockaddr_nl *tmp;
+    int *ret = (int *)arg;
+    tmp = nla;
+    *ret = err->error;
+    ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret)));
+    return NL_STOP;
+}
+
+/* Callback handlers registered for nl message send */
+static int ack_handler_wifi_config(struct nl_msg *msg, void *arg)
+{
+    int *ret = (int *)arg;
+    struct nl_msg * a;
+
+    a = msg;
+    *ret = 0;
+    return NL_STOP;
+}
+
+/* Callback handlers registered for nl message send */
+static int finish_handler_wifi_config(struct nl_msg *msg, void *arg)
+{
+  int *ret = (int *)arg;
+  struct nl_msg * a;
+
+  a = msg;
+  *ret = 0;
+  return NL_SKIP;
+}
+
+/*
+ * Override base class requestEvent and implement little differently here.
+ * This will send the request message.
+ * We don't wait for any response back in case of wificonfig,
+ * thus no wait for condition.
+ */
+wifi_error WiFiConfigCommand::requestEvent()
+{
+    int status;
+    wifi_error res = WIFI_SUCCESS;
+    struct nl_cb *cb = NULL;
+
+    cb = nl_cb_alloc(NL_CB_DEFAULT);
+    if (!cb) {
+        ALOGE("%s: Callback allocation failed",__FUNCTION__);
+        res = WIFI_ERROR_OUT_OF_MEMORY;
+        goto out;
+    }
+
+    status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
+        goto out;
+    }
+    status = 1;
+
+    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_config, &status);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_config,
+        &status);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_config, &status);
+
+    /* Err is populated as part of finish_handler. */
+    while (status > 0) {
+         nl_recvmsgs(mInfo->cmd_sock, cb);
+    }
+
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
+        goto out;
+    }
+
+    if (mWaitforRsp == true) {
+        struct timespec abstime;
+        abstime.tv_sec = 4;
+        abstime.tv_nsec = 0;
+        res = mCondition.wait(abstime);
+        if (res == WIFI_ERROR_TIMED_OUT)
+            ALOGE("%s: Time out happened.", __FUNCTION__);
+
+        ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d",
+            __FUNCTION__, res, mWaitforRsp);
+    }
+out:
+    nl_cb_put(cb);
+    /* Cleanup the mMsg */
+    mMsg.destroy();
+    return res;
+}
+
+
+
+static std::vector<std::string> added_ifaces;
+
+static bool is_dynamic_interface(const char * ifname)
+{
+    for (const auto& iface : added_ifaces) {
+        if (iface == std::string(ifname))
+            return true;
+    }
+    return false;
+}
+
+void wifi_cleanup_dynamic_ifaces(wifi_handle handle)
+{
+    int len = added_ifaces.size();
+    while (len--) {
+        wifi_virtual_interface_delete(handle, added_ifaces.front().c_str());
+    }
+    added_ifaces.clear(); // could be redundent. But to be on safe side.
+}
+
+static wifi_error wifi_set_interface_mode(wifi_handle handle,
+                                   const char* ifname,
+                                   u32 iface_type)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+
+    ALOGD("%s: ifname=%s iface_type=%u", __FUNCTION__, ifname, iface_type);
+
+    wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nl80211_iftype type;
+    switch(iface_type) {
+        case WIFI_INTERFACE_TYPE_STA:    /* IfaceType:STA */
+            type = NL80211_IFTYPE_STATION;
+            break;
+        case WIFI_INTERFACE_TYPE_AP:    /* IfaceType:AP */
+            type = NL80211_IFTYPE_AP;
+            break;
+        case WIFI_INTERFACE_TYPE_P2P:    /* IfaceType:P2P */
+            type = NL80211_IFTYPE_P2P_DEVICE;
+            break;
+        case WIFI_INTERFACE_TYPE_NAN:    /* IfaceType:NAN */
+            type = NL80211_IFTYPE_NAN;
+            break;
+        default:
+            ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto done;
+            break;
+    }
+    wifiConfigCommand->create_generic(NL80211_CMD_SET_INTERFACE);
+    wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
+    wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+    }
+
+done:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+wifi_error wifi_virtual_interface_create(wifi_handle handle,
+                                         const char* ifname,
+                                         wifi_interface_type iface_type)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    hal_info *info = getHalInfo(handle);
+    if (!info || info->num_interfaces < 1) {
+        ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    // Already exists and set interface mode only
+    if (if_nametoindex(ifname) != 0) {
+        return wifi_set_interface_mode(handle, ifname, iface_type);
+    }
+
+    ALOGD("%s: ifname=%s create", __FUNCTION__, ifname);
+
+    wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    nl80211_iftype type;
+    switch(iface_type) {
+        case WIFI_INTERFACE_TYPE_STA:    /* IfaceType:STA */
+            type = NL80211_IFTYPE_STATION;
+            break;
+        case WIFI_INTERFACE_TYPE_AP:    /* IfaceType:AP */
+            type = NL80211_IFTYPE_AP;
+            break;
+        case WIFI_INTERFACE_TYPE_P2P:    /* IfaceType:P2P */
+            type = NL80211_IFTYPE_P2P_DEVICE;
+            break;
+        case WIFI_INTERFACE_TYPE_NAN:    /* IfaceType:NAN */
+            type = NL80211_IFTYPE_NAN;
+            break;
+        default:
+            ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto done;
+            break;
+    }
+    wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE);
+    wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,info->interfaces[0]->id);
+    wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, ifname);
+    wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type);
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret);
+    }
+    // Update dynamic interface list
+    added_ifaces.push_back(std::string(ifname));
+    if (iface_type == WIFI_INTERFACE_TYPE_STA) {
+         int sock = socket(AF_INET, SOCK_DGRAM, 0);
+         if(sock < 0) {
+             ret = WIFI_ERROR_UNKNOWN;
+             ALOGE("%s :socket error, Failed to bring up iface \n", __func__);
+             goto done;
+        }
+        struct ifreq ifr;
+        memset(&ifr, 0, sizeof(ifr));
+        strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+        if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s :Could not read interface %s flags \n", __func__, ifname);
+            goto done;
+        }
+        ifr.ifr_flags |= IFF_UP;
+        if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
+            ret = WIFI_ERROR_UNKNOWN;
+            ALOGE("%s :Could not bring iface %s up \n", __func__, ifname);
+        }
+    }
+
+done:
+    delete wifiConfigCommand;
+    return ret;
+}
+
+wifi_error wifi_virtual_interface_delete(wifi_handle handle,
+                                         const char* ifname)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    if (!handle) {
+        ALOGE("%s: Error wifi_handle NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ALOGD("%s: ifname=%s delete", __FUNCTION__, ifname);
+    if (if_nametoindex(ifname) && !is_dynamic_interface(ifname)) {
+         // Do not remove interface if it was not added dynamically.
+         return WIFI_SUCCESS;
+    }
+    wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
+    wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret);
+    }
+    // Update dynamic interface list
+    added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)),
+                           added_ifaces.end());
+
+    delete wifiConfigCommand;
+    return ret;
+}
+
+/**
+ * Set latency level
+ */
+wifi_error wifi_set_latency_mode(wifi_interface_handle iface,
+                                 wifi_latency_mode mode)
+{
+    int requestId, ret = 0;
+    u16 level;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    ALOGD("%s: %d", __FUNCTION__, mode);
+
+    if (!(info->supported_feature_set & WIFI_FEATURE_SET_LATENCY_MODE)) {
+        ALOGE("%s: Latency Mode is not supported by driver", __FUNCTION__);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    };
+
+    switch (mode) {
+    case WIFI_LATENCY_MODE_NORMAL:
+        level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
+        break;
+    case WIFI_LATENCY_MODE_LOW:
+        level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW;
+        break;
+    default:
+        ALOGI("%s: Unsupported latency mode=%d, resetting to NORMAL!", __FUNCTION__, mode);
+        level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
+        break;
+    }
+
+    requestId = get_requestid();
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret < 0) {
+        ALOGE("%s: failed to create NL msg. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret < 0) {
+        ALOGE("%s: failed to set iface id. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u16(
+        QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL, level)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: failed to put vendor data. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != 0) {
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return (wifi_error)ret;
+}
+
+/**
+ * Set STA + STA primary iface connection
+ */
+wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle,
+                                 wifi_interface_handle iface)
+{
+    int requestId, ret = 0;
+    WiFiConfigCommand *wifiConfigCommand;
+    if (!handle) {
+        ALOGE("%s: Error wifi_handle NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+
+    requestId = get_requestid();
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            handle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret < 0) {
+        ALOGE("%s: failed to create NL msg. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret < 0) {
+        ALOGE("%s: failed to set iface id. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u8(
+        QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY, 1)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: failed to put vendor data. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != 0) {
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return (wifi_error)ret;
+}
+
+/**
+ * Set STA + STA use case
+ */
+wifi_error wifi_multi_sta_set_use_case(wifi_handle handle,
+                                       wifi_multi_sta_use_case case_info)
+{
+    int requestId, ret = 0;
+    u8 use_case;
+    WiFiConfigCommand *wifiConfigCommand;
+    if (!handle) {
+        ALOGE("%s: Error wifi_handle NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    struct nlattr *nlData;
+    hal_info *info = getHalInfo(handle);
+    if (!info || info->num_interfaces < 1) {
+        ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ALOGD("%s: %d", __FUNCTION__, case_info);
+
+    switch (case_info) {
+    case WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY:
+        use_case = QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY;
+        break;
+    case WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED:
+        use_case = QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED;
+        break;
+    default:
+        ALOGE("%s: Unknown use case %d", __FUNCTION__, case_info);
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;;
+    }
+
+    requestId = get_requestid();
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            handle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY);
+
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret < 0) {
+        ALOGE("%s: failed to create NL msg. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    if (wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
+                                   info->interfaces[0]->id)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: Failed to put iface id", __FUNCTION__);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u8(
+        QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG, use_case)) {
+        ret = WIFI_ERROR_UNKNOWN;
+        ALOGE("%s: failed to put use_case. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != 0) {
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return (wifi_error)ret;
+}
+
+/**
+ * Invoked to set voip optimization mode for the provided STA iface
+ */
+ wifi_error wifi_set_voip_mode(wifi_interface_handle iface, wifi_voip_mode mode)
+{
+    int requestId, ret = 0;
+    WiFiConfigCommand *wifiConfigCommand;
+
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    if (!wifiHandle) {
+        ALOGE("%s: Error wifi_handle NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    requestId = get_requestid();
+    ALOGV("%s: voip mode=%d", __FUNCTION__, mode);
+    wifiConfigCommand = new WiFiConfigCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
+
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret < 0) {
+        ALOGE("%s: failed to create NL msg. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+    if (ret < 0) {
+        ALOGE("%s: failed to set iface id. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u8(
+        QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE, (u8)mode)) {
+        ALOGE("%s: failed to put vendor data. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    /* Send the NL msg. */
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != 0) {
+        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return (wifi_error)ret;
+}
diff --git a/wcn6740/qcwcn/wifi_hal/wificonfigcommand.h b/wcn6740/qcwcn/wifi_hal/wificonfigcommand.h
new file mode 100644
index 0000000..cc0f9e0
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wificonfigcommand.h
@@ -0,0 +1,111 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_WIFI_CONFIG_COMMAND_H__
+#define __WIFI_HAL_WIFI_CONFIG_COMMAND_H__
+
+#include "common.h"
+#include "cpp_bindings.h"
+#ifdef __GNUC__
+#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
+#define STRUCT_PACKED __attribute__ ((packed))
+#else
+#define PRINTF_FORMAT(a,b)
+#define STRUCT_PACKED
+#endif
+#include "wifi_config.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int check_feature(enum qca_wlan_vendor_features feature, features_info *info);
+
+class WiFiConfigCommand: public WifiVendorCommand
+{
+private:
+    int                 mRequestId;
+    bool                mWaitforRsp;
+
+public:
+    WiFiConfigCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+    virtual ~WiFiConfigCommand();
+
+    /*
+     * This function implements creation of WiFiConfigCommand specific Request
+     * based on the QCA vendor specific request type.
+     */
+    virtual wifi_error create();
+    /*
+     * This function implements creation of WiFiConfigCommand specific Request
+     * based on the generic NL request type.
+     */
+    virtual wifi_error create_generic(u8 cmdId);
+    virtual void waitForRsp(bool wait);
+    virtual wifi_error requestEvent();
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/qcwcn/wifi_hal/wifihal_internal.h b/wcn6740/qcwcn/wifi_hal/wifihal_internal.h
old mode 100755
new mode 100644
similarity index 100%
copy from qcwcn/wifi_hal/wifihal_internal.h
copy to wcn6740/qcwcn/wifi_hal/wifihal_internal.h
diff --git a/wcn6740/qcwcn/wifi_hal/wifihal_vendor.cpp b/wcn6740/qcwcn/wifi_hal/wifihal_vendor.cpp
new file mode 100644
index 0000000..4837e63
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wifihal_vendor.cpp
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "wifihal_vendorcommand.h"
+
+#define MAX_INFO 1
+//Singleton Static Instance
+NUDStatsCommand* NUDStatsCommand::mNUDStatsCommandInstance  = NULL;
+
+// This function implements creation of Vendor command
+// For NUDStats just call base Vendor command create
+wifi_error NUDStatsCommand::create() {
+    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS) {
+        return ret;
+    }
+    // insert the oui in the msg
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+
+    // insert the subcmd in the msg
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+
+out:
+    return ret;
+}
+
+NUDStatsCommand::NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    memset(&mStats, 0,sizeof(nud_stats));
+    mpktInfo = NULL;
+    mnumStats = 0;
+}
+
+NUDStatsCommand::~NUDStatsCommand()
+{
+    mNUDStatsCommandInstance = NULL;
+}
+
+NUDStatsCommand* NUDStatsCommand::instance(wifi_handle handle)
+{
+    if (handle == NULL) {
+        ALOGE("Interface Handle is invalid");
+        return NULL;
+    }
+    if (mNUDStatsCommandInstance == NULL) {
+        mNUDStatsCommandInstance = new NUDStatsCommand(handle, 0,
+                OUI_QCA,
+                QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET);
+        return mNUDStatsCommandInstance;
+    }
+    else
+    {
+        if (handle != getWifiHandle(mNUDStatsCommandInstance->mInfo))
+        {
+            /* upper layer must have cleaned up the handle and reinitialized,
+               so we need to update the same */
+            ALOGE("Handle different, update the handle");
+            mNUDStatsCommandInstance->mInfo = (hal_info *)handle;
+        }
+    }
+    return mNUDStatsCommandInstance;
+}
+
+void NUDStatsCommand::setSubCmd(u32 subcmd)
+{
+    mSubcmd = subcmd;
+}
+
+void NUDStatsCommand::setHandler(pkt_stats_result_handler handler)
+{
+    mHandler = handler;
+}
+
+wifi_error NUDStatsCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+wifi_error NUDStatsCommand::notifyResponse()
+{
+    wifi_error ret = WIFI_SUCCESS;
+
+    if (mHandler.on_pkt_stats_results) {
+        mHandler.on_pkt_stats_results(&mStats, mnumStats,
+                                      mpktInfo);
+    } else {
+        ret = WIFI_ERROR_INVALID_ARGS;
+    }
+    return ret;
+}
+
+int NUDStatsCommand::handleResponse(WifiEvent &reply)
+{
+    wifi_error status = WIFI_ERROR_NONE;
+    WifiVendorCommand::handleResponse(reply);
+
+    // Parse the vendordata and get the attribute
+
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET:
+        {
+            struct nlattr *tb_vendor[QCA_ATTR_NUD_STATS_GET_MAX + 1];
+            nud_stats *stats = &mStats;
+
+            memset(stats, 0, sizeof(nud_stats));
+            nla_parse(tb_vendor, QCA_ATTR_NUD_STATS_GET_MAX,
+                      (struct nlattr *)mVendorData, mDataLen, NULL);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_req_count_from_netdev = nla_get_u16(tb_vendor[
+                            QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV]);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_req_count_to_lower_mac = nla_get_u16(tb_vendor[
+                            QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC]);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_req_rx_count_by_lower_mac = nla_get_u16(tb_vendor[
+                            QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC]);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_req_count_tx_success = nla_get_u16(tb_vendor[
+                            QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS]);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_rsp_rx_count_by_lower_mac = nla_get_u16(tb_vendor[
+                            QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC]);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_rsp_rx_count_by_upper_mac = nla_get_u16(tb_vendor[
+                            QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC]);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_rsp_count_to_netdev = nla_get_u16(tb_vendor[
+                            QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV]);
+
+            if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP])
+            {
+                ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP"
+                      " not found", __FUNCTION__);
+                status = WIFI_ERROR_INVALID_ARGS;
+                goto cleanup;
+            }
+            stats->arp_rsp_count_out_of_order_drop = nla_get_u16(tb_vendor[
+                           QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP]);
+
+            if (tb_vendor[QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE])
+                stats->ap_link_active = 1;
+
+            if (tb_vendor[QCA_ATTR_NUD_STATS_IS_DAD])
+                stats->is_duplicate_addr_detection = 1;
+
+            ALOGV(" req_from_netdev %d count_to_lower :%d"
+                  " count_by_lower :%d"
+                  " count_tx_succ :%d rsp_count_lower :%d"
+                  " rsp_count_upper :%d  rsp_count_netdev :%d"
+                  " out_of_order_drop :%d active_aplink %d"
+                  " DAD %d ",
+                  stats->arp_req_count_from_netdev,
+                  stats->arp_req_count_to_lower_mac,
+                  stats->arp_req_rx_count_by_lower_mac,
+                  stats->arp_req_count_tx_success,
+                  stats->arp_rsp_rx_count_by_lower_mac,
+                  stats->arp_rsp_rx_count_by_upper_mac,
+                  stats->arp_rsp_count_to_netdev,
+                  stats->arp_rsp_count_out_of_order_drop,
+                  stats->ap_link_active,
+                  stats->is_duplicate_addr_detection);
+
+            if (tb_vendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]) {
+                mNUDStatsCommandInstance->GetPktInfo(tb_vendor);
+            }
+        }
+    }
+cleanup:
+    if (status == WIFI_ERROR_INVALID_ARGS)
+       memset(&mStats,0,sizeof(nud_stats));
+       if(mpktInfo != NULL)
+         free(mpktInfo);
+
+    return status;
+}
+
+void NUDStatsCommand::GetPktInfo(struct nlattr **tbvendor)
+{
+    struct nlattr *tb;
+    int rem;
+    cmdData *pkt_stats;
+    char ipv6_address[INET6_ADDRSTRLEN];
+    cmdData pktstats;
+    int nbuff = 0;
+
+    for (tb = (struct nlattr *) nla_data(tbvendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]),
+         rem = nla_len(tbvendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]);
+         nla_ok(tb, rem); tb = nla_next(tb, &(rem)))
+       {
+           struct nlattr *tb2[QCA_ATTR_NUD_DATA_STATS_MAX + 1];
+           nla_parse(tb2, QCA_ATTR_NUD_DATA_STATS_MAX,
+                     (struct nlattr *) nla_data(tb), nla_len(tb), NULL);
+
+           memset(&pktstats, 0, sizeof(cmdData));
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_TYPE])
+           {
+              pktstats.pkt_Type = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_TYPE]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME])
+           {
+              pktstats.domain_name = nla_get_string(tb2[QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_SRC_PORT])
+           {
+              pktstats.src_port = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_SRC_PORT]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_PORT])
+           {
+              pktstats.dst_port = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_PORT]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV4])
+           {
+              pktstats.ipv4_addr.s_addr = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV4]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV6])
+           {
+              memcpy(pktstats.ipv6_addr, nla_data(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV6]),
+                     sizeof(pktstats.ipv6_addr));
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV])
+           {
+              pktstats.stats.pkt_req_count_from_netdev = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC])
+           {
+              pktstats.stats.pkt_req_count_to_lower_mac = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC])
+           {
+              pktstats.stats.pkt_req_rx_count_by_lower_mac = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS])
+           {
+              pktstats.stats.pkt_req_count_tx_success = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC])
+           {
+              pktstats.stats.pkt_rsp_rx_count_by_lower_mac = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC])
+           {
+              pktstats.stats.pkt_rsp_rx_count_by_upper_mac = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV])
+           {
+              pktstats.stats.pkt_rsp_count_to_netdev = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV]);
+           }
+
+           if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP])
+           {
+              pktstats.stats.pkt_rsp_count_out_of_order_drop = nla_get_u16(tb2[
+                            QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP]);
+           }
+
+           if (inet_ntop(AF_INET6, pktstats.ipv6_addr, ipv6_address,
+                         INET6_ADDRSTRLEN) == NULL) {
+               ALOGE("%s: failed to convert ipv6 address format", __FUNCTION__);
+           }
+
+           ALOGV(" pkt_type %d domain_name :%s"
+                 " src_port %d dst_port :%d"
+                 " ipv4_address :%x ipv6_address %s"
+                 " req_from_netdev %d count_to_lower :%d"
+                 " count_by_lower :%d"
+                 " count_tx_succ :%d rsp_count_lower :%d"
+                 " rsp_count_upper :%d  rsp_count_netdev :%d"
+                 " out_of_order_drop :%d ",
+                 pktstats.pkt_Type, pktstats.domain_name,
+                 pktstats.src_port, pktstats.dst_port,
+                 pktstats.ipv4_addr.s_addr, ipv6_address,
+                 pktstats.stats.pkt_req_count_from_netdev,
+                 pktstats.stats.pkt_req_count_to_lower_mac,
+                 pktstats.stats.pkt_req_rx_count_by_lower_mac,
+                 pktstats.stats.pkt_req_count_tx_success,
+                 pktstats.stats.pkt_rsp_rx_count_by_lower_mac,
+                 pktstats.stats.pkt_rsp_rx_count_by_upper_mac,
+                 pktstats.stats.pkt_rsp_count_to_netdev,
+                 pktstats.stats.pkt_rsp_count_out_of_order_drop);
+
+            if (nbuff == 0)
+               pkt_stats = (cmdData *)malloc(sizeof(cmdData));
+            else
+               pkt_stats = (cmdData *)realloc(pkt_stats,sizeof(cmdData) * (nbuff + 1));
+
+            mpktInfo = pkt_stats;
+            if (pkt_stats != NULL) {
+                memcpy(&pkt_stats[nbuff], &pktstats,sizeof(cmdData));
+                nbuff++;
+                mnumStats = nbuff;
+            }
+       }
+}
+
+void NUDStatsCommand::copyStats(nud_stats *stats, cmdData *pktstats)
+{
+    memcpy(stats, &mStats, sizeof(nud_stats));
+    pktstats = mpktInfo;
+}
+
+wifi_error wifi_set_nud_stats(wifi_interface_handle iface,
+                              u32 gw_addr, cmdData Data)
+{
+    wifi_error ret;
+    NUDStatsCommand *NUDCommand;
+    struct nlattr *nl_data,*nl_pktInfo;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    cmdData mData = Data;
+    cmdData pktstats = Data;
+
+    ALOGV("gw_addr : %x", gw_addr);
+    NUDCommand = NUDStatsCommand::instance(handle);
+    if (NUDCommand == NULL) {
+        ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET);
+
+    /* create the message */
+    ret = NUDCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = NUDCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /*add the attributes*/
+    nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data)
+        goto cleanup;
+    /**/
+    ret = NUDCommand->put_flag(QCA_ATTR_NUD_STATS_SET_START);
+
+    ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_GW_IPV4, gw_addr);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    if (mData.pkt_Type) {
+       /*start the packet info attributes in nested*/
+       nl_pktInfo = NUDCommand->attr_start(QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO);
+       if (!nl_pktInfo)
+           goto cleanup;
+       else {
+           ALOGV(" pkt_type %d domain_name :%s"
+                 " src_port %d dst_port :%d"
+                 " ipv4_address :%x ipv6_address %s",
+                 pktstats.pkt_Type, pktstats.domain_name,
+                 pktstats.src_port, pktstats.dst_port,
+                 pktstats.ipv4_addr.s_addr,pktstats.ipv6_addr);
+
+           for (int i=0; i < MAX_INFO ; i++) {
+               /*add the packet type attributes*/
+               struct nlattr *tb_tmp;
+               tb_tmp = NUDCommand->attr_start(i);
+
+               ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE,mData.pkt_Type);
+               if (ret != WIFI_SUCCESS)
+                   goto cleanup;
+
+               if (mData.domain_name) {
+                   /*add the domain name attributes*/
+                   ret = NUDCommand->put_string(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DNS_DOMAIN_NAME,
+                                                mData.domain_name);
+                   if (ret != WIFI_SUCCESS)
+                       goto cleanup;
+               }
+               /*add the source port attributes*/
+               ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_SRC_PORT,
+                                         mData.src_port);
+               if (ret != WIFI_SUCCESS)
+                   goto cleanup;
+
+               /*add the dest port attributes*/
+               ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_PORT,
+                                         mData.dst_port);
+               if (ret != WIFI_SUCCESS)
+                   goto cleanup;
+
+               /*add the ipv4 address attributes*/
+               ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV4,
+                                         mData.ipv4_addr.s_addr);
+               if (ret != WIFI_SUCCESS)
+                   goto cleanup;
+
+               /*add the ipv6 address attributes*/
+               ret = NUDCommand->put_ipv6_addr(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV6,
+                                               mData.ipv6_addr);
+               if (ret != WIFI_SUCCESS)
+                   goto cleanup;
+               NUDCommand->attr_end(tb_tmp);
+           }
+       }
+       NUDCommand->attr_end(nl_pktInfo);
+    }
+    NUDCommand->attr_end(nl_data);
+
+    ret = NUDCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+    }
+
+cleanup:
+    return ret;
+}
+
+
+wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
+                              pkt_stats_result_handler handler)
+{
+    wifi_error ret;
+    NUDStatsCommand *NUDCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+
+    NUDCommand = NUDStatsCommand::instance(handle);
+    if (NUDCommand == NULL) {
+        ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET);
+
+    NUDCommand->setHandler(handler);
+
+    /* create the message */
+    ret = NUDCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = NUDCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+    /*add the attributes*/
+    nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    /**/
+    NUDCommand->attr_end(nl_data);
+
+    ret = NUDCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    ret = NUDCommand->notifyResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+cleanup:
+    return ret;
+}
+
+
+wifi_error wifi_clear_nud_stats(wifi_interface_handle iface,
+                                cmdData Data)
+{
+    wifi_error ret;
+    NUDStatsCommand *NUDCommand;
+    struct nlattr *nl_data,*nl_pktInfo;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+    cmdData mData = Data;
+
+    NUDCommand = NUDStatsCommand::instance(handle);
+    if (NUDCommand == NULL) {
+        ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+    NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET);
+
+    /* create the message */
+    ret = NUDCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = NUDCommand->set_iface_id(iinfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /*add the attributes*/
+    nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nl_data){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    if (mData.pkt_Type) {
+       /*set the packet info attributes in nested*/
+       nl_pktInfo = NUDCommand->attr_start(QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO);
+       if (!nl_pktInfo){
+           ret = WIFI_ERROR_UNKNOWN;
+           goto cleanup;
+       }
+       else {
+           ALOGV(" %s: pkt_type %d domain_name :%s"
+                 " src_port %d dst_port :%d"
+                 " ipv4_address :%x ipv6_address %s",
+                 __FUNCTION__,mData.pkt_Type, mData.domain_name,
+                 mData.src_port, mData.dst_port,
+                 mData.ipv4_addr.s_addr,mData.ipv6_addr);
+
+           for (int i=0; i < MAX_INFO ; i++) {
+               /*add the packet type attributes*/
+               struct nlattr *tb_tmp;
+               tb_tmp = NUDCommand->attr_start(i);
+
+               ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE,mData.pkt_Type);
+               if (ret != WIFI_SUCCESS)
+                   goto cleanup;
+
+               NUDCommand->attr_end(tb_tmp);
+           }
+       }
+       NUDCommand->attr_end(nl_pktInfo);
+    }
+    NUDCommand->attr_end(nl_data);
+
+    ret = NUDCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+cleanup:
+    return ret;
+}
diff --git a/wcn6740/qcwcn/wifi_hal/wifihal_vendorcommand.h b/wcn6740/qcwcn/wifi_hal/wifihal_vendorcommand.h
new file mode 100644
index 0000000..123fe1e
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wifihal_vendorcommand.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_NUDSTATSCOMMAND_H__
+#define __WIFI_HAL_NUDSTATSCOMMAND_H__
+
+#include "nud_stats.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+class NUDStatsCommand: public WifiVendorCommand
+{
+private:
+    static NUDStatsCommand *mNUDStatsCommandInstance;
+
+    pkt_stats_result_handler mHandler;
+    nud_stats mStats;
+    cmdData *mpktInfo;
+    int mnumStats;
+    NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+
+public:
+    static NUDStatsCommand* instance(wifi_handle handle);
+
+    virtual ~NUDStatsCommand();
+
+    // This function implements creation of NUDStats specific Request
+    // based on  the request type
+    virtual wifi_error create();
+
+    virtual void setSubCmd(u32 subcmd);
+
+    virtual wifi_error requestResponse();
+
+    virtual wifi_error notifyResponse();
+
+    virtual int handleResponse(WifiEvent &reply);
+
+    virtual void setHandler(pkt_stats_result_handler handler);
+
+    void copyStats(nud_stats *stats, cmdData *pktdstats);
+
+    void GetPktInfo(struct nlattr **tbvendor);
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/wcn6740/qcwcn/wifi_hal/wifilogger.cpp b/wcn6740/qcwcn/wifi_hal/wifilogger.cpp
new file mode 100644
index 0000000..384633a
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wifilogger.cpp
@@ -0,0 +1,1529 @@
+/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sync.h"
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include <errno.h>
+#include <utils/Log.h>
+#include "wifiloggercmd.h"
+#include "rb_wrapper.h"
+#include <stdlib.h>
+
+#define LOGGER_MEMDUMP_FILENAME "/proc/debug/fwdump"
+#define DRIVER_MEMDUMP_FILENAME "/proc/debugdriver/driverdump"
+#define LOGGER_MEMDUMP_CHUNKSIZE (4 * 1024)
+#define DRIVER_MEMDUMP_MAX_FILESIZE (16 * 1024)
+
+char power_events_ring_name[] = "power_events_rb";
+char connectivity_events_ring_name[] = "connectivity_events_rb";
+char pkt_stats_ring_name[] = "pkt_stats_rb";
+char driver_prints_ring_name[] = "driver_prints_rb";
+char firmware_prints_ring_name[] = "firmware_prints_rb";
+
+static int get_ring_id(hal_info *info, char *ring_name)
+{
+    int rb_id;
+
+    for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
+        if (is_rb_name_match(&info->rb_infos[rb_id], ring_name)) {
+           return rb_id;
+        }
+    }
+    return -1;
+}
+
+//Implementation of the functions exposed in wifi_logger.h
+
+/* Function to intiate logging */
+wifi_error wifi_start_logging(wifi_interface_handle iface,
+                              u32 verbose_level, u32 flags,
+                              u32 max_interval_sec, u32 min_data_size,
+                              char *buffer_name)
+{
+    int requestId;
+    wifi_error ret;
+    WifiLoggerCommand *wifiLoggerCommand = NULL;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    int ring_id = 0;
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
+        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
+              info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+    /*
+     * No request id from caller, so generate one and pass it on to the driver.
+     * Generate one randomly.
+     */
+    requestId = get_requestid();
+
+    if (buffer_name == NULL) {
+        ALOGE("%s: Invalid Ring Name. \n", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    ring_id = get_ring_id(info, buffer_name);
+    if (ring_id < 0) {
+        ALOGE("%s: Invalid Ring Buffer Name ", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    wifiLoggerCommand = new WifiLoggerCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START);
+
+    if (wifiLoggerCommand == NULL) {
+       ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
+       return WIFI_ERROR_UNKNOWN;
+    }
+    /* Create the NL message. */
+    ret = wifiLoggerCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID,
+                                     ring_id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = wifiLoggerCommand->put_u32(
+                             QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL,
+                             verbose_level);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS,
+                                     flags);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    wifiLoggerCommand->attr_end(nlData);
+
+    /* Send the msg and wait for a response. */
+    ret = wifiLoggerCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+    ALOGV("%s: Logging Started for %s. with verboselevel %d",
+           __FUNCTION__, buffer_name,verbose_level);
+    rb_start_logging(&info->rb_infos[ring_id], verbose_level,
+                    flags, max_interval_sec, min_data_size);
+cleanup:
+    delete wifiLoggerCommand;
+    return ret;
+}
+
+/*  Function to get each ring related info */
+wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,
+                                        u32 *num_buffers,
+                                        wifi_ring_buffer_status *status)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    wifi_ring_buffer_status *rbs;
+    struct rb_info *rb_info;
+    int rb_id;
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
+        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
+              info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if ((*num_buffers) < NUM_RING_BUFS) {
+        ALOGE("%s: Input num_buffers:%u cannot be accommodated, "
+              "Total ring buffer num:%d", __FUNCTION__, *num_buffers,
+              NUM_RING_BUFS);
+        *num_buffers = 0;
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
+        rb_info = &info->rb_infos[rb_id];
+        rbs = status + rb_id;
+
+        get_rb_status(rb_info, rbs);
+    }
+    *num_buffers = NUM_RING_BUFS;
+    return WIFI_SUCCESS;
+}
+
+void push_out_all_ring_buffers(hal_info *info)
+{
+    int rb_id;
+
+    for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
+        push_out_rb_data(&info->rb_infos[rb_id]);
+    }
+}
+
+void send_alert(hal_info *info, int reason_code)
+{
+    wifi_alert_handler handler;
+    char alert_msg[20] = "Fatal Event";
+    pthread_mutex_lock(&info->ah_lock);
+    handler.on_alert = info->on_alert;
+    pthread_mutex_unlock(&info->ah_lock);
+
+    if (handler.on_alert) {
+        handler.on_alert(0, alert_msg, strlen(alert_msg), reason_code);
+    }
+}
+
+void WifiLoggerCommand::setFeatureSet(u32 *support) {
+    mSupportedSet = support;
+}
+
+/*  Function to get the supported feature set for logging.*/
+wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
+                                                 u32 *support)
+{
+    int requestId;
+    wifi_error ret;
+    WifiLoggerCommand *wifiLoggerCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate one randomly.
+     */
+    requestId = get_requestid();
+
+    wifiLoggerCommand = new WifiLoggerCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET);
+
+    if (wifiLoggerCommand == NULL) {
+        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    /* Create the NL message. */
+    ret = wifiLoggerCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
+                                     requestId);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    wifiLoggerCommand->attr_end(nlData);
+
+    wifiLoggerCommand->setFeatureSet(support);
+
+    /* Send the msg and wait for a response. */
+    ret = wifiLoggerCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+cleanup:
+    delete wifiLoggerCommand;
+    return ret;
+}
+
+/*  Function to get the data in each ring for the given ring ID.*/
+wifi_error wifi_get_ring_data(wifi_interface_handle iface,
+                              char *ring_name)
+{
+    int requestId;
+    wifi_error ret;
+    WifiLoggerCommand *wifiLoggerCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    int ring_id = 0;
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
+        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
+              info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ring_id = get_ring_id(info, ring_name);
+    if (ring_id < 0) {
+        ALOGE("%s: Invalid Ring Buffer Name ", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    requestId = get_requestid();
+
+    wifiLoggerCommand = new WifiLoggerCommand(
+                                wifiHandle,
+                                requestId,
+                                OUI_QCA,
+                                QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA);
+    if (wifiLoggerCommand == NULL) {
+        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    /* Create the NL message. */
+    ret = wifiLoggerCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    if (wifiLoggerCommand->put_u32(
+                QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID, ring_id))
+    {
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+    wifiLoggerCommand->attr_end(nlData);
+
+    /* Send the msg and wait for a response. */
+    ret = wifiLoggerCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+cleanup:
+    delete wifiLoggerCommand;
+    return ret;
+}
+
+void WifiLoggerCommand::setVersionInfo(char *buffer, int buffer_size) {
+    mVersion = buffer;
+    mVersionLen = buffer_size;
+}
+
+/*  Function to send enable request to the wifi driver.*/
+wifi_error wifi_get_firmware_version(wifi_interface_handle iface,
+                                     char *buffer, int buffer_size)
+{
+    int requestId;
+    wifi_error ret;
+    WifiLoggerCommand *wifiLoggerCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate one randomly.
+     */
+    requestId = get_requestid_u8();
+
+    wifiLoggerCommand = new WifiLoggerCommand(
+                                wifiHandle,
+                                requestId,
+                                OUI_QCA,
+                                QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO);
+    if (wifiLoggerCommand == NULL) {
+        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    /* Create the NL message. */
+    ret = wifiLoggerCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData)
+        goto cleanup;
+
+    ret = wifiLoggerCommand->put_u8(
+                QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION, requestId);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    wifiLoggerCommand->attr_end(nlData);
+
+    wifiLoggerCommand->setVersionInfo(buffer, buffer_size);
+
+    /* Send the msg and wait for a response. */
+    ret = wifiLoggerCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+cleanup:
+    delete wifiLoggerCommand;
+    return ret;
+
+}
+
+/*  Function to get wlan driver version.*/
+wifi_error wifi_get_driver_version(wifi_interface_handle iface,
+                                   char *buffer, int buffer_size)
+{
+
+    int requestId;
+    wifi_error ret;
+    WifiLoggerCommand *wifiLoggerCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate one randomly.
+     */
+    requestId = get_requestid_u8();
+
+    wifiLoggerCommand = new WifiLoggerCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO);
+    if (wifiLoggerCommand == NULL) {
+        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    /* Create the NL message. */
+    ret = wifiLoggerCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    ret = wifiLoggerCommand->put_u8(
+                      QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION, requestId);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    wifiLoggerCommand->attr_end(nlData);
+
+    wifiLoggerCommand->setVersionInfo(buffer, buffer_size);
+
+    /* Send the msg and wait for a response. */
+    ret = wifiLoggerCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+cleanup:
+    delete wifiLoggerCommand;
+    return ret;
+}
+
+
+/* Function to get the Firmware memory dump. */
+wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface,
+                                wifi_firmware_memory_dump_handler handler)
+{
+    wifi_error ret;
+    int requestId;
+    WifiLoggerCommand *wifiLoggerCommand;
+    struct nlattr *nlData;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set &
+          WIFI_LOGGER_MEMORY_DUMP_SUPPORTED)) {
+        ALOGE("%s: Firmware memory dump logging feature not supported %x",
+              __FUNCTION__, info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate one randomly.
+     */
+    requestId = get_requestid();
+
+    wifiLoggerCommand = new WifiLoggerCommand(
+                            wifiHandle,
+                            requestId,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP);
+    if (wifiLoggerCommand == NULL) {
+        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+    /* Create the NL message. */
+    ret = wifiLoggerCommand->create();
+
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
+
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Add the vendor specific attributes for the NL command. */
+    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData){
+        ret = WIFI_ERROR_UNKNOWN;
+        goto cleanup;
+    }
+
+    wifiLoggerCommand->attr_end(nlData);
+
+    /* copy the callback into callback handler */
+    WifiLoggerCallbackHandler callbackHandler;
+    memset(&callbackHandler, 0, sizeof(callbackHandler));
+    callbackHandler.on_firmware_memory_dump = \
+        handler.on_firmware_memory_dump;
+
+    ret = wifiLoggerCommand->setCallbackHandler(callbackHandler);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Send the msg and wait for the memory dump response */
+    ret = wifiLoggerCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+cleanup:
+    delete wifiLoggerCommand;
+    return ret;
+}
+
+wifi_error wifi_set_log_handler(wifi_request_id id,
+                                wifi_interface_handle iface,
+                                wifi_ring_buffer_data_handler handler)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    pthread_mutex_lock(&info->lh_lock);
+    info->on_ring_buffer_data = handler.on_ring_buffer_data;
+    pthread_mutex_unlock(&info->lh_lock);
+    if (handler.on_ring_buffer_data == NULL) {
+        ALOGE("Set log handler is NULL");
+        return WIFI_ERROR_UNKNOWN;
+    }
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_reset_log_handler(wifi_request_id id,
+                                  wifi_interface_handle iface)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    pthread_mutex_lock(&info->lh_lock);
+    info->on_ring_buffer_data = NULL;
+    pthread_mutex_unlock(&info->lh_lock);
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_set_alert_handler(wifi_request_id id,
+                                  wifi_interface_handle iface,
+                                  wifi_alert_handler handler)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    if (handler.on_alert == NULL) {
+        ALOGE("Set alert handler is NULL");
+        return WIFI_ERROR_UNKNOWN;
+    }
+    pthread_mutex_lock(&info->ah_lock);
+    info->on_alert = handler.on_alert;
+    pthread_mutex_unlock(&info->ah_lock);
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_reset_alert_handler(wifi_request_id id,
+                                    wifi_interface_handle iface)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    pthread_mutex_lock(&info->ah_lock);
+    info->on_alert = NULL;
+    pthread_mutex_unlock(&info->ah_lock);
+    return WIFI_SUCCESS;
+}
+
+
+/**
+    API to start packet fate monitoring.
+    - Once stared, monitoring should remain active until HAL is unloaded.
+    - When HAL is unloaded, all packet fate buffers should be cleared.
+*/
+wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle iface)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set &
+          WIFI_LOGGER_PACKET_FATE_SUPPORTED)) {
+        ALOGE("%s: packet fate logging feature not supported %x",
+              __FUNCTION__, info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    if (info->fate_monitoring_enabled == true) {
+        ALOGV("Packet monitoring is already enabled");
+        return WIFI_SUCCESS;
+    }
+
+    info->pkt_fate_stats = (packet_fate_monitor_info *) malloc (
+                                              sizeof(packet_fate_monitor_info));
+    if (info->pkt_fate_stats == NULL) {
+        ALOGE("Failed to allocate memory for : %zu bytes",
+              sizeof(packet_fate_monitor_info));
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    memset(info->pkt_fate_stats, 0, sizeof(packet_fate_monitor_info));
+
+    pthread_mutex_lock(&info->pkt_fate_stats_lock);
+    info->fate_monitoring_enabled = true;
+    pthread_mutex_unlock(&info->pkt_fate_stats_lock);
+
+    return WIFI_SUCCESS;
+}
+
+
+/**
+    API to retrieve fates of outbound packets.
+    - HAL implementation should fill |tx_report_bufs| with fates of
+      _first_ min(n_requested_fates, actual packets) frames
+      transmitted for the most recent association. The fate reports
+      should follow the same order as their respective packets.
+    - Packets reported by firmware, but not recognized by driver
+      should be included.  However, the ordering of the corresponding
+      reports is at the discretion of HAL implementation.
+    - Framework may call this API multiple times for the same association.
+    - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+    - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle iface,
+                                 wifi_tx_report *tx_report_bufs,
+                                 size_t n_requested_fates,
+                                 size_t *n_provided_fates)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    wifi_tx_report_i *tx_fate_stats;
+    size_t i;
+
+    if (info->fate_monitoring_enabled != true) {
+        ALOGE("Packet monitoring is not yet triggered");
+        return WIFI_ERROR_UNINITIALIZED;
+    }
+    pthread_mutex_lock(&info->pkt_fate_stats_lock);
+
+    tx_fate_stats = &info->pkt_fate_stats->tx_fate_stats[0];
+
+    *n_provided_fates = min(n_requested_fates,
+                            info->pkt_fate_stats->n_tx_stats_collected);
+
+    for (i=0; i < *n_provided_fates; i++) {
+        memcpy(tx_report_bufs[i].md5_prefix,
+                    tx_fate_stats[i].md5_prefix, MD5_PREFIX_LEN);
+        tx_report_bufs[i].fate = tx_fate_stats[i].fate;
+        tx_report_bufs[i].frame_inf.payload_type =
+            tx_fate_stats[i].frame_inf.payload_type;
+        tx_report_bufs[i].frame_inf.driver_timestamp_usec =
+            tx_fate_stats[i].frame_inf.driver_timestamp_usec;
+        tx_report_bufs[i].frame_inf.firmware_timestamp_usec =
+            tx_fate_stats[i].frame_inf.firmware_timestamp_usec;
+        tx_report_bufs[i].frame_inf.frame_len =
+            tx_fate_stats[i].frame_inf.frame_len;
+
+        if (tx_report_bufs[i].frame_inf.payload_type == FRAME_TYPE_ETHERNET_II)
+            memcpy(tx_report_bufs[i].frame_inf.frame_content.ethernet_ii_bytes,
+                   tx_fate_stats[i].frame_inf.frame_content,
+                   min(tx_fate_stats[i].frame_inf.frame_len,
+                       MAX_FRAME_LEN_ETHERNET));
+        else if (tx_report_bufs[i].frame_inf.payload_type ==
+                                                         FRAME_TYPE_80211_MGMT)
+            memcpy(
+                tx_report_bufs[i].frame_inf.frame_content.ieee_80211_mgmt_bytes,
+                tx_fate_stats[i].frame_inf.frame_content,
+                min(tx_fate_stats[i].frame_inf.frame_len,
+                    MAX_FRAME_LEN_80211_MGMT));
+        else
+            /* Currently framework is interested only two types(
+             * FRAME_TYPE_ETHERNET_II and FRAME_TYPE_80211_MGMT) of packets, so
+             * ignore the all other types of packets received from driver */
+            ALOGI("Unknown format packet");
+    }
+    pthread_mutex_unlock(&info->pkt_fate_stats_lock);
+
+    return WIFI_SUCCESS;
+}
+
+/**
+    API to retrieve fates of inbound packets.
+    - HAL implementation should fill |rx_report_bufs| with fates of
+      _first_ min(n_requested_fates, actual packets) frames
+      received for the most recent association. The fate reports
+      should follow the same order as their respective packets.
+    - Packets reported by firmware, but not recognized by driver
+      should be included.  However, the ordering of the corresponding
+      reports is at the discretion of HAL implementation.
+    - Framework may call this API multiple times for the same association.
+    - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+    - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle iface,
+                                 wifi_rx_report *rx_report_bufs,
+                                 size_t n_requested_fates,
+                                 size_t *n_provided_fates)
+{
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+    wifi_rx_report_i *rx_fate_stats;
+    size_t i;
+
+    if (info->fate_monitoring_enabled != true) {
+        ALOGE("Packet monitoring is not yet triggered");
+        return WIFI_ERROR_UNINITIALIZED;
+    }
+    pthread_mutex_lock(&info->pkt_fate_stats_lock);
+
+    rx_fate_stats = &info->pkt_fate_stats->rx_fate_stats[0];
+
+    *n_provided_fates = min(n_requested_fates,
+                            info->pkt_fate_stats->n_rx_stats_collected);
+
+    for (i=0; i < *n_provided_fates; i++) {
+        memcpy(rx_report_bufs[i].md5_prefix,
+                    rx_fate_stats[i].md5_prefix, MD5_PREFIX_LEN);
+        rx_report_bufs[i].fate = rx_fate_stats[i].fate;
+        rx_report_bufs[i].frame_inf.payload_type =
+            rx_fate_stats[i].frame_inf.payload_type;
+        rx_report_bufs[i].frame_inf.driver_timestamp_usec =
+            rx_fate_stats[i].frame_inf.driver_timestamp_usec;
+        rx_report_bufs[i].frame_inf.firmware_timestamp_usec =
+            rx_fate_stats[i].frame_inf.firmware_timestamp_usec;
+        rx_report_bufs[i].frame_inf.frame_len =
+            rx_fate_stats[i].frame_inf.frame_len;
+
+        if (rx_report_bufs[i].frame_inf.payload_type == FRAME_TYPE_ETHERNET_II)
+            memcpy(rx_report_bufs[i].frame_inf.frame_content.ethernet_ii_bytes,
+                   rx_fate_stats[i].frame_inf.frame_content,
+                   min(rx_fate_stats[i].frame_inf.frame_len,
+                   MAX_FRAME_LEN_ETHERNET));
+        else if (rx_report_bufs[i].frame_inf.payload_type ==
+                                                         FRAME_TYPE_80211_MGMT)
+            memcpy(
+                rx_report_bufs[i].frame_inf.frame_content.ieee_80211_mgmt_bytes,
+                rx_fate_stats[i].frame_inf.frame_content,
+                min(rx_fate_stats[i].frame_inf.frame_len,
+                    MAX_FRAME_LEN_80211_MGMT));
+        else
+            /* Currently framework is interested only two types(
+             * FRAME_TYPE_ETHERNET_II and FRAME_TYPE_80211_MGMT) of packets, so
+             * ignore the all other types of packets received from driver */
+            ALOGI("Unknown format packet");
+    }
+    pthread_mutex_unlock(&info->pkt_fate_stats_lock);
+
+    return WIFI_SUCCESS;
+}
+
+WifiLoggerCommand::WifiLoggerCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+        : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+    mVersion = NULL;
+    mVersionLen = 0;
+    mRequestId = id;
+    memset(&mHandler, 0,sizeof(mHandler));
+    mWaitforRsp = false;
+    mMoreData = false;
+    mSupportedSet = NULL;
+}
+
+WifiLoggerCommand::~WifiLoggerCommand()
+{
+    unregisterVendorHandler(mVendor_id, mSubcmd);
+}
+
+/* This function implements creation of Vendor command */
+wifi_error WifiLoggerCommand::create() {
+    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
+    /* Insert the oui in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+    /* Insert the subcmd in the msg */
+    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+    if (ret != WIFI_SUCCESS)
+        goto out;
+
+     ALOGV("%s: mVendor_id = %d, Subcmd = %d.",
+        __FUNCTION__, mVendor_id, mSubcmd);
+
+out:
+    return ret;
+}
+
+void rb_timerhandler(hal_info *info)
+{
+   struct timeval now;
+   int rb_id;
+
+   gettimeofday(&now,NULL);
+   for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
+       rb_check_for_timeout(&info->rb_infos[rb_id], &now);
+   }
+}
+
+wifi_error wifi_logger_ring_buffers_init(hal_info *info)
+{
+    wifi_error ret;
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
+        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
+              info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    ret = rb_init(info, &info->rb_infos[POWER_EVENTS_RB_ID],
+                  POWER_EVENTS_RB_ID,
+                  POWER_EVENTS_RB_BUF_SIZE,
+                  POWER_EVENTS_NUM_BUFS,
+                  power_events_ring_name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to initialize power events ring buffer");
+        goto cleanup;
+    }
+
+    ret = rb_init(info, &info->rb_infos[CONNECTIVITY_EVENTS_RB_ID],
+                  CONNECTIVITY_EVENTS_RB_ID,
+                  CONNECTIVITY_EVENTS_RB_BUF_SIZE,
+                  CONNECTIVITY_EVENTS_NUM_BUFS,
+                  connectivity_events_ring_name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to initialize connectivity events ring buffer");
+        goto cleanup;
+    }
+
+    ret = rb_init(info, &info->rb_infos[PKT_STATS_RB_ID],
+                  PKT_STATS_RB_ID,
+                  PKT_STATS_RB_BUF_SIZE,
+                  PKT_STATS_NUM_BUFS,
+                  pkt_stats_ring_name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to initialize per packet stats ring buffer");
+        goto cleanup;
+    }
+
+    ret = rb_init(info, &info->rb_infos[DRIVER_PRINTS_RB_ID],
+                  DRIVER_PRINTS_RB_ID,
+                  DRIVER_PRINTS_RB_BUF_SIZE,
+                  DRIVER_PRINTS_NUM_BUFS,
+                  driver_prints_ring_name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to initialize driver prints ring buffer");
+        goto cleanup;
+    }
+
+    ret = rb_init(info, &info->rb_infos[FIRMWARE_PRINTS_RB_ID],
+                  FIRMWARE_PRINTS_RB_ID,
+                  FIRMWARE_PRINTS_RB_BUF_SIZE,
+                  FIRMWARE_PRINTS_NUM_BUFS,
+                  firmware_prints_ring_name);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to initialize firmware prints ring buffer");
+        goto cleanup;
+    }
+
+    pthread_mutex_init(&info->lh_lock, NULL);
+    pthread_mutex_init(&info->ah_lock, NULL);
+
+    return ret;
+
+cleanup:
+    wifi_logger_ring_buffers_deinit(info);
+    return ret;
+}
+
+void wifi_logger_ring_buffers_deinit(hal_info *info)
+{
+    int i;
+
+    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER))
+        return;
+
+    for (i = 0; i < NUM_RING_BUFS; i++) {
+        rb_deinit(&info->rb_infos[i]);
+    }
+    pthread_mutex_destroy(&info->lh_lock);
+    pthread_mutex_destroy(&info->ah_lock);
+}
+
+
+/* Callback handlers registered for nl message send */
+static int error_handler_wifi_logger(struct sockaddr_nl *nla,
+                                     struct nlmsgerr *err,
+                                     void *arg)
+{
+    struct sockaddr_nl *tmp;
+    int *ret = (int *)arg;
+    tmp = nla;
+    *ret = err->error;
+    ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret)));
+    return NL_STOP;
+}
+
+/* Callback handlers registered for nl message send */
+static int ack_handler_wifi_logger(struct nl_msg *msg, void *arg)
+{
+    int *ret = (int *)arg;
+    struct nl_msg * a;
+
+    a = msg;
+    *ret = 0;
+    return NL_STOP;
+}
+
+/* Callback handlers registered for nl message send */
+static int finish_handler_wifi_logger(struct nl_msg *msg, void *arg)
+{
+  int *ret = (int *)arg;
+  struct nl_msg * a;
+
+  a = msg;
+  *ret = 0;
+  return NL_SKIP;
+}
+
+wifi_error WifiLoggerCommand::requestEvent()
+{
+    int status;
+    wifi_error res = WIFI_SUCCESS;
+    struct nl_cb *cb = NULL;
+
+    cb = nl_cb_alloc(NL_CB_DEFAULT);
+    if (!cb) {
+        ALOGE("%s: Callback allocation failed",__FUNCTION__);
+        res = WIFI_ERROR_OUT_OF_MEMORY;
+        goto out;
+    }
+
+    /* Send message */
+    status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
+        goto out;
+    }
+
+    status = 1;
+
+    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_logger, &status);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_logger, &status);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_logger, &status);
+
+    /* Err is populated as part of finish_handler. */
+    while (status > 0){
+         nl_recvmsgs(mInfo->cmd_sock, cb);
+    }
+
+    ALOGV("%s: Msg sent, status=%d, mWaitForRsp=%d", __FUNCTION__, status, mWaitforRsp);
+    /* Only wait for the asynchronous event if HDD returns success, res=0 */
+    if (!status && (mWaitforRsp == true)) {
+        struct timespec abstime;
+        abstime.tv_sec = 4;
+        abstime.tv_nsec = 0;
+        res = mCondition.wait(abstime);
+        if (res == WIFI_ERROR_TIMED_OUT)
+            ALOGE("%s: Time out happened.", __FUNCTION__);
+
+        ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d",
+            __FUNCTION__, res, mWaitforRsp);
+    }
+out:
+    nl_cb_put(cb);
+    /* Cleanup the mMsg */
+    mMsg.destroy();
+    return res;
+}
+
+wifi_error WifiLoggerCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+int WifiLoggerCommand::handleResponse(WifiEvent &reply) {
+    int len = 0, version;
+    char version_type[20];
+    char* memBuffer = NULL;
+    FILE* memDumpFilePtr = NULL;
+    WifiVendorCommand::handleResponse(reply);
+
+    memset(version_type, 0, 20);
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO:
+        {
+            struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
+
+            nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX,
+                            (struct nlattr *)mVendorData, mDataLen, NULL);
+
+            if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
+                len = nla_len(tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]);
+                memcpy(version_type, "Driver", strlen("Driver"));
+                version = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
+            } else if (
+                tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
+                len = nla_len(
+                        tb_vendor[
+                        QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]);
+                memcpy(version_type, "Firmware", strlen("Firmware"));
+                version = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
+            }
+            if (len && mVersion && mVersionLen) {
+                memset(mVersion, 0, mVersionLen);
+                /* if len is greater than the incoming length then
+                   accommodate 1 lesser than mVersionLen to have the
+                   string terminated with '\0' */
+                len = (len > mVersionLen)? (mVersionLen - 1) : len;
+                memcpy(mVersion, nla_data(tb_vendor[version]), len);
+                ALOGV("%s: WLAN %s version : %s ", __FUNCTION__,
+                      version_type, mVersion);
+            }
+        }
+        break;
+        case QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET:
+        {
+            struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_MAX + 1];
+
+            nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LOGGER_MAX,
+                            (struct nlattr *)mVendorData, mDataLen, NULL);
+
+            if (tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED]) {
+                *mSupportedSet =
+                nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED]);
+#ifdef QC_HAL_DEBUG
+                ALOGV("%s: Supported Feature Set : val 0x%x",
+                      __FUNCTION__, *mSupportedSet);
+#endif
+            }
+        }
+        break;
+
+        case QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP:
+        {
+            u32 memDumpSize = 0;
+            int numRecordsRead = 0;
+            u32 remaining = 0;
+            char* buffer = NULL;
+            struct nlattr *tbVendor[
+                QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX + 1];
+
+            nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX,
+                    (struct nlattr *)mVendorData,
+                    mDataLen, NULL);
+
+            if (!tbVendor[
+                QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE]) {
+                ALOGE("%s: LOGGER_RESULTS_MEMDUMP_SIZE not"
+                      "found", __FUNCTION__);
+                break;
+            }
+
+            memDumpSize = nla_get_u32(
+                tbVendor[QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE]
+                );
+
+            /* Allocate the memory indicated in memDumpSize */
+            memBuffer = (char*) malloc(sizeof(char) * memDumpSize);
+            if (memBuffer == NULL) {
+                ALOGE("%s: No Memory for allocating Buffer size of %d",
+                      __func__, memDumpSize);
+                break;
+            }
+            memset(memBuffer, 0, sizeof(char) * memDumpSize);
+
+            ALOGI("%s: Memory Dump size: %u", __func__,
+                  memDumpSize);
+
+            /* Open the proc or debugfs filesystem */
+            memDumpFilePtr = fopen(LOGGER_MEMDUMP_FILENAME, "r");
+            if (memDumpFilePtr == NULL) {
+                ALOGE("Failed to open %s file", LOGGER_MEMDUMP_FILENAME);
+                break;
+            }
+
+            /* Read the memDumpSize value at once */
+            numRecordsRead = fread(memBuffer, 1, memDumpSize,
+                                   memDumpFilePtr);
+            if (numRecordsRead <= 0 ||
+                numRecordsRead != (int) memDumpSize) {
+                ALOGE("%s: Read %d failed for reading at once.",
+                      __func__, numRecordsRead);
+                /* Lets try to read in chunks */
+                rewind(memDumpFilePtr);
+                remaining = memDumpSize;
+                buffer = memBuffer;
+                while (remaining) {
+                    u32 readSize = 0;
+                    if (remaining >= LOGGER_MEMDUMP_CHUNKSIZE) {
+                        readSize = LOGGER_MEMDUMP_CHUNKSIZE;
+                    }
+                    else {
+                        readSize = remaining;
+                    }
+                    numRecordsRead = fread(buffer, 1,
+                                           readSize, memDumpFilePtr);
+                    if (numRecordsRead) {
+                        remaining -= readSize;
+                        buffer += readSize;
+                        ALOGV("%s: Read successful for size:%u "
+                              "remaining:%u", __func__, readSize,
+                              remaining);
+                    }
+                    else {
+                        ALOGE("%s: Chunk read failed for size:%u",
+                              __func__, readSize);
+                        break;
+                    }
+                }
+            }
+
+            /* After successful read, call the callback handler*/
+            if (mHandler.on_firmware_memory_dump) {
+                mHandler.on_firmware_memory_dump(memBuffer,
+                                                 memDumpSize);
+
+            }
+        }
+        break;
+        case QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS:
+        {
+            struct nlattr *tbVendor[QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX+1];
+
+            /* parse and extract wake reason stats */
+            nla_parse(tbVendor, QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX,
+                      (struct nlattr *)mVendorData,
+                      mDataLen, NULL);
+
+            mGetWakeStats->cmd_event_wake_cnt_used = 0;
+
+            mGetWakeStats->driver_fw_local_wake_cnt_used = 0;
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE]) {
+                ALOGE("%s: TOTAL_RX_DATA_WAKE not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->total_rx_data_wake = nla_get_u32(tbVendor[
+                        QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT]) {
+                ALOGE("%s: RX_UNICAST_CNT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_details.rx_unicast_cnt = nla_get_u32(
+                    tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT]) {
+                ALOGE("%s: RX_MULTICAST_CNT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_details.rx_multicast_cnt = nla_get_u32(
+                    tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT]) {
+                ALOGE("%s: RX_BROADCAST_CNT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_details.rx_broadcast_cnt = nla_get_u32(
+                    tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT]) {
+                ALOGE("%s: ICMP_PKT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_pkt_classification_info.icmp_pkt =
+                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT]) {
+                ALOGE("%s: ICMP6_PKT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_pkt =
+                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA]) {
+                ALOGE("%s: ICMP6_RA not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_ra =
+                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA]) {
+                ALOGE("%s: ICMP6_NA not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_na =
+                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA]);
+
+            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS]) {
+                ALOGE("%s: ICMP6_NS not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_ns =
+                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS]);
+
+            if (!tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT]) {
+                ALOGE("%s: ICMP4_RX_MULTICAST_CNT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt =
+                nla_get_u32(tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT]);
+
+            if (!tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT]) {
+                ALOGE("%s: ICMP6_RX_MULTICAST_CNT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt =
+                nla_get_u32(tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT]);
+
+            if (!tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT]) {
+                ALOGE("%s: OTHER_RX_MULTICAST_CNT not found", __FUNCTION__);
+                break;
+            }
+            mGetWakeStats->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt =
+                nla_get_u32(tbVendor[
+                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT]);
+
+        }
+        break;
+
+        default :
+            ALOGE("%s: Wrong Wifi Logger subcmd response received %d",
+                __FUNCTION__, mSubcmd);
+    }
+
+    /* free the allocated memory */
+    if (memBuffer) {
+        free(memBuffer);
+    }
+    if (memDumpFilePtr) {
+        fclose(memDumpFilePtr);
+    }
+    return NL_SKIP;
+}
+
+/* This function will be the main handler for incoming (from driver)
+ * WIFI_LOGGER_SUBCMD.
+ * Calls the appropriate callback handler after parsing the vendor data.
+ */
+int WifiLoggerCommand::handleEvent(WifiEvent &event)
+{
+    WifiVendorCommand::handleEvent(event);
+
+    switch(mSubcmd)
+    {
+       default:
+           /* Error case should not happen print log */
+           ALOGE("%s: Wrong subcmd received %d", __func__, mSubcmd);
+           break;
+    }
+
+    return NL_SKIP;
+}
+
+wifi_error WifiLoggerCommand::setCallbackHandler(WifiLoggerCallbackHandler nHandler)
+{
+    wifi_error res;
+    mHandler = nHandler;
+    res = registerVendorHandler(mVendor_id, mSubcmd);
+    if (res != WIFI_SUCCESS) {
+        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
+              __FUNCTION__, mVendor_id, mSubcmd);
+    }
+    return res;
+}
+
+void WifiLoggerCommand::unregisterHandler(u32 subCmd)
+{
+    unregisterVendorHandler(mVendor_id, subCmd);
+}
+
+wifi_error WifiLoggerCommand::timed_wait(u16 wait_time)
+{
+    struct timespec absTime;
+    absTime.tv_sec = wait_time;
+    absTime.tv_nsec = 0;
+    return mCondition.wait(absTime);
+}
+
+void WifiLoggerCommand::waitForRsp(bool wait)
+{
+    mWaitforRsp = wait;
+}
+
+/* Function to get Driver memory dump */
+wifi_error wifi_get_driver_memory_dump(wifi_interface_handle iface,
+                                    wifi_driver_memory_dump_callbacks callback)
+{
+    FILE *fp;
+    size_t fileSize, remaining, readSize;
+    size_t numRecordsRead;
+    char *memBuffer = NULL, *buffer = NULL;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set &
+          WIFI_LOGGER_DRIVER_DUMP_SUPPORTED)) {
+        ALOGE("%s: Driver memory dump logging feature not supported %x",
+              __FUNCTION__, info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+    /* Open File */
+    fp = fopen(DRIVER_MEMDUMP_FILENAME, "r");
+    if (fp == NULL) {
+        ALOGE("Failed to open %s file", DRIVER_MEMDUMP_FILENAME);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    memBuffer = (char *) malloc(DRIVER_MEMDUMP_MAX_FILESIZE);
+    if (memBuffer == NULL) {
+        ALOGE("%s: malloc failed for size %d", __FUNCTION__,
+                    DRIVER_MEMDUMP_MAX_FILESIZE);
+        fclose(fp);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    /* Read the DRIVER_MEMDUMP_MAX_FILESIZE value at once */
+    numRecordsRead = fread(memBuffer, 1, DRIVER_MEMDUMP_MAX_FILESIZE, fp);
+    if (feof(fp))
+        fileSize = numRecordsRead;
+    else if (numRecordsRead == DRIVER_MEMDUMP_MAX_FILESIZE) {
+        ALOGE("%s: Reading only first %zu bytes from file", __FUNCTION__,
+                numRecordsRead);
+        fileSize = numRecordsRead;
+    } else {
+        ALOGE("%s: Read failed for reading at once, ret: %zu. Trying to read in"
+                "chunks", __FUNCTION__, numRecordsRead);
+        /* Lets try to read in chunks */
+        rewind(fp);
+        remaining = DRIVER_MEMDUMP_MAX_FILESIZE;
+        buffer = memBuffer;
+        fileSize = 0;
+        while (remaining) {
+            readSize = 0;
+            if (remaining >= LOGGER_MEMDUMP_CHUNKSIZE)
+                readSize = LOGGER_MEMDUMP_CHUNKSIZE;
+            else
+                readSize = remaining;
+
+            numRecordsRead = fread(buffer, 1, readSize, fp);
+            fileSize += numRecordsRead;
+            if (feof(fp))
+                break;
+            else if (numRecordsRead == readSize) {
+                remaining -= readSize;
+                buffer += readSize;
+                ALOGV("%s: Read successful for size:%zu remaining:%zu",
+                         __FUNCTION__, readSize, remaining);
+            } else {
+                ALOGE("%s: Chunk read failed for size:%zu", __FUNCTION__,
+                        readSize);
+                free(memBuffer);
+                memBuffer = NULL;
+                fclose(fp);
+                return WIFI_ERROR_UNKNOWN;
+            }
+        }
+    }
+    ALOGV("%s filename: %s fileSize: %zu", __FUNCTION__, DRIVER_MEMDUMP_FILENAME,
+            fileSize);
+    /* After successful read, call the callback function*/
+    callback.on_driver_memory_dump(memBuffer, fileSize);
+
+    /* free the allocated memory */
+    free(memBuffer);
+    fclose(fp);
+    return WIFI_SUCCESS;
+}
+
+/* Function to get wake lock stats */
+wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
+                             WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
+{
+    int requestId;
+    wifi_error ret;
+    WifiLoggerCommand *wifiLoggerCommand;
+    interface_info *ifaceInfo = getIfaceInfo(iface);
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    /* Check Supported logger capability */
+    if (!(info->supported_logger_feature_set &
+          WIFI_LOGGER_WAKE_LOCK_SUPPORTED)) {
+        ALOGE("%s: Wake lock logging feature not supported %x",
+              __FUNCTION__, info->supported_logger_feature_set);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    /* No request id from caller, so generate one and pass it on to the driver.
+     * Generate it randomly.
+     */
+    requestId = get_requestid();
+
+    if (!wifi_wake_reason_cnt) {
+        ALOGE("%s: Invalid buffer provided. Exit.",
+            __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    wifiLoggerCommand = new WifiLoggerCommand(
+                                wifiHandle,
+                                requestId,
+                                OUI_QCA,
+                                QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS);
+    if (wifiLoggerCommand == NULL) {
+        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiLoggerCommand->create();
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    /* Set the interface Id of the message. */
+    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    wifiLoggerCommand->getWakeStatsRspParams(wifi_wake_reason_cnt);
+
+    /* Send the msg and wait for a response. */
+    ret = wifiLoggerCommand->requestResponse();
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
+
+cleanup:
+    delete wifiLoggerCommand;
+    return ret;
+}
+
+void WifiLoggerCommand::getWakeStatsRspParams(
+                            WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
+{
+    mGetWakeStats = wifi_wake_reason_cnt;
+}
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/wcn6740/qcwcn/wifi_hal/wifilogger_diag.cpp
similarity index 93%
copy from qcwcn/wifi_hal/wifilogger_diag.cpp
copy to wcn6740/qcwcn/wifi_hal/wifilogger_diag.cpp
index bdc9c7f..f026a78 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/wcn6740/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -24,6 +24,40 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 /* Suppress -Waddress-of-packed-member for new toolchain update.
@@ -47,6 +81,7 @@
 #include <errno.h>
 #include "wifi_hal_ctrl.h"
 
+#define MAX_EVENT_REASON_CODE 1024
 static uint32_t get_le32(const uint8_t *pos)
 {
     return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24);
@@ -110,7 +145,7 @@
                               RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
     rbe->type = ENTRY_TYPE_CONNECT_EVENT;
     gettimeofday(&time,NULL);
-    rbe->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+    rbe->timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000;
 
     /* Write if verbose level and handler are set */
     if (info->rb_infos[CONNECTIVITY_EVENTS_RB_ID].verbose_level >= 1 &&
@@ -131,6 +166,8 @@
     wlan_ext_scan_capabilities_payload_type *pScanCapabilities;
     wifi_gscan_capabilities gscan_cap;
     gscan_capabilities_vendor_data_t cap_vendor_data;
+    memset(&cap_vendor_data, 0, sizeof(cap_vendor_data));
+
     tlv_log *pTlv;
     int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
     u8 out_buf[SCAN_CAP_ENTRY_SIZE];
@@ -138,7 +175,6 @@
 
     pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
     memset(pRingBufferEntry, 0, SCAN_CAP_ENTRY_SIZE);
-    memset(&cap_vendor_data, 0, sizeof(gscan_capabilities_vendor_data_t));
     pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
                      (pRingBufferEntry + 1);
 
@@ -702,10 +738,10 @@
         {
             wlan_roam_candidate_found_payload_type *pRoamCandidateFound;
             roam_candidate_found_vendor_data_t roamCandidateFoundVendata;
+            memset(&roamCandidateFoundVendata, 0,
+                                sizeof(roamCandidateFoundVendata));
             pConnectEvent->event = WIFI_EVENT_ROAM_CANDIDATE_FOUND;
             pRoamCandidateFound = (wlan_roam_candidate_found_payload_type *)buf;
-            memset(&roamCandidateFoundVendata, 0,
-                   sizeof(roam_candidate_found_vendor_data_t));
             pTlv = &pConnectEvent->tlvs[0];
             pTlv = addLoggerTlv(WIFI_TAG_CHANNEL,
                                 sizeof(pRoamCandidateFound->channel),
@@ -782,13 +818,17 @@
     rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
     rb_entry_hdr.type = ENTRY_TYPE_DATA;
     gettimeofday(&time, NULL);
-    rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+    rb_entry_hdr.timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000;
 
     /* Write if verbose and handler is set */
     if (info->rb_infos[FIRMWARE_PRINTS_RB_ID].verbose_level >= 1 &&
         info->on_ring_buffer_data) {
         /* Write header and payload separately to avoid
          * complete payload memcpy */
+        if (sizeof(wifi_ring_buffer_entry) + length > 2000) {
+            ALOGE("Invalid length of buffer wifi_ring_buffer_entry size: %zu length %u ",sizeof(wifi_ring_buffer_entry), length);
+            return WIFI_ERROR_UNKNOWN;
+        }
         status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID],
                                    (u8*)&rb_entry_hdr,
                                    sizeof(wifi_ring_buffer_entry),
@@ -848,10 +888,10 @@
     return status;
 }
 
-static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length)
+static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u32 length)
 {
-    u16 count = 0, id;
-    u16 payloadlen = 0;
+    u32 count = 0, id;
+    u32 payloadlen = 0;
     u16 hdr_size = 0;
     wifi_error status;
     fw_diag_msg_fixed_hdr_t *diag_msg_fixed_hdr;
@@ -862,8 +902,23 @@
     buf += 4;
     length -= 4;
 
-    while (length > (count + sizeof(fw_diag_msg_fixed_hdr_t))) {
+    while ((info && !info->clean_up)
+          && (length > (count + sizeof(fw_diag_msg_fixed_hdr_t)))) {
         diag_msg_fixed_hdr = (fw_diag_msg_fixed_hdr_t *)(buf + count);
+
+        if (diag_msg_fixed_hdr->diag_event_type > WLAN_DIAG_TYPE_LEGACY_MSG) {
+            hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
+        } else {
+            hdr_size = sizeof(fw_diag_msg_hdr_t);
+        }
+
+        if ((count + hdr_size) > length)
+        {
+            ALOGE("process_fw_diag_msg (%d) - possible buffer over access, length=%d count=%d hdr_size=%d",
+                  diag_msg_fixed_hdr->diag_event_type, length, count, hdr_size);
+            return WIFI_ERROR_UNKNOWN;
+        }
+
         switch (diag_msg_fixed_hdr->diag_event_type) {
             case WLAN_DIAG_TYPE_EVENT:
             case WLAN_DIAG_TYPE_EVENT_V2:
@@ -883,6 +938,12 @@
                     hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
                     payload = diag_msg_hdr_v2->payload;
                 }
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_EVENT - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
+
                 switch (id) {
                     case EVENT_WLAN_BT_COEX_BT_SCO_START:
                     case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
@@ -980,6 +1041,12 @@
                     hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
                     payload = diag_msg_hdr_v2->payload;
                 }
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_LOG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
+
                 switch (id) {
                 case LOG_WLAN_EXTSCAN_CAPABILITIES:
                     status = process_log_extscan_capabilities(info,
@@ -1002,6 +1069,11 @@
                 payloadlen = diag_msg_hdr->u.msg_hdr.payload_len;
                 hdr_size = sizeof(fw_diag_msg_hdr_t);
                 payload = diag_msg_hdr->payload;
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_MSG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
                 process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
                                        payloadlen + hdr_size);
                 break;
@@ -1012,6 +1084,11 @@
                 payloadlen = diag_msg_hdr_v2->u.msg_hdr.payload_len;
                 hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
                 payload = diag_msg_hdr_v2->payload;
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_MSG_V2 - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
                 process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
                                        payloadlen + hdr_size);
                 break;
@@ -1023,6 +1100,11 @@
                 payload = diag_msg_hdr->payload;
                 payloadlen = diag_msg_hdr->u.payload_len;
                 hdr_size = sizeof(fw_diag_msg_hdr_t);
+                if ((count + hdr_size + payloadlen) > length) {
+                    ALOGE("WLAN_DIAG_TYPE_CONFIG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+                           length, count, hdr_size, payloadlen);
+                    return WIFI_ERROR_UNKNOWN;
+                }
                 process_firmware_prints(info, (u8 *)diag_msg_hdr,
                                         payloadlen + hdr_size);
             }
@@ -1201,7 +1283,7 @@
                               RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
     pRingBufferEntry->type = ENTRY_TYPE_POWER_EVENT;
     gettimeofday(&time, NULL);
-    pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+    pRingBufferEntry->timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000;
 
     /* Write if verbose and handler is set */
     if (info->rb_infos[POWER_EVENTS_RB_ID].verbose_level >= 1 &&
@@ -1245,11 +1327,17 @@
                                           int length)
 {
    wlan_data_stall_event_t *event;
+   int reason_code = 0;
 
    ALOGV("Received Data Stall Event from Driver");
    event = (wlan_data_stall_event_t *)buf;
    ALOGE("Received Data Stall event, sending alert %d", event->reason);
-   send_alert(info, DATA_STALL_OFFSET_REASON_CODE + event->reason);
+   if(event->reason >= MAX_EVENT_REASON_CODE)
+       reason_code = 0;
+   else
+       reason_code = event->reason;
+
+   send_alert(info, DATA_STALL_OFFSET_REASON_CODE + reason_code);
 }
 
 static void process_wlan_low_resource_failure(hal_info *info,
@@ -1294,7 +1382,6 @@
     }
 }
 
-
 static wifi_error update_stats_to_ring_buf(hal_info *info,
                       u8 *rb_entry, u32 size)
 {
@@ -1308,10 +1395,10 @@
                               RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
     pRingBufferEntry->type = ENTRY_TYPE_PKT;
     gettimeofday(&time,NULL);
-    pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+    pRingBufferEntry->timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000;
 
     // Write if verbose and handler is set
-    if ((info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_REPRO_PROBLEM)
+    if ((info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_DEBUG_PROBLEM)
         && info->on_ring_buffer_data) {
         ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID],
                           (u8*)pRingBufferEntry,
@@ -1510,7 +1597,7 @@
     wifi_ring_per_packet_status_entry *pps_entry;
     u32 index = 0;
 
-    while (index < info->rx_buf_size_occupied) {
+    while (!info->clean_up && (index < info->rx_buf_size_occupied)) {
         pps_entry = (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
 
         pps_entry->MCS = info->aggr_stats.RxMCS.mcs;
@@ -2109,10 +2196,10 @@
     rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
     rb_entry_hdr.type = ENTRY_TYPE_PKT;
     gettimeofday(&time, NULL);
-    rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+    rb_entry_hdr.timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000;
 
     /* Write if verbose and handler is set */
-    if (info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_REPRO_PROBLEM &&
+    if (info->rb_infos[PKT_STATS_RB_ID].verbose_level >= 3 &&
         info->on_ring_buffer_data) {
         /* Write header and payload separately to avoid
          * complete payload memcpy */
@@ -2290,9 +2377,12 @@
     u8 *data;
     u8 *node_pkt_data;
     wh_pktlog_hdr_v2_t *pkt_stats_node_header;
-    int node_pkt_type,pkt_sub_type,node_pkt_len,i;
+    int node_pkt_type,pkt_sub_type,i;
+    int node_pkt_len = 0;
     wifi_error status = WIFI_SUCCESS;
     node_pkt_stats node_pkt_t;
+    node_pkt_t.bmap_enqueued = 0;
+    node_pkt_t.bmap_failed = 0;
     wifi_ring_buffer_entry *pRingBufferEntry =
         (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats;
 
@@ -2347,6 +2437,9 @@
                        rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
                       }
                  break;
+                 default:
+                 // TODO: Unexpected PKTLOG types
+                 break;
               }
               if (info->pkt_stats->tx_stats_events &  BIT(PKTLOG_TYPE_TX_STAT)) {
                  /* if bmap_enqueued is 1 ,Handle non aggregated cases */
@@ -2384,8 +2477,12 @@
            pkt_stats_len = (pkt_stats_len - (sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len));
            data = (u8*) (data + sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len);
            info->pkt_stats->tx_stats_events = 0;
+        } else {
+            //TODO parsing of unknown packet sub type
+            status = WIFI_ERROR_INVALID_ARGS;
+            break;
         }
-    } while (pkt_stats_len > 0);
+    } while (!info->clean_up && (pkt_stats_len > 0));
     return status;
 }
 
@@ -2417,9 +2514,14 @@
         pthread_mutex_unlock(&info->pkt_fate_stats_lock);
     } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_SW_EVENT) {
         status = parse_stats_sw_event(info, pkt_stats_header);
-    } else
-        ALOGE("%s: invalid log_type %d",__FUNCTION__, pkt_stats_header->log_type);
-
+    } else if (pkt_stats_header->log_type == PKTLOG_TYPE_TX_STAT ||
+               pkt_stats_header->log_type == PKTLOG_TYPE_RX_STATBUF ||
+               pkt_stats_header->log_type == PKTLOG_TYPE_LITE_T2H ||
+               pkt_stats_header->log_type == PKTLOG_TYPE_LITE_RX) {
+        //TODO Parsing of per packet log.
+    } else {
+        //No Parsing on Default packet log type.
+    }
     return status;
 }
 
@@ -2522,7 +2624,7 @@
         data += record_len;
         buflen -= record_len;
 
-    } while (buflen > 0);
+    } while (!info->clean_up && (buflen > 0));
 
     return status;
 }
@@ -2537,7 +2639,7 @@
     rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
     rb_entry_hdr.type = ENTRY_TYPE_DATA;
     gettimeofday(&time, NULL);
-    rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+    rb_entry_hdr.timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000;
 
     /* Write if verbose and handler is set */
     if (info->rb_infos[DRIVER_PRINTS_RB_ID].verbose_level >= 1 &&
@@ -2596,15 +2698,23 @@
                 if (tb_vendor[CLD80211_ATTR_DATA]) {
                     clh = (tAniCLDHdr *)nla_data(tb_vendor[CLD80211_ATTR_DATA]);
                 }
+            } else {
+                ALOGE("Invalid data received");
+                return WIFI_ERROR_UNKNOWN;
             }
-            if (!clh) {
+            if (genlh->cmd != WLAN_NL_MSG_OEM && !clh) {
                 ALOGE("Invalid data received from driver");
-                return WIFI_SUCCESS;
+                return WIFI_ERROR_UNKNOWN;
             }
+
             if((info->wifihal_ctrl_sock.s > 0) && (genlh->cmd == WLAN_NL_MSG_OEM)) {
                wifihal_ctrl_event_t *ctrl_evt;
                wifihal_mon_sock_t *reg;
 
+               if (!(tb_vendor[CLD80211_ATTR_DATA] || tb_vendor[CLD80211_ATTR_CMD])) {
+                   ALOGE("Invalid oem data received from driver");
+                   return WIFI_ERROR_UNKNOWN;
+               }
                ctrl_evt = (wifihal_ctrl_event_t *)malloc(sizeof(*ctrl_evt) + nlh->nlmsg_len);
 
                if(ctrl_evt == NULL)
@@ -2623,9 +2733,6 @@
 
                list_for_each_entry(reg, &info->monitor_sockets, list) {
 
-                   if(reg == NULL)
-                      break;
-
                    if (reg->family_name != CLD80211_FAMILY || reg->cmd_id != WLAN_NL_MSG_OEM)
                        continue;
 
@@ -2633,6 +2740,7 @@
                    /* Indicate the received OEM msg to respective client
                       it is responsibility of the registered client to check
                       the oem_msg is meant for them or not based on oem_msg sub type */
+                   ALOGI("send oem msg of len : %d to apps",ctrl_evt->data_len);
                    if (sendto(info->wifihal_ctrl_sock.s, (char *)ctrl_evt,
                               sizeof(*ctrl_evt) + ctrl_evt->data_len, 0,
                               (struct sockaddr *)&reg->monsock, reg->monsock_len) < 0)
@@ -2653,6 +2761,7 @@
                    }
                }
                free(ctrl_evt);
+               return WIFI_SUCCESS;
             }
         }
     } else {
@@ -2707,6 +2816,12 @@
                     case EVENT_WLAN_STA_DATA_STALL:
                         process_wlan_data_stall_event(info, buf, event_hdr->length);
                         break;
+                    case EVENT_WLAN_POWERSAVE_WOW:
+                    case EVENT_WLAN_POWERSAVE_WOW_STATS:
+                    case EVENT_WLAN_STA_KICKOUT:
+                    case EVENT_WLAN_BRINGUP_STATUS:
+                        /* Handle DIAG events properly */
+                        break;
                     default:
                         return WIFI_SUCCESS;
                 }
@@ -2790,20 +2905,20 @@
         diag_fw_type = event_hdr->diag_type;
         if (diag_fw_type == DIAG_TYPE_FW_MSG) {
             dbglog_slot *slot;
-            u16 length = 0;
+            u32 length = 0;
 
             slot = (dbglog_slot *)buf;
+            length = get_le32((u8 *)&slot->length);
             if (nlh->nlmsg_len < (NLMSG_HDRLEN + sizeof(dbglog_slot) +
-                                        slot->length)) {
+                                        length)) {
                 ALOGE("Received CNSS_DIAG message with insufficent length: %d:"
                               " expected: %zu, %s:%d",
                       nlh->nlmsg_len,
-                      (NLMSG_HDRLEN + sizeof(dbglog_slot) +slot->length),
+                      (NLMSG_HDRLEN + sizeof(dbglog_slot) +length),
                       __FUNCTION__,
                       __LINE__);
                 return WIFI_ERROR_UNKNOWN;
             }
-            length = get_le32((u8 *)&slot->length);
             process_fw_diag_msg(info, &slot->payload[0], length);
         }
     }
diff --git a/qcwcn/wifi_hal/wifilogger_diag.h b/wcn6740/qcwcn/wifi_hal/wifilogger_diag.h
similarity index 100%
copy from qcwcn/wifi_hal/wifilogger_diag.h
copy to wcn6740/qcwcn/wifi_hal/wifilogger_diag.h
diff --git a/wcn6740/qcwcn/wifi_hal/wifilogger_event_defs.h b/wcn6740/qcwcn/wifi_hal/wifilogger_event_defs.h
new file mode 100644
index 0000000..86b198c
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wifilogger_event_defs.h
@@ -0,0 +1,516 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WIFILOGGER_EVENT_DEFS_H
+#define WIFILOGGER_EVENT_DEFS_H
+
+typedef enum {
+    EVENT_DROP_ID = 0,
+
+    EVENT_WLAN_PE = 0x67A, /* 16 byte payload */
+
+    /* Events between 0x67b to 0x67f are not used */
+
+    EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS = 0x67B,        /* 11 byte payload */
+    EVENT_WLAN_ADD_BLOCK_ACK_FAILED = 0x67C,         /* 9 byte payload */
+    EVENT_WLAN_BRINGUP_STATUS = 0x680,               /* 12 byte payload */
+    EVENT_WLAN_POWERSAVE_WOW = 0x682,                /* 11 byte payload */
+
+    EVENT_WLAN_EXTSCAN_FEATURE_STARTED =   0xA8E, /* 240 byte payload */
+    EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG = 0xA8F, /* 243 byte payload */
+    EVENT_WLAN_EXTSCAN_CYCLE_STARTED = 0xA90, /* 12 byte payload */
+    EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED = 0xA91, /* 12 byte payload */
+    EVENT_WLAN_EXTSCAN_BUCKET_STARTED = 0xA92, /* 1 byte payload */
+    EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED = 0xA93, /* 4 byte payload */
+    EVENT_WLAN_ROAM_SCAN_STARTED = 0xA94, /* 128 byte payload */
+
+
+    EVENT_WLAN_ROAM_SCAN_COMPLETE = 0xA95,
+    EVENT_WLAN_ROAM_CANDIDATE_FOUND = 0xA96,
+    EVENT_WLAN_ROAM_SCAN_CONFIG = 0xA97,
+    EVENT_WLAN_BT_COEX_BT_SCO_START = 0xA98,
+    EVENT_WLAN_BT_COEX_BT_SCO_STOP = 0xA99,
+    EVENT_WLAN_BT_COEX_BT_SCAN_START = 0xA9A,
+    EVENT_WLAN_BT_COEX_BT_SCAN_STOP = 0xA9B,
+    EVENT_WLAN_BT_COEX_BT_HID_START = 0xA9C,
+    EVENT_WLAN_BT_COEX_BT_HID_STOP = 0xA9D,
+    EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */
+    EVENT_WLAN_EAPOL = 0xA8D, /* 96 bytes payload */
+    EVENT_WLAN_EXTSCAN_FEATURE_STOP = 0xAA3,
+    EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE = 0xAA4,
+    EVENT_WLAN_BEACON_EVENT = 0xAA6,
+    EVENT_WLAN_LOG_COMPLETE = 0xAA7,
+    EVENT_WLAN_LOW_RESOURCE_FAILURE = 0xABB,
+    EVENT_WLAN_POWERSAVE_WOW_STATS = 0xB33, /* 76 bytes payload */
+    EVENT_WLAN_STA_KICKOUT = 0xB39, /* 11 bytes payload */
+    EVENT_WLAN_STA_DATA_STALL = 0xB3A,
+
+    EVENT_MAX_ID = 0x0FFF
+} event_id_enum_type;
+
+typedef enum {
+    LOG_DROP_ID = 0,
+    LOG_WLAN_EXTSCAN_CAPABILITIES = 0x18F1,
+    LOG_WLAN_EXTSCAN_FEATURE_STARTED = 0x18F2,
+} log_id_enum_type;
+
+typedef enum
+{
+    WLAN_PE_DIAG_SCAN_REQ_EVENT = 0,
+    WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT,
+    WLAN_PE_DIAG_SCAN_RSP_EVENT,
+    WLAN_PE_DIAG_JOIN_REQ_EVENT,
+    WLAN_PE_DIAG_JOIN_RSP_EVENT,
+    WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
+    WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+    WLAN_PE_DIAG_REASSOC_REQ_EVENT,
+    WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+    WLAN_PE_DIAG_AUTH_REQ_EVENT,
+    WLAN_PE_DIAG_AUTH_RSP_EVENT = 10,
+    WLAN_PE_DIAG_DISASSOC_REQ_EVENT,
+    WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+    WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+    WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
+    WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
+    WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+    WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+    WLAN_PE_DIAG_START_BSS_REQ_EVENT,
+    WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+    WLAN_PE_DIAG_AUTH_IND_EVENT = 20,
+    WLAN_PE_DIAG_ASSOC_IND_EVENT,
+    WLAN_PE_DIAG_ASSOC_CNF_EVENT,
+    WLAN_PE_DIAG_REASSOC_IND_EVENT,
+    WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT,
+    WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT,
+    WLAN_PE_DIAG_STOP_BSS_REQ_EVENT,
+    WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+    WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
+    WLAN_PE_DIAG_ADDTS_REQ_EVENT,
+    WLAN_PE_DIAG_ADDTS_RSP_EVENT = 30,
+    WLAN_PE_DIAG_DELTS_REQ_EVENT,
+    WLAN_PE_DIAG_DELTS_RSP_EVENT,
+    WLAN_PE_DIAG_DELTS_IND_EVENT,
+    WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT,
+    WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT,
+    WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT,
+    WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT,
+    WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT,
+    WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT,
+    WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT = 40,
+    WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT,
+    WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT,
+    WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT,
+    WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT,
+    WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT,
+    WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT,
+    WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT,
+    WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT,
+    WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT,
+    WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT = 50,
+    WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT,
+    WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT,
+    WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT,
+    WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT,
+    WLAN_PE_DIAG_HAL_DELBA_IND_EVENT,
+    WLAN_PE_DIAG_HB_FAILURE_TIMEOUT,
+    WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
+    WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT,
+    WLAN_PE_DIAG_PREAUTH_DONE,
+    WLAN_PE_DIAG_REASSOCIATING = 60,
+    WLAN_PE_DIAG_CONNECTED,
+    WLAN_PE_DIAG_ASSOC_REQ_EVENT,
+    WLAN_PE_DIAG_AUTH_COMP_EVENT,
+    WLAN_PE_DIAG_ASSOC_COMP_EVENT,
+    WLAN_PE_DIAG_AUTH_START_EVENT,
+    WLAN_PE_DIAG_ASSOC_START_EVENT,
+    WLAN_PE_DIAG_REASSOC_START_EVENT,
+    WLAN_PE_DIAG_ROAM_AUTH_START_EVENT,
+    WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT,
+    WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT = 70,
+    WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT,
+    WLAN_PE_DIAG_SCAN_COMP_EVENT,
+    WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT,
+    WLAN_PE_DIAG_ASSOC_TIMEOUT,
+    WLAN_PE_DIAG_AUTH_TIMEOUT,
+} wlan_host_diag_event_type;
+
+typedef struct wlan_pe_event {
+    char bssid[6];
+    u16 event_type;
+    u16 sme_state;
+    u16 mlm_state;
+    u16 status;
+    u16 reason_code;
+} __attribute__((packed)) wlan_pe_event_t;
+
+typedef enum {
+    WLAN_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED = 0,
+    WLAN_DRIVER_EAPOL_FRAME_RECEIVED,
+} wlan_eapol_event_type;
+
+#define EAPOL_MASK 0x8013
+#define EAPOL_M1_MASK 0x8000
+#define EAPOL_M2_MASK 0x0001
+#define EAPOL_M3_MASK 0x8013
+#define EAPOL_M4_MASK 0x0003
+
+typedef struct wlan_eapol_event {
+    u8 event_sub_type;
+    u8 eapol_packet_type;
+    u16 eapol_key_info;
+    u16 eapol_rate;
+    u8 dest_addr[6];
+    u8 src_addr[6];
+} __attribute__((packed)) wlan_eapol_event_t;
+
+/*EVENT_WLAN_EXTSCAN_FEATURE_STARTED */
+typedef struct wlan_ext_bucket {
+    u8 bucket_id;
+    u8 base_period_multiplier;
+    u16 min_dwell_time_active;
+    u16 max_dwell_time_active;
+    u16 min_dwell_time_passive;
+    u16 max_dwell_time_passive;
+    u8 num_channels;
+    u8 channel_offset;
+    u8 forwarding_flags;
+    u8 channel_band;
+    u32 notify_extscan_events;
+} __attribute__((packed)) wlan_ext_bucket_t;
+
+typedef struct {
+    u32 base_period;
+    u32 max_iterations;
+    u32 forwarding_flags;
+    u32 configuration_flags;
+    u32 notify_extscan_events;
+    u32 scan_priority;
+    u32 max_bssids_per_scan_cycle;
+    u32 min_rssi;
+    u32 max_table_usage;
+    u32 min_dwell_time_active;
+    u32 max_dwell_time_active;
+    u32 min_dwell_time_passive;
+    u32 max_dwell_time_passive;
+    u32 min_rest_time;
+    u32 max_rest_time;
+    u32 n_probes;
+    u32 repeat_probe_time;
+    u32 probe_spacing_time;
+    u32 idle_time;
+    u32 max_scan_time;
+    u32 probe_delay;
+    u32 scan_ctrl_flags;
+    u32 burst_duration;
+    u32 num_buckets;
+    wlan_ext_bucket bucket_list[8];
+} __attribute__((packed)) wlan_ext_scan_feature_started_payload_type;
+/*End EVENT_WLAN_EXTSCAN_FEATURE_STARTED*/
+
+/*EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG*/
+typedef struct {
+    u8 bucket_id;
+    u16 scan_channels[40];
+} __attribute__((packed)) wlan_ext_bucket_channels;
+
+typedef struct {
+    wlan_ext_bucket_channels bucket_list[3];
+} __attribute__((packed)) wlan_ext_bucket_channel_config_payload_type;
+
+/*End EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG*/
+
+/*EVENT_WLAN_EXTSCAN_CYCLE_STARTED*/
+typedef struct {
+    u32 scan_id;
+    u32 timer_tick;
+    u32 scheduled_bucket_mask;
+    u32 scan_cycle_count;
+} __attribute__((packed)) wlan_ext_scan_cycle_started_payload_type;
+/*End EVENT_WLAN_EXTSCAN_CYCLE_STARTED*/
+
+/*EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED*/
+typedef struct {
+    u32 scan_id;
+    u32 timer_tick;
+    u32 scheduled_bucket_mask;
+    u32 scan_cycle_count;
+} __attribute__((packed)) wlan_ext_scan_cycle_completed_payload_type;
+/*End EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED*/
+
+/*EVENT_WLAN_EXTSCAN_BUCKET_STARTED*/
+typedef struct {
+    u8 bucket_id;
+} __attribute__((packed)) wlan_ext_scan_bucket_started_payload_type;
+/*End EVENT_WLAN_EXTSCAN_BUCKET_STARTED*/
+
+/*EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED*/
+typedef struct {
+    u8 bucket_id;
+} __attribute__((packed))  wlan_ext_scan_bucket_completed_payload_type;
+/*End EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED*/
+
+/*EVENT_WLAN_ROAM_SCAN_STARTED*/
+typedef struct {
+    u32 scan_id;
+    u32 roam_scan_flags;
+    u32 cur_rssi;
+    u16 scan_params[18];
+    u16 scan_channels[40]; // first 40 channels only
+} __attribute__((packed)) wlan_roam_scan_started_payload_type;
+/*End EVENT_WLAN_ROAM_SCAN_STARTED*/
+
+/*EVENT_WLAN_ROAM_SCAN_COMPLETE*/
+typedef struct {
+    u32 scan_id;
+    u32 reason;
+    u32 completion_flags;
+    u32 num_candidate;
+    u32 flags;
+} __attribute__((packed)) wlan_roam_scan_complete_payload_type;
+/*End EVENT_WLAN_ROAM_SCAN_COMPLETE*/
+
+/*EVENT_WLAN_ROAM_CANDIDATE_FOUND*/
+typedef struct {
+    u8 channel;
+    u8 rssi;
+    u8 bssid[6];
+    u8 ssid[33];
+    u8 auth_mode;
+    u8 ucast_cipher;
+    u8 mcast_cipher;
+} __attribute__((packed)) wlan_roam_candidate_found_payload_type;
+/*End EVENT_WLAN_ROAM_CANDIDATE_FOUND*/
+
+/*EVENT_WLAN_ROAM_SCAN_CONFIG*/
+typedef struct {
+    u32 flags;
+    u32 roam_scan_config[8];
+} __attribute__((packed)) wlan_roam_scan_config_payload_type;
+/*End EVENT_WLAN_ROAM_SCAN_CONFIG*/
+
+/* EVENT_WLAN_BT_COEX_BT_SCO_START */
+typedef struct {
+    u8 link_id;
+    u8 link_state;
+    u8 link_role;
+    u8 link_type;
+    u16 Tsco;
+    u8 Rsco;
+} __attribute__((packed)) wlan_bt_coex_bt_sco_start_payload_type;
+/* End EVENT_WLAN_BT_COEX_BT_SCO_START */
+
+/* EVENT_WLAN_BT_COEX_BT_SCO_STOP */
+typedef struct {
+    u8 link_id;
+    u8 link_state;
+    u8 link_role;
+    u8 link_type;
+    u16 Tsco;
+    u8 Rsco;
+} __attribute__((packed)) wlan_bt_coex_bt_sco_stop_payload_type;
+/* End EVENT_WLAN_BT_COEX_BT_SCO_STOP */
+
+/* EVENT_WLAN_BT_COEX_BT_SCAN_START */
+typedef struct {
+    u8 scan_type;
+    u8 scan_bitmap;
+} __attribute__((packed)) wlan_bt_coex_bt_scan_start_payload_type;
+
+/* End EVENT_WLAN_BT_COEX_BT_SCAN_START */
+
+/* EVENT_WLAN_BT_COEX_BT_SCAN_STOP */
+typedef struct {
+    u8 scan_type;
+    u8 scan_bitmap;
+} __attribute__((packed)) wlan_bt_coex_bt_scan_stop_payload_type;
+/* End EVENT_WLAN_BT_COEX_BT_SCAN_STOP */
+
+/* EVENT_WIFI_BT_COEX_BT_HID_START */
+typedef struct {
+    u8 link_id;
+    u8 link_state;
+    u8 link_role;
+    u8 Tsniff;
+    u8 attempts;
+} __attribute__((packed)) wlan_bt_coex_bt_hid_start_payload_type;
+/* End EVENT_WIFI_BT_COEX_BT_HID_START */
+
+/* EVENT_WIFI_BT_COEX_BT_HID_STOP */
+typedef struct {
+    u8 link_id;
+    u8 link_state;
+    u8 link_role;
+    u8 Tsniff;
+    u8 attempts;
+} __attribute__((packed)) wlan_bt_coex_bt_hid_stop_payload_type;
+/* End EVENT_WIFI_BT_COEX_BT_HID_STOP */
+
+/* EVENT_WLAN_EXTSCAN_FEATURE_STOP */
+typedef struct {
+    u32 request_id;
+} __attribute__((packed)) wlan_ext_scan_feature_stop_payload_type;
+/* End EVENT_WLAN_EXTSCAN_FEATURE_STOP */
+
+/* EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE */
+typedef struct {
+    u32 request_id;
+    u32 table_type;
+    u32 entries_in_use;
+    u32 maximum_entries;
+    u32 scan_count_after_getResults;
+    u8 threshold_num_scans;
+} __attribute__((packed)) wlan_ext_scan_results_available_payload_type;
+/* End EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE */
+
+/* Log LOG_WLAN_EXTSCAN_CAPABILITIES */
+typedef struct {
+    u32 header;
+    u32 request_id;
+    u32 requestor_id;
+    u32 vdev_id;
+    u32 num_extscan_cache_tables;
+    u32 num_wlan_change_monitor_tables;
+    u32 num_hotlist_monitor_tables;
+    u32 rtt_one_sided_supported;
+    u32 rtt_11v_supported;
+    u32 rtt_ftm_supported;
+    u32 num_extscan_cache_capabilities;
+    u32 num_extscan_wlan_change_capabilities;
+    u32 num_extscan_hotlist_capabilities;
+    u32 num_roam_ssid_whitelist;
+    u32 num_roam_bssid_blacklist;
+    u32 num_roam_bssid_preferred_list;
+    u32 num_extscan_hotlist_ssid;
+    u32 num_epno_networks;
+} __attribute__((packed)) wlan_extscan_capabilities_event_fixed_param;
+
+typedef struct {
+    u32 header;
+    u32 table_id;
+    u32 scan_cache_entry_size;
+    u32 max_scan_cache_entries;
+    u32 max_buckets;
+    u32 max_bssid_per_scan;
+    u32 max_table_usage_threshold;
+} __attribute__((packed)) wlan_extscan_cache_capabilities;
+
+typedef struct {
+    u32 tlv_header;
+    u32 table_id;
+    u32 wlan_hotlist_entry_size;
+    u32 max_hotlist_entries;
+} __attribute__((packed)) wlan_extscan_hotlist_monitor_capabilities;
+
+typedef struct {
+    u32 request_id;
+    wlan_extscan_capabilities_event_fixed_param extscan_capabilities;
+    wlan_extscan_cache_capabilities extscan_cache_capabilities;
+    wlan_extscan_hotlist_monitor_capabilities extscan_hotlist_monitor_capabilities;
+} __attribute__((packed)) wlan_ext_scan_capabilities_payload_type;
+/* End LOG_WLAN_EXTSCAN_CAPABILITIES */
+
+/* EVENT_WLAN_BEACON_RECEIVED */
+typedef struct {
+    u8 bssid[6];
+    u32 beacon_rssi;
+} __attribute__((packed)) wlan_beacon_received_payload_type;
+/* End EVENT_WLAN_BEACON_RECEIVED */
+
+typedef struct {
+    u8 ucBaPeerMac[6];
+    u8 ucBaTid;
+    u8 ucBaBufferSize;
+    u16 ucBaSSN;
+    u8 fInitiator;
+} __attribute__((packed)) wlan_add_block_ack_success_payload_type;
+
+/* EVENT_WLAN_ADD_BLOCK_ACK_FAILED */
+typedef struct {
+    u8 ucBaPeerMac[6];
+    u8 ucBaTid;
+    u8 ucReasonCode;
+    u8 fInitiator;
+} __attribute__((packed)) wlan_add_block_ack_failed_payload_type;
+
+typedef enum
+{
+    WIFI_EVENT_MEMORY_FAILURE,
+} resource_failure_type;
+
+typedef struct wlan_low_resource_failure_event
+{
+    resource_failure_type event_sub_type;
+} __attribute__((packed)) wlan_low_resource_failure_event_t;
+
+/* EVENT_WLAN_POWERSAVE_WOW */
+typedef struct {
+    u8 event_subtype;
+    u8 wow_type;
+    u8 wow_magic_pattern[6];
+    u8 wow_del_ptrn_id;
+    u8 wow_wakeup_cause;
+    u8 wow_wakeup_cause_pbm_ptrn_id;
+} __attribute__((packed)) wlan_wow_payload_t;
+
+/* EVENT_WLAN_POWERSAVE_WOW_STATS */
+typedef struct {
+    u32 wow_ucast_wake_up_count;
+    u32 wow_bcast_wake_up_count;
+    u32 wow_ipv4_mcast_wake_up_count;
+    u32 wow_ipv6_mcast_wake_up_count;
+    u32 wow_ipv6_mcast_ra_stats;
+    u32 wow_ipv6_mcast_ns_stats;
+    u32 wow_ipv6_mcast_na_stats;
+    u32 wow_pno_match_wake_up_count;
+    u32 wow_pno_complete_wake_up_count;
+    u32 wow_gscan_wake_up_count;
+    u32 wow_low_rssi_wake_up_count;
+    u32 wow_rssi_breach_wake_up_count;
+    u32 wow_icmpv4_count;
+    u32 wow_icmpv6_count;
+    u32 wow_oem_response_wake_up_count;
+    u32 Reserved_1;
+    u32 Reserved_2;
+    u32 Reserved_3;
+    u32 Reserved_4;
+} __attribute__((packed)) wlan_wow_stats_t;
+
+/* EVENT_WLAN_STA_KICKOUT */
+typedef struct {
+    u32 reasoncode;
+    u8 peer_mac[6];
+    u8 vdev_id;
+} __attribute__((packed)) wlan_kickout_t;
+
+/* EVENT_WLAN_BRINGUP_STATUS */
+typedef struct {
+    u16 wlan_status;
+    u8 driver_version[10];
+} __attribute__((packed)) wlan_status_payload_t;
+
+#endif /* WIFILOGGER_EVENT_DEFS_H */
diff --git a/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h b/wcn6740/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
similarity index 100%
copy from qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
copy to wcn6740/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
diff --git a/wcn6740/qcwcn/wifi_hal/wifiloggercmd.h b/wcn6740/qcwcn/wifi_hal/wifiloggercmd.h
new file mode 100644
index 0000000..9361821
--- /dev/null
+++ b/wcn6740/qcwcn/wifi_hal/wifiloggercmd.h
@@ -0,0 +1,120 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_WIFILOGGER_COMMAND_H__
+#define __WIFI_HAL_WIFILOGGER_COMMAND_H__
+
+#include "common.h"
+#include "cpp_bindings.h"
+#include "wifi_logger.h"
+#include "wifilogger_diag.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define POWER_EVENTS_RB_BUF_SIZE 2048
+#define POWER_EVENTS_NUM_BUFS    4
+
+#define CONNECTIVITY_EVENTS_RB_BUF_SIZE 4096
+#define CONNECTIVITY_EVENTS_NUM_BUFS    4
+
+#define PKT_STATS_RB_BUF_SIZE 4096
+#define PKT_STATS_NUM_BUFS    32
+
+#define DRIVER_PRINTS_RB_BUF_SIZE 4096
+#define DRIVER_PRINTS_NUM_BUFS    128
+
+#define FIRMWARE_PRINTS_RB_BUF_SIZE 32768
+#define FIRMWARE_PRINTS_NUM_BUFS    16
+
+#define LOGGER_RING_BUFFER (WIFI_LOGGER_CONNECT_EVENT_SUPPORTED \
+                            | WIFI_LOGGER_POWER_EVENT_SUPPORTED \
+                            | WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED)
+
+enum rb_info_indices {
+    POWER_EVENTS_RB_ID = 0,
+    CONNECTIVITY_EVENTS_RB_ID = 1,
+    PKT_STATS_RB_ID = 2,
+    DRIVER_PRINTS_RB_ID = 3,
+    FIRMWARE_PRINTS_RB_ID = 4,
+};
+
+typedef struct {
+  void (*on_firmware_memory_dump) (char *buffer,
+                                   int buffer_size);
+
+} WifiLoggerCallbackHandler;
+
+
+class WifiLoggerCommand : public WifiVendorCommand
+{
+private:
+    WifiLoggerCallbackHandler mHandler;
+    char                      *mVersion;
+    int                       mVersionLen;
+    u32                       *mSupportedSet;
+    int                       mRequestId;
+    bool                      mWaitforRsp;
+    bool                      mMoreData;
+    WLAN_DRIVER_WAKE_REASON_CNT *mGetWakeStats;
+public:
+
+    WifiLoggerCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+
+    static WifiLoggerCommand* instance(wifi_handle handle);
+    virtual ~WifiLoggerCommand();
+
+    // This function implements creation of WifiLogger specific Request
+    // based on  the request type
+    virtual wifi_error create();
+    virtual wifi_error requestEvent();
+    virtual wifi_error requestResponse();
+    virtual int handleResponse(WifiEvent &reply);
+    virtual int handleEvent(WifiEvent &event);
+    wifi_error setCallbackHandler(WifiLoggerCallbackHandler nHandler);
+    virtual void unregisterHandler(u32 subCmd);
+
+    /* Takes wait time in seconds. */
+    virtual wifi_error timed_wait(u16 wait_time);
+    virtual void waitForRsp(bool wait);
+    virtual void setVersionInfo(char *buffer, int buffer_size);
+    virtual void setFeatureSet(u32 *support);
+    virtual void getWakeStatsRspParams(
+                    WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
+};
+void rb_timerhandler(hal_info *info);
+wifi_error wifi_logger_ring_buffers_init(hal_info *info);
+void wifi_logger_ring_buffers_deinit(hal_info *info);
+void push_out_all_ring_buffers(hal_info *info);
+void send_alert(hal_info *info, int reason_code);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __WIFI_HAL_WIFILOGGER_COMMAND_H__ */
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/Android.mk b/wcn6740/qcwcn/wpa_supplicant_8_lib/Android.mk
new file mode 100644
index 0000000..8e2ab2d
--- /dev/null
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/Android.mk
@@ -0,0 +1,79 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X)
+
+ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
+  CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
+endif
+
+WPA_SUPPL_DIR := external/wpa_supplicant_8
+WPA_SRC_FILE :=
+
+include $(WPA_SUPPL_DIR)/wpa_supplicant/android.config
+
+WPA_SUPPL_DIR_INCLUDE := $(WPA_SUPPL_DIR)/src \
+	$(WPA_SUPPL_DIR)/src/common \
+	$(WPA_SUPPL_DIR)/src/drivers \
+	$(WPA_SUPPL_DIR)/src/l2_packet \
+	$(WPA_SUPPL_DIR)/src/utils \
+	$(WPA_SUPPL_DIR)/src/wps \
+	$(WPA_SUPPL_DIR)/src/ap \
+	$(WPA_SUPPL_DIR)/wpa_supplicant
+
+ifdef CONFIG_DRIVER_NL80211
+WPA_SUPPL_DIR_INCLUDE += external/libnl/include
+WPA_SRC_FILE += driver_cmd_nl80211_extn.c \
+		driver_cmd_nl80211.c
+endif
+
+ifeq ($(TARGET_ARCH),arm)
+# To force sizeof(enum) = 4
+L_CFLAGS += -mabi=aapcs-linux
+endif
+
+ifdef CONFIG_ANDROID_LOG
+L_CFLAGS += -DCONFIG_ANDROID_LOG
+endif
+
+ifdef CONFIG_P2P
+L_CFLAGS += -DCONFIG_P2P
+endif
+
+L_CFLAGS += -Werror
+
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := lib_driver_cmd_qcwcn
+LOCAL_SHARED_LIBRARIES := libc libcutils
+ifneq ($(wildcard external/libnl),)
+LOCAL_SHARED_LIBRARIES += libnl
+endif
+LOCAL_SHARED_LIBRARIES += libdl
+LOCAL_CFLAGS := $(L_CFLAGS) -Wall
+LOCAL_SRC_FILES := $(WPA_SRC_FILE)
+LOCAL_C_INCLUDES := $(WPA_SUPPL_DIR_INCLUDE)
+LOCAL_VENDOR_MODULE := true
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
+include $(BUILD_STATIC_LIBRARY)
+
+########################
+
+endif
diff --git a/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD b/wcn6740/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD
similarity index 100%
copy from qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD
copy to wcn6740/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am b/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am
new file mode 100644
index 0000000..8c09e3e
--- /dev/null
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am
@@ -0,0 +1,37 @@
+# Makefile.am - Automake script for wpa_supplicant_8_lib
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CFLAGS = -Wall
+
+if DEBUG
+AM_CFLAGS += -g
+else
+AM_CFLAGS += -O2
+endif
+
+AM_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast \
+             -Wno-maybe-uninitialized -Wno-parentheses \
+             -DCONFIG_P2P
+
+h_sources = driver_cmd_nl80211_extn.h
+library_includedir = $(pkgincludedir)
+library_include_HEADERS = $(h_sources)
+
+libwpa_supplicant_8_lib_la_SOURCES = driver_cmd_nl80211.c
+libwpa_supplicant_8_lib_la_SOURCES += driver_cmd_nl80211_extn.c
+libwpa_supplicant_8_lib_la_CFLAGS = ${AM_CFLAGS} ${LIBNL_CFLAGS}
+
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/common"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/drivers"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/l2_packet"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/utils"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/src/wps"
+libwpa_supplicant_8_lib_la_CFLAGS += "-I${WPA_SUPPLICANT_DIR}/wpa_supplicant"
+libwpa_supplicant_8_lib_la_CFLAGS +=  "-DLINUX_EMBEDDED"
+
+
+libwpa_supplicant_8_lib_la_LIBADD = ${LIBNL_LIBS}
+lib_LTLIBRARIES = libwpa_supplicant_8_lib.la
+
+pkgconfigdir = $(libdir)/pkgconfig
diff --git a/qcwcn/wpa_supplicant_8_lib/NOTICE b/wcn6740/qcwcn/wpa_supplicant_8_lib/NOTICE
similarity index 100%
copy from qcwcn/wpa_supplicant_8_lib/NOTICE
copy to wcn6740/qcwcn/wpa_supplicant_8_lib/NOTICE
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac b/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac
new file mode 100644
index 0000000..76eda02
--- /dev/null
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac
@@ -0,0 +1,72 @@
+# -*- Autoconf -*-
+# configure.ac -- Autoconf script for qcacld-tools
+#
+
+AC_PREREQ(2.61)
+AC_INIT([wpa_supplicant_8_lib], 1.0.0)
+AM_INIT_AUTOMAKE([foreign])
+AM_MAINTAINER_MODE
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+LT_INIT
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_LIBTOOL
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+
+AC_ARG_ENABLE([debug],
+        [  --enable-debug    Turn on debugging],
+        [case "${enableval}" in
+            yes) debug=true ;;
+            no)  debug=false ;;
+            *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
+        esac],[debug=false])
+AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])
+
+has_libnl_ver=0
+# libnl-2 provides only libnl-2.0.pc file, so we check for separate libnl-genl-3.0.pc
+# pkg-config file just for libnl-3.0 case.
+#
+PKG_CHECK_MODULES([LIBNL], [libnl-3.0 >= 3.0 libnl-genl-3.0 >= 3.0], [has_libnl_ver=3], [
+   PKG_CHECK_MODULES([LIBNL], [libnl-2.0 >= 2.0], [has_libnl_ver=2], [
+           PKG_CHECK_MODULES([LIBNL], [libnl-1], [has_libnl_ver=1], [has_libnl_ver=0])])])
+
+if (test "$has_libnl_ver" -eq 0); then
+        AC_MSG_ERROR(libnl and libnl-genl are required but were not found)
+fi
+
+
+AC_ARG_VAR(WPA_SUPPLICANT_DIR,[Path to Wpa-supplicant-dir ])
+AS_IF([test "${WPA_SUPPLICANT_DIR}" = ""],[AC_MSG_ERROR("Provide WPA_SUPPLICANT_DIR=path to wpa_supplicant dir")])
+
+AC_SUBST([LIBNL_CFLAGS])
+AC_SUBST([LIBNL_LIBS])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_HEADER_STDC
+AC_C_INLINE
+AC_TYPE_INT64_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT8_T
+
+# Checks for library functions.
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FORK
+AC_FUNC_MALLOC
+
+AC_CONFIG_FILES([ \
+    Makefile
+])
+AC_OUTPUT
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
new file mode 100644
index 0000000..9656710
--- /dev/null
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
@@ -0,0 +1,5924 @@
+/*
+ * Driver interaction with extended Linux CFG8021
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *
+ *    * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+#include <sys/types.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/object-api.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/pkt_sched.h>
+
+#include "common.h"
+#include "linux_ioctl.h"
+#include "driver_nl80211.h"
+#include "wpa_supplicant_i.h"
+#include "config.h"
+#include "wpa_driver_common_lib.h"
+#include "ap/hostapd.h"
+#include "ap/sta_info.h"
+#ifdef LINUX_EMBEDDED
+#include <sys/ioctl.h>
+#endif
+#if defined(ANDROID) || defined(LINUX_EMBEDDED)
+#include "android_drv.h"
+#endif
+#include "driver_cmd_nl80211_extn.h"
+
+#define WPA_PS_ENABLED		0
+#define WPA_PS_DISABLED		1
+#define UNUSED(x)	(void)(x)
+#define NL80211_ATTR_MAX_INTERNAL 256
+#define CSI_STATUS_REJECTED      -1
+#define CSI_STATUS_SUCCESS        0
+#define ENHANCED_CFR_VER          2
+#define CSI_GROUP_BITMAP          1
+#define CSI_DEFAULT_GROUP_ID      0
+#define CSI_FC_STYPE_BEACON       8
+#define CSI_MGMT_BEACON           (1<<WLAN_FC_STYPE_BEACON)
+
+#define TWT_SETUP_WAKE_INTVL_MANTISSA_MAX       0xFFFF
+#define TWT_SETUP_WAKE_DURATION_MAX             0xFF
+#define TWT_SETUP_WAKE_INTVL_EXP_MAX            31
+#define TWT_WAKE_INTERVAL_TU_FACTOR		1024
+
+#define TWT_SETUP_STR        "twt_session_setup"
+#define TWT_TERMINATE_STR    "twt_session_terminate"
+#define TWT_PAUSE_STR        "twt_session_pause"
+#define TWT_RESUME_STR       "twt_session_resume"
+#define TWT_NUDGE_STR        "twt_session_nudge"
+#define TWT_GET_PARAMS_STR   "twt_session_get_params"
+#define TWT_GET_STATS_STR    "twt_session_get_stats"
+#define TWT_CLEAR_STATS_STR  "twt_session_clear_stats"
+#define TWT_GET_CAP_STR      "twt_get_capability"
+#define TWT_SET_PARAM_STR    "twt_set_param"
+
+#define TWT_SETUP_STRLEN         strlen(TWT_SETUP_STR)
+#define TWT_TERMINATE_STR_LEN    strlen(TWT_TERMINATE_STR)
+#define TWT_PAUSE_STR_LEN        strlen(TWT_PAUSE_STR)
+#define TWT_RESUME_STR_LEN       strlen(TWT_RESUME_STR)
+#define TWT_NUDGE_STR_LEN        strlen(TWT_NUDGE_STR)
+#define TWT_GET_PARAMS_STR_LEN   strlen(TWT_GET_PARAMS_STR)
+#define TWT_GET_STATS_STR_LEN    strlen(TWT_GET_STATS_STR)
+#define TWT_CLEAR_STATS_STR_LEN  strlen(TWT_CLEAR_STATS_STR)
+#define TWT_GET_CAP_STR_LEN      strlen(TWT_GET_CAP_STR)
+#define TWT_SET_PARAM_STR_LEN    strlen(TWT_SET_PARAM_STR)
+
+#define TWT_CMD_NOT_EXIST -EINVAL
+#define DEFAULT_IFNAME "wlan0"
+#define TWT_RESP_BUF_LEN 512
+
+#define SINGLE_SPACE_LEN 1
+#define SINGLE_DIGIT_LEN 1
+
+#define DIALOG_ID_STR           "dialog_id"
+#define REQ_TYPE_STR            "req_type"
+#define TRIG_TYPE_STR           "trig_type"
+#define FLOW_TYPE_STR           "flow_type"
+#define WAKE_INTR_EXP_STR       "wake_intr_exp"
+#define PROTECTION_STR          "protection"
+#define WAKE_TIME_STR           "wake_time"
+#define WAKE_DUR_STR            "wake_dur"
+#define WAKE_INTR_MANTISSA_STR  "wake_intr_mantissa"
+#define BROADCAST_STR           "broadcast"
+#define MIN_WAKE_INTVL_STR      "min_wake_intvl"
+#define MAX_WAKE_INTVL_STR      "max_wake_intvl"
+#define MIN_WAKE_DUR_STR        "min_wake_duration"
+#define MAX_WAKE_DUR_STR        "max_wake_duration"
+#define NEXT_TWT_STR            "next_twt"
+#define NEXT2_TWT_STR           "next2_twt"
+#define NEXT_TWT_SIZE_STR       "next_twt_size"
+#define PAUSE_DURATION_STR      "pause_duration"
+#define WAKE_TSF_STR            "wake_tsf"
+#define ANNOUNCE_TIMEOUT_STR    "announce_timeout"
+#define AP_AC_VALUE_STR         "ap_ac_value"
+#define MAC_ADDRESS_STR         "mac_addr"
+
+#define DIALOG_ID_STR_LEN               strlen(DIALOG_ID_STR)
+#define REQ_TYPE_STR_LEN                strlen(REQ_TYPE_STR)
+#define TRIG_TYPE_STR_LEN               strlen(TRIG_TYPE_STR)
+#define FLOW_TYPE_STR_LEN               strlen(FLOW_TYPE_STR)
+#define WAKE_INTR_EXP_STR_LEN           strlen(WAKE_INTR_EXP_STR)
+#define PROTECTION_STR_LEN              strlen(PROTECTION_STR)
+#define WAKE_TIME_STR_LEN               strlen(WAKE_TIME_STR)
+#define WAKE_DUR_STR_LEN                strlen(WAKE_DUR_STR)
+#define WAKE_INTR_MANTISSA_STR_LEN      strlen(WAKE_INTR_MANTISSA_STR)
+#define BROADCAST_STR_LEN               strlen(BROADCAST_STR)
+#define MIN_WAKE_INTVL_STR_LEN          strlen(MIN_WAKE_INTVL_STR)
+#define MAX_WAKE_INTVL_STR_LEN          strlen(MAX_WAKE_INTVL_STR)
+#define MIN_WAKE_DUR_STR_LEN            strlen(MIN_WAKE_DUR_STR)
+#define MAX_WAKE_DUR_STR_LEN            strlen(MAX_WAKE_DUR_STR)
+#define NEXT_TWT_STR_LEN		strlen(NEXT_TWT_STR)
+#define NEXT2_TWT_STR_LEN		strlen(NEXT2_TWT_STR)
+#define NEXT_TWT_SIZE_STR_LEN		strlen(NEXT_TWT_SIZE_STR)
+#define PAUSE_DURATION_STR_LEN          strlen(PAUSE_DURATION_STR)
+#define WAKE_TSF_STR_LEN                strlen(WAKE_TSF_STR)
+#define ANNOUNCE_TIMEOUT_STR_LEN        strlen(ANNOUNCE_TIMEOUT_STR)
+#define AP_AC_VALUE_STR_LEN             strlen(AP_AC_VALUE_STR)
+#define MAC_ADDR_STR_LEN             	strlen(MAC_ADDRESS_STR)
+
+#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+
+#define TWT_CTRL_EVENT           "CTRL-EVENT-TWT"
+#define TWT_SETUP_RESP           "CTRL-EVENT-TWT SETUP"
+#define TWT_TEARDOWN_RESP        "CTRL-EVENT-TWT TERMINATE"
+#define TWT_PAUSE_RESP           "CTRL-EVENT-TWT PAUSE"
+#define TWT_RESUME_RESP          "CTRL-EVENT-TWT RESUME"
+#define TWT_NOTIFY_RESP          "CTRL-EVENT-TWT NOTIFY"
+#define TWT_SETUP_RESP_LEN       strlen(TWT_SETUP_RESP)
+#define TWT_TEARDOWN_RESP_LEN    strlen(TWT_TEARDOWN_RESP)
+#define TWT_PAUSE_RESP_LEN       strlen(TWT_PAUSE_RESP)
+#define TWT_RESUME_RESP_LEN      strlen(TWT_RESUME_RESP)
+#define TWT_NOTIFY_RESP_LEN      strlen(TWT_NOTIFY_RESP)
+
+static int twt_async_support = -1;
+
+struct twt_setup_parameters {
+	u8 dialog_id;
+	u8 req_type;
+	u8 trig_type;
+	u8 flow_type;
+	u8 wake_intr_exp;
+	u8 protection;
+	u32 wake_time;
+	u32 wake_dur;
+	u32 wake_intr_mantissa;
+	u8 bcast;
+	u32 min_wake_intvl;
+	u32 max_wake_intvl;
+	u32 min_wake_duration;
+	u32 max_wake_duration;
+	u64 wake_tsf;
+	u32 announce_timeout_us;
+};
+
+struct twt_resume_parameters {
+	u8 dialog_id;
+	u8 next_twt;
+	u32 next2_twt;
+	u32 next_twt_size;
+};
+
+struct twt_nudge_parameters {
+	u8 dialog_id;
+	u32 wake_time;
+	u32 next_twt_size;
+};
+
+struct twt_set_parameters {
+	u8 ap_ac_value;
+};
+
+struct twt_resp_info {
+	char *reply_buf;
+	int reply_buf_len;
+	enum qca_wlan_twt_operation twt_oper;
+	struct wpa_driver_nl80211_data *drv;
+};
+
+
+static int wpa_driver_twt_async_resp_event(struct wpa_driver_nl80211_data *drv,
+					   u32 vendor_id, u32 subcmd, u8 *data, size_t len);
+
+/* ============ nl80211 driver extensions ===========  */
+enum csi_state {
+	CSI_STATE_STOP = 0,
+	CSI_STATE_START,
+};
+
+struct csi_global_params {
+	struct i802_bss *bss;
+	enum csi_state current_state;
+	char connected_bssid[MAC_ADDR_LEN];
+	int transport_mode;
+};
+
+static struct csi_global_params g_csi_param = {0};
+
+static wpa_driver_oem_cb_table_t *oem_cb_table = NULL;
+
+#define MCC_QUOTA_MIN 10
+#define MCC_QUOTA_MAX 90
+/* Only one quota entry for now */
+#define MCC_QUOTA_ENTRIES_MAX 1
+
+struct mcc_quota {
+       uint32_t if_idx;
+       uint32_t quota;
+};
+
+
+static char *get_next_arg(char *cmd)
+{
+	char *pos = cmd;
+
+	while (*pos != ' ' && *pos != '\0')
+		pos++;
+
+	return pos;
+}
+
+static int wpa_driver_cmd_set_ani_level(struct i802_bss *bss, int mode, int ofdmlvl)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg = NULL;
+	struct nlattr *params = NULL;
+	int ret = 0;
+
+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+			QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
+		!(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+		nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_SETTING, mode)) {
+			nlmsg_free(msg);
+			return -1;
+	}
+	if(mode == QCA_WLAN_ANI_SETTING_FIXED) {
+		if(nla_put(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL, sizeof(int32_t), &ofdmlvl)){
+			nlmsg_free(msg);
+			return -1;
+		}
+	}
+	nla_nest_end(msg, params);
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+	if (!ret)
+		return 0;
+	wpa_printf(MSG_ERROR, "%s: Failed set_ani_level, ofdmlvl=%d, ret=%d",
+		   __FUNCTION__, ofdmlvl, ret);
+	return ret;
+}
+
+static int wpa_driver_cmd_set_congestion_report(struct i802_bss *bss, char *cmd)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg;
+	struct nlattr *params = NULL;
+	char *endptr = NULL;
+	int ret;
+	int enable = -1, threshold = -1, interval = -1;
+
+	wpa_printf(MSG_INFO, "%s enter", __FUNCTION__);
+
+	enable = strtol(cmd, &endptr, 10);
+	if (enable != 0 && enable != 1) {
+		wpa_printf(MSG_ERROR, "%s: invalid enable arg %d", __FUNCTION__, enable);
+		return -EINVAL;
+	}
+
+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+		  QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS) ||
+		!(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+		nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE,
+		  QCA_WLAN_MEDIUM_ASSESS_CONGESTION_REPORT) ||
+		nla_put_u8(msg,
+		  QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_ENABLE,
+		  enable)) {
+			nlmsg_free(msg);
+			return -1;
+	}
+	if (enable == 1) {
+		if (!(*endptr) ||
+		  ((threshold = strtol(endptr, &endptr, 10)) < 0 || threshold > 100) ||
+		  !(*endptr) ||
+		  ((interval = strtol(endptr, &endptr, 10)) < 1 || interval > 30)) {
+			wpa_printf(MSG_ERROR, "%s: args less or invalid", __FUNCTION__);
+			nlmsg_free(msg);
+			return -EINVAL;
+		}
+		if (nla_put_u8(msg,
+		  QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_THRESHOLD,
+		  threshold) || nla_put_u8(msg,
+		  QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_INTERVAL,
+		  interval)) {
+			nlmsg_free(msg);
+			return -1;
+		}
+	}
+	nla_nest_end(msg, params);
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+	wpa_printf(MSG_INFO, "%s: set congestion report: enable=%d, threshold=%d,"
+			"interval=%d", __FUNCTION__, enable, threshold, interval);
+	if (!ret)
+		return 0;
+	wpa_printf(MSG_ERROR, "%s: Failed set congestion report, ret=%d", __FUNCTION__, ret);
+	return ret;
+}
+
+static int wpa_driver_cmd_set_tx_power(struct i802_bss *bss, char *cmd)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg;
+	char *endptr = NULL;
+	int ret;
+	int dbm, mbm;
+
+	wpa_printf(MSG_INFO, "%s enter: dbm=%s", __FUNCTION__, cmd);
+
+	dbm = strtol(cmd, &endptr, 10);
+	if (*endptr || dbm < 0) {
+		wpa_printf(MSG_ERROR, "%s: invalid dbm %d", __FUNCTION__, dbm);
+		return -EINVAL;
+	}
+	mbm = dbm * 100;
+	if (mbm < 0) { // integer overflow
+		wpa_printf(MSG_ERROR, "%s: invalid mbm %d", __FUNCTION__, mbm);
+		return -EINVAL;
+	}
+
+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) ||
+	    nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING,
+		NL80211_TX_POWER_LIMITED) ||
+	    nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, mbm)) {
+		nlmsg_free(msg);
+		return -ENOBUFS;
+	}
+
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+	if (!ret)
+		return 0;
+
+	wpa_printf(MSG_ERROR, "%s: Failed set_tx_power dbm=%d, ret=%d",
+		   __FUNCTION__, dbm, ret);
+	return ret;
+}
+
+/* Return type for setBand*/
+enum {
+	SEND_CHANNEL_CHANGE_EVENT = 0,
+	DO_NOT_SEND_CHANNEL_CHANGE_EVENT,
+};
+
+typedef struct android_wifi_priv_cmd {
+	char *buf;
+	int used_len;
+	int total_len;
+} android_wifi_priv_cmd;
+
+static int drv_errors = 0;
+
+static void wpa_driver_notify_country_change(void *ctx, char *cmd)
+{
+	if ((os_strncasecmp(cmd, "COUNTRY", 7) == 0) ||
+	    (os_strncasecmp(cmd, "SETBAND", 7) == 0)) {
+		union wpa_event_data event;
+
+		os_memset(&event, 0, sizeof(event));
+		event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
+		if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
+			event.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
+			if (os_strlen(cmd) > 9) {
+				event.channel_list_changed.alpha2[0] = cmd[8];
+				event.channel_list_changed.alpha2[1] = cmd[9];
+			}
+		} else {
+			event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
+		}
+		wpa_supplicant_event(ctx, EVENT_CHANNEL_LIST_CHANGED, &event);
+	}
+}
+
+static struct remote_sta_info g_sta_info = {0};
+static struct bss_info g_bss_info = {0};
+
+static struct nl_msg *prepare_nlmsg(struct wpa_driver_nl80211_data *drv,
+				    char *ifname, int cmdid, int subcmd,
+				    int flag)
+{
+	int res;
+	struct nl_msg *nlmsg = nlmsg_alloc();
+	int ifindex;
+
+	if (nlmsg == NULL) {
+		wpa_printf(MSG_ERROR,"Out of memory");
+		return NULL;
+	}
+
+	genlmsg_put(nlmsg, /* pid = */ 0, /* seq = */ 0,
+		    drv->global->nl80211_id, 0, flag, cmdid, 0);
+
+	if (cmdid == NL80211_CMD_VENDOR) {
+		res = nla_put_u32(nlmsg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+		if (res < 0) {
+			wpa_printf(MSG_ERROR,"Failed to put vendor id");
+			goto cleanup;
+		}
+
+		res = nla_put_u32(nlmsg, NL80211_ATTR_VENDOR_SUBCMD, subcmd);
+		if (res < 0) {
+			wpa_printf(MSG_ERROR,"Failed to put vendor sub command");
+			goto cleanup;
+		}
+	}
+
+	if (ifname && (strlen(ifname) > 0))
+		ifindex = if_nametoindex(ifname);
+	else
+		ifindex = if_nametoindex(DEFAULT_IFNAME);
+
+	if (nla_put_u32(nlmsg, NL80211_ATTR_IFINDEX, ifindex) != 0) {
+		wpa_printf(MSG_ERROR,"Failed to get iface index for iface: %s", ifname);
+		goto cleanup;
+	}
+
+	return nlmsg;
+
+cleanup:
+	if (nlmsg)
+		nlmsg_free(nlmsg);
+	return NULL;
+}
+
+static struct nl_msg *prepare_vendor_nlmsg(struct wpa_driver_nl80211_data *drv,
+					   char *ifname, int subcmd)
+{
+	return prepare_nlmsg(drv, ifname, NL80211_CMD_VENDOR, subcmd, 0);
+}
+
+static int parse_station_info(struct resp_info *info, struct nlattr *vendata,
+			      int datalen)
+{
+	struct nlattr *tb_vendor[GET_STATION_INFO_MAX + 1];
+	struct nlattr *attr, *attr1, *attr2;
+	u8 *beacon_ies = NULL;
+	size_t beacon_ies_len = 0;
+	u8 seg1;
+
+	g_bss_info.oui[0] = (OUI_QCA) & 0xFF;
+	g_bss_info.oui[1] = ((OUI_QCA)>>8) & 0xFF;
+	g_bss_info.oui[2] = ((OUI_QCA)>>16) & 0xFF;
+
+	nla_parse(tb_vendor, GET_STATION_INFO_MAX,
+		  vendata, datalen, NULL);
+
+	attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR];
+	if (attr) {
+		struct nlattr *tb1[NL80211_ATTR_MAX + 1];
+
+		nla_parse(tb1, NL80211_ATTR_MAX, nla_data(attr),
+			  nla_len(attr), NULL);
+		if (tb1[NL80211_ATTR_SSID] &&
+		    (nla_len(tb1[NL80211_ATTR_SSID]) <= MAX_SSID_LEN)) {
+			os_memcpy(g_bss_info.ssid, nla_data(tb1[NL80211_ATTR_SSID]),
+					  nla_len(tb1[NL80211_ATTR_SSID]));
+			g_bss_info.ssid[nla_len(tb1[NL80211_ATTR_SSID])] = '\0';
+		} else {
+			wpa_printf(MSG_ERROR,"NL80211_ATTR_SSID not found");
+		}
+		if (tb1[NL80211_ATTR_MAC]) {
+			os_memcpy(g_bss_info.oui, nla_data(tb1[NL80211_ATTR_MAC]), OUI_LEN);
+		} else {
+			wpa_printf(MSG_ERROR,"NL80211_ATTR_MAC not found");
+		}
+		if (tb1[NL80211_ATTR_SURVEY_INFO]) {
+			struct nlattr *tb2[NL80211_SURVEY_INFO_MAX + 1];
+
+			nla_parse(tb2, NL80211_SURVEY_INFO_MAX,
+				  nla_data(tb1[NL80211_ATTR_SURVEY_INFO]),
+				  nla_len(tb1[NL80211_ATTR_SURVEY_INFO]), NULL);
+			if (tb2[NL80211_SURVEY_INFO_FREQUENCY]) {
+				g_bss_info.channel =
+				nla_get_u32(tb2[NL80211_SURVEY_INFO_FREQUENCY]);
+			} else {
+				wpa_printf(MSG_ERROR,
+				    "NL80211_SURVEY_INFO_FREQUENCY not found");
+			}
+			if (tb2[NL80211_SURVEY_INFO_NOISE]) {
+				g_bss_info.noise =
+				nla_get_u8(tb2[NL80211_SURVEY_INFO_NOISE]);
+				g_bss_info.noise -= 100;
+			} else {
+				wpa_printf(MSG_ERROR,"NL80211_SURVEY_INFO_NOISE not found");
+			}
+		} else {
+			wpa_printf(MSG_ERROR,"NL80211_ATTR_SURVEY_INFO not found");
+		}
+
+		if (tb1[NL80211_ATTR_STA_INFO]) {
+			struct nlattr *tb2[NL80211_STA_INFO_MAX + 1];
+
+			nla_parse(tb2, NL80211_STA_INFO_MAX,
+				  nla_data(tb1[NL80211_ATTR_STA_INFO]),
+				  nla_len(tb1[NL80211_ATTR_STA_INFO]), NULL);
+			if (tb2[NL80211_STA_INFO_SIGNAL]) {
+				g_bss_info.rssi =
+				nla_get_u8(tb2[NL80211_STA_INFO_SIGNAL]);
+				g_bss_info.rssi -= 100;
+			} else {
+				wpa_printf(MSG_ERROR,"NL80211_STA_INFO_SIGNAL not found");
+			}
+			g_bss_info.snr = g_bss_info.rssi - g_bss_info.noise;
+
+			attr1 = tb2[NL80211_STA_INFO_TX_BITRATE];
+			if (attr1) {
+				struct nlattr *tb3[NL80211_RATE_INFO_MAX + 1];
+
+				nla_parse(tb3, NL80211_RATE_INFO_MAX,
+					  nla_data(attr1), nla_len(attr1),
+					  NULL);
+				if (tb3[NL80211_RATE_INFO_BITRATE32]) {
+					g_bss_info.data_rate = nla_get_u32(
+					tb3[NL80211_RATE_INFO_BITRATE32])/10;
+				} else if (tb3[NL80211_RATE_INFO_BITRATE]) {
+					g_bss_info.data_rate = nla_get_u16(
+					tb3[NL80211_RATE_INFO_BITRATE])/10;
+				}
+
+			} else {
+				wpa_printf(MSG_ERROR,"NL80211_STA_INFO_TX_BITRATE not found");
+			}
+		} else {
+			wpa_printf(MSG_ERROR,"NL80211_ATTR_STA_INFO not found");
+		}
+	} else {
+		wpa_printf(MSG_ERROR,
+		   "QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR not found");
+	}
+
+	if (tb_vendor[GET_STATION_INFO_AKM]) {
+		g_bss_info.akm = nla_get_u32(
+			tb_vendor[GET_STATION_INFO_AKM]);
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE])
+		g_bss_info.mode_80211 = nla_get_u32(
+			tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE]);
+
+	attr = tb_vendor[GET_STATION_INFO_VHT_OPERATION];
+	attr1 = tb_vendor[GET_STATION_INFO_HT_OPERATION];
+	attr2 = tb_vendor[GET_STATION_INFO_HE_OPERATION];
+	if (attr) {
+		struct ieee80211_vht_operation *info = nla_data(attr);
+
+		switch (info->vht_op_info_chwidth) {
+		case CHANWIDTH_USE_HT:
+			if (attr1) {
+				struct ieee80211_ht_operation *info;
+
+				info = nla_data(attr1);
+				g_bss_info.bw = info->ht_param ? 40:20;
+			}
+			break;
+		case CHANWIDTH_80MHZ:
+			seg1 = info->vht_op_info_chan_center_freq_seg1_idx;
+			if (seg1)
+				/* Notifying 80P80 also as bandwidth = 160 */
+				g_bss_info.bw = 160;
+			else
+				g_bss_info.bw = 80;
+			break;
+		case CHANWIDTH_160MHZ:
+			g_bss_info.bw = 160;
+			break;
+		case CHANWIDTH_80P80MHZ:
+			g_bss_info.bw = 160;
+			break;
+		default:
+			wpa_printf(MSG_ERROR,"Invalid channel width received : %u",
+						 info->vht_op_info_chwidth);
+		}
+	} else if (attr1) {
+		struct ieee80211_ht_operation *info = nla_data(attr1);
+
+		g_bss_info.bw = info->ht_param ? 40:20;
+	} else
+		g_bss_info.bw = 20;
+
+	if (attr2) {
+		struct ieee80211_he_operation *he_info = nla_data(attr2);
+		uint8_t *opr, ch_bw = CHANNEL_BW_INVALID;
+
+		/* Check optional field in he_info is present of not */
+		if (!he_info || (nla_len(attr2) <=
+		    (sizeof(he_info->he_oper_params) +
+		    sizeof(he_info->he_mcs_nss_set)))) {
+			he_info ? wpa_printf(MSG_ERROR,"Invalid he operation len: %d", nla_len(attr2)):
+			wpa_printf(MSG_ERROR,"Invalid he_info: NULL");
+			goto parse_beacon_ies;
+		}
+
+		opr = (uint8_t *)he_info;
+		/* Point to operational field */
+		opr += (sizeof(he_info->he_oper_params) +
+			sizeof(he_info->he_mcs_nss_set));
+		if (he_info->he_oper_params &
+		    IEEE80211_HE_OPERATION_VHT_OPER_MASK) {
+			ch_bw = opr[HE_OPER_VHT_CH_WIDTH_OFFSET];
+			switch (ch_bw) {
+			case CHANWIDTH_USE_HT:
+				/* TO DO */
+				break;
+			case CHANWIDTH_80MHZ:
+				seg1 = opr[HE_OPER_VHT_CENTER_FRQ_SEG1_OFFSET];
+				if (seg1)
+					/* Notifying 80P80 also as bandwidth = 160 */
+					g_bss_info.bw = 160;
+				else
+					g_bss_info.bw = 80;
+				break;
+			case CHANWIDTH_160MHZ:
+				g_bss_info.bw = 160;
+				break;
+			case CHANWIDTH_80P80MHZ:
+				g_bss_info.bw = 160;
+				break;
+			default:
+				break;
+			}
+			opr += (HE_OPER_VHT_MAX_OFFSET + 1);
+		}
+
+		if (he_info->he_oper_params &
+		    IEEE80211_HE_OPERATION_CO_LOC_BSS_MASK) {
+			opr += (HE_OPER_CO_LOCATED_MAX_OFFSET + 1);
+		}
+
+		if (he_info->he_oper_params &
+		    IEEE80211_HE_OPERATION_6G_OPER_MASK) {
+			ch_bw = (opr[HE_OPER_6G_PARAMS_OFFSET] &
+				 HE_OPER_6G_PARAMS_SUB_CH_BW_MASK);
+			switch (ch_bw) {
+			case HE_CHANWIDTH_20MHZ:
+				g_bss_info.bw = 20;
+				break;
+			case HE_CHANWIDTH_40MHZ:
+				g_bss_info.bw = 40;
+				break;
+			case HE_CHANWIDTH_80MHZ:
+				g_bss_info.bw = 80;
+				break;
+			case HE_CHANWIDTH_160MHZ:
+				/* Notifying 80P80 also as bandwidth = 160 */
+				g_bss_info.bw = 160;
+				break;
+			default:
+				wpa_printf(MSG_ERROR,"Invalid channel width received : %u", ch_bw);
+			}
+		}
+
+	}
+
+parse_beacon_ies:
+	attr = tb_vendor[GET_STATION_INFO_BEACON_IES];
+	if (attr) {
+		beacon_ies = nla_data(attr);
+
+		beacon_ies_len = nla_len(attr);
+		if (beacon_ies && beacon_ies_len > 12) {
+			beacon_ies += 12;
+			beacon_ies_len -= 12;
+		}
+	}
+
+	if (tb_vendor[GET_STATION_INFO_DRIVER_DISCONNECT_REASON]) {
+		g_bss_info.disc_reasn_code = nla_get_u32(tb_vendor[
+			GET_STATION_INFO_DRIVER_DISCONNECT_REASON]);
+	}
+	snprintf(info->reply_buf, info->reply_buf_len,
+		 "%02x%02x%02x %s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %u %s %d %d %d %d %d %d %d %d %d %d %d %d %d",
+		 g_bss_info.oui[0],
+		 g_bss_info.oui[1],
+		 g_bss_info.oui[2],
+		 g_bss_info.ssid,
+		 g_bss_info.channel,
+		 g_bss_info.bw,
+		 g_bss_info.rssi,
+		 g_bss_info.data_rate,
+		 g_bss_info.mode_80211,
+		 -1,
+		 -1,
+		 -1,
+		 g_bss_info.snr,
+		 g_bss_info.noise,
+		 g_bss_info.akm,
+		 g_bss_info.roaming_count,
+		 -1,
+		 -1,
+		 -1,
+		 -1,
+		 g_bss_info.disc_reasn_code,
+		 info->country,
+		 g_bss_info.ani_level,
+		 -1,
+		 -1,
+		 -1,
+		 g_bss_info.roam_trigger_reason,
+		 g_bss_info.roam_fail_reason,
+		 g_bss_info.roam_invoke_fail_reason,
+		 g_bss_info.tsf_out_of_sync_count,
+		 g_bss_info.latest_tx_power,
+		 g_bss_info.latest_tx_rate,
+		 g_bss_info.target_power_24g_1mbps,
+		 g_bss_info.target_power_24g_6mbps,
+		 g_bss_info.target_power_5g_6mbps);
+
+	return 0;
+}
+
+static int parse_get_feature_info(struct resp_info *info, struct nlattr *vendata,
+				  int datalen)
+{
+	struct nlattr *tb_vendor[NUM_QCA_WLAN_VENDOR_FEATURES + 1];
+	struct nlattr *attr;
+	nla_parse(tb_vendor, NUM_QCA_WLAN_VENDOR_FEATURES,
+		  vendata, datalen, NULL);
+	attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
+	if (attr) {
+		snprintf(info->reply_buf, info->reply_buf_len, "%u",
+			 nla_get_u32(attr));
+		wpa_printf(MSG_DEBUG, "%s: driver supported feature info  = %s",
+			   __func__, info->reply_buf);
+	} else {
+		snprintf(info->reply_buf, info->reply_buf_len, "FAIL");
+		return -1;
+	}
+	return 0;
+}
+static int handle_response(struct resp_info *info, struct nlattr *vendata,
+			   int datalen)
+{
+	switch (info->subcmd) {
+	case QCA_NL80211_VENDOR_SUBCMD_GET_STATION:
+		os_memset(info->reply_buf, 0, info->reply_buf_len);
+		if (info->cmd_type == GETSTATSBSSINFO)
+			parse_station_info(info, vendata, datalen);
+
+		wpa_printf(MSG_INFO,"STAINFO: %s", info->reply_buf);
+		break;
+	case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
+		os_memset(info->reply_buf, 0, info->reply_buf_len);
+		parse_get_feature_info(info, vendata, datalen);
+		break;
+	default:
+		wpa_printf(MSG_ERROR,"Unsupported response type: %d", info->subcmd);
+		break;
+	}
+	return 0;
+}
+
+static int response_handler(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *mHeader;
+	struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1];
+	struct nlattr *vendata;
+	int datalen;
+	struct resp_info *info = (struct resp_info *) arg;
+	int status;
+
+	mHeader = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
+	nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL,
+			  genlmsg_attrdata(mHeader, 0),
+			  genlmsg_attrlen(mHeader, 0), NULL);
+
+	if (mAttributes[NL80211_ATTR_VENDOR_DATA]) {
+		vendata = nla_data(mAttributes[NL80211_ATTR_VENDOR_DATA]);
+		datalen = nla_len(mAttributes[NL80211_ATTR_VENDOR_DATA]);
+		if (!vendata) {
+			wpa_printf(MSG_ERROR,"Vendor data not found");
+			return -1;
+		}
+		status = handle_response(info, vendata, datalen);
+	} else {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found");
+		status = -1;
+	}
+
+	return status;
+}
+
+static int ack_handler(struct nl_msg *msg, void *arg)
+{
+	int *err = (int *)arg;
+
+	*err = 0;
+	return NL_STOP;
+}
+
+int wpa_driver_nl80211_oem_event(struct wpa_driver_nl80211_data *drv,
+					   u32 vendor_id, u32 subcmd,
+					   u8 *data, size_t len)
+{
+	int ret = -1, lib_n;
+	if (wpa_driver_oem_initialize(&oem_cb_table) != WPA_DRIVER_OEM_STATUS_FAILURE &&
+	    oem_cb_table) {
+		for (lib_n = 0;
+		     oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb != NULL;
+		     lib_n++) {
+			if(oem_cb_table[lib_n].wpa_driver_nl80211_driver_oem_event) {
+				ret = oem_cb_table[lib_n].wpa_driver_nl80211_driver_oem_event(
+						drv, vendor_id,subcmd, data, len);
+				if (ret == WPA_DRIVER_OEM_STATUS_SUCCESS ) {
+					break;
+				}  else if (ret == WPA_DRIVER_OEM_STATUS_ENOSUPP) {
+					continue;
+				}  else if (ret == WPA_DRIVER_OEM_STATUS_FAILURE) {
+					wpa_printf(MSG_DEBUG, "%s: Received error: %d",
+						__func__, ret);
+					break;
+				}
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int wpa_driver_restart_csi(struct i802_bss *bss, int *status);
+
+int wpa_driver_nl80211_driver_event(struct wpa_driver_nl80211_data *drv,
+					   u32 vendor_id, u32 subcmd,
+					   u8 *data, size_t len)
+{
+	int ret = -1;
+	int status = -1;
+	struct i802_bss *bss;
+
+	ret = wpa_driver_nl80211_oem_event(drv, vendor_id, subcmd,
+			data, len);
+
+	if(ret != WPA_DRIVER_OEM_STATUS_ENOSUPP)
+		return ret;
+
+	switch(subcmd) {
+		case QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT:
+			ret = wpa_driver_twt_async_resp_event(drv, vendor_id, subcmd,
+							      data, len);
+			break;
+		case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
+			if(g_csi_param.current_state == CSI_STATE_START) {
+				bss = get_bss_ifindex(drv, drv->ifindex);
+				if(bss == NULL) {
+					wpa_printf(MSG_DEBUG, "%s: bss is NULL",
+							__func__);
+					break;
+				}
+				if(wpa_driver_restart_csi(bss, &status))
+					wpa_printf(MSG_DEBUG, "csi_restart failed %d",
+						   status);
+			}
+			break;
+		default:
+			break;
+	}
+	return ret;
+}
+
+static int finish_handler(struct nl_msg *msg, void *arg)
+{
+	int *ret = (int *)arg;
+
+	*ret = 0;
+	return NL_SKIP;
+}
+
+
+static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
+						 void *arg)
+{
+	int *ret = (int *)arg;
+
+	*ret = err->error;
+	wpa_printf(MSG_ERROR,"%s received : %d - %s", __func__,
+	      err->error, strerror(err->error));
+	return NL_SKIP;
+}
+
+
+static int no_seq_check(struct nl_msg *msg, void *arg)
+{
+	return NL_OK;
+}
+
+static int send_nlmsg(struct nl_sock *cmd_sock, struct nl_msg *nlmsg,
+		      nl_recvmsg_msg_cb_t customer_cb, void *arg)
+{
+	int err = 0;
+	struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
+
+	if (!cb)
+		goto out;
+
+	err = nl_send_auto_complete(cmd_sock, nlmsg);	/* send message */
+	if (err < 0)
+		goto out;
+
+	err = 1;
+
+	nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
+	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
+	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
+	if (customer_cb)
+		nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, customer_cb, arg);
+
+	while (err > 0) {				   /* wait for reply */
+		int res = nl_recvmsgs(cmd_sock, cb);
+
+		if (res)
+			wpa_printf(MSG_ERROR,"nl80211: %s->nl_recvmsgs failed: %d",
+				 __func__, res);
+	}
+out:
+	nl_cb_put(cb);
+	if (nlmsg)
+		nlmsg_free(nlmsg);
+	return err;
+}
+
+static int chartohex(char c)
+{
+	int val = -1;
+
+	if (c >= '0' && c <= '9')
+		val = c - '0';
+	else if (c >= 'a' && c <= 'f')
+		val = c - 'a' + 10;
+	else if (c >= 'A' && c <= 'F')
+		val = c - 'A' + 10;
+
+	return val;
+}
+
+static int convert_string_to_bytes(u8 *addr, const char *text, u16 max_bytes)
+{
+	u16 i = 0;
+	int nibble;
+	const char *temp = text;
+
+	while (temp && *temp != '\0' && i < max_bytes) {
+		nibble = chartohex(*temp++);
+		if (nibble == -1)
+			return -1;
+		addr[i] = nibble << 4;
+		nibble = chartohex(*temp++);
+		if (nibble == -1)
+			return -1;
+		addr[i++] += nibble;
+		if (*temp == ':')
+			temp++;
+	}
+
+	return i;
+}
+
+/*
+ * Client can send the cell switch mode in below format
+ *
+ * SETCELLSWITCHMODE <cs mode>
+ *
+ * examples:
+ * For Default Mode   - "SETCELLSWITCHMODE 0"
+ * To Disable Roaming - "SETCELLSWITCHMODE 1"
+ * For Partial Scan   - "SETCELLSWITCHMODE 2"
+ */
+static int parse_and_populate_setcellswitchmode(struct nl_msg *nlmsg,
+						    char *cmd)
+{
+	uint32_t all_trigger_bitmap, scan_scheme_bitmap;
+	uint32_t cellswm;
+	struct nlattr *config;
+
+	cellswm = atoi(cmd);
+	if (cellswm < 0 || cellswm > 2) {
+		wpa_printf(MSG_ERROR,"Invalid cell switch mode: %d", cellswm);
+		return -1;
+	}
+	wpa_printf(MSG_DEBUG, "cell switch mode: %d", cellswm);
+
+	all_trigger_bitmap = QCA_ROAM_TRIGGER_REASON_PER |
+			     QCA_ROAM_TRIGGER_REASON_BEACON_MISS |
+			     QCA_ROAM_TRIGGER_REASON_POOR_RSSI |
+			     QCA_ROAM_TRIGGER_REASON_BETTER_RSSI |
+			     QCA_ROAM_TRIGGER_REASON_PERIODIC |
+			     QCA_ROAM_TRIGGER_REASON_DENSE |
+			     QCA_ROAM_TRIGGER_REASON_BTM |
+			     QCA_ROAM_TRIGGER_REASON_BSS_LOAD |
+			     QCA_ROAM_TRIGGER_REASON_USER_TRIGGER |
+			     QCA_ROAM_TRIGGER_REASON_DEAUTH |
+			     QCA_ROAM_TRIGGER_REASON_IDLE |
+			     QCA_ROAM_TRIGGER_REASON_TX_FAILURES |
+			     QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN;
+
+	scan_scheme_bitmap = QCA_ROAM_TRIGGER_REASON_PER |
+			     QCA_ROAM_TRIGGER_REASON_BEACON_MISS |
+			     QCA_ROAM_TRIGGER_REASON_POOR_RSSI |
+			     QCA_ROAM_TRIGGER_REASON_BSS_LOAD |
+			     QCA_ROAM_TRIGGER_REASON_BTM;
+
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
+		QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET) ||
+	    nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID, 1)) {
+		wpa_printf(MSG_ERROR,"Failed to put: roam_subcmd/REQ_ID");
+	}
+
+	config = nla_nest_start(nlmsg,
+			QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL);
+	if (config == NULL)
+		goto fail;
+
+	switch (cellswm){
+	case 0:
+		if (nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_TRIGGERS, all_trigger_bitmap)) {
+			wpa_printf(MSG_ERROR,"Failed to set: ROAM_CONTROL_TRIGGERS");
+			goto fail;
+		}
+		break;
+	case 1:
+		if (nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_TRIGGERS, 0)) {
+			wpa_printf(MSG_ERROR,"Failed to unset: ROAM_CONTROL_TRIGGERS");
+			goto fail;
+		}
+		break;
+	case 2:
+		if (nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_TRIGGERS, all_trigger_bitmap) ||
+		    nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS, scan_scheme_bitmap)) {
+			wpa_printf(MSG_ERROR,"Failed to set: ROAM_CONTROL_TRIGGERS_SCAN_SCHEME");
+			goto fail;
+		}
+		break;
+	}
+	nla_nest_end(nlmsg, config);
+
+	return 0;
+fail:
+	return -1;
+
+}
+
+static int populate_nlmsg(struct nl_msg *nlmsg, char *cmd,
+			  enum get_info_cmd type)
+{
+	struct nlattr *attr;
+
+	attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (attr == NULL)
+		return -1;
+
+	switch (type) {
+	case GETSTATSBSSINFO:
+		if (nla_put_flag(nlmsg,
+				 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO)) {
+			wpa_printf(MSG_ERROR,"Failed to put flag QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO");
+			return -1;
+		}
+		break;
+	case SETCELLSWITCHMODE:
+		if (parse_and_populate_setcellswitchmode(nlmsg, cmd) != 0) {
+			wpa_printf(MSG_ERROR, "Failed to populate nlmsg");
+			return -1;
+		}
+		break;
+	default:
+		wpa_printf(MSG_ERROR,"Unsupported command: %d", type);
+		break;
+	}
+
+	nla_nest_end(nlmsg, attr);
+	return 0;
+}
+
+static char *skip_white_space(char *cmd)
+{
+	char *pos = cmd;
+
+	while (*pos == ' ')
+		pos++;
+
+	return pos;
+}
+
+void ap_sta_copy_supp_op_classes(const u8 *supp_op_classes,
+				 size_t supp_op_classes_len) {
+	if (!supp_op_classes)
+		return;
+	os_free(g_sta_info.supp_op_classes);
+	g_sta_info.supp_op_classes = malloc(1 + supp_op_classes_len);
+	if(!g_sta_info.supp_op_classes)
+		return;
+	g_sta_info.supp_op_classes[0] = supp_op_classes_len;
+	os_memcpy(g_sta_info.supp_op_classes + 1, supp_op_classes,
+		  supp_op_classes_len);
+}
+
+void ap_sta_copy_channels(const u8 *supp_channels,
+				 size_t supp_channels_len) {
+	if (!supp_channels)
+		return;
+	os_free(g_sta_info.supp_channels);
+	g_sta_info.supp_channels = malloc(1 + supp_channels_len);
+	if(!g_sta_info.supp_channels)
+		return;
+	g_sta_info.supp_channels[0] = supp_channels_len;
+	os_memcpy(g_sta_info.supp_channels + 1, supp_channels,
+		  supp_channels_len);
+}
+
+static void parse_ext_ie(const u8 *ie, int ie_len)
+{
+	u8 ext_id;
+
+	if (ie_len < 1) {
+		wpa_printf(MSG_ERROR,"parse error, ie_len = %d", ie_len);
+		return;
+	}
+
+	ext_id = *ie++;
+	ie_len--;
+
+	switch (ext_id) {
+	case WLAN_EID_EXT_HE_CAPABILITIES:
+		wpa_printf(MSG_INFO,"HE supported");
+		g_sta_info.flags.he_supported = 1;
+		break;
+	default:
+		wpa_printf(MSG_DEBUG,"ext_id = %d", ext_id);
+		break;
+	}
+
+	return;
+}
+
+static void parse_assoc_req_ies(const u8 *ies, int ies_len)
+{
+	int left = ies_len;
+	const u8 *pos = ies;
+
+	while (left >= 2) {
+		u8 id, ie_len;
+		id = *pos++;
+		ie_len = *pos++;
+		left -= 2;
+
+		if (ie_len > left) {
+			wpa_printf(MSG_ERROR,"parse error, id = %d, ie_len = %d, left = %d",
+			      id, ie_len, left);
+			return;
+		}
+
+		switch (id) {
+		case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
+			ap_sta_copy_supp_op_classes(pos, ie_len);
+			break;
+		case WLAN_EID_SUPPORTED_CHANNELS:
+			ap_sta_copy_channels(pos, ie_len);
+			break;
+		case WLAN_EID_HT_CAP:
+			wpa_printf(MSG_INFO,"HT supported");
+			g_sta_info.flags.ht_supported = 1;
+			break;
+		case WLAN_EID_VHT_CAP:
+			wpa_printf(MSG_INFO,"VHT supported");
+			g_sta_info.flags.vht_supported = 1;
+			break;
+		case WLAN_EID_EXTENSION:
+			parse_ext_ie(pos, ie_len);
+			break;
+		default:
+			break;
+		}
+
+		left -= ie_len;
+		pos += ie_len;
+	}
+
+	if (left)
+		wpa_printf(MSG_ERROR,"parse error, left = %d", left);
+}
+
+void op_class_band_conversion(u8 *op_classes) {
+	int count = (g_sta_info.supp_op_classes[0]);
+	int i = 1;
+	int temp;
+
+	if (count <= 1)
+		g_sta_info.supported_band = 0;
+	while((count-1) != 0) {
+		temp = g_sta_info.supp_op_classes[i];
+		if (temp >= 81 && temp <= 84)
+			g_sta_info.supported_band |= BIT(0);
+		else if (temp >= 115 && temp <= 130)
+			g_sta_info.supported_band |= BIT(1);
+		else if (temp >= 131 && temp <= 135)
+			g_sta_info.supported_band |= BIT(2);
+		i++;
+		count--;
+	}
+}
+
+void supp_channels_band_conversion(u8 *supp_channels) {
+	int count = 0;
+	int i = 1;
+	int temp = 0;
+
+	count = (g_sta_info.supp_channels[0]);
+	if (count < 2)
+		g_sta_info.supported_band = 0;
+
+	while((count-1) >= 0) {
+		temp = g_sta_info.supp_channels[i];
+		if (temp >= 1 && temp <= 13)
+			g_sta_info.supported_band |= BIT(0);
+		else if (temp >= 32 && temp <= 173)
+			g_sta_info.supported_band |= BIT(1);
+		i += 2;
+		count -= 2;
+	}
+}
+
+static int fill_sta_info(struct remote_sta_info *sta_info,
+			   char *buf, size_t buf_len)
+{
+	int ret;
+	if (sta_info->num_sta == 1) {
+		if (sta_info->show_band)
+			ret = snprintf(buf, buf_len,
+				 "%02x:%02x:%02x:%02x:%02x:%02x %d %d %04x %02x:%02x:%02x %d %d %d %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d %d %d",
+				 sta_info->mac_addr[0], sta_info->mac_addr[1],
+				 sta_info->mac_addr[2], sta_info->mac_addr[3],
+				 sta_info->mac_addr[4], sta_info->mac_addr[5],
+				 sta_info->rx_retry_pkts, sta_info->rx_bcmc_pkts,
+				 sta_info->cap, sta_info->mac_addr[0],
+				 sta_info->mac_addr[1], sta_info->mac_addr[2],
+				 sta_info->freq,
+				 sta_info->bandwidth,
+				 sta_info->rssi,
+				 sta_info->data_rate,
+				 sta_info->dot11_mode,
+				 -1,
+				 -1,
+				 sta_info->reason,
+				 sta_info->supported_mode,
+				 sta_info->country,
+				 sta_info->ani_level,
+				 -1,
+				 -1,
+				 -1,
+				 sta_info->roam_trigger_reason,
+				 sta_info->roam_fail_reason,
+				 sta_info->roam_invoke_fail_reason,
+				 sta_info->tsf_out_of_sync_count,
+				 sta_info->latest_tx_power,
+				 sta_info->latest_tx_rate,
+				 sta_info->target_power_24g_1mbps,
+				 sta_info->target_power_24g_6mbps,
+				 sta_info->target_power_5g_6mbps);
+		else
+			ret = snprintf(buf, buf_len,
+				 "%02x:%02x:%02x:%02x:%02x:%02x %d %d %04x %02x:%02x:%02x %d %d %d %d %d %d %d %d %u %s %d %d %d %d %d %d %d %d %d %d %d %d %d",
+				 sta_info->mac_addr[0], sta_info->mac_addr[1],
+				 sta_info->mac_addr[2], sta_info->mac_addr[3],
+				 sta_info->mac_addr[4], sta_info->mac_addr[5],
+				 sta_info->rx_retry_pkts, sta_info->rx_bcmc_pkts,
+				 sta_info->cap, sta_info->mac_addr[0],
+				 sta_info->mac_addr[1], sta_info->mac_addr[2],
+				 sta_info->freq,
+				 sta_info->bandwidth,
+				 sta_info->rssi,
+				 sta_info->data_rate,
+				 sta_info->supported_mode,
+				 -1,
+				 -1,
+				 sta_info->reason,
+				 sta_info->supported_band,
+				 sta_info->country,
+				 sta_info->ani_level,
+				 -1,
+				 -1,
+				 -1,
+				 sta_info->roam_trigger_reason,
+				 sta_info->roam_fail_reason,
+				 sta_info->roam_invoke_fail_reason,
+				 sta_info->tsf_out_of_sync_count,
+				 sta_info->latest_tx_power,
+				 sta_info->latest_tx_rate,
+				 sta_info->target_power_24g_1mbps,
+				 sta_info->target_power_24g_6mbps,
+				 sta_info->target_power_5g_6mbps);
+	} else {
+		ret = snprintf(buf, buf_len,
+			 "%d %d %04x %d %d %d %d %d %d %d %d %d %s",
+			 sta_info->rx_retry_pkts, sta_info->rx_bcmc_pkts,
+			 -1, /* CAP */
+			 -1, /* Channel */
+			 -1, /* Bandwidth */
+			 -1, /* Rssi */
+			 -1, /* Data_rate */
+			 -1, /* 11_mode */
+			 -1,
+			 -1,
+			 -1, /* Reason */
+			 -1, /* Support_mode */
+			 sta_info->country);
+	}
+	return ret;
+}
+
+static int get_sta_info_legacy_handler(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *msg_hdr;
+	struct nlattr *tb[NL80211_ATTR_MAX_INTERNAL + 1];
+	struct nlattr *tb_vendor[NL80211_ATTR_MAX_INTERNAL + 1];
+	struct nlattr *vendor_data, *attr_link_info;
+	int vendor_len;
+	struct resp_info *info = (struct resp_info *)arg;
+	u8 *assoc_req_ie = NULL;
+	size_t assoc_req_ie_len = 0;
+
+	if (!info) {
+		wpa_printf(MSG_ERROR,"Invalid arg");
+		return -1;
+	}
+
+	wpa_printf(MSG_INFO,"Recv STA info %02x:%02x:%02x:%02x:%02x:%02x",
+	      info->mac_addr[0], info->mac_addr[1], info->mac_addr[2],
+	      info->mac_addr[3], info->mac_addr[4], info->mac_addr[5]);
+
+	msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
+	nla_parse(tb, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(msg_hdr, 0),
+		  genlmsg_attrlen(msg_hdr, 0), NULL);
+
+	if (!tb[NL80211_ATTR_VENDOR_DATA]) {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA parse error");
+		return -1;
+	}
+
+	vendor_data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
+	vendor_len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
+
+	if (nla_parse(tb_vendor, NL80211_ATTR_MAX_INTERNAL,
+		      vendor_data, vendor_len, NULL)) {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found");
+		return -1;
+	}
+
+	attr_link_info = tb_vendor[QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR];
+	if (attr_link_info) {
+		struct nlattr *tb_link_info[NL80211_ATTR_MAX + 1];
+		struct nlattr *attr_survey_info, *attr_sta_info;
+
+		nla_parse(tb_link_info, NL80211_ATTR_MAX, nla_data(attr_link_info),
+			  nla_len(attr_link_info), NULL);
+		attr_survey_info = tb_link_info[NL80211_ATTR_SURVEY_INFO];
+		if (attr_survey_info) {
+			struct nlattr *tb_survey_info[NL80211_SURVEY_INFO_MAX + 1];
+
+			nla_parse(tb_survey_info, NL80211_SURVEY_INFO_MAX,
+				  nla_data(attr_survey_info),
+				  nla_len(attr_survey_info), NULL);
+			if (tb_survey_info[NL80211_SURVEY_INFO_FREQUENCY]) {
+				g_sta_info.freq =
+					nla_get_u32(tb_survey_info[NL80211_SURVEY_INFO_FREQUENCY]);
+				wpa_printf(MSG_INFO,"channel %d", g_sta_info.freq);
+			}
+		}
+
+		attr_sta_info = tb_link_info[NL80211_ATTR_STA_INFO];
+		if (attr_sta_info) {
+			struct nlattr *tb_sta_info[NL80211_STA_INFO_MAX + 1];
+
+			nla_parse(tb_sta_info, NL80211_STA_INFO_MAX,
+				  nla_data(attr_sta_info),
+				  nla_len(attr_sta_info), NULL);
+			if (tb_sta_info[NL80211_STA_INFO_SIGNAL]) {
+				g_sta_info.rssi = nla_get_u8(tb_sta_info[NL80211_STA_INFO_SIGNAL]);
+				g_sta_info.rssi -= NOISE_FLOOR_DBM;
+				wpa_printf(MSG_INFO,"rssi %d", g_sta_info.rssi);
+			}
+			if (tb_sta_info[NL80211_STA_INFO_TX_BITRATE]) {
+				struct nlattr *tb_antenna_info[NL80211_RATE_INFO_MAX + 1];
+				nla_parse(tb_antenna_info, NL80211_RATE_INFO_MAX,
+					  nla_data(tb_sta_info[NL80211_STA_INFO_TX_BITRATE]),
+					  nla_len(tb_sta_info[NL80211_STA_INFO_TX_BITRATE]),
+					  NULL);
+			}
+		}
+
+		if (tb_link_info[NL80211_ATTR_REASON_CODE]) {
+			g_sta_info.reason =
+				nla_get_u32(tb_link_info[NL80211_ATTR_REASON_CODE]);
+			wpa_printf(MSG_INFO,"reason %d", g_sta_info.reason);
+		}
+
+		if (tb_link_info[NL80211_ATTR_STA_CAPABILITY]) {
+			g_sta_info.cap =
+				nla_get_u16(tb_link_info[NL80211_ATTR_STA_CAPABILITY]);
+			wpa_printf(MSG_INFO,"cap %04x", g_sta_info.cap);
+		}
+	}
+
+	if (tb_vendor[GET_STATION_INFO_REMOTE_LAST_RX_RATE]) {
+		g_sta_info.data_rate =
+			nla_get_u32(tb_vendor[GET_STATION_INFO_REMOTE_LAST_RX_RATE]);
+		wpa_printf(MSG_INFO,"data_rate %d", g_sta_info.data_rate);
+	}
+
+	if (tb_vendor[GET_STATION_INFO_REMOTE_RX_RETRY_COUNT]) {
+		g_sta_info.rx_retry_pkts +=
+			nla_get_u32(tb_vendor[GET_STATION_INFO_REMOTE_RX_RETRY_COUNT]);
+		wpa_printf(MSG_INFO,"rx_retry_pkts %d", g_sta_info.rx_retry_pkts);
+	}
+
+	if (tb_vendor[GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT]) {
+		g_sta_info.rx_bcmc_pkts +=
+			nla_get_u32(tb_vendor[GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT]);
+		wpa_printf(MSG_INFO,"rx_bcmc_pkts %d", g_sta_info.rx_bcmc_pkts);
+	}
+
+	if (tb_vendor[GET_STATION_INFO_REMOTE_CH_WIDTH]) {
+		g_sta_info.bandwidth =
+			nla_get_u8(tb_vendor[GET_STATION_INFO_REMOTE_CH_WIDTH]);
+		wpa_printf(MSG_INFO,"bandwidth %d", g_sta_info.bandwidth);
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE]) {
+		g_sta_info.dot11_mode =
+			nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE]);
+		wpa_printf(MSG_INFO,"dot11_mode %d", g_sta_info.dot11_mode);
+	}
+
+	if (tb_vendor[GET_STATION_INFO_REMOTE_SUPPORTED_MODE]) {
+		g_sta_info.supported_mode =
+			nla_get_u8(tb_vendor[GET_STATION_INFO_REMOTE_SUPPORTED_MODE]);
+		wpa_printf(MSG_INFO,"supported_mode %d", g_sta_info.supported_mode);
+	}
+
+	if (tb_vendor[GET_STATION_INFO_ASSOC_REQ_IES]) {
+		assoc_req_ie =
+			nla_data(tb_vendor[GET_STATION_INFO_ASSOC_REQ_IES]);
+		assoc_req_ie_len =
+			nla_len(tb_vendor[GET_STATION_INFO_ASSOC_REQ_IES]);
+	}
+
+	parse_assoc_req_ies(assoc_req_ie, assoc_req_ie_len);
+
+	if (g_sta_info.supp_op_classes) {
+		op_class_band_conversion(g_sta_info.supp_op_classes);
+		g_sta_info.show_band = true;
+	}
+	else if (g_sta_info.supp_channels) {
+		supp_channels_band_conversion(g_sta_info.supp_channels);
+		g_sta_info.show_band = true;
+	}
+	else
+		wpa_printf(MSG_ERROR,"supp_op_classes and supp_channels both are null");
+
+	g_sta_info.num_received_vendor_sta_info++;
+
+	wpa_printf(MSG_INFO,"num_received_vendor_sta_info %d",
+	      g_sta_info.num_received_vendor_sta_info);
+
+	return 0;
+}
+
+static int
+wpa_driver_send_get_sta_info_legacy_cmd(struct i802_bss *bss, u8 *mac,
+					int *status)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *nlmsg;
+	struct nlattr *attr;
+	struct resp_info info;
+
+	memset(&info, 0, sizeof(info));
+	os_memcpy(&info.mac_addr[0], mac, MAC_ADDR_LEN);
+	os_memcpy(&g_sta_info.mac_addr[0], mac, MAC_ADDR_LEN);
+
+	nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+				     QCA_NL80211_VENDOR_SUBCMD_GET_STATION);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR,"Failed to allocate nl message");
+		return -1;
+	}
+
+	attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (!attr) {
+		nlmsg_free(nlmsg);
+		return -1;
+	}
+
+	if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE,
+		    MAC_ADDR_LEN, mac)) {
+		wpa_printf(MSG_ERROR,"Failed to put QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE");
+		nlmsg_free(nlmsg);
+		return -1;
+	}
+
+	nla_nest_end(nlmsg, attr);
+
+	*status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+			     get_sta_info_legacy_handler, &info);
+	if (*status != 0) {
+		wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", *status);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int get_sta_info_handler(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *msg_hdr;
+	struct nlattr *tb[NL80211_ATTR_MAX_INTERNAL + 1];
+	struct nlattr *tb_vendor[GET_STA_INFO_MAX + 1];
+	struct nlattr *vendor_data;
+	int vendor_len;
+	struct resp_info *info = (struct resp_info *)arg;
+	uint8_t mac_addr[MAC_ADDR_LEN];
+
+	if (!info) {
+		wpa_printf(MSG_ERROR,"Invalid arg");
+		return -1;
+	}
+
+	msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
+	nla_parse(tb, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(msg_hdr, 0),
+		  genlmsg_attrlen(msg_hdr, 0), NULL);
+
+	if (!tb[NL80211_ATTR_VENDOR_DATA]) {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found");
+		return -1;
+	}
+
+	vendor_data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
+	vendor_len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
+
+	if (nla_parse(tb_vendor, GET_STA_INFO_MAX,
+		      vendor_data, vendor_len, NULL)) {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA parse error");
+		return -1;
+	}
+
+	if (tb_vendor[GET_STA_INFO_MAC]) {
+		nla_memcpy(mac_addr,
+			tb_vendor[GET_STA_INFO_MAC],MAC_ADDR_LEN);
+		if (os_memcmp(mac_addr, info->mac_addr, MAC_ADDR_LEN)) {
+			wpa_printf(MSG_ERROR,"MAC address mismatch");
+			return -1;
+		}
+	}
+
+	wpa_printf(MSG_INFO,"Recv STA info %02x:%02x:%02x:%02x:%02x:%02x",
+	      info->mac_addr[0], info->mac_addr[1], info->mac_addr[2],
+	      info->mac_addr[3], info->mac_addr[4], info->mac_addr[5]);
+
+	if (tb_vendor[GET_STA_INFO_RX_RETRY_COUNT]) {
+		g_sta_info.rx_retry_pkts +=
+			nla_get_u32(tb_vendor[GET_STA_INFO_RX_RETRY_COUNT]);
+		wpa_printf(MSG_INFO,"rx_retry_pkts %d", g_sta_info.rx_retry_pkts);
+	}
+
+	if (tb_vendor[GET_STA_INFO_RX_BC_MC_COUNT]) {
+		g_sta_info.rx_bcmc_pkts +=
+			nla_get_u32(tb_vendor[GET_STA_INFO_RX_BC_MC_COUNT]);
+		wpa_printf(MSG_INFO,"rx_bcmc_pkts %d", g_sta_info.rx_bcmc_pkts);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TX_RETRY_SUCCEED]) {
+		g_sta_info.tx_pkts_retried +=
+			nla_get_u32(tb_vendor[GET_STA_INFO_TX_RETRY_SUCCEED]);
+		wpa_printf(MSG_INFO,"tx_pkts_retried %d", g_sta_info.tx_pkts_retried);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TX_RETRY_EXHAUSTED]) {
+		g_sta_info.tx_pkts_retry_exhausted +=
+			nla_get_u32(tb_vendor[GET_STA_INFO_TX_RETRY_EXHAUSTED]);
+		wpa_printf(MSG_INFO,"tx_pkts_retry_exhausted %d", g_sta_info.tx_pkts_retry_exhausted);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TARGET_TX_TOTAL]) {
+		g_sta_info.tx_pkts_fw_total +=
+			nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_TX_TOTAL]);
+		wpa_printf(MSG_INFO,"tx_pkts_fw_total %d", g_sta_info.tx_pkts_fw_total);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TARGET_TX_RETRY]) {
+		g_sta_info.tx_pkts_fw_retries +=
+			nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_TX_RETRY]);
+		wpa_printf(MSG_INFO,"tx_pkts_fw_retries %d", g_sta_info.tx_pkts_fw_retries);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED]) {
+		g_sta_info.tx_pkts_fw_retry_exhausted +=
+			nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED]);
+		wpa_printf(MSG_INFO,"tx_pkts_fw_retry_exhausted %d", g_sta_info.tx_pkts_fw_retry_exhausted);
+	}
+
+	if (tb_vendor[GET_STA_INFO_ANI_LEVEL]) {
+		g_sta_info.ani_level =
+			nla_get_u32(tb_vendor[GET_STA_INFO_ANI_LEVEL]);
+		wpa_printf(MSG_INFO,"ani_level %d", g_sta_info.ani_level);
+	}
+
+	if (tb_vendor[GET_STA_INFO_ROAM_TRIGGER_REASON]) {
+		g_sta_info.roam_trigger_reason =
+			nla_get_u32(tb_vendor[GET_STA_INFO_ROAM_TRIGGER_REASON]);
+		wpa_printf(MSG_INFO,"roam_trigger_reason %d", g_sta_info.roam_trigger_reason);
+	}
+
+	if (tb_vendor[GET_STA_INFO_ROAM_FAIL_REASON]) {
+		g_sta_info.roam_fail_reason =
+			nla_get_u32(tb_vendor[GET_STA_INFO_ROAM_FAIL_REASON]);
+		wpa_printf(MSG_INFO,"roam_fail_reason %d", g_sta_info.roam_fail_reason);
+	}
+
+	if (tb_vendor[GET_STA_INFO_ROAM_INVOKE_FAIL_REASON]) {
+		g_sta_info.roam_invoke_fail_reason =
+			nla_get_u32(tb_vendor[GET_STA_INFO_ROAM_INVOKE_FAIL_REASON]);
+		wpa_printf(MSG_INFO,"roam_invoke_fail_reason %d", g_sta_info.roam_invoke_fail_reason);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT]) {
+		g_sta_info.tsf_out_of_sync_count =
+			nla_get_u32(tb_vendor[GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT]);
+		wpa_printf(MSG_INFO,"tsf_out_of_sync_count %d", g_sta_info.tsf_out_of_sync_count);
+	}
+
+	if (tb_vendor[GET_STA_INFO_LATEST_TX_POWER]) {
+		g_sta_info.latest_tx_power =
+			nla_get_u32(tb_vendor[GET_STA_INFO_LATEST_TX_POWER]);
+		wpa_printf(MSG_INFO,"latest_tx_power %d", g_sta_info.latest_tx_power);
+	}
+
+	if (tb_vendor[GET_STA_INFO_LATEST_TX_RATE]) {
+		g_sta_info.latest_tx_rate =
+			nla_get_u32(tb_vendor[GET_STA_INFO_LATEST_TX_RATE]);
+		wpa_printf(MSG_INFO,"latest_tx_rate %d", g_sta_info.latest_tx_rate);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TARGET_POWER_24G_1MBPS]) {
+		g_sta_info.target_power_24g_1mbps =
+			nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_POWER_24G_1MBPS]);
+		wpa_printf(MSG_INFO,"target_power_24g_1mbps %d", g_sta_info.target_power_24g_1mbps);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TARGET_POWER_24G_6MBPS]) {
+		g_sta_info.target_power_24g_6mbps =
+			nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_POWER_24G_6MBPS]);
+		wpa_printf(MSG_INFO,"target_power_24g_6mbps %d", g_sta_info.target_power_24g_6mbps);
+	}
+
+	if (tb_vendor[GET_STA_INFO_TARGET_POWER_5G_6MBPS]) {
+		g_sta_info.target_power_5g_6mbps =
+			nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_POWER_5G_6MBPS]);
+		wpa_printf(MSG_INFO,"target_power_5g_6mbps %d", g_sta_info.target_power_5g_6mbps);
+	}
+
+	if (tb_vendor[GET_STA_INFO_LATEST_RIX]) {
+		g_sta_info.latest_rix =
+			nla_get_u32(tb_vendor[GET_STA_INFO_LATEST_RIX]);
+		wpa_printf(MSG_INFO,"latest_rix %d", g_sta_info.latest_rix);
+	}
+
+
+	g_sta_info.num_received_vendor_sta_info++;
+
+	wpa_printf(MSG_INFO,"num_received_vendor_sta_info %d",
+	      g_sta_info.num_received_vendor_sta_info);
+
+	return 0;
+}
+
+static int wpa_driver_ioctl(struct i802_bss *bss, char *cmd,
+				 char *buf, size_t buf_len, int *status,
+				 struct wpa_driver_nl80211_data *drv) {
+	struct ifreq ifr;
+	android_wifi_priv_cmd priv_cmd;
+	memset(&ifr, 0, sizeof(ifr));
+	memset(&priv_cmd, 0, sizeof(priv_cmd));
+	os_memcpy(buf, cmd, strlen(cmd) + 1);
+	os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
+	priv_cmd.buf = buf;
+	priv_cmd.used_len = buf_len;
+	priv_cmd.total_len = buf_len;
+	ifr.ifr_data = &priv_cmd;
+
+	if ((ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
+		wpa_printf(MSG_ERROR,"%s: failed to issue private commands\n", __func__);
+		*status = 1;
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	} else {
+		wpa_printf(MSG_ERROR,"Response: %s", buf);
+		return WPA_DRIVER_OEM_STATUS_SUCCESS;
+	}
+}
+
+static int wpa_driver_send_get_sta_info_cmd(struct i802_bss *bss, u8 *mac,
+					    int *status, bool *new_cmd)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *nlmsg;
+	struct nlattr *attr;
+	struct resp_info info;
+
+	memset(&info, 0, sizeof(info));
+	os_memcpy(&info.mac_addr[0], mac, MAC_ADDR_LEN);
+	os_memcpy(&g_sta_info.mac_addr[0], mac, MAC_ADDR_LEN);
+
+	*new_cmd = true;
+
+
+	nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+				     QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR,"Failed to allocate nl message");
+		return -1;
+	}
+
+	attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (!attr) {
+		nlmsg_free(nlmsg);
+		return -1;
+	}
+
+	if (nla_put(nlmsg, GET_STA_INFO_MAC,
+		    MAC_ADDR_LEN, mac)) {
+		wpa_printf(MSG_ERROR,"Failed to put GET_STA_INFO_MAC");
+		nlmsg_free(nlmsg);
+		return -1;
+	}
+
+	nla_nest_end(nlmsg, attr);
+
+	*status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+			     get_sta_info_handler, &info);
+	if (*status != 0) {
+		wpa_printf(MSG_ERROR,"Failed to send nl message with err %d, retrying with legacy command", *status);
+		*new_cmd = false;
+		return wpa_driver_send_get_sta_info_legacy_cmd(bss,mac,status);
+	}
+
+	g_sta_info.num_request_vendor_sta_info++;
+	wpa_printf(MSG_INFO,"num_request_vendor_sta_info %d",
+	      g_sta_info.num_request_vendor_sta_info);
+
+	return 0;
+}
+
+static int get_station_handler(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *msg_hdr;
+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
+	struct nlattr *tb_sinfo[NL80211_STA_INFO_MAX + 1];
+	struct nlattr *tb_rate[NL80211_RATE_INFO_MAX + 1];
+	struct nlattr *sinfo_data, *attr;
+	int sinfo_len, tmp, num_chain = 0;
+	struct resp_info *info = (struct resp_info *)arg;
+	uint8_t mac_addr[MAC_ADDR_LEN];
+
+	if (!info) {
+		wpa_printf(MSG_ERROR,"Invalid arg");
+		return -1;
+	}
+
+	msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(msg_hdr, 0),
+		  genlmsg_attrlen(msg_hdr, 0), NULL);
+
+	if (tb[NL80211_ATTR_MAC]) {
+		nla_memcpy(mac_addr, tb[NL80211_ATTR_MAC], MAC_ADDR_LEN);
+		if (os_memcmp(mac_addr, info->mac_addr, MAC_ADDR_LEN)) {
+			wpa_printf(MSG_ERROR,"MAC address mismatch");
+			return -1;
+		}
+	}
+
+	wpa_printf(MSG_INFO,"Recv STA info %02x:%02x:%02x:%02x:%02x:%02x",
+	      info->mac_addr[0], info->mac_addr[1], info->mac_addr[2],
+	      info->mac_addr[3], info->mac_addr[4], info->mac_addr[5]);
+
+	if (!tb[NL80211_ATTR_STA_INFO]) {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_STA_INFO not found");
+		return -1;
+	}
+
+	sinfo_data = nla_data(tb[NL80211_ATTR_STA_INFO]);
+	sinfo_len = nla_len(tb[NL80211_ATTR_STA_INFO]);
+
+	if (nla_parse(tb_sinfo, NL80211_STA_INFO_MAX, sinfo_data, sinfo_len,
+		      NULL)) {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_STA_INFO parse error");
+		return -1;
+	}
+
+	/* No need to read for summary */
+	if (g_sta_info.num_sta == 1) {
+		if (tb[NL80211_ATTR_IE])
+			parse_assoc_req_ies(nla_data(tb[NL80211_ATTR_IE]),
+					    nla_len(tb[NL80211_ATTR_IE]));
+
+		attr = tb_sinfo[NL80211_STA_INFO_TX_BITRATE];
+		if (attr) {
+			nla_parse(tb_rate, NL80211_RATE_INFO_MAX,
+				  nla_data(attr), nla_len(attr), NULL);
+
+			if (tb_rate[NL80211_RATE_INFO_BITRATE32]) {
+				g_sta_info.tx_rate =
+					nla_get_u32(tb_rate[NL80211_RATE_INFO_BITRATE32]);
+				wpa_printf(MSG_INFO,"tx_rate %d", g_sta_info.tx_rate);
+			}
+
+			if (tb_rate[NL80211_RATE_INFO_160_MHZ_WIDTH])
+				g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_160;
+			else if (tb_rate[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
+				g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_80_80;
+			else if (tb_rate[NL80211_RATE_INFO_80_MHZ_WIDTH])
+				g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_80;
+			else if (tb_rate[NL80211_RATE_INFO_40_MHZ_WIDTH])
+				g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_40;
+			else
+				g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_20;
+			wpa_printf(MSG_INFO,"bandwidth %d", g_sta_info.bandwidth);
+		}
+
+		attr = tb_sinfo[NL80211_STA_INFO_RX_BITRATE];
+		if (attr) {
+			nla_parse(tb_rate, NL80211_RATE_INFO_MAX,
+				  nla_data(attr), nla_len(attr), NULL);
+			if (tb_rate[NL80211_RATE_INFO_BITRATE32]) {
+				g_sta_info.data_rate =
+					nla_get_u32(tb_rate[NL80211_RATE_INFO_BITRATE32]);
+				wpa_printf(MSG_INFO,"data_rate %d", g_sta_info.data_rate);
+			}
+		}
+
+		if (tb_sinfo[NL80211_STA_INFO_SIGNAL_AVG]) {
+			g_sta_info.rssi =
+				nla_get_u8(tb_sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
+			g_sta_info.rssi -= NOISE_FLOOR_DBM;
+			wpa_printf(MSG_INFO,"rssi %d", g_sta_info.rssi);
+		}
+
+		if (tb_sinfo[NL80211_STA_INFO_SIGNAL]) {
+			g_sta_info.rx_lastpkt_rssi =
+				nla_get_u8(tb_sinfo[NL80211_STA_INFO_SIGNAL]);
+			g_sta_info.rx_lastpkt_rssi -= NOISE_FLOOR_DBM;
+			wpa_printf(MSG_INFO,"rx_lastpkt_rssi %d", g_sta_info.rx_lastpkt_rssi);
+		}
+
+		if (tb_sinfo[NL80211_STA_INFO_CHAIN_SIGNAL_AVG]) {
+			nla_for_each_nested(attr,
+					    tb_sinfo[NL80211_STA_INFO_CHAIN_SIGNAL_AVG],
+					    tmp) {
+				if (num_chain >= WMI_MAX_CHAINS) {
+					wpa_printf(MSG_ERROR,"WMI_MAX_CHAINS reached");
+					break;
+				}
+				g_sta_info.avg_rssi_per_chain[num_chain] = nla_get_u8(attr);
+				g_sta_info.avg_rssi_per_chain[num_chain] -= NOISE_FLOOR_DBM;
+				wpa_printf(MSG_INFO,"avg_rssi_per_chain[%d] %d", num_chain,
+				      g_sta_info.avg_rssi_per_chain[num_chain]);
+				num_chain++;
+			}
+		}
+	}
+
+	if (tb_sinfo[NL80211_STA_INFO_TX_PACKETS]) {
+		g_sta_info.tx_pkts_total +=
+			nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_PACKETS]);
+		g_sta_info.tx_pckts +=
+			nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_PACKETS]);
+		wpa_printf(MSG_INFO,"tx_pkts_total %d", g_sta_info.tx_pkts_total);
+		wpa_printf(MSG_INFO,"tx_pckts %d", g_sta_info.tx_pckts);
+	}
+
+	if (tb_sinfo[NL80211_STA_INFO_TX_FAILED]) {
+		g_sta_info.tx_failures +=
+			nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_FAILED]);
+		wpa_printf(MSG_INFO,"tx_failures %d", g_sta_info.tx_failures);
+	}
+
+	if (tb_sinfo[NL80211_STA_INFO_TX_RETRIES]) {
+		g_sta_info.tx_pkts_retries +=
+			nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_RETRIES]);
+		wpa_printf(MSG_INFO,"tx_pkts_retries %d", g_sta_info.tx_pkts_retries);
+	}
+
+
+	g_sta_info.num_received_nl80211_sta_info++;
+
+	wpa_printf(MSG_INFO,"num_received_nl80211_sta_info %d",
+	      g_sta_info.num_received_nl80211_sta_info);
+
+	return 0;
+}
+
+static int wpa_driver_send_get_station_cmd(struct i802_bss *bss, u8 *mac,
+					   int *status)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *nlmsg;
+	struct resp_info info;
+
+	memset(&info, 0, sizeof(info));
+	os_memcpy(&info.mac_addr[0], mac, MAC_ADDR_LEN);
+	os_memcpy(&g_sta_info.mac_addr[0], mac, MAC_ADDR_LEN);
+
+	nlmsg = prepare_nlmsg(drv, bss->ifname, NL80211_CMD_GET_STATION, 0, 0);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR,"Failed to allocate nl message");
+		return -1;
+	}
+
+	if (nla_put(nlmsg, NL80211_ATTR_MAC, MAC_ADDR_LEN, mac)) {
+		wpa_printf(MSG_ERROR,"Failed to put NL80211_ATTR_MAC");
+		nlmsg_free(nlmsg);
+		return -1;
+	}
+
+	*status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+			     get_station_handler, &info);
+	if (*status != 0) {
+		wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", *status);
+		return -1;
+	}
+
+	g_sta_info.num_request_nl80211_sta_info++;
+	wpa_printf(MSG_INFO,"num_request_nl80211_sta_info %d",
+	      g_sta_info.num_request_nl80211_sta_info);
+
+	return 0;
+}
+
+static int wpa_driver_get_sta_info(struct i802_bss *bss, u8 *mac,
+				   int *status)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct hostapd_data *hapd = bss->ctx;
+	struct sta_info *iter, *sta = NULL;
+	bool new_cmd;
+	int ret;
+	char buf[MAX_DRV_CMD_SIZE];
+	char *p;
+
+	memset(buf, 0, sizeof(buf));
+
+	ret = wpa_driver_send_get_sta_info_cmd(bss, mac, status, &new_cmd);
+	if (ret < 0)
+		return ret;
+
+	if (new_cmd) {
+		ret = wpa_driver_send_get_station_cmd(bss, mac, status);
+		if (ret < 0)
+			return ret;
+
+		/* No need to read for summary */
+		if (g_sta_info.num_sta == 1) {
+			if (!hapd) {
+				wpa_printf(MSG_ERROR,"hapd is NULL");
+				return -1;
+			}
+			iter = hapd->sta_list;
+			while (iter) {
+				if (os_memcmp(mac, iter->addr, MAC_ADDR_LEN) == 0) {
+					sta = iter;
+					break;
+				}
+				iter = iter->next;
+			}
+			if (!sta) {
+				wpa_printf(MSG_ERROR,"STA is not found");
+				return -1;
+			}
+
+			g_sta_info.cap = sta->capability;
+			wpa_printf(MSG_INFO,"cap %04x", g_sta_info.cap);
+			g_sta_info.freq = (u32)hapd->iface->freq;
+			wpa_printf(MSG_INFO,"freq %d", g_sta_info.freq);
+
+			if (g_sta_info.flags.he_supported) {
+				g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_AX;
+				g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_HE;
+			} else if (g_sta_info.flags.vht_supported) {
+				g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_AC;
+				g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_VHT;
+			} else if (g_sta_info.flags.ht_supported) {
+				g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_N;
+				g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_HT;
+			} else {
+				if (g_sta_info.freq < 4900) {
+					if (hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211B)
+						g_sta_info.dot11_mode =
+							QCA_VENDOR_WLAN_802_11_MODE_B;
+					else
+						g_sta_info.dot11_mode =
+							QCA_VENDOR_WLAN_802_11_MODE_G;
+				} else {
+					g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_A;
+				}
+				g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_LEGACY;
+			}
+
+			wpa_printf(MSG_INFO,"dot11_mode %d", g_sta_info.dot11_mode);
+			wpa_printf(MSG_INFO,"supported_mode %d", g_sta_info.supported_mode);
+		}
+	}
+
+	if(wpa_driver_ioctl(bss, "GETCOUNTRYREV", buf, sizeof(buf), &status, drv) == 0){
+		p = strstr(buf, " ");
+		if(p != NULL)
+			memcpy(g_sta_info.country, (p+1), strlen(p+1)+1);//length of p including null
+	}else{
+	}
+
+	wpa_printf(MSG_INFO,"STA information completed");
+
+	return 0;
+}
+
+static int wpa_driver_get_all_sta_info(struct i802_bss *bss, int *status)
+{
+	struct hostapd_data *hapd = bss->ctx;
+	struct sta_info *sta;
+	int ret, total_ret = 0;
+
+	if(bss->drv && bss->drv->nlmode != NL80211_IFTYPE_AP) {
+		wpa_printf(MSG_ERROR,"Not a hapd interface");
+		return -1;
+	}
+
+	if (!hapd) {
+		wpa_printf(MSG_ERROR,"hapd is NULL");
+		return -1;
+	}
+
+	g_sta_info.num_sta = hapd->num_sta;
+
+	sta = hapd->sta_list;
+	while (sta) {
+		ret = wpa_driver_get_sta_info(bss, sta->addr, status);
+		if (ret < 0)
+			return ret;
+		sta = sta->next;
+		total_ret += ret;
+	}
+
+	wpa_printf(MSG_INFO,"All STAs information completed");
+
+	return total_ret;
+}
+
+static int wpa_driver_handle_get_sta_info(struct i802_bss *bss, char *cmd,
+					  char *buf, size_t buf_len,
+					  int *status)
+{
+	u8 mac[MAC_ADDR_LEN];
+	int ret;
+
+	os_memset(&g_sta_info, 0, sizeof(g_sta_info));
+
+	cmd = skip_white_space(cmd);
+	if (strlen(cmd) >= MAC_ADDR_LEN * 2 + MAC_ADDR_LEN - 1
+	    && convert_string_to_bytes(mac, cmd, MAC_ADDR_LEN) > 0) {
+		g_sta_info.num_sta = 1;
+		ret = wpa_driver_get_sta_info(bss, mac, status);
+		if (ret < 0)
+			return ret;
+	} else {
+		ret = wpa_driver_get_all_sta_info(bss, status);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (ret == 0) {
+		ret = fill_sta_info(&g_sta_info, buf, buf_len);
+		wpa_printf(MSG_INFO,"%s", buf);
+	} else {
+		wpa_printf(MSG_ERROR,"Failed to get STA info, num_sta %d vendor_sent %d vendor_recv %d nl80211_send %d nl80211 recv %d",
+		      g_sta_info.num_sta,
+		      g_sta_info.num_request_vendor_sta_info,
+		      g_sta_info.num_received_vendor_sta_info,
+		      g_sta_info.num_request_nl80211_sta_info,
+		      g_sta_info.num_received_nl80211_sta_info);
+		wpa_printf(MSG_ERROR,"GETSTAINFO failed");
+	}
+
+	return ret;
+}
+
+static int thermal_info_handler(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	int *param = arg;
+	struct nlattr *nl_vendor;
+	struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+
+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+	    genlmsg_attrlen(gnlh, 0), NULL);
+
+	nl_vendor = tb[NL80211_ATTR_VENDOR_DATA];
+	if (!nl_vendor || nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
+	    nla_data(nl_vendor), nla_len(nl_vendor), NULL)) {
+		wpa_printf(MSG_ERROR, "%s: No vendor data found", __func__);
+		return NL_SKIP;
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA])
+		*param = (int) nla_get_u32(
+		    tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA]);
+	else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL])
+		*param = (int) nla_get_u32(
+		    tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]);
+	else
+		wpa_printf(MSG_ERROR, "%s: failed to parse data", __func__);
+
+	return NL_SKIP;
+}
+
+static int wpa_driver_cmd_get_thermal_info(struct i802_bss *bss, int *result, int attr)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg = NULL;
+	struct nlattr *params = NULL;
+	int ret = 0;
+
+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+			QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD) ||
+	    !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+	    nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE, attr)) {
+		nlmsg_free(msg);
+		return -1;
+	}
+
+	nla_nest_end(msg, params);
+	ret = send_and_recv_msgs(drv, msg, thermal_info_handler, result, NULL, NULL);
+	if (!ret)
+		return 0;
+	wpa_printf(MSG_ERROR, "%s: Failed get thermal info, ret=%d(%s)",
+				__func__, ret, strerror(-ret));
+	return ret;
+}
+
+static int get_scan_handler(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *msg_hdr;
+	struct nlattr *attr[NL80211_ATTR_MAX + 1];
+	struct resp_info *info = (struct resp_info *)arg;
+	struct nlattr *bss_attr[NL80211_BSS_MAX + 1];
+	char *bssid;
+	static struct nla_policy get_scan_policy[NL80211_BSS_MAX + 1] = {
+		[NL80211_BSS_BSSID] = {},
+		[NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
+		[NL80211_BSS_STATUS] = { .type = NLA_U32 },
+		[NL80211_BSS_CHAN_WIDTH] = { .type = NLA_U32 },
+	};
+
+	if (!info) {
+		wpa_printf(MSG_DEBUG, "resp_info is NULL");
+		return NL_SKIP;
+	}
+
+	msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
+	nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(msg_hdr, 0),
+		  genlmsg_attrlen(msg_hdr, 0), NULL);
+
+	if (!attr[NL80211_ATTR_BSS]) {
+		wpa_printf(MSG_DEBUG, "no bss info");
+		return NL_SKIP;
+	}
+
+	if (nla_parse_nested(bss_attr, NL80211_BSS_MAX,
+			     attr[NL80211_ATTR_BSS],
+			     get_scan_policy)) {
+		wpa_printf(MSG_DEBUG, "parse bss attr fail");
+		return NL_SKIP;
+	}
+
+	if (!bss_attr[NL80211_BSS_BSSID])
+		return NL_SKIP;
+
+	if (!bss_attr[NL80211_BSS_STATUS])
+		return NL_SKIP;
+
+	if (nla_get_u32(bss_attr[NL80211_BSS_STATUS]) !=
+	    NL80211_BSS_STATUS_ASSOCIATED)
+		return NL_SKIP;
+
+	bssid = nla_data(bss_attr[NL80211_BSS_BSSID]);
+	os_memcpy(g_csi_param.connected_bssid, bssid, MAC_ADDR_LEN);
+
+	wpa_printf(MSG_DEBUG, "get connected bss");
+	if (bss_attr[NL80211_BSS_FREQUENCY])
+		wpa_printf(MSG_DEBUG, "freq %d", nla_get_u32(bss_attr[NL80211_BSS_FREQUENCY]));
+
+	if (bss_attr[NL80211_BSS_CHAN_WIDTH])
+		wpa_printf(MSG_DEBUG, "BW %d", nla_get_u32(bss_attr[NL80211_BSS_CHAN_WIDTH]));
+
+	return 0;
+}
+
+static int wpa_driver_send_get_scan_cmd(struct i802_bss *bss, int *status)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *nlmsg;
+	struct resp_info info;
+
+	os_memset(g_csi_param.connected_bssid, 0xff, MAC_ADDR_LEN);
+	nlmsg = prepare_nlmsg(drv, bss->ifname, NL80211_CMD_GET_SCAN, 0, NLM_F_DUMP);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR, "Failed to allocate nl message");
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	*status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+			     get_scan_handler, &info);
+	if (*status != 0) {
+		wpa_printf(MSG_ERROR, "Failed to send nl message with err %d", *status);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	return WPA_DRIVER_OEM_STATUS_SUCCESS;
+}
+
+static int wpa_driver_start_csi_capture(struct i802_bss *bss, int *status,
+					int transport_mode)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *nlmsg;
+	struct nlattr *attr, *attr_table, *attr_entry;
+	char ta_mask[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+	nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+				     QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR, "Failed to allocate nl message");
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (!attr) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION,
+		       ENHANCED_CFR_VER)) {
+		wpa_printf(MSG_ERROR, "Failed to csi version");
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE,
+		       transport_mode)) {
+		wpa_printf(MSG_ERROR, "Failed to set transport mode");
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_flag(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE)) {
+		wpa_printf(MSG_ERROR, "Failed to csi enable flag");
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP,
+			CSI_GROUP_BITMAP)) {
+		wpa_printf(MSG_ERROR, "Failed to csi group bitmap");
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE,
+			QCA_WLAN_VENDOR_CFR_TA_RA)) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	attr_table = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE);
+	if (!attr_table) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	attr_entry = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY);
+	if (!attr_entry) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER,
+			CSI_DEFAULT_GROUP_ID)) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER,
+			CSI_MGMT_BEACON)) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA,
+		    MAC_ADDR_LEN, g_csi_param.connected_bssid)) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK,
+		    MAC_ADDR_LEN, ta_mask)) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+	nla_nest_end(nlmsg, attr_entry);
+	nla_nest_end(nlmsg, attr_table);
+	nla_nest_end(nlmsg, attr);
+
+	*status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL);
+	if (*status != 0) {
+		wpa_printf(MSG_ERROR, "Failed to send nl message with err %d", *status);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	g_csi_param.current_state = CSI_STATE_START;
+
+	return WPA_DRIVER_OEM_STATUS_SUCCESS;
+}
+
+static int wpa_driver_stop_csi_capture(struct i802_bss *bss, int *status)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *nlmsg;
+	struct nlattr *attr;
+
+	nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+				     QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR, "Failed to allocate nl message");
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (!attr) {
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION,
+			ENHANCED_CFR_VER)) {
+		wpa_printf(MSG_ERROR, "Failed to csi version");
+		nlmsg_free(nlmsg);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	wpa_printf(MSG_DEBUG, "send stop csi cmd");
+	nla_nest_end(nlmsg, attr);
+	*status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL);
+	if (*status != 0) {
+		wpa_printf(MSG_ERROR, "Failed to send nl message with err %d", *status);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	g_csi_param.current_state = CSI_STATE_STOP;
+
+	return WPA_DRIVER_OEM_STATUS_SUCCESS;
+}
+
+static void stop_csi_callback(int nsec)
+{
+	int status = 0;
+
+	wpa_printf(MSG_DEBUG, "enter %s, nsec %d", __func__, nsec);
+
+	wpa_driver_stop_csi_capture(g_csi_param.bss, &status);
+	if (status)
+		wpa_printf(MSG_ERROR, "Stop CSI failed");
+}
+
+static int wpa_driver_handle_csi_cmd(struct i802_bss *bss, char *cmd,
+				     char *buf, size_t buf_len,
+				     int *status)
+{
+	int csi_duration = -1;
+	int transport_mode = -1;
+	char *next_arg;
+
+	cmd = skip_white_space(cmd);
+	wpa_printf(MSG_DEBUG, "cmd:%s", cmd);
+	if (os_strncasecmp(cmd, "start", 5) == 0) {
+		next_arg = get_next_arg(cmd);
+		csi_duration = atoi(next_arg);
+
+		if (csi_duration < 0) {
+			wpa_printf(MSG_ERROR, "Invalid duration");
+			snprintf(buf, buf_len, "FAIL, Invalid duration");
+			*status = CSI_STATUS_REJECTED;
+			return WPA_DRIVER_OEM_STATUS_FAILURE;
+		}
+
+		wpa_driver_send_get_scan_cmd(bss, status);
+		if (g_csi_param.connected_bssid[0] == 0xff) {
+			wpa_printf(MSG_DEBUG, "Not connected");
+			snprintf(buf, buf_len, "FAIL, Not connected");
+			*status = CSI_STATUS_REJECTED;
+			return WPA_DRIVER_OEM_STATUS_FAILURE;
+		}
+
+		if (g_csi_param.current_state == CSI_STATE_START) {
+			wpa_driver_stop_csi_capture(bss, status);
+			alarm(0);
+		}
+
+		g_csi_param.bss = bss;
+		cmd += 6;
+		next_arg = get_next_arg(cmd);
+		if (*next_arg != '\0' && *next_arg == ' ')
+			transport_mode = atoi(next_arg);
+
+		if (transport_mode == 1 || transport_mode == -1)
+			transport_mode = 1;
+		g_csi_param.transport_mode = transport_mode;
+
+		wpa_driver_start_csi_capture(bss, status, transport_mode);
+		if (*status == 0 && csi_duration > 0) {
+			signal(SIGALRM, stop_csi_callback);
+			alarm(csi_duration);
+			wpa_printf(MSG_DEBUG, "set alarm %ds done", csi_duration);
+		}
+	} else if (os_strncasecmp(cmd, "stop", 4) == 0) {
+		if (g_csi_param.current_state != CSI_STATE_START)
+			return WPA_DRIVER_OEM_STATUS_SUCCESS;
+
+		wpa_driver_stop_csi_capture(bss, status);
+		wpa_printf(MSG_DEBUG, "stop csi cmd");
+	} else {
+		wpa_printf(MSG_ERROR, "invalid command");
+		*status = CSI_STATUS_REJECTED;
+		snprintf(buf, buf_len, "FAIL, Invalid command");
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	return WPA_DRIVER_OEM_STATUS_SUCCESS;
+}
+
+static int wpa_driver_restart_csi(struct i802_bss *bss, int *status)
+{
+	wpa_driver_send_get_scan_cmd(bss, status);
+	if (g_csi_param.connected_bssid[0] == 0xff) {
+		wpa_printf(MSG_DEBUG, "%s: Not connected", __func__);
+		*status = CSI_STATUS_REJECTED;
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+	/* Stop CSI capture on previous bss */
+	if(wpa_driver_stop_csi_capture(g_csi_param.bss, status)) {
+		wpa_printf(MSG_DEBUG, "%s: csi stop failed", __func__);
+	}
+	g_csi_param.bss = bss;
+	if(wpa_driver_start_csi_capture(g_csi_param.bss, status,
+				g_csi_param.transport_mode)) {
+		*status = CSI_STATUS_REJECTED;
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+	*status = CSI_STATUS_SUCCESS;
+	return WPA_DRIVER_OEM_STATUS_SUCCESS;
+}
+
+/**
+ * twt_status_to_string() - Mapping twt response status into string
+ * @status: enum qca_wlan_vendor_twt_status values
+ *
+ * This function will map the twt response status into corresponding
+ * string.
+ *
+ * Return: pointer to the string
+ */
+static const char *twt_status_to_string(enum qca_wlan_vendor_twt_status status)
+{
+	switch (status) {
+	case QCA_WLAN_VENDOR_TWT_STATUS_OK:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_OK";
+	case QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED";
+	case QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID";
+	case QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY";
+	case QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST";
+	case QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED";
+	case QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM";
+	case QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY";
+	case QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE";
+	case QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK";
+	case QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE";
+	case QCA_WLAN_VENDOR_TWT_STATUS_DENIED:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_DENIED";
+	case QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR";
+	case QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED";
+	case QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID:
+	       return "QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID";
+	case QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE";
+	case QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE";
+	case QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE:
+		return "QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE";
+	default:
+		return "INVALID TWT STATUS";
+	}
+}
+
+/**
+ * check_for_twt_cmd() - Check if the command string is a TWT command
+ * @cmd: Command string
+ *
+ * This function will identify a TWT operation in the command string
+ * and return one of the values in enum qca_wlan_twt_operation.
+ *
+ * Return: A valid TWT opertion if found, or error if not found
+ *
+ */
+static int check_for_twt_cmd(char **cmd)
+{
+	if (os_strncasecmp(*cmd, TWT_SETUP_STR, TWT_SETUP_STRLEN) == 0) {
+		*cmd += (TWT_SETUP_STRLEN + 1);
+		return QCA_WLAN_TWT_SET;
+	} else if (os_strncasecmp(*cmd, TWT_TERMINATE_STR,
+				  TWT_TERMINATE_STR_LEN) == 0) {
+		*cmd += (TWT_TERMINATE_STR_LEN + 1);
+		return QCA_WLAN_TWT_TERMINATE;
+	} else if (os_strncasecmp(*cmd, TWT_PAUSE_STR, TWT_PAUSE_STR_LEN) == 0) {
+		*cmd += (TWT_PAUSE_STR_LEN + 1);
+		return QCA_WLAN_TWT_SUSPEND;
+	} else if (os_strncasecmp(*cmd, TWT_RESUME_STR, TWT_RESUME_STR_LEN) == 0) {
+		*cmd += (TWT_RESUME_STR_LEN + 1);
+		return QCA_WLAN_TWT_RESUME;
+	} else if (os_strncasecmp(*cmd, TWT_GET_PARAMS_STR,
+				  TWT_GET_PARAMS_STR_LEN) == 0) {
+		*cmd += (TWT_GET_PARAMS_STR_LEN + 1);
+		return QCA_WLAN_TWT_GET;
+	} else if (os_strncasecmp(*cmd, TWT_NUDGE_STR,
+				  TWT_NUDGE_STR_LEN) == 0) {
+		*cmd += (TWT_NUDGE_STR_LEN + 1);
+		return QCA_WLAN_TWT_NUDGE;
+	} else if (os_strncasecmp(*cmd, TWT_GET_STATS_STR,
+				  TWT_GET_STATS_STR_LEN) == 0) {
+		*cmd += (TWT_GET_STATS_STR_LEN + 1);
+		return QCA_WLAN_TWT_GET_STATS;
+	} else if (os_strncasecmp(*cmd, TWT_CLEAR_STATS_STR,
+				  TWT_CLEAR_STATS_STR_LEN) == 0) {
+		*cmd += (TWT_CLEAR_STATS_STR_LEN + 1);
+		return QCA_WLAN_TWT_CLEAR_STATS;
+	} else if (os_strncasecmp(*cmd, TWT_GET_CAP_STR,
+				  TWT_GET_CAP_STR_LEN) == 0) {
+		*cmd += (TWT_GET_CAP_STR_LEN + 1);
+		return QCA_WLAN_TWT_GET_CAPABILITIES;
+	} else if (os_strncasecmp(*cmd, TWT_SET_PARAM_STR,
+				  TWT_SET_PARAM_STR_LEN) == 0) {
+		*cmd += (TWT_SET_PARAM_STR_LEN + 1);
+		return QCA_WLAN_TWT_SET_PARAM;
+	} else {
+		wpa_printf(MSG_DEBUG, "Not a TWT command");
+		return TWT_CMD_NOT_EXIST;
+	}
+}
+
+static u64 get_u64_from_string(char *cmd_string, int *ret)
+{
+	u64 val = 0;
+	char *cmd = cmd_string;
+
+	while (*cmd != ' ')
+		cmd++;
+
+	*ret = 0;
+	errno = 0;
+	val = strtoll(cmd_string, NULL, 10);
+	if (errno == ERANGE || (errno != 0 && val == 0)) {
+		wpa_printf(MSG_ERROR, "invalid value");
+		*ret = -EINVAL;
+        }
+	return val;
+}
+
+
+static u32 get_u32_from_string(char *cmd_string, int *ret)
+{
+	u32 val = 0;
+	char *cmd = cmd_string;
+
+	while (*cmd != ' ')
+		cmd++;
+
+	*ret = 0;
+	errno = 0;
+	val = strtol(cmd_string, NULL, 10);
+	if (errno == ERANGE || (errno != 0 && val == 0)) {
+		wpa_printf(MSG_ERROR, "invalid value");
+		*ret = -EINVAL;
+        }
+	return val;
+}
+
+static u8 get_u8_from_string(char *cmd_string, int *ret)
+{
+	char *cmd = cmd_string;
+	u8 val = 0;
+
+	while (*cmd != ' ')
+		cmd++;
+
+	*ret = 0;
+	errno = 0;
+	val = strtol(cmd_string, NULL, 10) & 0xFF;
+	if (errno == ERANGE || (errno != 0 && val == 0)) {
+		wpa_printf(MSG_ERROR, "invalid value");
+		*ret = -EINVAL;
+        }
+	return val;
+}
+
+char *move_to_next_str(char *cmd)
+{
+	if (*cmd == '\0')
+		return cmd;
+
+	while (*cmd != ' ') {
+		cmd++;
+		if (*cmd == '\0')
+			return cmd;
+	}
+
+	while (*cmd == ' ')
+		cmd++;
+
+	return cmd;
+}
+
+static int is_binary(u8 value) {
+	if(value == 0 || value == 1)
+		return 0;
+	return -1;
+}
+
+static
+void print_setup_cmd_values(struct twt_setup_parameters *twt_setup_params)
+{
+	wpa_printf(MSG_DEBUG, "TWT: setup dialog_id: %x",
+		   twt_setup_params->dialog_id);
+	wpa_printf(MSG_DEBUG, "TWT: setup req type: %d ",
+		   twt_setup_params->req_type);
+	wpa_printf(MSG_DEBUG, "TWT: setup trig type: %d ",
+		   twt_setup_params->trig_type);
+	wpa_printf(MSG_DEBUG, "TWT: setup flow type: 0x%x",
+		   twt_setup_params->flow_type);
+	wpa_printf(MSG_DEBUG, "TWT: setup wake exp: 0x%x",
+		   twt_setup_params->wake_intr_exp);
+	wpa_printf(MSG_DEBUG, "TWT: setup protection: 0x%x",
+		   twt_setup_params->protection);
+	wpa_printf(MSG_DEBUG, "TWT: setup wake time: 0x%x",
+		   twt_setup_params->wake_time);
+	wpa_printf(MSG_DEBUG, "TWT: setup wake dur: 0x%x",
+		   twt_setup_params->wake_dur);
+	wpa_printf(MSG_DEBUG, "TWT: setup wake intr mantissa: 0x%x",
+		   twt_setup_params->wake_intr_mantissa);
+	wpa_printf(MSG_DEBUG, "TWT: setup bcast: %d ",
+		   twt_setup_params->bcast);
+	wpa_printf(MSG_DEBUG, "TWT: min wake intvl: %d ",
+		   twt_setup_params->min_wake_intvl);
+	wpa_printf(MSG_DEBUG, "TWT: max wake intvl: %d ",
+		   twt_setup_params->max_wake_intvl);
+	wpa_printf(MSG_DEBUG, "TWT: min wake duration: %d ",
+		   twt_setup_params->min_wake_duration);
+	wpa_printf(MSG_DEBUG, "TWT: max wake duration: %d ",
+		   twt_setup_params->max_wake_duration);
+	wpa_printf(MSG_DEBUG, "TWT: wake tsf: 0x%lx ",
+		   twt_setup_params->wake_tsf);
+	wpa_printf(MSG_DEBUG, "TWT: announce timeout(in us): %u",
+		   twt_setup_params->announce_timeout_us);
+}
+
+static int check_cmd_input(char *cmd_string)
+{
+	u32 cmd_string_len;
+
+	if (!cmd_string) {
+		wpa_printf(MSG_ERROR, "cmd string null");
+		return -EINVAL;
+	}
+
+	cmd_string_len = strlen(cmd_string);
+
+	wpa_printf(MSG_DEBUG, "TWT: cmd string - %s len = %u", cmd_string,
+		   cmd_string_len);
+	if (cmd_string_len < DIALOG_ID_STR_LEN + SINGLE_SPACE_LEN +
+			     SINGLE_DIGIT_LEN) {
+		wpa_printf(MSG_ERROR, "TWT: Dialog_id parameter missing");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * process_twt_setup_cmd_string() - Process a TWT setup command string
+ * @cmd: Command string
+ * @twt_setup_params: TWT setup parameters to fill
+ *
+ * This function parses the TWT setup command and populates twt_setup_params.
+ *
+ * Return: 0 on successs, error if invalid params are found
+ *
+ */
+static
+int process_twt_setup_cmd_string(char *cmd,
+				 struct twt_setup_parameters *twt_setup_params)
+{
+	int ret = 0;
+
+	if (!twt_setup_params) {
+		wpa_printf(MSG_ERROR, "cmd or twt_setup_params null");
+		return -EINVAL;
+	}
+
+	if (check_cmd_input(cmd))
+		return -EINVAL;
+
+	wpa_printf(MSG_DEBUG, "process twt setup command string: %s", cmd);
+	while (*cmd == ' ')
+		cmd++;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) {
+		cmd += (DIALOG_ID_STR_LEN + 1);
+		twt_setup_params->dialog_id = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (os_strncasecmp(cmd, REQ_TYPE_STR, REQ_TYPE_STR_LEN) == 0) {
+		cmd += (REQ_TYPE_STR_LEN + 1);
+		twt_setup_params->req_type = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (os_strncasecmp(cmd, TRIG_TYPE_STR, TRIG_TYPE_STR_LEN) == 0) {
+		cmd += (TRIG_TYPE_STR_LEN + 1);
+		twt_setup_params->trig_type = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+
+		if (is_binary(twt_setup_params->trig_type)) {
+			wpa_printf(MSG_ERROR, "Invalid trigger type");
+			return -EINVAL;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, FLOW_TYPE_STR, FLOW_TYPE_STR_LEN) == 0) {
+		cmd += (FLOW_TYPE_STR_LEN + 1);
+		twt_setup_params->flow_type = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+
+		if (is_binary(twt_setup_params->flow_type)) {
+			wpa_printf(MSG_ERROR, "Invalid flow type");
+			return -EINVAL;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, WAKE_INTR_EXP_STR, WAKE_INTR_EXP_STR_LEN) == 0) {
+		cmd += (WAKE_INTR_EXP_STR_LEN + 1);
+		twt_setup_params->wake_intr_exp = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+
+		if (twt_setup_params->wake_intr_exp >
+		    TWT_SETUP_WAKE_INTVL_EXP_MAX) {
+			wpa_printf(MSG_DEBUG, "Invalid wake_intr_exp %u",
+				   twt_setup_params->wake_intr_exp);
+			return -EINVAL;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, PROTECTION_STR, PROTECTION_STR_LEN) == 0) {
+		cmd += (PROTECTION_STR_LEN + 1);
+		twt_setup_params->protection = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+
+		if (is_binary(twt_setup_params->protection)) {
+			wpa_printf(MSG_ERROR, "Invalid protection value");
+			return -EINVAL;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, WAKE_TIME_STR, WAKE_TIME_STR_LEN) == 0) {
+		cmd += (WAKE_TIME_STR_LEN + 1);
+		twt_setup_params->wake_time = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, WAKE_DUR_STR, WAKE_DUR_STR_LEN) == 0) {
+		cmd += (WAKE_DUR_STR_LEN + 1);
+		twt_setup_params->wake_dur = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+
+		if (twt_setup_params->wake_dur == 0 ||
+		    twt_setup_params->wake_dur > TWT_SETUP_WAKE_DURATION_MAX) {
+			wpa_printf(MSG_ERROR, "Invalid wake_dura_us %u",
+				   twt_setup_params->wake_dur);
+			return -EINVAL;
+		}
+
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, WAKE_INTR_MANTISSA_STR,
+		    WAKE_INTR_MANTISSA_STR_LEN) == 0) {
+		cmd += (WAKE_INTR_MANTISSA_STR_LEN + 1);
+		twt_setup_params->wake_intr_mantissa = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		if (twt_setup_params->wake_intr_mantissa >
+		    TWT_SETUP_WAKE_INTVL_MANTISSA_MAX) {
+			wpa_printf(MSG_ERROR, "Invalid wake_intr_mantissa %u",
+				   twt_setup_params->wake_intr_mantissa);
+			return -EINVAL;
+		}
+
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, BROADCAST_STR, BROADCAST_STR_LEN) == 0) {
+		cmd += (BROADCAST_STR_LEN + 1);
+		twt_setup_params->bcast = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+
+		if (is_binary(twt_setup_params->bcast)) {
+			wpa_printf(MSG_ERROR, "Invalid broadcast value");
+			return -EINVAL;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, MIN_WAKE_INTVL_STR, MIN_WAKE_INTVL_STR_LEN) == 0) {
+		cmd += (MIN_WAKE_INTVL_STR_LEN + 1);
+		twt_setup_params->min_wake_intvl = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, MAX_WAKE_INTVL_STR, MAX_WAKE_INTVL_STR_LEN) == 0) {
+		cmd += (MAX_WAKE_INTVL_STR_LEN + 1);
+		twt_setup_params->max_wake_intvl = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, MIN_WAKE_DUR_STR, MIN_WAKE_DUR_STR_LEN) == 0) {
+		cmd += (MIN_WAKE_DUR_STR_LEN + 1);
+		twt_setup_params->min_wake_duration = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, MAX_WAKE_DUR_STR, MAX_WAKE_DUR_STR_LEN) == 0) {
+		cmd += (MAX_WAKE_DUR_STR_LEN + 1);
+		twt_setup_params->max_wake_duration = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, WAKE_TSF_STR, WAKE_TSF_STR_LEN) == 0) {
+		cmd += (WAKE_TSF_STR_LEN + 1);
+		twt_setup_params->wake_tsf = get_u64_from_string(cmd, &ret);
+		if(ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (strncmp(cmd, ANNOUNCE_TIMEOUT_STR, ANNOUNCE_TIMEOUT_STR_LEN) == 0) {
+		cmd += (ANNOUNCE_TIMEOUT_STR_LEN + 1);
+		twt_setup_params->announce_timeout_us =
+					get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	print_setup_cmd_values(twt_setup_params);
+
+	return 0;
+}
+
+static
+int prepare_twt_setup_nlmsg(struct nl_msg *nlmsg,
+			    struct twt_setup_parameters *twt_setup_params)
+{
+	struct nlattr *twt_attr;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_SET)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_SET");
+		goto fail;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				  QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (twt_attr == NULL)
+		goto fail;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID,
+		       twt_setup_params->dialog_id)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+		goto fail;
+	}
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE,
+		       twt_setup_params->req_type)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put req type");
+		goto fail;
+	}
+
+	if (twt_setup_params->trig_type) {
+		if (nla_put_flag(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)
+				 ) {
+			wpa_printf(MSG_DEBUG, "TWT: Failed to put trig type");
+			goto fail;
+		}
+	}
+
+	/*0 - Announced/ 1 - Unannounced*/
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
+		       twt_setup_params->flow_type)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put flow type");
+		goto fail;
+	}
+
+	if (nla_put_u8(nlmsg,
+		       QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
+		       twt_setup_params->wake_intr_exp)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put wake exp");
+		goto fail;
+	}
+
+	if (twt_setup_params->protection) {
+		if (nla_put_flag(nlmsg,
+		    QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) {
+			wpa_printf(MSG_DEBUG,
+				   "TWT: Failed to add protection");
+			goto fail;
+		}
+	}
+
+	/*offset to add with TBTT after which 1st SP will start*/
+	if (nla_put_u32(nlmsg,
+			QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
+			twt_setup_params->wake_time)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put wake time");
+		goto fail;
+	}
+
+	/*TWT Wake Duration in units of us, must be <= 65280*/
+	if (nla_put_u32(nlmsg,
+			QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
+			twt_setup_params->wake_dur)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put wake dur");
+		goto fail;
+	}
+
+	if (nla_put_u32(nlmsg,
+		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA,
+		twt_setup_params->wake_intr_mantissa)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put wake intr mantissa");
+		goto fail;
+	}
+
+	if (nla_put_u32(nlmsg,
+		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
+		twt_setup_params->wake_intr_mantissa/TWT_WAKE_INTERVAL_TU_FACTOR)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put wake intr mantissa");
+		goto fail;
+	}
+
+	if (twt_setup_params->bcast) {
+		if (nla_put_flag(nlmsg,
+			QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) {
+			wpa_printf(MSG_DEBUG, "TWT: Failed to put bcast");
+			goto fail;
+		}
+	}
+
+	if (nla_put_u32(nlmsg,
+		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL,
+		twt_setup_params->min_wake_intvl)) {
+		wpa_printf(MSG_ERROR, "TWT: Failed to put min wake intr ");
+		goto fail;
+	}
+
+	if (nla_put_u32(nlmsg,
+		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL,
+		twt_setup_params->max_wake_intvl)) {
+		wpa_printf(MSG_ERROR,"TWT: Failed to put max wake intr");
+		goto fail;
+	}
+
+	if (nla_put_u32(nlmsg,
+		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION,
+		twt_setup_params->min_wake_duration)) {
+		wpa_printf(MSG_ERROR,"TWT: Failed to put min wake dur");
+		goto fail;
+	}
+
+	if (nla_put_u32(nlmsg,
+		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION,
+		twt_setup_params->max_wake_duration)) {
+		wpa_printf(MSG_ERROR,"TWT: Failed to put max wake dur");
+		goto fail;
+	}
+
+	if (twt_setup_params->wake_tsf) {
+		if (nla_put_u64(nlmsg,
+			QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF,
+			twt_setup_params->wake_tsf)) {
+			wpa_printf(MSG_ERROR,"TWT: Failed to put wake time tsf value");
+			goto fail;
+		}
+	}
+
+	if (twt_setup_params->announce_timeout_us) {
+		if (nla_put_u32(nlmsg,
+		   QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT,
+		   twt_setup_params->announce_timeout_us)) {
+			wpa_printf(MSG_ERROR, "TWT: Failed to put announce timeout value");
+			goto fail;
+		}
+	}
+
+	nla_nest_end(nlmsg, twt_attr);
+	wpa_printf(MSG_DEBUG, "TWT: setup command nla end");
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int prepare_twt_terminate_nlmsg(struct nl_msg *nlmsg, char *cmd)
+{
+	u8 dialog_id;
+	struct nlattr *twt_attr;
+	int ret = 0;
+
+	if(check_cmd_input(cmd))
+		return -EINVAL;
+
+	while(*cmd == ' ')
+		cmd++;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) {
+		cmd += (DIALOG_ID_STR_LEN + 1);
+		dialog_id = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+	} else {
+		wpa_printf(MSG_ERROR, "TWT: no dialog_id found");
+		goto fail;
+	}
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_TERMINATE)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_TERMINATE");
+		goto fail;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				  QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (twt_attr == NULL)
+		goto fail;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID,
+		       dialog_id)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+		goto fail;
+	}
+
+	nla_nest_end(nlmsg, twt_attr);
+	wpa_printf(MSG_DEBUG, "TWT: terminate sent with dialog_id: %x",
+		   dialog_id);
+
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+static int prepare_twt_pause_nlmsg(struct nl_msg *nlmsg, char *cmd)
+{
+	u8 dialog_id;
+	struct nlattr *twt_attr;
+	int ret = 0;
+
+	if(check_cmd_input(cmd))
+		return -EINVAL;
+
+	while(*cmd == ' ')
+		cmd++;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) {
+		cmd += (DIALOG_ID_STR_LEN + 1);
+		dialog_id = get_u8_from_string(cmd, &ret);
+		if(ret < 0)
+			return ret;
+	} else {
+		wpa_printf(MSG_ERROR, "TWT: no dialog_id found");
+		goto fail;
+	}
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_SUSPEND)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_TERMINATE");
+		goto fail;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (twt_attr == NULL)
+		goto fail;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID,
+		       dialog_id)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+		goto fail;
+	}
+
+	nla_nest_end(nlmsg, twt_attr);
+	wpa_printf(MSG_DEBUG, "TWT: pause sent with dialog_id: %x", dialog_id);
+
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * process_twt_resume_cmd_string() - Process a TWT resume command string
+ * @cmd: Command string
+ * @resume_params: TWT resume parameters to fill
+ *
+ * This function parses the TWT resume command and populates resume_params.
+ *
+ * Return: 0 on successs, error if invalid params are found
+ *
+ */
+static
+int process_twt_resume_cmd_string(char *cmd,
+				  struct twt_resume_parameters *resume_params)
+{
+	int ret = 0;
+
+	if (!resume_params) {
+		wpa_printf(MSG_ERROR, "TWT: cmd or resume_params null");
+		return -EINVAL;
+	}
+
+	if(check_cmd_input(cmd))
+		return -EINVAL;
+
+	while(*cmd == ' ')
+		cmd++;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) != 0) {
+		wpa_printf(MSG_ERROR, "TWT: dialog ID parameter is required");
+		return -EINVAL;
+	}
+	cmd += (DIALOG_ID_STR_LEN + 1);
+	resume_params->dialog_id = get_u8_from_string(cmd, &ret);
+	if (ret < 0)
+		return ret;
+	cmd = move_to_next_str(cmd);
+
+	if (os_strncasecmp(cmd, NEXT_TWT_STR, NEXT_TWT_STR_LEN) == 0) {
+		cmd += (NEXT_TWT_STR_LEN + 1);
+		resume_params->next_twt = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		wpa_printf(MSG_DEBUG, "TWT: NEXT TWT %d", resume_params->next_twt);
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (os_strncasecmp(cmd, NEXT2_TWT_STR, NEXT2_TWT_STR_LEN) == 0) {
+		cmd += (NEXT2_TWT_STR_LEN + 1);
+		resume_params->next2_twt = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		wpa_printf(MSG_DEBUG, "TWT: NEXT2 TWT %d", resume_params->next2_twt);
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (os_strncasecmp(cmd, NEXT_TWT_SIZE_STR, NEXT_TWT_SIZE_STR_LEN) != 0) {
+		wpa_printf(MSG_ERROR, "TWT: next_twt_size parameter is required");
+		return -EINVAL;
+	}
+	cmd += (NEXT_TWT_SIZE_STR_LEN + 1);
+	resume_params->next_twt_size = get_u32_from_string(cmd, &ret);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static
+int prepare_twt_resume_nlmsg(struct nl_msg *nlmsg,
+			     struct twt_resume_parameters *resume_params)
+{
+	struct nlattr *twt_attr;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_RESUME)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_RESUME");
+		return -EINVAL;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (twt_attr == NULL)
+		return -EINVAL;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID,
+		       resume_params->dialog_id)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+		return -EINVAL;
+	}
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT,
+		       resume_params->next_twt)) {
+		wpa_printf(MSG_DEBUG, "TWT: next_twt");
+		return -EINVAL;
+	}
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
+			resume_params->next2_twt)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put next2_twt");
+		return -EINVAL;
+	}
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
+			resume_params->next_twt_size)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put next_twt_size");
+		return -EINVAL;
+	}
+	nla_nest_end(nlmsg, twt_attr);
+
+	wpa_printf(MSG_DEBUG,"TWT: resume dialog_id: 0x%x next_twt (us): 0x%x next2_twt (us): 0x%x next_twt_size: %u",
+		   resume_params->dialog_id, resume_params->next_twt,
+		   resume_params->next2_twt,resume_params->next_twt_size);
+
+	return 0;
+}
+
+/**
+ * process_twt_nudge_cmd_string()- processes command string for nudge command.
+ *
+ * @Param cmd: expects the command
+ * @Param nudge_params: return parsed nudge parameters
+ *
+ * @Returns 0 on Success, -EINVAL on Failure
+ */
+static
+int process_twt_nudge_cmd_string(char *cmd,
+				 struct twt_nudge_parameters *nudge_params)
+{
+	int ret = 0;
+
+	if (!nudge_params) {
+		wpa_printf(MSG_ERROR, "TWT: nudge_params null");
+		return -EINVAL;
+	}
+
+	if(check_cmd_input(cmd))
+		return -EINVAL;
+
+	while(*cmd == ' ')
+		cmd++;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) != 0) {
+		wpa_printf(MSG_ERROR, "TWT: dialog_id parameter is required");
+		return -EINVAL;
+	}
+	cmd += (DIALOG_ID_STR_LEN + 1);
+	nudge_params->dialog_id = get_u8_from_string(cmd, &ret);
+	if (ret < 0)
+		return ret;
+	cmd = move_to_next_str(cmd);
+
+	if (os_strncasecmp(cmd, PAUSE_DURATION_STR, PAUSE_DURATION_STR_LEN) == 0) {
+		cmd += (PAUSE_DURATION_STR_LEN + 1);
+		nudge_params->wake_time = get_u32_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		wpa_printf(MSG_DEBUG, "TWT: WAKE TIME %d", nudge_params->wake_time);
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (os_strncasecmp(cmd, NEXT_TWT_SIZE_STR, NEXT_TWT_SIZE_STR_LEN) != 0) {
+		wpa_printf(MSG_ERROR, "TWT: next_twt_size parameter is required");
+		return -EINVAL;
+	}
+	cmd += (NEXT_TWT_SIZE_STR_LEN + 1);
+	nudge_params->next_twt_size = get_u32_from_string(cmd, &ret);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+/**
+ * prepare_twt_nudge_nlmsg()- prepare twt_session_nudge command .
+ *
+ * @Param nlmsg: nl command buffer
+ * @Param nudge_params: nudge parameters to prepare command
+ *
+ * @Returns 0 on Success, -EINVAL on Failure
+ */
+static
+int prepare_twt_nudge_nlmsg(struct nl_msg *nlmsg,
+			    struct twt_nudge_parameters *nudge_params)
+{
+	struct nlattr *twt_attr;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_NUDGE)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put twt operation");
+		return -EINVAL;
+	}
+
+	twt_attr = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (twt_attr == NULL)
+		return -EINVAL;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID,
+		       nudge_params->dialog_id)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+		return -EINVAL;
+	}
+
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
+		        nudge_params->wake_time)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put wake_time");
+		return -EINVAL;
+	}
+
+	if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
+			nudge_params->next_twt_size)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put next_twt_size");
+		return -EINVAL;
+	}
+	nla_nest_end(nlmsg, twt_attr);
+
+	wpa_printf(MSG_DEBUG,"TWT: nudge dialog_id: 0x%x wake_time(us): 0x%x next_twt_size: %u",
+		   nudge_params->dialog_id, nudge_params->wake_time,
+		   nudge_params->next_twt_size);
+
+	return 0;
+}
+
+/**
+ * process_twt_set_param_cmd_string()- processes command
+ * string for set parameters command.
+ *
+ * @Param cmd: expects the command
+ * @Param set_params: return parsed TWT set parameters
+ *
+ * @Returns 0 on Success, -EINVAL on Failure
+ */
+static
+int process_twt_set_param_cmd_string(char *cmd,
+				     struct twt_set_parameters *set_params)
+{
+	int ret = -EINVAL;
+
+	if (!set_params) {
+		wpa_printf(MSG_ERROR, "TWT: set_params null");
+		return -EINVAL;
+	}
+
+	if (check_cmd_input(cmd))
+		return -EINVAL;
+
+	while (*cmd == ' ')
+		cmd++;
+
+	if (os_strncasecmp(cmd, AP_AC_VALUE_STR, AP_AC_VALUE_STR_LEN) == 0) {
+		cmd += (AP_AC_VALUE_STR_LEN + 1);
+		set_params->ap_ac_value = get_u8_from_string(cmd, &ret);
+		wpa_printf(MSG_DEBUG, "TWT: AP AC VALUE: %d", set_params->ap_ac_value);
+		if (ret < 0)
+			return ret;
+		cmd = move_to_next_str(cmd);
+	}
+
+	return ret;
+}
+
+/**
+ * prepare_twt_set_param_nlmsg()- prepare twt_set_param command .
+ *
+ * @Param nlmsg: nl command buffer
+ * @Param set_params: set parameters to prepare command
+ *
+ * @Returns 0 on Success, -EINVAL on Failure
+ */
+static
+int prepare_twt_set_param_nlmsg(struct nl_msg *nlmsg,
+			        struct twt_set_parameters *set_params)
+{
+	struct nlattr *twt_attr;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_SET_PARAM)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put twt operation");
+		return -EINVAL;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				  QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (!twt_attr)
+		return -EINVAL;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE,
+		set_params->ap_ac_value)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put ap_ac_value");
+		return -EINVAL;
+	}
+
+	nla_nest_end(nlmsg, twt_attr);
+
+	wpa_printf(MSG_DEBUG, "TWT: set parameters -  ap_ac_value: %d",
+		   set_params->ap_ac_value);
+
+	return 0;
+}
+
+/**
+ * prepare_twt_clear_stats_nlmsg()- prepare twt_session_clear_stats command.
+ *
+ * @Param nlmsg: nl command buffer
+ * @Param cmd: command string
+ *
+ * @Returns 0 on Success, -EINVAL on Failure
+ */
+static int prepare_twt_clear_stats_nlmsg(struct nl_msg *nlmsg, char *cmd)
+{
+	struct nlattr *twt_attr;
+	u8 dialog_id;
+	int ret = 0;
+
+	while(*cmd == ' ')
+		cmd++;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_CLEAR_STATS)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_CLEAR_STATS");
+		goto fail;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				  QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (!twt_attr)
+		return -EINVAL;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) {
+		cmd += DIALOG_ID_STR_LEN + 1;
+
+		dialog_id = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID,
+			       dialog_id)) {
+			wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+			return -EINVAL;
+		}
+		wpa_printf(MSG_DEBUG, "TWT: clear_stats dialog_id:%d", dialog_id);
+		cmd = move_to_next_str(cmd);
+	} else {
+		wpa_printf(MSG_DEBUG, "TWT: dialog_id not found");
+		goto fail;
+	}
+
+	nla_nest_end(nlmsg, twt_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * prepare_twt_get_stats_nlmsg()- prepare twt_session_get_stats command.
+ *
+ * @Param nlmsg: nl command buffer
+ * @Param cmd: command string
+ *
+ * @Returns 0 on Success, -EINVAL on Failure
+ */
+static int prepare_twt_get_stats_nlmsg(struct nl_msg *nlmsg, char *cmd)
+{
+	struct nlattr *twt_attr;
+	u8 dialog_id;
+	int ret = 0;
+
+	while(*cmd == ' ')
+		cmd++;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_GET_STATS)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_GET_STATS");
+		goto fail;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				  QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (!twt_attr)
+		return -EINVAL;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) {
+		cmd += DIALOG_ID_STR_LEN + 1;
+
+		dialog_id = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+		if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID,
+			       dialog_id)) {
+			wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+			return -EINVAL;
+		}
+		wpa_printf(MSG_DEBUG, "TWT: get_stats dialog_id:%d", dialog_id);
+		cmd = move_to_next_str(cmd);
+	} else {
+		wpa_printf(MSG_DEBUG, "TWT: dialog_id not found");
+		goto fail;
+	}
+
+	nla_nest_end(nlmsg, twt_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+static int prepare_twt_get_params_nlmsg(struct nl_msg *nlmsg, char *cmd)
+{
+	struct nlattr *twt_attr;
+	u8 dialog_id;
+	int ret = 0;
+	uint8_t peer_mac[MAC_ADDR_LEN];
+
+	while(*cmd == ' ')
+		cmd++;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_GET)) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_GET");
+		goto fail;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				  QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (!twt_attr)
+		return -EINVAL;
+
+	if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) {
+		cmd += DIALOG_ID_STR_LEN + 1;
+
+		dialog_id = get_u8_from_string(cmd, &ret);
+		if (ret < 0)
+			return ret;
+
+		if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID,
+			       dialog_id)) {
+			wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id");
+			return -EINVAL;
+		}
+		wpa_printf(MSG_DEBUG, "TWT: get_param dialog_id:%d", dialog_id);
+		cmd = move_to_next_str(cmd);
+	} else {
+		wpa_printf(MSG_ERROR, "TWT: dialog_id not found");
+		goto fail;
+	}
+
+
+	if (os_strncasecmp(cmd, MAC_ADDRESS_STR, MAC_ADDR_STR_LEN) == 0) {
+		cmd += MAC_ADDR_STR_LEN + 1;
+
+		if (convert_string_to_bytes(peer_mac, cmd, MAC_ADDR_LEN) !=
+		    MAC_ADDR_LEN) {
+			wpa_printf(MSG_ERROR, "TWT: invalid mac address");
+			goto fail;
+		}
+
+	        if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR,
+			    MAC_ADDR_LEN, peer_mac)) {
+			wpa_printf(MSG_ERROR, "TWT: Failed to put mac address");
+			goto fail;
+	        }
+	}
+
+	nla_nest_end(nlmsg, twt_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+* prepare_twt_get_cap_nlmsg()- processes and packs get capability command.
+* The command is expected in below format:
+* TWT_GET_CAP
+*
+* @Param nlmsg: stores the nlmsg
+* @Param cmd: expects the command
+*
+* @Returns 0 on Success, -EINVAL on Failure
+*/
+static int prepare_twt_get_cap_nlmsg(struct nl_msg *nlmsg, char *cmd)
+{
+	struct nlattr *twt_attr;
+
+	if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_GET_CAPABILITIES)) {
+		wpa_printf(MSG_ERROR,"TWT: Failed to put QCA_WLAN_TWT_GET_CAPABILITIES");
+		goto fail;
+	}
+
+	twt_attr = nla_nest_start(nlmsg,
+				  QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (twt_attr == NULL)
+		goto fail;
+	nla_nest_end(nlmsg, twt_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+static int pack_nlmsg_twt_params(struct nl_msg *twt_nl_msg, char *cmd,
+				 enum qca_wlan_twt_operation type)
+{
+	struct nlattr *attr;
+	int ret = 0;
+
+	attr = nla_nest_start(twt_nl_msg, NL80211_ATTR_VENDOR_DATA);
+	if (attr == NULL)
+		return -EINVAL;
+
+	switch (type) {
+	case QCA_WLAN_TWT_SET:
+	{
+		struct twt_setup_parameters setup_params = {0};
+
+		if (process_twt_setup_cmd_string(cmd, &setup_params))
+			return -EINVAL;
+		ret = prepare_twt_setup_nlmsg(twt_nl_msg, &setup_params);
+		break;
+	}
+	case QCA_WLAN_TWT_TERMINATE:
+		ret = prepare_twt_terminate_nlmsg(twt_nl_msg, cmd);
+		break;
+	case QCA_WLAN_TWT_SUSPEND:
+		ret = prepare_twt_pause_nlmsg(twt_nl_msg, cmd);
+		break;
+	case QCA_WLAN_TWT_RESUME:
+	{
+		struct twt_resume_parameters resume_params = {0};
+
+		if (process_twt_resume_cmd_string(cmd, &resume_params))
+			return -EINVAL;
+		ret = prepare_twt_resume_nlmsg(twt_nl_msg, &resume_params);
+		break;
+	}
+	case QCA_WLAN_TWT_NUDGE:
+	{
+		struct twt_nudge_parameters nudge_params = {0};
+
+		if (process_twt_nudge_cmd_string(cmd, &nudge_params))
+			return -EINVAL;
+		ret = prepare_twt_nudge_nlmsg(twt_nl_msg, &nudge_params);
+		break;
+	}
+	case QCA_WLAN_TWT_SET_PARAM:
+	{
+		struct twt_set_parameters set_params = {0};
+
+		if (process_twt_set_param_cmd_string(cmd, &set_params))
+			return -EINVAL;
+		ret = prepare_twt_set_param_nlmsg(twt_nl_msg, &set_params);
+		break;
+	}
+	case QCA_WLAN_TWT_GET_CAPABILITIES:
+		ret = prepare_twt_get_cap_nlmsg(twt_nl_msg, cmd);
+		break;
+	case QCA_WLAN_TWT_CLEAR_STATS:
+		ret = prepare_twt_clear_stats_nlmsg(twt_nl_msg, cmd);
+		break;
+	case QCA_WLAN_TWT_GET_STATS:
+		ret = prepare_twt_get_stats_nlmsg(twt_nl_msg, cmd);
+		break;
+	case QCA_WLAN_TWT_GET:
+		ret = prepare_twt_get_params_nlmsg(twt_nl_msg, cmd);
+		break;
+	default:
+		wpa_printf(MSG_DEBUG, "Unsupported command: %d", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	if (!ret)
+		nla_nest_end(twt_nl_msg, attr);
+
+	return ret;
+}
+
+char *result_copy_to_buf(char *src, char *dst_buf, int *dst_len)
+{
+	int str_len, remaining = 0;
+
+	remaining = *dst_len;
+	str_len = strlen(src);
+	remaining = remaining - (str_len + 1);
+
+	if (remaining <= 0) {
+		wpa_printf(MSG_ERROR, "destination buffer length not enough");
+		return NULL;
+	}
+	os_memcpy(dst_buf, src, str_len);
+
+	*dst_len = remaining;
+	*(dst_buf + str_len) = ' ';
+
+	return (dst_buf + str_len + 1);
+}
+
+static int
+unpack_twt_get_params_resp(struct nlattr **tb, char *buf, int buf_len)
+{
+	int cmd_id, val, len;
+	uint8_t exp;
+	uint32_t value;
+	unsigned long wake_tsf;
+	char temp[TWT_RESP_BUF_LEN];
+	char *start = buf;
+
+	os_memset(temp, 0, TWT_RESP_BUF_LEN);
+
+	/* Mac Address */
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR;
+	if (!tb[cmd_id]) {
+		wpa_printf(MSG_ERROR, "twt_get_params resp: no mac_addr");
+		return -EINVAL;
+	}
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "<mac_addr " MAC_ADDR_STR,
+		    MAC_ADDR_ARRAY((char *)nla_data(tb[cmd_id])));
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* Flow Id */
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID;
+	if (!tb[cmd_id]) {
+		wpa_printf(MSG_ERROR, "twt_get_params resp: no dialog_id");
+		return -EINVAL;
+	}
+	val = nla_get_u8(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+
+	/* Broadcast */
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST;
+	if (tb[cmd_id])
+		val = nla_get_flag(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "bcast %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* Trigger Type */
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER;
+	if (tb[cmd_id])
+		val = nla_get_flag(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "trig_type %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* Announce */
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE;
+	if (tb[cmd_id])
+		val = nla_get_flag(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "flow_type %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* Protection */
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION;
+	if (tb[cmd_id])
+		val = nla_get_flag(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "protection %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* info */
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED;
+	if (tb[cmd_id])
+		val = nla_get_flag(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "info_enabled %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* Wake Duration */
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION;
+	if (!tb[cmd_id]) {
+		wpa_printf(MSG_ERROR, "twt_get_params resp: no wake duration");
+		return -EINVAL;
+	}
+	value = nla_get_u32(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_dur %d", value);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* Wake Interval Mantissa */
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA;
+	if (!tb[cmd_id]) {
+		cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA;
+		if (!tb[cmd_id]) {
+			wpa_printf(MSG_ERROR, "twt_get_params resp: no wake mantissa");
+			return -EINVAL;
+		}
+		value = nla_get_u32(tb[cmd_id]);
+		value = value * TWT_WAKE_INTERVAL_TU_FACTOR;
+	} else {
+		value = nla_get_u32(tb[cmd_id]);
+	}
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl_mantis %d", value);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* Wake Interval Exponent */
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP;
+	if (!tb[cmd_id]) {
+		wpa_printf(MSG_ERROR, "twt_get_params resp: no wake intvl exp");
+		return -EINVAL;
+	}
+	exp = nla_get_u8(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl_exp %d", exp);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* TSF Value */
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF;
+	if (!tb[cmd_id]) {
+		wpa_printf(MSG_ERROR, "twt_get_params resp: no wake time tsf");
+		return -EINVAL;
+	}
+	wake_tsf = nla_get_u64(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_time_tsf 0x%lx>", wake_tsf);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE;
+	if (!tb[cmd_id]) {
+		wpa_printf(MSG_ERROR, "twt_get_params resp: no state info");
+		return -EINVAL;
+	}
+	value = nla_get_u32(tb[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "state %d", value);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE;
+	if (tb[cmd_id]) {
+		val = nla_get_u8(tb[cmd_id]);
+
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "responder_pm %d", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+
+	len = (buf - start);
+	*buf = '\0';
+
+	return len;
+}
+
+static int wpa_get_twt_setup_resp_val(struct nlattr **tb2, char *buf,
+				      int buf_len)
+{
+	uint32_t wake_intvl_exp = 0, wake_intvl_mantis = 0;
+	int cmd_id, val;
+	uint32_t value;
+	unsigned long wake_tsf;
+	char temp[TWT_RESP_BUF_LEN];
+
+	buf = result_copy_to_buf(TWT_SETUP_RESP, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	os_memset(temp, 0, TWT_RESP_BUF_LEN);
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "TWT dialog id missing");
+		return -EINVAL;
+	}
+
+	val = nla_get_u8(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %d ", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "TWT resp status missing");
+		return -EINVAL;
+	}
+
+	val = nla_get_u8(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "status %d ", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	os_memset(temp, 0, TWT_RESP_BUF_LEN);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val));
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	/* In case of failure only status is updated */
+	if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
+		*buf = '\0';
+		return 0;
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "TWT resp type missing");
+		return -EINVAL;
+	}
+	val = nla_get_u8(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "resp_reason %d ", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "TWT_SETUP_WAKE_INTVL_EXP is must");
+		return -EINVAL;
+	}
+	wake_intvl_exp = nla_get_u8(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl_exp %d ",
+		    wake_intvl_exp);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST;
+	if (tb2[cmd_id])
+		val = nla_get_flag(tb2[cmd_id]);
+
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "bcast %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER;
+	if (tb2[cmd_id])
+		val = nla_get_flag(tb2[cmd_id]);
+
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "trig_type %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "TWT_SETUP_FLOW_TYPE is must");
+		return -EINVAL;
+	}
+	val = nla_get_u8(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "flow_type %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION;
+	if (tb2[cmd_id])
+		val = nla_get_flag(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "protection %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	value = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME;
+	if (tb2[cmd_id])
+		value = nla_get_u32(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_time 0x%x", value);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "TWT_SETUP_WAKE_DURATION is must");
+		return -EINVAL;
+	}
+	value = nla_get_u32(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_dur %d", value);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA;
+	if (!tb2[cmd_id]) {
+		cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA;
+		if (!tb2[cmd_id]) {
+			wpa_printf(MSG_ERROR, "SETUP_WAKE_INTVL_MANTISSA is must");
+			return -EINVAL;
+		}
+		wake_intvl_mantis = nla_get_u32(tb2[cmd_id]);
+		wake_intvl_mantis = wake_intvl_mantis * TWT_WAKE_INTERVAL_TU_FACTOR;
+	} else {
+		wake_intvl_mantis = nla_get_u32(tb2[cmd_id]);
+	}
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl %d", wake_intvl_mantis);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	wake_tsf = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF;
+	if (tb2[cmd_id])
+		wake_tsf = nla_get_u64(tb2[cmd_id]);
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_tsf 0x%lx", wake_tsf);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED;
+	if (tb2[cmd_id])
+		val = nla_get_flag(tb2[cmd_id]);
+
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "info_enabled %d", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	val = 0;
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE;
+	if (tb2[cmd_id]) {
+		val = nla_get_u8(tb2[cmd_id]);
+
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "responder_pm %d", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+
+	*buf = '\0';
+
+	return 0;
+}
+
+/**
+ * unpack_twt_get_params_nlmsg()- unpacks and prints the twt get_param
+ * response recieved from driver synchronously for twt_session_get_params.
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -1 on Failure
+ */
+static int unpack_twt_get_params_nlmsg(struct nl_msg **tb, char *buf, int buf_len)
+{
+	int ret, rem, id, len = 0, num_twt_sessions = 0;
+	struct nlattr *config_attr[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
+	struct nlattr *setup_attr[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+	struct nlattr *attr;
+
+	if (nla_parse_nested(config_attr, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
+			     tb[NL80211_ATTR_VENDOR_DATA], NULL)) {
+		wpa_printf(MSG_ERROR, "twt_get_params: nla_parse_nested fail");
+		return -EINVAL;
+	}
+
+	id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS;
+	attr = config_attr[id];
+	if (!attr) {
+		wpa_printf(MSG_ERROR, "twt_get_params: config_twt_params fail");
+		return -EINVAL;
+	}
+
+	num_twt_sessions = 0;
+	nla_for_each_nested(attr, config_attr[id], rem) {
+		num_twt_sessions++;
+		if (nla_parse(setup_attr, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+			      nla_data(attr), nla_len(attr), NULL)) {
+			wpa_printf(MSG_ERROR, "twt_get_params: nla_parse fail");
+			return -EINVAL;
+		}
+		ret = unpack_twt_get_params_resp(setup_attr, buf + len,
+						 buf_len - len);
+		if (ret < 0)
+			return ret;
+		len += ret;
+	}
+
+	wpa_printf(MSG_ERROR, "twt_get_params: number of twt sessions = %d",
+		   num_twt_sessions);
+
+	return 0;
+}
+
+/**
+ * wpa_get_twt_stats_resp_val()- parse twt get_stats response
+ * recieved from driver synchronously for twt_session_get_stats.
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -1 on Failure
+ */
+static int wpa_get_twt_stats_resp_val(struct nlattr **tb2, char *buf,
+				      int buf_len)
+{
+	int cmd_id, len;
+	u32  val = 0;
+	u8 val1 = 0;
+	char temp[TWT_RESP_BUF_LEN];
+	char *start = buf;
+
+	os_memset(temp, 0, TWT_RESP_BUF_LEN);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats flow id missing", __func__);
+	} else {
+		val1 = nla_get_u8(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "flow_id %u", val1);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT stats flow id : %u", val1);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats num sp iterations missing", __func__);
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "num_sp_iteration %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT num sp Iterations : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats min wake duration missing", __func__);
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "min_wake_dur %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT min wake duration : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats max wake duration missing", __func__);
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "max_wake_dur %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT Max wake duration : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats sess_wake_dur missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "session_wake_dur %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT stats session wake duration : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats avg_wake_dur missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "avg_wake_dur %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT stats avg wake duration : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats average tx mpdu missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "tx_mpdu %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT stats average tx mpdu : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats average rx mpdu missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "rx_mpdu %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT stats average rx mpdu : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats average tx packet size missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "tx_pkt_size %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT stats average tx packet size : %u", val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR,"%s TWT stats average rx packet size missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u32(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "rx_pkt_size %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+		wpa_printf(MSG_INFO,"TWT stats average rx packet size : %u", val);
+	}
+	len = (buf - start);
+	*buf = '\0';
+
+	return len;
+}
+
+/**
+ * unpack_twt_get_stats_nlmsg()- unpacks and prints the twt get_stats
+ * response recieved from driver synchronously for twt_session_get_stats.
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -1 on Failure
+ */
+static
+int unpack_twt_get_stats_nlmsg(struct nl_msg **tb, char *buf, int buf_len)
+{
+	int ret, rem, id, len = 0, num_twt_sessions = 0;
+	struct nlattr *config_attr[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
+	struct nlattr *setup_attr[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+	struct nlattr *attr;
+
+	if (nla_parse_nested(config_attr, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
+			     tb[NL80211_ATTR_VENDOR_DATA], NULL)) {
+		wpa_printf(MSG_ERROR, "twt_get_stats: nla_parse_nested fail");
+		return -EINVAL;
+	}
+
+	id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS;
+	attr = config_attr[id];
+	if (!attr) {
+		wpa_printf(MSG_ERROR, "twt_get_stats: config_twt_params fail");
+		return -EINVAL;
+	}
+
+	num_twt_sessions = 0;
+	nla_for_each_nested(attr, config_attr[id], rem) {
+		num_twt_sessions++;
+		if (nla_parse(setup_attr, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+				nla_data(attr), nla_len(attr), NULL)) {
+			wpa_printf(MSG_ERROR, "twt_get_stats: nla_parse fail");
+			return -EINVAL;
+		}
+		ret = wpa_get_twt_stats_resp_val(setup_attr, buf + len,
+		                                 buf_len - len);
+		if (ret < 0)
+			return ret;
+		len += ret;
+	}
+	wpa_printf(MSG_INFO,"twt_get_stats: number of twt sessions = %d", num_twt_sessions);
+
+	return 0;
+}
+
+static int wpa_get_twt_capabilities_resp_val(struct nlattr **tb2, char *buf,
+					     int buf_len)
+{
+	int cmd_id;
+	u16 msb, lsb;
+	u32 val;
+	char temp[TWT_RESP_BUF_LEN];
+
+	os_memset(temp, 0, TWT_RESP_BUF_LEN);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_INFO,"%s TWT self capabilities missing", __func__);
+		return -EINVAL;
+	} else {
+		msb = nla_get_u16(tb2[cmd_id]);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_INFO,"%s TWT peer capabilities missing", __func__);
+		return -EINVAL;
+	} else {
+		lsb  = nla_get_u16(tb2[cmd_id]);
+	}
+	wpa_printf(MSG_INFO,"TWT self_capab:%d, TWT peer_capab:%d", msb, lsb);
+	val = (msb << 16) | lsb;
+	os_snprintf(temp, TWT_RESP_BUF_LEN, "0x%x", val);
+	buf = result_copy_to_buf(temp, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+	*buf = '\0';
+
+	return 0;
+}
+
+/**
+ * unpack_twt_get_capab_nlmsg()- unpacks and prints the twt get capabilities
+ * response recieved from driver synchronously for TWT_GET_CAP command.
+ * The response is printed in below hex-format:
+ * 0xHIGHLOW
+ * HIGH: Self capabilities
+ * LOW:  Peer capabilities
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -1 on Failure
+ */
+static int unpack_twt_get_capab_nlmsg(struct nl_msg **tb, char *buf, int buf_len)
+{
+	int ret, id;
+	struct nlattr *config_attr[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
+	struct nlattr *setup_attr[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+	struct nlattr *attr;
+
+	if (nla_parse_nested(config_attr, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
+			     tb[NL80211_ATTR_VENDOR_DATA], NULL)) {
+		wpa_printf(MSG_ERROR, "twt_get_capability: nla_parse_nested fail");
+		return -EINVAL;
+	}
+
+	id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS;
+	attr = config_attr[id];
+	if (!attr) {
+		wpa_printf(MSG_ERROR, "twt_get_capability: config_twt_params fail");
+		return -EINVAL;
+	}
+
+	if (nla_parse(setup_attr, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+		      nla_data(attr), nla_len(attr), NULL)) {
+		wpa_printf(MSG_ERROR, "twt_get_capability: nla_parse fail");
+		return -EINVAL;
+	}
+
+	ret = wpa_get_twt_capabilities_resp_val(setup_attr, buf, buf_len);
+	return ret;
+}
+
+/**
+ * unpack_twt_setup_nlmsg()- unpacks twt_session_setup response recieved
+ * The response is printed in below format:
+ * CTRL-EVENT-TWT SETUP dialog_id <dialog_id> status <status> ..
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -EINVAL on invalid response
+ */
+static int unpack_twt_setup_nlmsg(struct nlattr **tb, char *buf, int buf_len)
+{
+	int ret = 0;
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+
+	if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+			     tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) {
+		wpa_printf(MSG_ERROR, "nla_parse failed\n");
+		return -EINVAL;
+	}
+
+	ret = wpa_get_twt_setup_resp_val(tb2, buf, buf_len);
+
+	return ret;
+}
+
+static int unpack_nlmsg_twt_params(struct nl_msg *twt_nl_msg,
+				   enum qca_wlan_twt_operation type,
+				   char *buf, int buf_len)
+{
+	int ret = 0;
+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(twt_nl_msg));
+
+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+	switch (type) {
+	case QCA_WLAN_TWT_GET:
+		ret = unpack_twt_get_params_nlmsg(tb, buf, buf_len);
+		break;
+	case QCA_WLAN_TWT_GET_STATS:
+		ret = unpack_twt_get_stats_nlmsg(tb, buf, buf_len);
+		break;
+	case QCA_WLAN_TWT_GET_CAPABILITIES:
+		ret = unpack_twt_get_capab_nlmsg(tb, buf, buf_len);
+		break;
+	default:
+		wpa_printf(MSG_DEBUG, "Unsupported command: %d", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int twt_response_handler(struct nl_msg *msg, void *arg)
+{
+	struct twt_resp_info *info = (struct twt_resp_info *) arg;
+	struct wpa_driver_nl80211_data *drv = NULL;
+	int ret;
+
+	drv = info->drv;
+	ret = unpack_nlmsg_twt_params(msg, info->twt_oper, info->reply_buf,
+				      info->reply_buf_len);
+	wpa_printf(MSG_DEBUG, "%s - twt_oper %d", __func__, info->twt_oper);
+	if (!ret)
+		wpa_msg(drv->ctx, MSG_INFO,
+			TWT_CTRL_EVENT " %s : OK", info->reply_buf);
+	else
+		wpa_msg(drv->ctx, MSG_INFO,
+			TWT_CTRL_EVENT " %s : Error = %d",
+			info->reply_buf, ret);
+
+	return ret;
+}
+
+struct features_info {
+	u8 *flags;
+	size_t flags_len;
+};
+
+static
+int check_feature(enum qca_wlan_vendor_features feature,
+		  struct features_info *info)
+{
+	size_t idx = feature / 8;
+
+	return (idx < info->flags_len) &&
+		(info->flags[idx] & BIT(feature % 8));
+}
+
+/* features_info_handler() - parse sync response for get_feature cmd
+ *
+ * @param msg: nl_msg buffer
+ * @Param arg: feature infor
+ *
+ * @Returns 0 on Success, error code on invalid response
+ */
+static
+int features_info_handler(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *mHeader;
+	struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1];
+	struct nlattr *vendata, *attr;
+	int datalen;
+
+	struct features_info *info = (struct features_info *) arg;
+	int status = 0;
+
+
+	mHeader = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
+	nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL,
+			  genlmsg_attrdata(mHeader, 0),
+			  genlmsg_attrlen(mHeader, 0), NULL);
+
+	if (mAttributes[NL80211_ATTR_VENDOR_DATA]) {
+		vendata = nla_data(mAttributes[NL80211_ATTR_VENDOR_DATA]);
+		datalen = nla_len(mAttributes[NL80211_ATTR_VENDOR_DATA]);
+		if (!vendata) {
+			wpa_printf(MSG_ERROR,"Vendor data not found");
+			return -1;
+		}
+		struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+
+		nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
+				vendata, datalen, NULL);
+
+		attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
+		if (attr) {
+			int len = nla_len(attr);
+			info->flags = os_malloc(len);
+			if (info->flags != NULL) {
+				os_memcpy(info->flags, nla_data(attr), len);
+				info->flags_len = len;
+			}
+		} else {
+			wpa_printf(MSG_ERROR,"VENDOR_ATTR_FEATURE_FLAGS not found");
+		}
+	} else {
+		wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found");
+		status = -1;
+	}
+
+	return status;
+}
+
+/* pack_nlmsg_vendor_feature_hdr() - pack get_features command
+ *
+ * @param drv_nl_msg: nl_msg buffer
+ * @Param drv: nl data
+ * @Param ifname: interface name
+ *
+ * @Returns 0 on Success, error code on invalid response
+ */
+static
+int pack_nlmsg_vendor_feature_hdr(struct nl_msg *drv_nl_msg,
+				  struct wpa_driver_nl80211_data *drv,
+				  char *ifname)
+{
+	int ret;
+	int ifindex;
+
+	genlmsg_put(drv_nl_msg, NL_AUTO_PORT, NL_AUTO_SEQ,
+		    drv->global->nl80211_id, 0, 0,
+		    NL80211_CMD_VENDOR, 0);
+
+	ret = nla_put_u32(drv_nl_msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+	if (ret < 0) {
+		wpa_printf(MSG_ERROR, "Failed to put vendor id");
+		return ret;
+	}
+
+	ret = nla_put_u32(drv_nl_msg, NL80211_ATTR_VENDOR_SUBCMD,
+			  QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES);
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "nl put twt vendor subcmd failed");
+		return ret;
+	}
+
+	if (ifname && (strlen(ifname) > 0))
+		ifindex = if_nametoindex(ifname);
+	else
+		ifindex = if_nametoindex(DEFAULT_IFNAME);
+
+	ret = nla_put_u32(drv_nl_msg, NL80211_ATTR_IFINDEX, ifindex);
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "nl put iface: %s failed", ifname);
+		return ret;
+	}
+	return ret;
+}
+
+/* check_wifi_twt_async_feature() - check if driver supports twt async feature
+ *
+ * @Param drv: nl data
+ * @Param ifname: interface name
+ *
+ * @Returns 1 if twt async feature is supported, 0 otherwise
+ */
+static int check_wifi_twt_async_feature(struct wpa_driver_nl80211_data *drv,
+					char *ifname)
+{
+	struct nl_msg *nlmsg;
+	struct features_info info;
+	int ret;
+
+	if (twt_async_support != -1) {
+		return twt_async_support;
+	}
+
+        nlmsg = nlmsg_alloc();
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR, "nlmg alloc failure");
+		return -ENOMEM;
+	}
+
+	pack_nlmsg_vendor_feature_hdr(nlmsg, drv, ifname);
+	os_memset(&info, 0, sizeof(info));
+	ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+			 features_info_handler, &info);
+
+	if (ret || !info.flags) {
+		nlmsg_free(nlmsg);
+		return 0;
+	}
+
+	if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info)) {
+		twt_async_support = 1;
+	} else {
+		twt_async_support = 0;
+	}
+
+	os_free(info.flags);
+	return twt_async_support;
+}
+
+static int wpa_driver_twt_cmd_handler(struct wpa_driver_nl80211_data *drv,
+				      char *ifname,
+				      enum qca_wlan_twt_operation twt_oper,
+				      char *param, char *buf,
+				      size_t buf_len, int *status)
+{
+	struct nl_msg *twt_nl_msg;
+	struct twt_resp_info reply_info;
+	int ret = 0;
+
+	if (!param) {
+		wpa_printf(MSG_ERROR, "%s:TWT cmd args missing\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!buf) {
+		wpa_printf(MSG_ERROR, "buf is NULL");
+		return -EINVAL;
+	}
+
+	wpa_printf(MSG_DEBUG, "TWT DRIVER cmd: %s", param);
+
+	memset(&reply_info, 0, sizeof(struct twt_resp_info));
+	os_memset(buf, 0, buf_len);
+
+	reply_info.twt_oper = twt_oper;
+	reply_info.reply_buf = buf;
+	reply_info.reply_buf_len = buf_len;
+	reply_info.drv = drv;
+
+	twt_nl_msg = prepare_nlmsg(drv, ifname, NL80211_CMD_VENDOR,
+				   QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT, 0);
+	if (!twt_nl_msg) {
+		ret = -EINVAL;
+		goto err_msg;
+	}
+
+	ret = pack_nlmsg_twt_params(twt_nl_msg, param, twt_oper);
+	if (ret) {
+		nlmsg_free(twt_nl_msg);
+		goto err_msg;
+	}
+
+	switch(twt_oper) {
+	case QCA_WLAN_TWT_GET:
+	case QCA_WLAN_TWT_GET_CAPABILITIES:
+	case QCA_WLAN_TWT_GET_STATS:
+		*status = send_nlmsg((struct nl_sock *)drv->global->nl,
+				     twt_nl_msg, twt_response_handler,
+				     &reply_info);
+		if (*status != 0) {
+			wpa_printf(MSG_ERROR, "Failed to send nlmsg - err %d", *status);
+			ret = -EINVAL;
+		}
+		break;
+	case QCA_WLAN_TWT_CLEAR_STATS:
+		*status = send_nlmsg((struct nl_sock *)drv->global->nl,
+				      twt_nl_msg, NULL, NULL);
+		if (*status != 0) {
+			wpa_printf(MSG_ERROR, "Failed to send nlmsg - err %d", *status);
+			ret = -EINVAL;
+		}
+		break;
+	case QCA_WLAN_TWT_SET:
+	case QCA_WLAN_TWT_TERMINATE:
+	case QCA_WLAN_TWT_SUSPEND:
+	case QCA_WLAN_TWT_RESUME:
+	case QCA_WLAN_TWT_NUDGE:
+	case QCA_WLAN_TWT_SET_PARAM:
+		if(check_wifi_twt_async_feature(drv, ifname) == 0) {
+			wpa_printf(MSG_ERROR, "Asynchronous TWT Feature is missing");
+			ret = -EINVAL;
+		} else {
+			*status = send_nlmsg((struct nl_sock *)drv->global->nl,
+					     twt_nl_msg, NULL, NULL);
+			if (*status != 0) {
+				wpa_printf(MSG_ERROR, "Failed to send nlmsg - err %d", *status);
+				ret = -EINVAL;
+			}
+		}
+		break;
+	default:
+		wpa_printf(MSG_ERROR, "nlmg send failure");
+		ret = -EINVAL;
+		goto err_msg;
+	}
+
+err_msg:
+	wpa_printf(MSG_ERROR, "sent nlmsg - status %d", *status);
+	return ret;
+}
+
+/**
+ * unpack_twt_terminate_event()- unpacks twt_session_terminate response recieved
+ * The response is printed in below format:
+ * CTRL-EVENT-TWT TERMINATE dialog_id <dialog_id> status <status>
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -EINVAL on invalid response
+ */
+static
+int unpack_twt_terminate_event(struct nlattr **tb, char *buf, int buf_len)
+{
+	int cmd_id;
+	u8 val;
+	char temp[TWT_RESP_BUF_LEN];
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+
+	if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+			     tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) {
+		wpa_printf(MSG_ERROR, "nla_parse failed");
+		return -EINVAL;
+	}
+
+	buf = result_copy_to_buf(TWT_TEARDOWN_RESP, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	os_memset(temp, 0, TWT_TEARDOWN_RESP_LEN);
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "%s TWT dialog id missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u8(tb2[cmd_id]);
+		if(val == 255) {
+			val = 0;
+		}
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "%s TWT resp status missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u8(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "status %u ", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val));
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+	*buf = '\0';
+
+	return 0;
+}
+
+/**
+ * unpack_twt_suspend_event()- unpacks twt_session_pause response recieved
+ * The response is printed in below format:
+ * CTRL-EVENT-TWT PAUSE dialog_id <dialog_id> status <status>
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -EINVAL on invalid response
+ */
+static
+int unpack_twt_suspend_event(struct nlattr **tb, char *buf, int buf_len)
+{
+	int cmd_id;
+	u8 val;
+	char temp[TWT_RESP_BUF_LEN];
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+
+	if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+			     tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) {
+		wpa_printf(MSG_ERROR, "nla_parse failed");
+		return -1;
+	}
+
+	buf = result_copy_to_buf(TWT_PAUSE_RESP, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	os_memset(temp, 0, TWT_PAUSE_RESP_LEN);
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "%s TWT dialog id missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u8(tb2[cmd_id]);
+		if(val == 255) {
+			val = 0;
+		}
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "%s TWT resp status missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u8(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "status %u ", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val));
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+	*buf = '\0';
+
+	return 0;
+}
+
+/**
+ * unpack_twt_resume_event()- unpacks twt_session_resume response recieved
+ * The response is printed in below format:
+ * CTRL-EVENT-TWT RESUME dialog_id <dialog_id> status <status>
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -EINVAL on invalid response
+ */
+static
+int unpack_twt_resume_event(struct nlattr **tb, char *buf, int buf_len)
+{
+	int cmd_id;
+	u8 val;
+	char temp[TWT_RESP_BUF_LEN];
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+
+	if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+			     tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) {
+		wpa_printf(MSG_ERROR, "nla_parse failed");
+		return -1;
+	}
+
+	buf = result_copy_to_buf(TWT_RESUME_RESP, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	os_memset(temp, 0, TWT_RESUME_RESP_LEN);
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "%s TWT dialog id missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u8(tb2[cmd_id]);
+		if(val == 255) {
+			val = 0;
+		}
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %u", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
+	if (!tb2[cmd_id]) {
+		wpa_printf(MSG_ERROR, "%s TWT resp status missing", __func__);
+		return -EINVAL;
+	} else {
+		val = nla_get_u8(tb2[cmd_id]);
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "status %u ", val);
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+
+		os_memset(temp, 0, TWT_RESP_BUF_LEN);
+		os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val));
+		buf = result_copy_to_buf(temp, buf, &buf_len);
+		if (!buf)
+			return -EINVAL;
+	}
+	*buf = '\0';
+
+	return 0;
+}
+
+/**
+ * unpack_twt_notify_event()- prints the twt notify response recieved from driver
+ * asynchronously for QCA_WLAN_TWT_SETUP_READY_NOTIFY event.
+ * The response is printed in below format:
+ * CTRL-EVENT-TWT NOTIFY
+ *
+ * @Param tb: vendor nl data
+ * @Param buf: stores the response
+ * @Param buf_len: length of the response buffer
+ *
+ * @Returns 0 on Success, -EINVAL on invalid response
+ */
+int unpack_twt_notify_event(struct nlattr **tb, char *buf, int buf_len)
+{
+	char temp[TWT_RESP_BUF_LEN];
+
+	os_memset(temp, 0, TWT_RESP_BUF_LEN);
+
+	buf = result_copy_to_buf(TWT_NOTIFY_RESP, buf, &buf_len);
+	if (!buf)
+		return -EINVAL;
+
+	*buf = '\0';
+        return 0;
+}
+
+/**
+ * wpa_driver_twt_async_resp_handler()- handler for asynchronous twt vendor event
+ * recieved from the driver.
+ *
+ * @Param drv- wpa_driver_nl80211_data
+ * @Param vendor_id- vendor id for vendor specific command
+ * @Param subcmd- subcmd as defined by enum qca_nl80211_vendor_subcmds
+ * @Param data- vendor data
+ * @Param len- vendor data length
+ *
+ * @Returns 0 for Success, -1 for Failure
+ */
+static int wpa_driver_twt_async_resp_event(struct wpa_driver_nl80211_data *drv,
+					   u32 vendor_id, u32 subcmd, u8 *data, size_t len)
+{
+	int ret = 0;
+	char *buf;
+	buf = (char *)malloc(TWT_RESP_BUF_LEN);
+	int buf_len = TWT_RESP_BUF_LEN;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
+	u8 twt_operation_type;
+
+	if (!buf)
+		return -1;
+
+	ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
+			(struct nlattr *) data, len, NULL);
+	if (ret) {
+		wpa_printf(MSG_ERROR, "nla_parse failed %d", ret);
+		goto fail;
+	}
+
+	if (!buf) {
+		wpa_printf(MSG_ERROR, "buf not allocated");
+		return -1;
+	}
+
+	memset(buf, 0, TWT_RESP_BUF_LEN);
+
+	twt_operation_type = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
+
+	switch(twt_operation_type) {
+	case QCA_WLAN_TWT_SET:
+		ret = unpack_twt_setup_nlmsg(tb, buf, buf_len);
+		break;
+	case QCA_WLAN_TWT_TERMINATE:
+		ret = unpack_twt_terminate_event(tb, buf, buf_len);
+		break;
+	case QCA_WLAN_TWT_SUSPEND:
+		ret = unpack_twt_suspend_event(tb, buf, buf_len);
+		break;
+	case QCA_WLAN_TWT_RESUME:
+		ret = unpack_twt_resume_event(tb, buf, buf_len);
+		break;
+	case QCA_WLAN_TWT_SETUP_READY_NOTIFY:
+		ret = unpack_twt_notify_event(tb, buf, buf_len);
+		break;
+	default:
+		ret = -1;
+	}
+
+	if(ret) {
+		wpa_printf(MSG_ERROR, "Async event parsing failed for operation %d",
+			   twt_operation_type);
+		goto fail;
+	}
+	wpa_printf(MSG_ERROR,"%s", buf);
+	wpa_msg(drv->ctx, MSG_INFO, "%s", buf);
+fail:
+	free(buf);
+	return ret;
+}
+
+static int wpa_driver_form_clear_mcc_quota_msg(struct i802_bss *bss,
+					       char *cmd)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nlattr *nl_attr;
+	struct nl_msg *nlmsg;
+	uint32_t if_index = 0;
+	int ret;
+
+	/* First comes interface name - optional */
+	if (os_strncasecmp(cmd, "iface", 5) == 0) {
+		char *iface;
+		cmd = move_to_next_str(cmd);
+		/* null terminate the iface name in the cmd string */
+		iface = strchr(cmd, ' ');
+		if (iface == NULL) {
+			wpa_printf(MSG_ERROR, "mcc_quota: iface is not found"
+				   " in cmd string");
+			return -EINVAL;
+		}
+		*iface = '\0';
+		iface = cmd;
+		errno = 0;
+		if_index = if_nametoindex(cmd);
+		if (if_index == 0) {
+			wpa_printf(MSG_ERROR, "mcc_quota: iface %s not found %d",
+				   cmd, errno);
+			return -EINVAL;
+		}
+		wpa_printf(MSG_INFO, "mcc_quota: ifindex %u", if_index);
+		cmd += strlen(iface) + 1;
+	}
+
+	nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+				     QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Failed to allocate nl message");
+		return -ENOMEM;
+	}
+
+	nl_attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (!nl_attr) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc nlattr");
+		ret = -ENOMEM;
+		goto fail;
+	}
+	/* Put the quota type */
+	ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE,
+			  QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR);
+	if (ret) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Failed to add type attr %d", ret);
+		goto fail;
+	}
+
+	if (if_index) {
+		ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX, if_index);
+		if (ret) {
+			wpa_printf(MSG_ERROR, "mcc_quota: Failed to add if_index attr %d", ret);
+			goto fail;
+		}
+	}
+	nla_nest_end(nlmsg, nl_attr);
+
+	ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL);
+
+	if (ret) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Error sending nlmsg %d", ret);
+		return ret;
+	}
+
+	return 0;
+fail:
+	nlmsg_free(nlmsg);
+	return ret;
+}
+
+static int wpa_driver_form_set_mcc_quota_msg(struct i802_bss *bss,
+					     char *cmd)
+{
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct mcc_quota mccquota[MCC_QUOTA_ENTRIES_MAX];
+	uint32_t if_index, quota;
+	struct nlattr *nl_attr, *mcc_attr_list;
+	struct nlattr *mcc_attr;
+	struct nl_msg *nlmsg;
+	int ret, entry, i;
+
+	wpa_printf(MSG_INFO, "mcc_quota: %s", cmd);
+
+	entry = 0;
+	while (*cmd != '\0') {
+		if (entry >= MCC_QUOTA_ENTRIES_MAX) {
+			wpa_printf(MSG_INFO, "mcc_quota: Only %d entries accepted", entry);
+			break;
+		}
+		/* First comes interface name */
+		if (os_strncasecmp(cmd, "iface", 5) == 0) {
+			char *iface;
+			cmd = move_to_next_str(cmd);
+			/* null terminate the iface name in the cmd string */
+			iface = strchr(cmd, ' ');
+			if (iface == NULL) {
+				wpa_printf(MSG_ERROR, "mcc_quota: iface is not"
+					   " found in cmd string");
+				return -EINVAL;
+			}
+			*iface = '\0';
+			iface = cmd;
+			errno = 0;
+			if_index = if_nametoindex(cmd);
+			if (if_index == 0) {
+				wpa_printf(MSG_ERROR, "mcc_quota: iface %s not found %d",
+						cmd, errno);
+				return -EINVAL;
+			}
+			wpa_printf(MSG_INFO, "mcc_quota: ifindex %u", if_index);
+			cmd += strlen(iface) + 1;
+		} else {
+			wpa_printf(MSG_ERROR, "mcc_quota: Iface name not in order");
+			return -EINVAL;
+		}
+
+		/* Second comes quota value */
+		if (os_strncasecmp(cmd, "quota", 5) == 0) {
+			cmd = move_to_next_str(cmd);
+			quota = get_u32_from_string(cmd, &ret);
+			if (ret < 0)
+				return ret;
+		} else {
+			wpa_printf(MSG_ERROR, "mcc_quota: Quota not in order");
+			return -EINVAL;
+		}
+
+		if (quota < MCC_QUOTA_MIN || quota > MCC_QUOTA_MAX) {
+			wpa_printf(MSG_ERROR, "mcc_quota: Invalid quota value %u", quota);
+			return -EINVAL;
+		}
+
+		mccquota[entry].if_idx = if_index;
+		mccquota[entry].quota = quota;
+		cmd = move_to_next_str(cmd);
+		entry++;
+	}
+	wpa_printf(MSG_INFO, "mcc_quota: Entries : %d", entry);
+	if (entry < 1) {
+		wpa_printf(MSG_ERROR, "mcc_quota: No valid entries?");
+		return -EINVAL;
+	}
+
+	nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+				     QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR,"mcc_quota: Failed to allocate nl message");
+		return -ENOMEM;
+	}
+
+	nl_attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (nl_attr == NULL) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc nlattr");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* Put the quota type */
+	ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE,
+			  QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED);
+	if (ret) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Failed to add type attr %d", ret);
+		goto fail;
+	}
+
+	mcc_attr_list = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES);
+	if (!mcc_attr_list) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc mcc_attr_list");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	for (i = 0; i < entry  && entry <= MCC_QUOTA_ENTRIES_MAX; i++) {
+		/* Nest the (iface ,quota) */
+		mcc_attr = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES);
+		if (mcc_attr == NULL) {
+			wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc mccattr");
+			ret = -ENOMEM;
+			goto fail;
+		}
+		ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX, mccquota[i].if_idx);
+		if (ret) {
+			wpa_printf(MSG_ERROR, "mcc_quota: Failed to add if_index attr %d", ret);
+			goto fail;
+		}
+
+		ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE, mccquota[i].quota);
+		if (ret) {
+			wpa_printf(MSG_ERROR, "mcc_quota: Failed to add quota attr %d", ret);
+			goto fail;
+		}
+
+		nla_nest_end(nlmsg, mcc_attr);
+	}
+	nla_nest_end(nlmsg, mcc_attr_list);
+
+	nla_nest_end(nlmsg, nl_attr);
+
+	ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL);
+
+	if (ret) {
+		wpa_printf(MSG_ERROR, "mcc_quota: Error sending nlmsg %d", ret);
+		return ret;
+	}
+
+	return 0;
+fail:
+	nlmsg_free(nlmsg);
+	return ret;
+}
+
+int wpa_driver_cmd_send_mcc_quota(struct i802_bss *bss,
+				  char *cmd)
+{
+	int ret;
+
+	wpa_printf(MSG_INFO, "mcc_quota: %s", cmd);
+
+	if (os_strncasecmp(cmd, "set", 3) == 0) {
+		cmd = move_to_next_str(cmd);
+		ret = wpa_driver_form_set_mcc_quota_msg(bss, cmd);
+		return ret;
+	}
+
+	if (os_strncasecmp(cmd, "clear", 5) == 0) {
+		cmd = move_to_next_str(cmd);
+		ret = wpa_driver_form_clear_mcc_quota_msg(bss, cmd);
+		return ret;
+	}
+
+	wpa_printf(MSG_ERROR, "mcc_quota: Unknown operation");
+	return -EINVAL;
+}
+
+static int wpa_driver_form_flush_queue_config_msg(struct i802_bss *bss, char *cmd)
+{
+	uint32_t tid_mask = 0, flush_policy = 0;
+	u8 mac[MAC_ADDR_LEN], ac_mask = 0;
+	struct nl_msg *nlmsg = NULL;
+	struct nlattr *nl_attr;
+	char *ptr = cmd;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "flush_queue_config: %s", cmd);
+
+	/* First parameter: MAC address of peer */
+	if (os_strncasecmp(cmd, "peer", 4) == 0) {
+		cmd = move_to_next_str(cmd);
+		if ((strlen(cmd) < (MAC_ADDR_LEN * 2 + MAC_ADDR_LEN - 1)) ||
+		    convert_string_to_bytes(mac, cmd, MAC_ADDR_LEN) !=
+		    MAC_ADDR_LEN) {
+			wpa_printf(MSG_ERROR, "flush_queue_config: Invalid MAC address");
+			wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+			return -EINVAL;
+		}
+		cmd = move_to_next_str(cmd);
+	} else {
+		wpa_printf(MSG_ERROR, "flush_queue_config: peer MAC address is missing");
+		wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+		return -EINVAL;
+	}
+
+	/* Second parameter: flush config */
+	if (os_strncasecmp(cmd, "policy", 6) == 0) {
+		cmd = move_to_next_str(cmd);
+		flush_policy = get_u32_from_string(cmd, &ret);
+		if (ret < 0) {
+			wpa_printf(MSG_ERROR, "flush_queue_config: Invalid flush policy");
+			wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+			return ret;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	/* Third parameter: Follow QCA_WLAN_VENDOR_ATTR_AC  for ac bit mask */
+	if (os_strncasecmp(cmd, "ac", 2) == 0) {
+		cmd = move_to_next_str(cmd);
+		ac_mask = get_u8_from_string(cmd, &ret);
+		if (ret < 0) {
+			wpa_printf(MSG_ERROR, "flush_queue_config: AC mask error");
+			wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+			return ret;
+		}
+
+		if (!(ac_mask & (BIT(QCA_WLAN_VENDOR_TOS_BK) | BIT(QCA_WLAN_VENDOR_TOS_BE) |
+				 BIT(QCA_WLAN_VENDOR_TOS_VI) | BIT(QCA_WLAN_VENDOR_TOS_VO)))) {
+			wpa_printf(MSG_ERROR, "flush_queue_config: Invalid AC mask");
+			wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+			return -EINVAL;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	/* Fourth parameter: tid mask */
+	if (os_strncasecmp(cmd, "tid", 3) == 0) {
+		cmd = move_to_next_str(cmd);
+		tid_mask = get_u32_from_string(cmd, &ret);
+		if (ret < 0) {
+			wpa_printf(MSG_ERROR, "flush_queue_config: TID mask error");
+			wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+			return ret;
+		}
+		cmd = move_to_next_str(cmd);
+	}
+
+	if (!tid_mask && !ac_mask) {
+		wpa_printf(MSG_ERROR, "flush_queue_config: Neither TID not AC mask provided");
+		wpa_printf(MSG_ERROR, "flush_queue_config cmd: %s", ptr);
+		return -EINVAL;
+	}
+
+	nlmsg =
+	prepare_vendor_nlmsg(bss->drv, bss->ifname,
+			     QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING);
+	if (!nlmsg) {
+		wpa_printf(MSG_ERROR, "flush_queue_config: Failed to allocate nl message");
+		return -ENOMEM;
+	}
+
+	nl_attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+	if (!nl_attr) {
+		wpa_printf(MSG_ERROR, "flush_queue_config: Failed to alloc nlattr");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* Put the peer MAC address */
+	ret = nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_ADDR, MAC_ADDR_LEN, mac);
+	if (ret) {
+		wpa_printf(MSG_ERROR, "flush_queue_config: Error add hw addr attr %d", ret);
+		goto fail;
+	}
+
+	/* Put the flush_policy */
+	ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY,
+			  flush_policy);
+	if (ret) {
+		wpa_printf(MSG_ERROR,
+			   "flush_queue_config: Error add policy attr %d", ret);
+		goto fail;
+	}
+
+	if (tid_mask) {
+		/* Put the tid mask */
+		ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TID_MASK,
+				  tid_mask);
+		if (ret) {
+			wpa_printf(MSG_ERROR, "flush_queue_config: Error add tid mask attr %d", ret);
+			goto fail;
+		}
+	} else {
+		/* Put the ac mask */
+		ret = nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_AC, ac_mask);
+		if (ret) {
+			wpa_printf(MSG_ERROR, "flush_queue_config: Error add ac attr %d", ret);
+			goto fail;
+		}
+	}
+
+	nla_nest_end(nlmsg, nl_attr);
+	ret = send_nlmsg((struct nl_sock *)bss->drv->global->nl, nlmsg,
+			 NULL, NULL);
+	if (ret) {
+		wpa_printf(MSG_ERROR, "flush_queue_config: Error sending nlmsg %d", ret);
+		return ret;
+	}
+	return 0;
+fail:
+	if (nlmsg)
+		nlmsg_free(nlmsg);
+	return ret;
+}
+
+int wpa_driver_cmd_send_peer_flush_queue_config(struct i802_bss *bss, char *cmd)
+{
+	int ret;
+
+	if (os_strncasecmp(cmd, "set", 3) == 0) {
+		cmd = move_to_next_str(cmd);
+		ret = wpa_driver_form_flush_queue_config_msg(bss, cmd);
+		return ret;
+	}
+
+	wpa_printf(MSG_ERROR, "peer_flush_config: Unknown operation");
+	return -EINVAL;
+}
+
+int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
+				  size_t buf_len )
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = NULL;
+	struct wpa_driver_nl80211_data *driver;
+	struct ifreq ifr;
+	android_wifi_priv_cmd priv_cmd;
+	int ret = 0, status = 0, lib_n = 0;
+
+	if (bss) {
+		drv = bss->drv;
+	} else {
+		if (os_strncasecmp(cmd, "SET_AP_SUSPEND", 14)) {
+			wpa_printf(MSG_ERROR, "%s: bss is NULL for cmd %s\n",
+				   __func__, cmd);
+			return -EINVAL;
+		}
+	}
+
+	if (wpa_driver_oem_initialize(&oem_cb_table) != WPA_DRIVER_OEM_STATUS_FAILURE &&
+	    oem_cb_table) {
+
+		for (lib_n = 0;
+		     oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb != NULL;
+		     lib_n++)
+		{
+			ret = oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb(
+					priv, cmd, buf, buf_len, &status);
+			if (ret == WPA_DRIVER_OEM_STATUS_SUCCESS ) {
+				return strlen(buf);
+			} else if (ret == WPA_DRIVER_OEM_STATUS_ENOSUPP) {
+				continue;
+			} else if ((ret == WPA_DRIVER_OEM_STATUS_FAILURE) &&
+				   (status != 0)) {
+				wpa_printf(MSG_DEBUG, "%s: Received error: %d",
+						__func__, status);
+				return status;
+			}
+		}
+		/* else proceed with legacy handling as below */
+	}
+
+	if (!drv) {
+		wpa_printf(MSG_ERROR, "%s: drv is NULL for cmd %s\n",
+			   __func__, cmd);
+		return -EINVAL;
+	}
+
+	if (os_strcasecmp(cmd, "START") == 0) {
+		dl_list_for_each(driver, &drv->global->interfaces, struct wpa_driver_nl80211_data, list) {
+			linux_set_iface_flags(drv->global->ioctl_sock, driver->first_bss->ifname, 1);
+			wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+		}
+	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
+		u8 macaddr[ETH_ALEN] = {};
+
+		ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
+		if (!ret)
+			ret = os_snprintf(buf, buf_len,
+					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
+	} else if (os_strncasecmp(cmd, "SET_CONGESTION_REPORT ", 22) == 0) {
+		return wpa_driver_cmd_set_congestion_report(priv, cmd + 22);
+	} else if (os_strncasecmp(cmd, "SET_TXPOWER ", 12) == 0) {
+		return wpa_driver_cmd_set_tx_power(priv, cmd + 12);
+	} else if (os_strncasecmp(cmd, "CSI", 3) == 0) {
+		cmd += 3;
+		return wpa_driver_handle_csi_cmd(bss, cmd, buf, buf_len, &status);
+	} else if(os_strncasecmp(cmd, "GETSTATSBSSINFO", 15) == 0) {
+
+		struct resp_info info,info2;
+		struct nl_msg *nlmsg;
+		struct nlattr *attr;
+
+		os_memset(&g_bss_info, 0, sizeof(struct bss_info));
+
+		memset(&info, 0, sizeof(struct resp_info));
+		memset(&info2, 0, sizeof(struct resp_info));
+
+		info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION;
+		info.cmd_type = GETSTATSBSSINFO;
+		char *p;
+		if(wpa_driver_ioctl(bss, "GETCOUNTRYREV", buf, buf_len, &status, drv) == 0){
+			p = strstr(buf, " ");
+			if(p != NULL)
+				memcpy(info.country, (p+1), strlen(p+1)+1);//length of p including null
+		}
+		cmd += 16;
+		os_memset(buf, 0, buf_len);
+
+		u8 mac[MAC_ADDR_LEN];
+
+		cmd = skip_white_space(cmd);
+
+		if (strlen(cmd) >= MAC_ADDR_LEN * 2 + MAC_ADDR_LEN - 1
+		    && convert_string_to_bytes(mac, cmd, MAC_ADDR_LEN) > 0) {
+			wpa_printf(MSG_INFO,"invoking QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO to retrieve new attributes");
+			os_memcpy(&info2.mac_addr[0], mac, MAC_ADDR_LEN);
+			nlmsg = prepare_vendor_nlmsg(bss->drv, bss->ifname,
+						     QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO);
+			if (!nlmsg) {
+				wpa_printf(MSG_ERROR,"Failed to allocate nl message");
+				return -1;
+			}
+
+			attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA);
+			if (!attr) {
+				nlmsg_free(nlmsg);
+				return -1;
+			}
+
+			if (nla_put(nlmsg, GET_STA_INFO_MAC,
+				    MAC_ADDR_LEN, mac)) {
+				wpa_printf(MSG_ERROR,"Failed to put GET_STA_INFO_MAC");
+				nlmsg_free(nlmsg);
+				return -1;
+			}
+
+			nla_nest_end(nlmsg, attr);
+
+			ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+					     get_sta_info_handler, &info2);
+			if (ret != 0) {
+				if (ret == -EOPNOTSUPP) {
+					wpa_printf(MSG_INFO,"Command is not supported, sending -1 for all new vendor attributes");
+				} else {
+					wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", ret);
+					return -1;
+				}
+				g_bss_info.ani_level = -1;
+				g_bss_info.roam_trigger_reason = -1;
+				g_bss_info.roam_fail_reason = -1;
+				g_bss_info.roam_invoke_fail_reason = -1;
+				g_bss_info.tsf_out_of_sync_count = -1;
+				g_bss_info.latest_tx_power = -1;
+				g_bss_info.latest_tx_rate = -1;
+				g_bss_info.target_power_24g_1mbps = -1;
+				g_bss_info.target_power_24g_6mbps = -1;
+				g_bss_info.target_power_5g_6mbps = -1;
+			} else {
+				wpa_printf(MSG_INFO,"Command successfully invoked");
+				g_bss_info.ani_level = g_sta_info.ani_level;
+				g_bss_info.roam_trigger_reason = g_sta_info.roam_trigger_reason;
+				g_bss_info.roam_fail_reason = g_sta_info.roam_fail_reason;
+				g_bss_info.roam_invoke_fail_reason = g_sta_info.roam_invoke_fail_reason;
+				g_bss_info.tsf_out_of_sync_count = g_sta_info.tsf_out_of_sync_count;
+				g_bss_info.latest_tx_power = g_sta_info.latest_tx_power;
+				g_bss_info.latest_tx_rate = g_sta_info.latest_tx_rate;
+				g_bss_info.target_power_24g_1mbps = g_sta_info.target_power_24g_1mbps;
+				g_bss_info.target_power_24g_6mbps = g_sta_info.target_power_24g_6mbps;
+				g_bss_info.target_power_5g_6mbps = g_sta_info.target_power_5g_6mbps;
+			}
+		}
+
+		info.reply_buf = buf;
+		info.reply_buf_len = buf_len;
+
+		nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+					     info.subcmd);
+		if (!nlmsg) {
+			wpa_printf(MSG_ERROR,"Failed to allocate nl message");
+			return -1;
+		}
+
+		if (populate_nlmsg(nlmsg, cmd, info.cmd_type)) {
+			wpa_printf(MSG_ERROR,"Failed to populate nl message");
+			nlmsg_free(nlmsg);
+			return -1;
+		}
+
+		status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+				     response_handler, &info);
+		if (status != 0) {
+			wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", status);
+			return -1;
+		}
+
+		return strlen(info.reply_buf);
+	} else if (os_strncasecmp(cmd, "GETSTATSSTAINFO", 15) == 0) {
+		cmd += 15;
+		return wpa_driver_handle_get_sta_info(bss, cmd, buf, buf_len,
+						      &status);
+	} else if (os_strncasecmp(cmd, "SETCELLSWITCHMODE", 17) == 0) {
+		cmd += 17;
+		struct resp_info info;
+		struct nl_msg *nlmsg;
+
+		memset(&info, 0, sizeof(struct resp_info));
+
+		info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM;
+		info.cmd_type = SETCELLSWITCHMODE;
+
+		nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+					     info.subcmd);
+		if (!nlmsg) {
+			wpa_printf(MSG_ERROR,"Failed to allocate nl message");
+			return WPA_DRIVER_OEM_STATUS_FAILURE;
+		}
+
+		if (populate_nlmsg(nlmsg, cmd, info.cmd_type)) {
+			wpa_printf(MSG_ERROR,"Failed to populate nl message");
+			nlmsg_free(nlmsg);
+			return WPA_DRIVER_OEM_STATUS_FAILURE;
+		}
+
+		status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+				     NULL, NULL);
+		if (status != 0) {
+			wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", status);
+			return WPA_DRIVER_OEM_STATUS_FAILURE;
+		}
+
+		return WPA_DRIVER_OEM_STATUS_SUCCESS;
+	} else if (os_strncasecmp(cmd, "SET_ANI_LEVEL ", 14) == 0) {
+		char *endptr = NULL;
+		int mode = 0;
+		int ofdmlvl = 0;
+		mode = strtol(cmd + 14, &endptr, 10);
+		if (mode == 1) {
+			if(!(*endptr)) {
+				wpa_printf(MSG_ERROR, "%s: failed to set ani setting,\
+			          invalid cmd: %s\n", __func__, cmd);
+				return -EINVAL;
+			}
+			ofdmlvl = strtol(endptr, NULL, 10);
+		}
+		return wpa_driver_cmd_set_ani_level(priv, mode, ofdmlvl);
+	} else if (os_strncasecmp(cmd, "GET_THERMAL_INFO", 16) == 0) {
+		int temperature = -1;
+		int thermal_state = -1;
+		int ret, ret2;
+
+		ret = wpa_driver_cmd_get_thermal_info(priv, &temperature,
+		    QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE);
+		if (ret)
+			return -1;
+		ret2 = wpa_driver_cmd_get_thermal_info(priv, &thermal_state,
+		    QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL);
+		if (ret2)
+			return -1;
+
+		snprintf(buf, buf_len, "%d %d", temperature, thermal_state);
+		return strlen(buf);
+	} else if (os_strncasecmp(cmd, "GET_DRIVER_SUPPORTED_FEATURES", 29) == 0) {
+		struct resp_info info;
+		struct nl_msg *nlmsg;
+		memset(&info, 0, sizeof(struct resp_info));
+		info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES;
+		os_memset(buf, 0, buf_len);
+		info.reply_buf = buf;
+		info.reply_buf_len = buf_len;
+		nlmsg = prepare_vendor_nlmsg(drv, bss->ifname,
+		                             info.subcmd);
+		if (!nlmsg) {
+		        wpa_printf(MSG_ERROR,"Failed to allocate nl message");
+		        return -1;
+		}
+
+		status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg,
+		                     response_handler, &info);
+		if (status != 0) {
+		        wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", status);
+		        return -1;
+		}
+
+		return WPA_DRIVER_OEM_STATUS_SUCCESS;
+	} else if ((ret = check_for_twt_cmd(&cmd)) != TWT_CMD_NOT_EXIST) {
+		enum qca_wlan_twt_operation twt_oper = ret;
+		u8 is_twt_feature_supported = 0;
+
+		if (oem_cb_table) {
+			for (lib_n = 0;
+			     oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb != NULL;
+			     lib_n++)
+			{
+				if (oem_cb_table[lib_n].wpa_driver_oem_feature_check_cb) {
+					if (oem_cb_table[lib_n].wpa_driver_oem_feature_check_cb(FEATURE_TWT_SUPPORT))
+						is_twt_feature_supported = 1;
+						break;
+				}
+			}
+		}
+
+		if (is_twt_feature_supported) {
+			wpa_printf(MSG_ERROR, "%s: TWT feature already supported by oem lib %d\n", __func__, lib_n);
+			ret = -EINVAL;
+		} else {
+			ret = wpa_driver_twt_cmd_handler(drv, bss->ifname, twt_oper, cmd, buf, buf_len,
+							 &status);
+			if (ret)
+				ret = os_snprintf(buf, buf_len, "TWT failed for operation %d", twt_oper);
+		}
+	} else if (os_strncasecmp(cmd, "MCC_QUOTA", 9) == 0) {
+		/* DRIVER MCC_QUOTA set iface <name> quota <val>
+		 * DRIVER MCC_QUOTA clear iface <name>
+		 */
+		/* Move cmd by string len and space */
+		cmd += 10;
+		return wpa_driver_cmd_send_mcc_quota(priv, cmd);
+	} else if (os_strncasecmp(cmd, "FLUSH_QUEUE_CONFIG", 18) == 0) {
+		/* DRIVER FLUSH_QUEUE_CONFIG set peer <mac addr> policy <val>
+		 * tid <tid mask> ac <ac mask>
+		 */
+		/* Move cmd by string len and space */
+		cmd += 19;
+		return wpa_driver_cmd_send_peer_flush_queue_config(priv, cmd);
+	} else { /* Use private command */
+		memset(&ifr, 0, sizeof(ifr));
+		memset(&priv_cmd, 0, sizeof(priv_cmd));
+		os_memcpy(buf, cmd, strlen(cmd) + 1);
+		os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
+
+		priv_cmd.buf = buf;
+		priv_cmd.used_len = buf_len;
+		priv_cmd.total_len = buf_len;
+		ifr.ifr_data = &priv_cmd;
+
+		if ((ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
+			wpa_printf(MSG_ERROR, "%s: failed to issue private commands, ret:%d, errno:%d\n", __func__, ret, errno);
+		} else {
+			drv_errors = 0;
+			if((os_strncasecmp(cmd, "SETBAND", 7) == 0) &&
+				ret == DO_NOT_SEND_CHANNEL_CHANGE_EVENT) {
+				return 0;
+			}
+
+			ret = 0;
+			if ((os_strcasecmp(cmd, "LINKSPEED") == 0) ||
+			    (os_strcasecmp(cmd, "RSSI") == 0) ||
+			    (os_strstr(cmd, "GET") != NULL))
+				ret = strlen(buf);
+			else if (os_strcasecmp(cmd, "P2P_DEV_ADDR") == 0)
+				wpa_printf(MSG_DEBUG, "%s: P2P: Device address ("MACSTR")",
+					__func__, MAC2STR(buf));
+			else if (os_strcasecmp(cmd, "P2P_SET_PS") == 0)
+				wpa_printf(MSG_DEBUG, "%s: P2P: %s ", __func__, buf);
+			else if (os_strcasecmp(cmd, "P2P_SET_NOA") == 0)
+				wpa_printf(MSG_DEBUG, "%s: P2P: %s ", __func__, buf);
+			else if (os_strcasecmp(cmd, "STOP") == 0) {
+				wpa_printf(MSG_DEBUG, "%s: %s ", __func__, buf);
+				dl_list_for_each(driver, &drv->global->interfaces, struct wpa_driver_nl80211_data, list) {
+					linux_set_iface_flags(drv->global->ioctl_sock, driver->first_bss->ifname, 0);
+					wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+				}
+			}
+			else
+				wpa_printf(MSG_DEBUG, "%s %s len = %d, %zu", __func__, buf, ret, buf_len);
+			wpa_driver_notify_country_change(drv->ctx, cmd);
+		}
+	}
+	return ret;
+}
+
+int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration)
+{
+	char buf[MAX_DRV_CMD_SIZE];
+	char reply_buf[MAX_DRV_CMD_SIZE];
+
+	memset(buf, 0, sizeof(buf));
+	memset(reply_buf, 0, sizeof(reply_buf));
+	wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
+	snprintf(buf, sizeof(buf), "P2P_SET_NOA %d %d %d", count, start, duration);
+	return wpa_driver_nl80211_driver_cmd(priv, buf, reply_buf, sizeof(reply_buf));
+}
+
+int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len)
+{
+	UNUSED(priv), UNUSED(buf), UNUSED(len);
+	/* Return 0 till we handle p2p_presence request completely in the driver */
+	return 0;
+}
+
+int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow)
+{
+	char buf[MAX_DRV_CMD_SIZE];
+	char reply_buf[MAX_DRV_CMD_SIZE];
+
+	memset(buf, 0, sizeof(buf));
+	memset(reply_buf, 0, sizeof(reply_buf));
+	wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
+	snprintf(buf, sizeof(buf), "P2P_SET_PS %d %d %d", legacy_ps, opp_ps, ctwindow);
+	return wpa_driver_nl80211_driver_cmd(priv, buf, reply_buf, sizeof(reply_buf));
+}
+
+int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
+				 const struct wpabuf *proberesp,
+				 const struct wpabuf *assocresp)
+{
+	UNUSED(priv), UNUSED(beacon), UNUSED(proberesp), UNUSED(assocresp);
+	return 0;
+}
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c
new file mode 100644
index 0000000..7df7166
--- /dev/null
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c
@@ -0,0 +1,185 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *
+ *    * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <netlink/object-api.h>
+#include <linux/pkt_sched.h>
+#include <dlfcn.h>
+#include <dirent.h>
+#include <string.h>
+#include "common.h"
+#include "driver_cmd_nl80211_extn.h"
+
+#define QCA_NL80211_VENDOR_SUBCMD_DIAG_DATA 201
+#define MAX_OEM_LIBS 5
+#define MAX_LIB_NAME_SIZE 30
+#define CB_SUFFIX "_cb"
+static wpa_driver_oem_cb_table_t oem_cb_array[MAX_OEM_LIBS + 1];
+
+void wpa_msg_handler(struct wpa_driver_nl80211_data *drv, char *msg, u32 subcmd) {
+    if (subcmd == QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
+	wpa_msg(drv->ctx, MSG_INFO, "%s", msg);
+    }
+}
+
+int wpa_driver_oem_initialize(wpa_driver_oem_cb_table_t **oem_cb_table)
+{
+	wpa_driver_oem_get_cb_table_t *get_oem_table;
+	wpa_driver_oem_cb_table_t *oem_cb_table_local;
+	struct dirent *entry;
+	void *oem_handle_n;
+	char cb_sym_name[MAX_LIB_NAME_SIZE], *tmp;
+	DIR *oem_lib_dir;
+	unsigned int lib_n;
+#ifdef ANDROID
+#if __WORDSIZE == 64
+	char *oem_lib_path = "/vendor/lib64/";
+#else
+	char *oem_lib_path  = "/vendor/lib/";
+#endif
+#else
+	char *oem_lib_path  = "/usr/lib/";
+#endif
+	/* Return the callback table if it is already initialized*/
+	if (*oem_cb_table)
+		return WPA_DRIVER_OEM_STATUS_SUCCESS;
+
+	for (lib_n = 0; lib_n < MAX_OEM_LIBS; lib_n++) {
+		oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb = NULL;
+		oem_cb_array[lib_n].wpa_driver_nl80211_driver_oem_event = NULL;
+		oem_cb_array[lib_n].wpa_driver_oem_feature_check_cb = NULL;
+	}
+
+	oem_lib_dir = opendir(oem_lib_path);
+	if (!oem_lib_dir) {
+		wpa_printf(MSG_ERROR, "%s: Unable to open %s", __FUNCTION__, oem_lib_path);
+		return WPA_DRIVER_OEM_STATUS_FAILURE;
+	}
+
+	lib_n = 0;
+	while((entry = readdir(oem_lib_dir)) != NULL) {
+		if (strncmp(entry->d_name, "libwpa_drv_oem", 14))
+			continue;
+
+		wpa_printf(MSG_DEBUG, "%s: Opening lib %s", __FUNCTION__, entry->d_name);
+		oem_handle_n = dlopen(entry->d_name, RTLD_NOW);
+
+		if (!oem_handle_n) {
+			wpa_printf(MSG_ERROR, "%s: Could not load %s", __FUNCTION__, entry->d_name);
+			/* let's not worry much, continue with others */
+			continue;
+		}
+
+		if (strlen(entry->d_name)  >= (sizeof(cb_sym_name) - sizeof(CB_SUFFIX))) {
+			wpa_printf(MSG_ERROR, "%s: libname (%s) too lengthy", __FUNCTION__, entry->d_name);
+			continue;
+		}
+
+		os_strlcpy(cb_sym_name, entry->d_name, sizeof(cb_sym_name));
+		tmp = strchr(cb_sym_name, '.');
+		if (!tmp) {
+			wpa_printf(MSG_ERROR, "%s: libname (%s) incorrect?", __FUNCTION__, entry->d_name);
+			continue;
+		}
+
+		os_strlcpy(tmp, CB_SUFFIX, sizeof(CB_SUFFIX));
+		wpa_printf(MSG_DEBUG, "%s: Loading sym %s", __FUNCTION__, cb_sym_name);
+
+		/* Get the lib's function table callback */
+		get_oem_table = (wpa_driver_oem_get_cb_table_t *)dlsym(oem_handle_n,
+				cb_sym_name);
+
+		if (!get_oem_table) {
+			wpa_printf(MSG_ERROR, "%s: Could not get sym table", __FUNCTION__);
+			continue;
+		}
+
+		oem_cb_table_local = get_oem_table();
+
+		oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb =
+			oem_cb_table_local->wpa_driver_driver_cmd_oem_cb;
+		oem_cb_array[lib_n].wpa_driver_nl80211_driver_oem_event =
+			oem_cb_table_local->wpa_driver_nl80211_driver_oem_event;
+		oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb =
+			oem_cb_table_local->wpa_driver_driver_wpa_msg_oem_cb;
+		oem_cb_array[lib_n].wpa_driver_oem_feature_check_cb =
+			oem_cb_table_local->wpa_driver_oem_feature_check_cb;
+
+		/* Register wpa message callback with the oem library */
+		if(oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb) {
+			oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb(wpa_msg_handler);
+		}
+
+		lib_n++;
+
+		if (lib_n == MAX_OEM_LIBS) {
+			wpa_printf(MSG_DEBUG, "%s: Exceeded max libs %d", __FUNCTION__, lib_n);
+			break;
+		}
+	}
+
+	oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb = NULL;
+	*oem_cb_table = oem_cb_array;
+	wpa_printf(MSG_DEBUG, "%s: OEM lib initialized\n", __func__);
+	closedir(oem_lib_dir);
+
+	return WPA_DRIVER_OEM_STATUS_SUCCESS;
+}
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.h b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.h
new file mode 100755
index 0000000..6246602
--- /dev/null
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.h
@@ -0,0 +1,99 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *
+ *    * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef __DRIVER_CMD_NL80211_EXTN__
+#define __DRIVER_CMD_NL80211_EXTN__
+
+#include "qca-vendor_copy.h"
+#include <stdbool.h>
+#include <sys/types.h>
+#include "driver_nl80211.h"
+
+
+#define IFNAMSIZ 16
+
+enum wpa_driver_oem_status {
+	WPA_DRIVER_OEM_STATUS_SUCCESS = 0,
+	WPA_DRIVER_OEM_STATUS_FAILURE = -1,
+	WPA_DRIVER_OEM_STATUS_ENOSUPP = -2,
+};
+
+#define FEATURE_TWT_SUPPORT	0x0001
+
+/*
+ * This structure is a table of function pointers to the functions
+ * used by the wpa_supplicant_lib to interface with oem specific APIs
+ */
+typedef struct
+{
+    int (*wpa_driver_driver_cmd_oem_cb)(void *priv,
+			char *cmd, char *buf, size_t buf_len, int *status);
+    int (*wpa_driver_nl80211_driver_oem_event)(struct wpa_driver_nl80211_data *drv,
+                                u32 vendor_id, u32 subcmd, u8 *data, size_t len);
+    void (*wpa_driver_driver_wpa_msg_oem_cb)(void(*)(struct wpa_driver_nl80211_data *drv,
+								  char *msg, u32 subcmd));
+    int (*wpa_driver_oem_feature_check_cb)(u32 feature);
+} wpa_driver_oem_cb_table_t;
+
+typedef wpa_driver_oem_cb_table_t* (wpa_driver_oem_get_cb_table_t)();
+
+int wpa_driver_oem_initialize(wpa_driver_oem_cb_table_t **oem_lib_params);
+#endif
diff --git a/qcwcn/wifi_hal/qca-vendor_copy.h b/wcn6740/qcwcn/wpa_supplicant_8_lib/qca-vendor_copy.h
similarity index 79%
copy from qcwcn/wifi_hal/qca-vendor_copy.h
copy to wcn6740/qcwcn/wpa_supplicant_8_lib/qca-vendor_copy.h
index 11442ee..40b0cd4 100644
--- a/qcwcn/wifi_hal/qca-vendor_copy.h
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/qca-vendor_copy.h
@@ -1,7 +1,7 @@
 /*
  * Qualcomm Atheros OUI and vendor specific assignments
  * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
- * Copyright (c) 2018-2019, The Linux Foundation
+ * Copyright (c) 2018-2021, The Linux Foundation
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -512,7 +512,9 @@
  * @QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG: This command is used to
  *	configure parameters per peer to capture Channel Frequency Response
  *	(CFR) and enable Periodic CFR capture. The attributes for this command
- *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr.
+ *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr. This command
+ *	can also be used to send CFR data from the driver to userspace when
+ *	netlink events are used to send CFR data.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: Event to indicate changes
  *	in throughput dynamically. The driver estimates the throughput based on
@@ -620,7 +622,14 @@
  *	This new command is alternative to existing command
  *	QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY since existing command/event
  *	is using stream of bytes instead of structured data using vendor
- *	attributes.
+ *	attributes. User space sends unsafe frequency ranges to the driver using
+ *	a nested attribute %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE. On
+ *	reception of this command, the driver shall check if an interface is
+ *	operating on an unsafe frequency and the driver shall try to move to a
+ *	safe channel when needed. If the driver is not able to find a safe
+ *	channel the interface can keep operating on an unsafe channel with the
+ *	TX power limit derived based on internal configurations	like
+ *	regulatory/SAR rules.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE: This vendor subcommand is used to
  *	add the STA node details in driver/firmware. Attributes for this event
@@ -664,36 +673,121 @@
  *	qca_wlan_vendor_attr_driver_disconnect_reason.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC: This vendor subcommand is used to
- *     add/delete TSPEC for each AC. One command is for one specific AC only.
- *     This command can only be used in STA mode and the STA must be
- *     associated with an AP when the command is issued. Uses attributes
- *     defined in enum qca_wlan_vendor_attr_config_tspec.
+ *	add/delete TSPEC for each AC. One command is for one specific AC only.
+ *	This command can only be used in STA mode and the STA must be
+ *	associated with an AP when the command is issued. Uses attributes
+ *	defined in enum qca_wlan_vendor_attr_config_tspec.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT: Vendor subcommand to configure TWT.
- *     Uses attributes defined in enum qca_wlan_vendor_attr_config_twt.
+ *	Uses attributes defined in enum qca_wlan_vendor_attr_config_twt.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_GETBAND: Command to get the enabled band(s) from
- *     the driver. The band configurations obtained are referred through
- *     QCA_WLAN_VENDOR_ATTR_SETBAND_MASK.
+ *	the driver. The band configurations obtained are referred through
+ *	QCA_WLAN_VENDOR_ATTR_SETBAND_MASK.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS: Vendor subcommand/event for medium
- *     assessment.
- *     Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess.
+ *	assessment.
+ *	Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID: This acts as a vendor event and is
- *     used to update SSID information in hostapd when it is updated in the
- *     driver. Uses the attribute NL80211_ATTR_SSID.
+ *	used to update SSID information in hostapd when it is updated in the
+ *	driver. Uses the attribute NL80211_ATTR_SSID.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS: This vendor subcommand is used by
- *     the driver to send opaque data from the firmware to userspace. The
- *     driver sends an event to userspace whenever such data is received from
- *     the firmware.
+ *	the driver to send opaque data from the firmware to userspace. The
+ *	driver sends an event to userspace whenever such data is received from
+ *	the firmware.
  *
- *     QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to
- *     send this opaque data for this event.
+ *	QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to
+ *	send this opaque data for this event.
  *
- *     The format of the opaque data is specific to the particular firmware
- *     version and there is no guarantee of the format remaining same.
+ *	The format of the opaque data is specific to the particular firmware
+ *	version and there is no guarantee of the format remaining same.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS: This acts as an event.
+ *	The host driver selects Tx VDEV, and notifies user. The attributes
+ *	used with this event are defined in enum
+ *	qca_wlan_vendor_attr_mbssid_tx_vdev_status.
+ *	This event contains Tx VDEV group information, other VDEVs
+ *	interface index, and status information.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY: Vendor command to
+ *	configure the concurrent session policies when multiple STA interfaces
+ *	are (getting) active. The attributes used by this command are defined
+ *	in enum qca_wlan_vendor_attr_concurrent_sta_policy.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS: Userspace can use this command
+ *	to query usable channels for different interface types such as STA,
+ *	AP, P2P GO, P2P Client, NAN, etc. The driver shall report all usable
+ *	channels in the response based on country code, different static
+ *	configurations, concurrency combinations, etc. The attributes used
+ *	with this command are defined in
+ *	enum qca_wlan_vendor_attr_usable_channels.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY: This vendor subcommand is used
+ *	to get DFS radar history from the driver to userspace. The driver
+ *	returns QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES attribute with an
+ *	array of nested entries.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD: Userspace can use this command to
+ *	enable/disable mDNS offload to the firmware. The attributes used with
+ *	this command are defined in enum qca_wlan_vendor_attr_mdns_offload.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used
+ *	to set packet monitor mode that aims to send the specified set of TX and
+ *	RX frames on the current client interface to an active monitor
+ *	interface. If this monitor mode is set, the driver will send the
+ *	configured frames, from the interface on which the command is issued, to
+ *	an active monitor interface. The attributes used with this command are
+ *	defined in enum qca_wlan_vendor_attr_set_monitor_mode.
+ *
+ *	Though the monitor mode is configured for the respective
+ *	Data/Management/Control frames, it is up to the respective WLAN
+ *	driver/firmware/hardware designs to consider the possibility of sending
+ *	these frames over the monitor interface. For example, the Control frames
+ *	are handled within the hardware and thus passing such frames over the
+ *	monitor interface is left to the respective designs.
+ *
+ *	Also, this monitor mode is governed to behave accordingly in
+ *	suspend/resume states. If the firmware handles any of such frames in
+ *	suspend state without waking up the host and if the monitor mode is
+ *	configured to notify all such frames, the firmware is expected to resume
+ *	the host and forward the respective frames to the monitor interface.
+ *	Please note that such a request to get the frames over the monitor
+ *	interface will have a definite power implication.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both
+ *	as a request to set the driver/firmware with the parameters to trigger
+ *	the roaming events, and also used by the driver/firmware to pass on the
+ *	various roam events to userspace.
+ *	Applicable only for the STA mode. The attributes used with this command
+ *	are defined in enum qca_wlan_vendor_attr_roam_events.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG: Subcommand to set or reset the
+ *	rate mask config for a list of PHY types. Userspace shall provide an
+ *	array of the vendor attributes defined in
+ *	enum qca_wlan_vendor_attr_ratemask_params.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA: Multi-channel Concurrency (MCC) occurs
+ *	when two interfaces are active on the same band, using two different
+ *	home channels, and only supported by a single radio. In this scenario
+ *	the device must split the use of the radio between the two interfaces.
+ *	The percentage of time allocated to a given interface is the quota.
+ *	Depending on the configuration, the quota can either be fixed or
+ *	dynamic.
+ *
+ *	When used as an event, the device will report the quota type, and for
+ *	all interfaces operating in MCC it will report the current quota.
+ *	When used as a command, the device can be configured for a specific
+ *	quota type, and in the case of a fixed quota, the quota to apply to one
+ *	of the interfaces.
+ *
+ *	Applications can use the event to do TX bitrate control based on the
+ *	information, and can use the command to explicitly set the quota to
+ *	enhance performance in specific scenarios.
+ *
+ *	The attributes used with this command are defined in
+ *	enum qca_wlan_vendor_attr_mcc_quota.
  */
 enum qca_nl80211_vendor_subcmds {
 	QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@@ -879,6 +973,16 @@
 	QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS = 193,
 	QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID = 194,
 	QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS = 195,
+	QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS = 196,
+	QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY = 197,
+	QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198,
+	QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY = 199,
+	QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD = 200,
+	/* 201 - reserved for QCA */
+	QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202,
+	QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203,
+	QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG = 204,
+	QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA = 205,
 };
 
 enum qca_wlan_vendor_attr {
@@ -1117,7 +1221,7 @@
  * @QCA_ROAM_REASON_CONGESTION: Roam triggered considering the connected channel
  * or environment being very noisy or congested.
  *
- * @QCA_ROAM_REASON_EXPLICIT_REQUEST: Roam triggered due to an explicit request
+ * @QCA_ROAM_REASON_USER_TRIGGER: Roam triggered due to an explicit request
  * from the user (user space).
  *
  * @QCA_ROAM_REASON_BTM: Roam triggered due to BTM Request frame received from
@@ -1125,6 +1229,26 @@
  *
  * @QCA_ROAM_REASON_BSS_LOAD: Roam triggered due to the channel utilization
  * breaching out the configured threshold.
+ *
+ * @QCA_ROAM_REASON_WTC: Roam triggered due to Wireless to Cellular BSS
+ * transition request.
+ *
+ * @QCA_ROAM_REASON_IDLE: Roam triggered when device is suspended, there is no
+ * data activity with the AP and the current RSSI falls below a certain
+ * threshold.
+ *
+ * @QCA_ROAM_REASON_DISCONNECTION: Roam triggered due to Deauthentication or
+ * Disassociation frames received from the connected AP.
+ *
+ * @QCA_ROAM_REASON_PERIODIC_TIMER: Roam triggered as part of the periodic scan
+ * that happens when there is no candidate AP found during the poor RSSI scan
+ * trigger.
+ *
+ * @QCA_ROAM_REASON_BACKGROUND_SCAN: Roam triggered based on the scan results
+ * obtained from an external scan (not aimed at roaming).
+ *
+ * @QCA_ROAM_REASON_BT_ACTIVITY: Roam triggered due to Bluetooth connection is
+ * established when the station is connected in the 2.4 GHz band.
  */
 enum qca_roam_reason {
 	QCA_ROAM_REASON_UNKNOWN,
@@ -1136,6 +1260,12 @@
 	QCA_ROAM_REASON_USER_TRIGGER,
 	QCA_ROAM_REASON_BTM,
 	QCA_ROAM_REASON_BSS_LOAD,
+	QCA_ROAM_REASON_WTC,
+	QCA_ROAM_REASON_IDLE,
+	QCA_ROAM_REASON_DISCONNECTION,
+	QCA_ROAM_REASON_PERIODIC_TIMER,
+	QCA_ROAM_REASON_BACKGROUND_SCAN,
+	QCA_ROAM_REASON_BT_ACTIVITY,
 };
 
 enum qca_wlan_vendor_attr_roam_auth {
@@ -1355,6 +1485,16 @@
  * Used with event to notify the EDMG channel number selected in ACS
  * operation.
  * EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP: Optional (u16).
+ * Used with event to notify the puncture pattern selected in ACS operation.
+ * Encoding for this attribute will follow the convention used in the Disabled
+ * Subchannel Bitmap field of the EHT Operation IE.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED: Flag attribute.
+ * Used with command to configure ACS operation for EHT mode.
+ * Disable (flag attribute not present) - EHT disabled and
+ * Enable (flag attribute present) - EHT enabled.
  */
 enum qca_wlan_vendor_attr_acs_offload {
 	QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
@@ -1375,6 +1515,8 @@
 	QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17,
+	QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP = 18,
+	QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED = 19,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
@@ -1438,6 +1580,25 @@
  *	%QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL and
  *	%QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW attributes from
  *	userspace.
+ * @QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R: Device supports Adaptive 11r.
+ *	With Adaptive 11r feature, access points advertise the vendor
+ *	specific IEs and MDE but do not include FT AKM in the RSNE.
+ *	The Adaptive 11r supported stations are expected to identify
+ *	such vendor specific IEs and connect to the AP in FT mode though
+ *	the profile is configured in non-FT mode.
+ *	The driver-based SME cases also need to have this support for
+ *	Adaptive 11r to handle the connection and roaming scenarios.
+ *	This flag indicates the support for the same to the user space.
+ * @QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS: Device supports
+ *	concurrent network sessions on different Wi-Fi bands. This feature
+ *	capability is attributed to the hardware's capability to support
+ *	the same (e.g., DBS).
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT: Flag indicating whether the
+ *	responses for the respective TWT operations are asynchronous (separate
+ *	event message) from the driver. If not specified, the responses are
+ *	synchronous (in vendor command reply) to the request. Each TWT
+ *	operation is specifically mentioned (against its respective
+ *	documentation) to support either of these or both modes.
  * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
  */
 enum qca_wlan_vendor_features {
@@ -1453,6 +1614,9 @@
 	QCA_WLAN_VENDOR_FEATURE_11AX			= 9,
 	QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT		= 10,
 	QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG		= 11,
+	QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R		= 12,
+	QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13,
+	QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT	= 14,
 	NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
 };
 
@@ -1658,32 +1822,62 @@
 };
 
 /**
- * enum qca_vendor_attr_get_tsf: Vendor attributes for TSF capture
- * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: enum qca_tsf_operation (u32)
- * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Unsigned 64 bit TSF timer value
- * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Unsigned 64 bit Synchronized
- *	SOC timer value at TSF capture
+ * enum qca_vendor_attr_tsf_cmd: Vendor attributes for TSF capture
+ * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: Required (u32)
+ * Specify the TSF command. Possible values are defined in
+ * &enum qca_tsf_cmd.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Optional (u64)
+ * This attribute contains TSF timer value. This attribute is only available
+ * in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Optional (u64)
+ * This attribute contains SOC timer value at TSF capture. This attribute is
+ * only available in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL: Optional (u32)
+ * This attribute is used to provide TSF sync interval and only applicable when
+ * TSF command is %QCA_TSF_SYNC_START. If this attribute is not provided, the
+ * driver will use the default value. Time unit is in milliseconds.
  */
 enum qca_vendor_attr_tsf_cmd {
 	QCA_WLAN_VENDOR_ATTR_TSF_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_TSF_CMD,
 	QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE,
 	QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE,
+	QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL,
 	QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_TSF_MAX =
 	QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST - 1
 };
 
 /**
- * enum qca_tsf_operation: TSF driver commands
+ * enum qca_tsf_cmd: TSF driver commands
  * @QCA_TSF_CAPTURE: Initiate TSF Capture
  * @QCA_TSF_GET: Get TSF capture value
  * @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value
+ * @QCA_TSF_AUTO_REPORT_ENABLE: Used in STA mode only. Once set, the target
+ * will automatically send TSF report to the host. To query
+ * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY, this operation needs to be
+ * initiated first.
+ * @QCA_TSF_AUTO_REPORT_DISABLE: Used in STA mode only. Once set, the target
+ * will not automatically send TSF report to the host. If
+ * %QCA_TSF_AUTO_REPORT_ENABLE is initiated and
+ * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY is not queried anymore, this
+ * operation needs to be initiated.
+ * @QCA_TSF_SYNC_START: Start periodic TSF sync feature. The driver periodically
+ * fetches TSF and host time mapping from the firmware with interval configured
+ * through the %QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL attribute. If the
+ * interval value is not provided the driver will use the default value. The
+ * userspace can query the TSF and host time mapping via the %QCA_TSF_GET
+ * command.
+ * @QCA_TSF_SYNC_STOP: Stop periodic TSF sync feature.
  */
 enum qca_tsf_cmd {
 	QCA_TSF_CAPTURE,
 	QCA_TSF_GET,
 	QCA_TSF_SYNC_GET,
+	QCA_TSF_AUTO_REPORT_ENABLE,
+	QCA_TSF_AUTO_REPORT_DISABLE,
+	QCA_TSF_SYNC_START,
+	QCA_TSF_SYNC_STOP,
 };
 
 /**
@@ -1777,6 +1971,23 @@
 };
 
 /**
+ * enum qca_wlan_vendor_scan_priority - Specifies the valid values that the
+ * vendor scan attribute QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY can take.
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW: Very low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW: Low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM: Medium priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH: High priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH: Very high priority
+ */
+enum qca_wlan_vendor_scan_priority {
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW = 0,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW = 1,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM = 2,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH = 3,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH = 4,
+};
+
+/**
  * enum qca_wlan_vendor_attr_scan - Specifies vendor scan attributes
  *
  * @QCA_WLAN_VENDOR_ATTR_SCAN_IE: IEs that should be included as part of scan
@@ -1801,6 +2012,11 @@
  * @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in
  *	microseconds. This is a common value which applies across all
  *	frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES.
+ * @QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY: Priority of vendor scan relative to
+ *	other scan requests. It is a u32 attribute and takes values from enum
+ *	qca_wlan_vendor_scan_priority. This is an optional attribute.
+ *	If this attribute is not configured, the driver shall use
+ *	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH as the priority of vendor scan.
  */
 enum qca_wlan_vendor_attr_scan {
 	QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0,
@@ -1816,6 +2032,7 @@
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10,
 	QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11,
 	QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12,
+	QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13,
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAX =
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1
@@ -2278,6 +2495,10 @@
 	 * frame. The updated NSS value after the connection shall not be
 	 * greater than the one negotiated during the connection. Any such
 	 * higher value configuration shall be returned with a failure.
+	 * Only symmetric NSS configuration (such as 2X2 or 1X1) can be done
+	 * using this attribute. QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes shall be used to
+	 * configure the asymmetric NSS configuration (such as 1X2).
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_NSS = 70,
 	/* 8-bit unsigned value to trigger Optimized Power Management:
@@ -2326,6 +2547,86 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL = 76,
 
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for transmitting the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The TX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver
+	 * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77,
+
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for receiving the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The RX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver
+	 * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78,
+
+	/*
+	 * 8-bit unsigned value. This attribute, when set, indicates whether the
+	 * specified interface is the primary STA interface when there are more
+	 * than one STA interfaces concurrently active.
+	 *
+	 * This configuration helps the firmware/hardware to support certain
+	 * features (e.g., roaming) on this primary interface, if the same
+	 * cannot be supported on the concurrent STA interfaces simultaneously.
+	 *
+	 * This configuration is only applicable for a single STA interface on
+	 * a device and gives the priority for it only over other concurrent STA
+	 * interfaces.
+	 *
+	 * If the device is a multi wiphy/soc, this configuration applies to a
+	 * single STA interface across the wiphys.
+	 *
+	 * 1-Enable (is the primary STA), 0-Disable (is not the primary STA)
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY = 79,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * driver to enable/disable FT-over-DS feature. Possible values for
+	 * this attribute are 1-Enable and 0-Disable.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS = 80,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * firmware to enable/disable ARP/NS offload feature. Possible values
+	 * for this attribute are 0-Disable and 1-Enable.
+	 *
+	 * This attribute is only applicable for STA/P2P-Client interface,
+	 * and is optional, default behavior is ARP/NS offload enabled.
+	 *
+	 * This attribute can be set in disconnected and connected state, and
+	 * will restore to the default behavior if the interface is closed.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD = 81,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@@ -2421,23 +2722,50 @@
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
  * %QCA_WLAN_VENDOR_GPIO_OUTPUT.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Optional (u32)
  * value to specify the GPIO pull type. Please refer to enum qca_gpio_pull_type
  * for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Optional (u32)
  * value to specify the GPIO interrupt mode. Please refer to enum
  * qca_gpio_interrupt_mode for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
  *
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Optional (u32)
  * value to specify the GPIO direction. Please refer to enum qca_gpio_direction
  * for the available values.
  * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG: Optional (u32)
+ * Value to specify the mux config. Meaning of a given value is dependent
+ * on the target chipset and GPIO pin. Must be of the range 0-15.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to 0.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE: Optional (u32)
+ * Value to specify the drive, refer to enum qca_gpio_drive.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to QCA_WLAN_GPIO_DRIVE_2MA(0).
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG: Optional (flag)
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. When present this attribute signals that all
+ * other parameters for the given GPIO will be obtained from internal
+ * configuration. Only %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM must be
+ * specified to indicate the GPIO pin being configured.
  */
 enum qca_wlan_gpio_attr {
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INVALID = 0,
@@ -2453,6 +2781,12 @@
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE = 5,
 	/* Unsigned 32-bit attribute for GPIO direction to configure */
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR = 6,
+	/* Unsigned 32-bit attribute for GPIO mux config */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG = 7,
+	/* Unsigned 32-bit attribute for GPIO drive */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE = 8,
+	/* Flag attribute for using internal GPIO configuration */
+	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG = 9,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST,
@@ -2528,6 +2862,30 @@
 };
 
 /**
+ * enum qca_gpio_drive - GPIO drive
+ * @QCA_WLAN_GPIO_DRIVE_2MA: drive 2MA
+ * @QCA_WLAN_GPIO_DRIVE_4MA: drive 4MA
+ * @QCA_WLAN_GPIO_DRIVE_6MA: drive 6MA
+ * @QCA_WLAN_GPIO_DRIVE_8MA: drive 8MA
+ * @QCA_WLAN_GPIO_DRIVE_10MA: drive 10MA
+ * @QCA_WLAN_GPIO_DRIVE_12MA: drive 12MA
+ * @QCA_WLAN_GPIO_DRIVE_14MA: drive 14MA
+ * @QCA_WLAN_GPIO_DRIVE_16MA: drive 16MA
+ * @QCA_WLAN_GPIO_DRIVE_MAX: invalid GPIO drive
+ */
+enum qca_gpio_drive {
+	QCA_WLAN_GPIO_DRIVE_2MA = 0,
+	QCA_WLAN_GPIO_DRIVE_4MA = 1,
+	QCA_WLAN_GPIO_DRIVE_6MA = 2,
+	QCA_WLAN_GPIO_DRIVE_8MA = 3,
+	QCA_WLAN_GPIO_DRIVE_10MA = 4,
+	QCA_WLAN_GPIO_DRIVE_12MA = 5,
+	QCA_WLAN_GPIO_DRIVE_14MA = 6,
+	QCA_WLAN_GPIO_DRIVE_16MA = 7,
+	QCA_WLAN_GPIO_DRIVE_MAX,
+};
+
+/**
  * qca_wlan_set_qdepth_thresh_attr - Parameters for setting
  * MSDUQ depth threshold per peer per tid in the target
  *
@@ -3688,6 +4046,14 @@
 	 * QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO.
 	 */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85,
+	/* u8 value representing the channel load percentage. Possible values
+	 * are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86,
+	/* u8 value representing the time slicing duty cycle percentage.
+	 * Possible values are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87,
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX =
@@ -4035,6 +4401,30 @@
 	QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_roam_scan_scheme: Scan scheme
+ *
+ * @QCA_ROAM_SCAN_SCHEME_NO_SCAN: No frequencies specified to scan.
+ *     Indicates the driver to not scan on a Roam Trigger scenario, but
+ *     disconnect. E.g., on a BTM request from the AP the driver/firmware shall
+ *     disconnect from the current connected AP by notifying a failure
+ *     code in the BTM response.
+ *
+ * @QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN: Indicates the driver/firmware to
+ *     trigger partial frequency scans. These frequencies are the ones learned
+ *     or maintained by the driver based on the probability of finding the
+ *     BSSIDs in the ESS for which the roaming is triggered.
+ *
+ * @QCA_ROAM_SCAN_SCHEME_FULL_SCAN: Indicates the driver/firmware to
+ *     trigger the scan on all the valid frequencies to find better
+ *     candidates to roam.
+ */
+enum qca_roam_scan_scheme {
+	QCA_ROAM_SCAN_SCHEME_NO_SCAN = 0,
+	QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN = 1,
+	QCA_ROAM_SCAN_SCHEME_FULL_SCAN = 2,
+};
+
 /*
  * enum qca_vendor_roam_triggers: Bitmap of roaming triggers
  *
@@ -4055,6 +4445,18 @@
  *	when BTM Request frame is received from the connected AP.
  * @QCA_ROAM_TRIGGER_REASON_BSS_LOAD: Set if the roam has to be triggered
  *	when the channel utilization is goes above the configured threshold.
+ * @QCA_ROAM_TRIGGER_REASON_USER_TRIGGER: Set if the roam has to be triggered
+ *	based on the request from the user (space).
+ * @QCA_ROAM_TRIGGER_REASON_DEAUTH: Set if the roam has to be triggered when
+ *	device receives Deauthentication/Disassociation frame from connected AP.
+ * @QCA_ROAM_TRIGGER_REASON_IDLE: Set if the roam has to be triggered when the
+ *	device is in idle state (no TX/RX) and suspend mode, if the current RSSI
+ *	is determined to be a poor one.
+ * @QCA_ROAM_TRIGGER_REASON_TX_FAILURES: Set if the roam has to be triggered
+ *	based on continuous TX Data frame failures to the connected AP.
+ * @QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN: Set if the roam has to be triggered
+ *	based on the scan results obtained from an external scan (not triggered
+ *	to aim roaming).
  *
  * Set the corresponding roam trigger reason bit to consider it for roam
  * trigger.
@@ -4070,6 +4472,144 @@
 	QCA_ROAM_TRIGGER_REASON_DENSE		= 1 << 5,
 	QCA_ROAM_TRIGGER_REASON_BTM		= 1 << 6,
 	QCA_ROAM_TRIGGER_REASON_BSS_LOAD	= 1 << 7,
+	QCA_ROAM_TRIGGER_REASON_USER_TRIGGER	= 1 << 8,
+	QCA_ROAM_TRIGGER_REASON_DEAUTH          = 1 << 9,
+	QCA_ROAM_TRIGGER_REASON_IDLE		= 1 << 10,
+	QCA_ROAM_TRIGGER_REASON_TX_FAILURES	= 1 << 11,
+	QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN	= 1 << 12,
+};
+
+/*
+ * enum qca_vendor_roam_fail_reasons: Defines the various roam
+ * fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED: Roam module in the firmware is not
+ * able to trigger the scan.
+ * @QCA_ROAM_FAIL_REASON_NO_AP_FOUND: No roamable APs found during roam scan.
+ * @QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: No candidate APs found during roam
+ * scan.
+ * @QCA_ROAM_FAIL_REASON_HOST: Roam fail due to disconnect issued from host.
+ * @QCA_ROAM_FAIL_REASON_AUTH_SEND: Unable to send Authentication frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_RECV: Received Authentication frame with error
+ * status code.
+ * @QCA_ROAM_FAIL_REASON_NO_AUTH_RESP: Authentication frame not received.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_SEND: Unable to send Reassociation Request
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_RECV: Received Reassociation Response frame
+ * with error status code.
+ * @QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP: Reassociation Response frame not
+ * received.
+ * @QCA_ROAM_FAIL_REASON_SCAN_FAIL: Scan module not able to start scan.
+ * @QCA_ROAM_FAIL_REASON_AUTH_NO_ACK: No ACK is received for Authentication
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: Authentication frame is dropped
+ * internally before transmission.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK: No ACK is received for Reassociation
+ * Request frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: Reassociation Request frame is
+ * dropped internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT: EAPOL-Key M1 is not received and
+ * times out.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND: Unable to send EAPOL-Key M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: EAPOL-Key M2 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: No ACK is received for EAPOL-Key
+ * M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: EAPOL-Key M3 frame is not received.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND: Unable to send EAPOL-Key M4 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: EAPOL-Key M4 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: No ACK is received for EAPOL-Key M4
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS: Roam scan is not
+ * started for final beacon miss case.
+ * @QCA_ROAM_FAIL_REASON_DISCONNECT: Deauthentication or Disassociation frame
+ * received from the AP during roaming handoff.
+ * @QCA_ROAM_FAIL_REASON_RESUME_ABORT: Firmware roams to the AP when the Apps
+ * or host is suspended and gives the indication of the last roamed AP only
+ * when the Apps is resumed. If the Apps is resumed while the roaming is in
+ * progress, this ongoing roaming is aborted and the last roamed AP is
+ * indicated to host.
+ * @QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID: WPA3-SAE invalid PMKID.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: WPA3-SAE pre-authentication times
+ * out.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: WPA3-SAE pre-authentication fails.
+ */
+enum qca_vendor_roam_fail_reasons {
+	QCA_ROAM_FAIL_REASON_NONE = 0,
+	QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED = 1,
+	QCA_ROAM_FAIL_REASON_NO_AP_FOUND = 2,
+	QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND = 3,
+	QCA_ROAM_FAIL_REASON_HOST = 4,
+	QCA_ROAM_FAIL_REASON_AUTH_SEND = 5,
+	QCA_ROAM_FAIL_REASON_AUTH_RECV = 6,
+	QCA_ROAM_FAIL_REASON_NO_AUTH_RESP = 7,
+	QCA_ROAM_FAIL_REASON_REASSOC_SEND = 8,
+	QCA_ROAM_FAIL_REASON_REASSOC_RECV = 9,
+	QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP = 10,
+	QCA_ROAM_FAIL_REASON_SCAN_FAIL = 11,
+	QCA_ROAM_FAIL_REASON_AUTH_NO_ACK = 12,
+	QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP = 13,
+	QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK = 14,
+	QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP = 15,
+	QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT = 16,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND = 17,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP = 18,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK = 19,
+	QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT = 20,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND = 21,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP = 22,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK = 23,
+	QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS = 24,
+	QCA_ROAM_FAIL_REASON_DISCONNECT = 25,
+	QCA_ROAM_FAIL_REASON_RESUME_ABORT = 26,
+	QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID = 27,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT = 28,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL = 29,
+};
+
+/*
+ * enum qca_vendor_roam_invoke_fail_reasons: Defines the various roam
+ * invoke fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_INVOKE_STATUS_IFACE_INVALID: Invalid interface ID is passed
+ * in roam invoke command.
+ * @QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE: Roam offload in firmware is not
+ * enabled.
+ * @QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID: Connected AP profile SSID
+ * length is invalid.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW: Firmware internal roaming is already
+ * in progress.
+ * @QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP: Host sends the Beacon/Probe Response
+ * of the AP in the roam invoke command to firmware. This reason is sent by the
+ * firmware when the given AP is configured to be ignored or SSID/security
+ * does not match.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL: Roam handoff failed because of
+ * firmware internal reasons.
+ * @QCA_ROAM_INVOKE_STATUS_DISALLOW: Roam invoke trigger is not enabled.
+ * @QCA_ROAM_INVOKE_STATUS_SCAN_FAIL: Scan start fail for roam invoke.
+ * @QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL: Roam handoff start fail.
+ * @QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS: Roam invoke parameters are invalid.
+ * @QCA_ROAM_INVOKE_STATUS_NO_CAND_AP: No candidate AP found to roam to.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_FAIL: Roam handoff failed.
+ */
+enum qca_vendor_roam_invoke_fail_reasons {
+	QCA_ROAM_INVOKE_STATUS_NONE = 0,
+	QCA_ROAM_INVOKE_STATUS_IFACE_INVALID = 1,
+	QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE = 2,
+	QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID = 3,
+	QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW = 4,
+	QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP = 5,
+	QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL = 6,
+	QCA_ROAM_INVOKE_STATUS_DISALLOW = 7,
+	QCA_ROAM_INVOKE_STATUS_SCAN_FAIL = 8,
+	QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL = 9,
+	QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS = 10,
+	QCA_ROAM_INVOKE_STATUS_NO_CAND_AP = 11,
+	QCA_ROAM_INVOKE_STATUS_ROAM_FAIL = 12,
+
 };
 
 /**
@@ -4226,6 +4766,109 @@
  *
  *	Clears the selection criteria configured in the driver when specified
  *	with clear command.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME: Unsigned 32-bit value.
+ *	Represents value of the scan frequency scheme from enum
+ *	qca_roam_scan_scheme.
+ *	It's an optional attribute. If this attribute is not configured, the
+ *	driver shall proceed with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD: Signed 32-bit value in dBm,
+ *	signifying the RSSI threshold of the current connected AP, indicating
+ *	the driver to trigger roam only when the current connected AP's RSSI
+ *	is less than this threshold.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD: Signed 32-bit value in dBm,
+ *	signifying the RSSI threshold of the candidate AP, indicating
+ *	the driver to trigger roam only to the candidate AP with RSSI
+ *	better than this threshold. If RSSI thresholds for candidate APs found
+ *	in the 2.4 GHz, 5 GHz, and 6 GHz bands are configured separately using
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ,
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ, and/or
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ, those values will
+ *	take precedence over the value configured using the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_USER_REASON: Unsigned 32-bit value. Represents the
+ *	user defined reason code to be sent to the AP in response to AP's
+ *	request to trigger the roam if the roaming cannot be triggered.
+ *	Applies to all the scenarios of AP assisted roaming (e.g., BTM).
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS: Unsigned 32-bit value.
+ *	Carries a bitmap of the roam triggers specified in
+ *	enum qca_vendor_roam_triggers.
+ *	Represents the roam triggers for which the specific scan scheme from
+ *	enum qca_roam_scan_scheme has to be applied.
+ *	It's an optional attribute. If this attribute is not configured, but
+ *	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is specified, the scan scheme
+ *	specified through QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is applicable for
+ *	all the roams.
+ *	If both QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME and
+ *	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS are not specified, the
+ *	driver shall proceed with the default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ: Signed 32-bit value
+ *	in dBm, signifying the RSSI threshold of the candidate AP found in the
+ *	2.4 GHz band. The driver/firmware shall trigger roaming to the candidate
+ *	AP found in the 2.4 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 5
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 5 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by tge
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 6
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 6 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_BAND_MASK: Unsigned 32-bit value.
+ *	Carries bitmask value of bits from &enum qca_set_band and represents
+ *	all the bands in which roaming is allowed. The configuration is valid
+ *	until next disconnection. If this attribute is not present, the
+ *	existing configuration shall be used. By default, roaming is allowed on
+ *	all bands supported by the local device. When the value is set to
+ *	%QCA_SETBAND_AUTO, all supported bands shall be enabled.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for active channels in the 2.4/5 GHz
+ *	bands. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for passive channels in the 5 GHz
+ *	band. If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME: u16 value in milliseconds.
+ *	Optional parameter. The minimum duration to stay on the connected AP
+ *	channel during the channel scanning. If this attribute is not
+ *	configured, the driver shall proceed with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME: u16 value in milliseconds.
+ *	Optional parameter. The maximum duration for which the radio can scan
+ *	foreign channels consecutively without coming back to home channel. If
+ *	this attribute is not configured, the driver shall proceed with default
+ *	behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Preferred Scanning Channels.
+ *	If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Non Preferred Scanning
+ *	Channels. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
  */
 enum qca_vendor_attr_roam_control {
 	QCA_ATTR_ROAM_CONTROL_ENABLE = 1,
@@ -4236,6 +4879,21 @@
 	QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD = 6,
 	QCA_ATTR_ROAM_CONTROL_TRIGGERS = 7,
 	QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA = 8,
+	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME = 9,
+	QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD = 10,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD = 11,
+	QCA_ATTR_ROAM_CONTROL_USER_REASON = 12,
+	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS = 13,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ = 14,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ = 15,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ = 16,
+	QCA_ATTR_ROAM_CONTROL_BAND_MASK = 17,
+	QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME = 18,
+	QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME = 19,
+	QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME = 20,
+	QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME = 21,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME = 22,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME = 23,
 
 	/* keep last */
 	QCA_ATTR_ROAM_CONTROL_AFTER_LAST,
@@ -4258,14 +4916,14 @@
  *	ignored BSSIDs and accordingly clear the respective ones with the
  *	matching ID.
  *
- * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS: Unsigned
- *	32-bit value.Represents the number of whitelist SSIDs configured.
+ * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS: Unsigned
+ *	32-bit value. Represents the number of allowlist SSIDs configured.
  *
- * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST: Nested attribute
- *	to carry the list of Whitelist SSIDs.
+ * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST: Nested attribute
+ *	to carry the list of allowlist SSIDs.
  *
- * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID: SSID (binary attribute,
- *	0..32 octets). Represents the white list SSID. Whitelist SSIDs
+ * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID: SSID (binary attribute,
+ *	0..32 octets). Represents the allow list SSID. Allowlist SSIDs
  *	represent the list of SSIDs to which the firmware/driver can consider
  *	to roam to.
  *
@@ -4303,7 +4961,7 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE: Unsigned 32-bit
  *	value. 1-Enable, 0-Disable. Represents "Lazy" mode, where
- *	firmware is hunting for a better BSSID or white listed SSID even though
+ *	firmware is hunting for a better BSSID or allow listed SSID even though
  *	the RSSI of the link is good. The parameters enabling the roaming are
  *	configured through the PARAM_A_BAND_XX attrbutes.
  *
@@ -4345,10 +5003,10 @@
 	QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD = 1,
 	QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID = 2,
 
-	/* Attributes for wifi_set_ssid_white_list */
-	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS = 3,
-	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST = 4,
-	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID = 5,
+	/* Attributes for wifi_set_ssid_allow_list */
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST = 4,
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID = 5,
 
 	/* Attributes for set_roam_params */
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD = 6,
@@ -4383,16 +5041,24 @@
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST - 1,
 };
 
+/* old names for API compatibility */
+#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS
+#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST
+#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID
+
 /*
  * enum qca_wlan_vendor_roaming_subcmd: Referred by
  * QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD.
  *
- * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST: Sub command to
- *	configure the white list SSIDs. These are configured through
+ * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST: Sub command to
+ *	configure the allow list SSIDs. These are configured through
  *	the following attributes.
- *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS,
- *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST,
- *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID
+ *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS,
+ *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST,
+ *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID
  *
  * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS: Sub command to
  *	configure the Roam params. These parameters are evaluated on the GScan
@@ -4408,7 +5074,7 @@
  *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS to set the BSSID
  *	preference.
  *
- * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID: Sets the list of BSSIDs
+ * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID: Sets the list of BSSIDs
  *	to ignore in roaming decision. Uses
  *	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS to set the list.
  *
@@ -4432,17 +5098,23 @@
  */
 enum qca_wlan_vendor_roaming_subcmd {
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_INVALID = 0,
-	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST = 1,
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST = 1,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS = 2,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_LAZY_ROAM = 3,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PREFS = 4,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PARAMS = 5,
-	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID = 6,
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID = 6,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET = 7,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET = 8,
 	QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR = 9,
 };
 
+/* old names for API compatibility */
+#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST \
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST
+#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID \
+	QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID
+
 enum qca_wlan_vendor_attr_gscan_config_params {
 	QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_INVALID = 0,
 
@@ -4801,7 +5473,7 @@
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID
 	= 43,
 	/* Unsigned 32-bit value; a GSCAN Capabilities attribute. */
-	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID
+	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID
 	= 44,
 
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED = 45,
@@ -4809,10 +5481,10 @@
 	/* Unsigned 32-bit value; a GSCAN Capabilities attribute.
 	 * This is used to limit the maximum number of BSSIDs while sending
 	 * the vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM with subcmd
-	 * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID and attribute
+	 * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID and attribute
 	 * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID.
 	 */
-	QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID = 46,
+	QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID = 46,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST,
@@ -4820,6 +5492,12 @@
 	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST - 1,
 };
 
+/* old names for API compatibility */
+#define QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID \
+	QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID
+#define QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID \
+	QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID
+
 enum qca_wlan_vendor_attr_pno_config_params {
 	QCA_WLAN_VENDOR_ATTR_PNO_INVALID = 0,
 	/* Attributes for data used by
@@ -5186,6 +5864,10 @@
 	 * bit 3 set: channel should be excluded in GO negotiation
 	 */
 	QCA_WLAN_VENDOR_ATTR_PCL_FLAG = 4,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_PCL_LAST,
+	QCA_WLAN_VENDOR_ATTR_PCL_MAX = QCA_WLAN_VENDOR_ATTR_PCL_LAST - 1
 };
 
 /**
@@ -5843,6 +6525,14 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2 = 29,
+	/* This attribute specifies the bandwidth to be used for spectral scan
+	 * operation. This is an u8 attribute and uses the values in enum
+	 * nl80211_chan_width. This is an optional attribute.
+	 * If this attribute is not populated, the driver should configure the
+	 * spectral scan bandwidth to the maximum value supported by the target
+	 * for the current operating bandwidth.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH = 30,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX =
@@ -5953,6 +6643,14 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ = 18,
+	/* Flag attribute to indicate agile spectral scan capability
+	 * for 320 MHz mode.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320 = 19,
+	/* Number of spectral detectors used for scan in 320 MHz.
+	 * u32 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ = 20,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX =
@@ -6135,6 +6833,16 @@
 	 * the FW on a specific VDEV.
 	 */
 	QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22,
+	/* WMI sequence mismatch between WMI command and Tx completion */
+	QCA_WLAN_HANG_WMI_BUF_SEQUENCE_MISMATCH = 23,
+	/* Write to Device HAL register failed */
+	QCA_WLAN_HANG_REG_WRITE_FAILURE = 24,
+	/* No credit left to send the wow_wakeup_from_sleep to firmware */
+	QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25,
+	/* Bus failure */
+	QCA_WLAN_HANG_BUS_FAILURE = 26,
+	/* tasklet/credit latency found */
+	QCA_WLAN_HANG_TASKLET_CREDIT_LATENCY_DETECT = 27,
 };
 
 /**
@@ -6160,6 +6868,28 @@
 };
 
 /**
+ * enum qca_wlan_vendor_flush_pending_policy: Represents values for
+ * the policy to flush pending frames, configured via
+ * %QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING. This enumeration defines the
+ * valid values for %QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY.
+ *
+ * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE: This value clears all
+ * the flush policy configured before. This command basically disables the
+ * flush config set by the user.
+ * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE: This value configures
+ * the flush policy to be immediate. All pending packets for the peer/TID are
+ * flushed when this command/policy is received.
+ * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END: This value configures
+ * the flush policy to the end of TWT SP. All pending packets for the peer/TID
+ * are flushed when the end of TWT SP is reached.
+ */
+enum qca_wlan_vendor_flush_pending_policy  {
+	QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE = 0,
+	QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE = 1,
+	QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_flush_pending - Attributes for
  * flushing pending traffic in firmware.
  *
@@ -6167,12 +6897,25 @@
  * @QCA_WLAN_VENDOR_ATTR_AC: Configure access category of the pending
  * packets. It is u8 value with bit 0~3 represent AC_BE, AC_BK,
  * AC_VI, AC_VO respectively. Set the corresponding bit to 1 to
- * flush packets with access category.
+ * flush packets with access category. This is optional. See below.
+ * @QCA_WLAN_VENDOR_ATTR_TID_MASK: Configure TID mask of the pending packets.
+ * It is a u32 value with bit 0-7 representing TID 0-7. Set corresponding
+ * bit to 1 to act upon the TID. This is optional. Either this attribute or
+ * %QCA_WLAN_VENDOR_ATTR_AC must be provided. If both are provided,
+ * %QCA_WLAN_VENDOR_ATTR_TID_MASK takes precedence. If neither are provided
+ * it is an error.
+ * @QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY: Policy of flushing the pending
+ * packets corresponding to the peer/TID provided. It is a u32 value,
+ * represented by %enum qca_wlan_vendor_flush_pending_policy. This
+ * value is honored only when TID mask is provided. This is not honored when AC
+ * mask is provided.
  */
 enum qca_wlan_vendor_attr_flush_pending {
 	QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_PEER_ADDR = 1,
 	QCA_WLAN_VENDOR_ATTR_AC = 2,
+	QCA_WLAN_VENDOR_ATTR_TID_MASK = 3,
+	QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY = 4,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_AFTER_LAST,
@@ -6289,8 +7032,9 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL:
  *	Default WLAN operation level which throughput orientated.
- * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE:
- *	Use moderate level to improve latency by limit scan duration.
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR:
+ *	Use XR level to benefit XR (extended reality) application to achieve
+ *	latency and power by via constraint scan/roaming/adaptive PS.
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW:
  *	Use low latency level to benifit application like concurrent
  *	downloading or video streaming via constraint scan/adaptive PS.
@@ -6301,7 +7045,10 @@
 enum qca_wlan_vendor_attr_config_latency_level {
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL = 1,
-	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE = 2,
+	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR = 2,
+	/* legacy name */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE =
+	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW = 3,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW = 4,
 
@@ -6801,8 +7548,9 @@
 
 /**
  * enum qca_wlan_vendor_thermal_level - Defines various thermal levels
- * configured by userspace to the driver/firmware. The values will be
- * encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL attribute.
+ * configured by userspace to the driver/firmware.
+ * The values can be encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL or
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL attribute.
  * The driver/firmware takes actions requested by userspace such as throttling
  * wifi TX etc. in order to mitigate high temperature.
  *
@@ -6836,8 +7584,9 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE = 1,
 	/* Userspace uses this attribute to configure thermal level to the
-	 * driver/firmware. Used in request, u32 attribute, possible values
-	 * are defined in enum qca_wlan_vendor_thermal_level.
+	 * driver/firmware, or get thermal level from the driver/firmware.
+	 * Used in request or response, u32 attribute,
+	 * possible values are defined in enum qca_wlan_vendor_thermal_level.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL = 2,
 	/* Userspace uses this attribute to configure the time in which the
@@ -6850,6 +7599,15 @@
 	 * there is any critical ongoing operation.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3,
+	/* Nested attribute, the driver/firmware uses this attribute to report
+	 * thermal statistics of different thermal levels to userspace when
+	 * requested using the
+	 * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command
+	 * type. This attribute contains a nested array of records of thermal
+	 * statistics of multiple levels. The attributes used inside this nested
+	 * attribute are defined in enum qca_wlan_vendor_attr_thermal_stats.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST,
@@ -6875,6 +7633,16 @@
  * resume action.
  * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL: Configure thermal level to
  * the driver/firmware.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current
+ * thermal level from the driver/firmware. The driver should respond with a
+ * thermal level defined in enum qca_wlan_vendor_thermal_level.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the
+ * current thermal statistics from the driver/firmware. The driver should
+ * respond with statistics of all thermal levels encapsulated in the attribute
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear
+ * the current thermal statistics for all thermal levels maintained in the
+ * driver/firmware and start counting from zero again.
  */
 enum qca_wlan_vendor_attr_thermal_cmd_type {
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS,
@@ -6882,6 +7650,9 @@
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS,
 };
 
 /**
@@ -6964,6 +7735,11 @@
 	 * NLA_FLAG attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_RESUME_COMPLETE,
+	/* Thermal level from the driver.
+	 * u32 attribute. Possible values are defined in
+	 * enum qca_wlan_vendor_thermal_level.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL = 3,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST,
@@ -6972,6 +7748,35 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes
+ * to get thermal status from the driver/firmware.
+ * enum values are used for NL attributes encapsulated inside the
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute.
+ *
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each
+ * thermal level in milliseconds. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number
+ * of times the temperature crossed into the temperature range defined by the
+ * thermal level from both higher and lower directions. u32 size.
+ */
+enum qca_wlan_vendor_attr_thermal_stats {
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1,
+};
+
+/**
  * enum he_fragmentation_val - HE fragmentation support values
  * Indicates level of dynamic fragmentation that is supported by
  * a STA as a recipient.
@@ -7130,6 +7935,21 @@
 };
 
 /**
+ * enum qca_wlan_keep_alive_data_type - Keep alive data type configuration
+ *
+ * Indicates the frame types to use for keep alive data.
+ *
+ * @QCA_WLAN_KEEP_ALIVE_DEFAULT: Driver default type used for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_DATA: Data frame type for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_MGMT: Management frame type for keep alive.
+ */
+enum qca_wlan_keep_alive_data_type {
+	QCA_WLAN_KEEP_ALIVE_DEFAULT = 0,
+	QCA_WLAN_KEEP_ALIVE_DATA = 1,
+	QCA_WLAN_KEEP_ALIVE_MGMT = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_he_omi_tx: Represents attributes for
  * HE operating mode control transmit request. These attributes are
  * sent as part of QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX and
@@ -7577,6 +8397,128 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT = 43,
 
+	/* 8-bit unsigned value to configure the driver/firmware to start or
+	 * stop transmitting FILS discovery frames.
+	 * 0 - Stop transmitting FILS discovery frames
+	 * 1 - Start transmitting FILS discovery frames
+	 * This attribute is used to configure the testbed device.
+	 * This attribute can be configured only in AP mode and the
+	 * configuration is valid until AP restart.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX = 44,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable full bandwidth UL MU-MIMO subfield in the HE PHY capabilities
+	 * information field.
+	 * 0 - Disable full bandwidth UL MU-MIMO subfield
+	 * 1 - Enable full bandwidth UL MU-MIMO subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO = 45,
+
+	/* 16-bit unsigned value to configure the driver with a specific BSS
+	 * max idle period to advertise in the BSS Max Idle Period element
+	 * (IEEE Std 802.11-2016, 9.4.2.79) in (Re)Association Request frames.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD = 46,
+
+	/* 8-bit unsigned value to configure the driver to use only RU 242 tone
+	 * for data transmission.
+	 * 0 - Default behavior, 1 - Configure RU 242 tone for data Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX = 47,
+
+	/* 8-bit unsigned value to configure the driver to disable data and
+	 * management response frame transmission to test the BSS max idle
+	 * feature.
+	 * 0 - Default behavior, 1 - Disable data and management response Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX = 48,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Punctured Preamble Rx subfield in the HE PHY capabilities
+	 * information field.
+	 * 0 - Disable Punctured Preamble Rx subfield
+	 * 1 - Enable Punctured Preamble Rx subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX = 49,
+
+	/* 8-bit unsigned value to configure the driver to ignore the SAE H2E
+	 * requirement mismatch for 6 GHz connection.
+	 * 0 - Default behavior, 1 - Ignore SAE H2E requirement mismatch.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE = 50,
+
+	/* 8-bit unsigned value to configure the driver to allow 6 GHz
+	 * connection with all security modes.
+	 * 0 - Default behavior, 1 - Allow 6 GHz connection with all security
+	 * modes.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_6GHZ_SECURITY_TEST_MODE = 51,
+
+	/* 8-bit unsigned value to configure the driver to transmit data with
+	 * ER SU PPDU type.
+	 *
+	 * 0 - Default behavior, 1 - Enable ER SU PPDU type TX.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE = 52,
+
+	/* 8-bit unsigned value to configure the driver to use Data or
+	 * Management frame type for keep alive data.
+	 * Uses enum qca_wlan_keep_alive_data_type values.
+	 *
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE = 53,
+
+	/* 8-bit unsigned value to configure the driver to use scan request
+	 * BSSID value in Probe Request frame RA(A1) during the scan. The
+	 * driver saves this configuration and applies this setting to all user
+	 * space scan requests until the setting is cleared. If this
+	 * configuration is set, the driver uses the BSSID value from the scan
+	 * request to set the RA(A1) in the Probe Request frames during the
+	 * scan.
+	 *
+	 * 0 - Default behavior uses the broadcast RA in Probe Request frames.
+	 * 1 - Uses the scan request BSSID in RA in Probe Request frames.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA = 54,
+
+	/* 8-bit unsigned value to configure the driver to enable/disable the
+	 * BSS max idle period support.
+	 *
+	 * 0 - Disable the BSS max idle support.
+	 * 1 - Enable the BSS max idle support.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Rx control frame to MultiBSS subfield in the HE MAC
+	 * capabilities information field.
+	 * 0 - Disable Rx control frame to MultiBSS subfield
+	 * 1 - Enable Rx control frame to MultiBSS subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS = 56,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Broadcast TWT support subfield in the HE MAC capabilities
+	 * information field.
+	 * 0 - Disable Broadcast TWT support subfield
+	 * 1 - Enable Broadcast TWT support subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT = 57,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@@ -7586,26 +8528,73 @@
 /**
  * enum qca_wlan_twt_operation - Operation of the config TWT request
  * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION.
+ * The response for the respective operations can be either synchronous or
+ * asynchronous (wherever specified). If synchronous, the response to this
+ * operation is obtained in the corresponding vendor command reply to the user
+ * space. For the asynchronous case the response is obtained as an event with
+ * the same operation type.
+ *
+ * Drivers shall support either of these modes but not both simultaneously.
+ * This support for asynchronous mode is advertised through the flag
+ * QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT. If this flag is not advertised,
+ * the driver shall support synchronous mode.
  *
  * @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured
  * through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. Depending upon the
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, this is either a
+ * synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. This is a synchronous operation.
  *
  * @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * This terminate can either get triggered by the user space or can as well be
+ * a notification from the firmware if it initiates a terminate.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * the request from user space can either be a synchronous or asynchronous
+ * operation.
  *
  * @QCA_WLAN_TWT_SUSPEND: Suspend the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * this is either a synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are
  * configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_resume. Valid only after the TWT session is setup.
+ * This can as well be a notification from the firmware on a QCA_WLAN_TWT_NUDGE
+ * request. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_NUDGE: Suspend and resume the TWT session. TWT nudge is a
+ * combination of suspend and resume in a single request. Required parameters
+ * are configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the
+ * enum qca_wlan_vendor_attr_twt_nudge. Valid only after the TWT session is
+ * setup. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_STATS: Get the TWT session traffic statistics information.
+ * Refers the enum qca_wlan_vendor_attr_twt_stats. Valid only after the TWT
+ * session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_CLEAR_STATS: Clear TWT session traffic statistics information.
+ * Valid only after the TWT session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_CAPABILITIES: Get TWT capabilities of this device and its
+ * peer. Refers the enum qca_wlan_vendor_attr_twt_capability. It's a synchronous
+ * operation.
+ *
+ * @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmare is
+ * ready for a new TWT session setup after it issued a TWT teardown.
+ *
+ * @QCA_WLAN_TWT_SET_PARAM: Configure TWT related parameters. Required
+ * parameters are obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refer
+ * the enum qca_wlan_vendor_attr_twt_set_param.
  */
 enum qca_wlan_twt_operation {
 	QCA_WLAN_TWT_SET = 0,
@@ -7613,6 +8602,12 @@
 	QCA_WLAN_TWT_TERMINATE = 2,
 	QCA_WLAN_TWT_SUSPEND = 3,
 	QCA_WLAN_TWT_RESUME = 4,
+	QCA_WLAN_TWT_NUDGE = 5,
+	QCA_WLAN_TWT_GET_STATS = 6,
+	QCA_WLAN_TWT_CLEAR_STATS = 7,
+	QCA_WLAN_TWT_GET_CAPABILITIES = 8,
+	QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9,
+	QCA_WLAN_TWT_SET_PARAM = 10,
 };
 
 /**
@@ -7626,8 +8621,9 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the
  * parameters configured for TWT. These parameters are represented by
- * enum qca_wlan_vendor_attr_twt_setup or enum qca_wlan_vendor_attr_twt_resume
- * based on the operation.
+ * enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume,
+ * enum qca_wlan_vendor_attr_twt_set_param, or
+ * enum qca_wlan_vendor_attr_twt_stats based on the operation.
  */
 enum qca_wlan_vendor_attr_config_twt {
 	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0,
@@ -7788,6 +8784,19 @@
 };
 
 /**
+ * qca_wlan_twt_setup_state: Represents the TWT session states.
+ *
+ * QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: TWT session not established.
+ * QCA_WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active.
+ * QCA_WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is in suspended state.
+ */
+enum qca_wlan_twt_setup_state {
+	QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0,
+	QCA_WLAN_TWT_SETUP_STATE_ACTIVE = 1,
+	QCA_WLAN_TWT_SETUP_STATE_SUSPEND = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_twt_setup: Represents attributes for
  * TWT (Target Wake Time) setup request. These attributes are sent as part of
  * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and
@@ -7837,6 +8846,14 @@
  * 2. TWT GET Request and Response
  * 3. TWT TERMINATE Request and Response
  * 4. TWT SUSPEND Request and Response
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions for the following
+ * 1. TWT TERMINATE Request and Response
+ * 2. TWT SUSPEND Request and Response
+ * 4. TWT CLEAR STATISTICS request
+ * 5. TWT GET STATISTICS request and response
+ * If an invalid dialog ID is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8)
  * This attribute (exp) is used along with the mantissa to derive the
@@ -7887,6 +8904,7 @@
  * 2. TWT TERMINATE Response
  * 3. TWT SUSPEND Response
  * 4. TWT RESUME Response
+ * 5. TWT NUDGE Response
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE: Required (u8)
  * This field is applicable for TWT response only.
@@ -7896,9 +8914,13 @@
  * response.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF: Required (u64)
- * This field is applicable for TWT response only.
- * This field contains absolute TSF value of the wake time received
- * from the TWT responder and is passed to the userspace.
+ * In TWT setup command this field contains absolute TSF that will
+ * be used by TWT requester during setup.
+ * In TWT response this field contains absolute TSF value of the
+ * wake time received from the TWT responder and is passed to
+ * the userspace.
+ * This is an optional parameter for
+ * 1. TWT SET Request
  * This is a required parameter for
  * 1. TWT SET Response
  * 2. TWT GET Response
@@ -7915,14 +8937,87 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer for which the TWT session
  * is being configured. This is used in AP mode to represent the respective
- * client. In AP mode, this is an optional parameter for response and is
- * a required parameter for
- * 1. TWT SET Request
- * 2. TWT GET Request
- * 3. TWT TERMINATE Request
- * 4. TWT SUSPEND Request
+ * client.
+ * In AP mode, this is a required parameter in response for
+ * 1. TWT SET
+ * 2. TWT GET
+ * 3. TWT TERMINATE
+ * 4. TWT SUSPEND
  * In STA mode, this is an optional parameter in request and response for
  * the above four TWT operations.
+ * In AP mode, this is a required parameter in request for
+ * 1. TWT GET
+ * 2. TWT TERMINATE
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL: Optional (u32)
+ * Minimum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL: Optional (u32)
+ * Maximum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION: Optional (u32)
+ * Minimum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION: Optional (u32)
+ * Maximum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE: Optional (u32)
+ * TWT state for the given dialog id. The values for this are represented
+ * by enum qca_wlan_twt_setup_state.
+ * This is obtained through TWT GET operation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA: Optional (u32)
+ * This attribute is used to configure wake interval mantissa.
+ * The unit is microseconds. This attribute, when specified, takes
+ * precedence over QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA.
+ * This parameter is used for
+ * 1. TWT SET Request and Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID: Optional (u8)
+ * This attribute is used to configure Broadcast TWT ID.
+ * The Broadcast TWT ID indicates a specific Broadcast TWT for which the
+ * transmitting STA is providing TWT parameters. The allowed values are 0 to 31.
+ * This parameter is used for
+ * 1. TWT SET Request
+ * 2. TWT TERMINATE Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION: Optional (u8)
+ * This attribute is used to configure Broadcast TWT recommendation.
+ * The Broadcast TWT Recommendation subfield contains a value that indicates
+ * recommendations on the types of frames that are transmitted by TWT
+ * scheduled STAs and scheduling AP during the broadcast TWT SP.
+ * The allowed values are 0 - 3.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE: Optional (u8)
+ * This attribute is used to configure Broadcast TWT Persistence.
+ * The Broadcast TWT Persistence subfield indicates the number of
+ * TBTTs during which the Broadcast TWT SPs corresponding to this
+ * broadcast TWT Parameter set are present. The number of beacon intervals
+ * during which the Broadcast TWT SPs are present is equal to the value in the
+ * Broadcast TWT Persistence subfield plus 1 except that the value 255
+ * indicates that the Broadcast TWT SPs are present until explicitly terminated.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE: Optional (u8)
+ * This attribute contains the value of the Responder PM Mode subfield (0 or 1)
+ * from TWT response frame.
+ * This parameter is used for
+ * 1. TWT SET Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT: Optional (u32)
+ * This attribute is used to configure the announce timeout value (in us) in
+ * the firmware. This timeout value is only applicable for the announced TWT. If
+ * the timeout value is non-zero the firmware waits up to the timeout value to
+ * use Data frame as an announcement frame. If the timeout value is 0 the
+ * firmware sends an explicit QoS NULL frame as the announcement frame on SP
+ * start. The default value in the firmware is 0.
+ * This parameter is used for
+ * 1. TWT SET Request
  */
 enum qca_wlan_vendor_attr_twt_setup {
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0,
@@ -7944,6 +9039,20 @@
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED = 14,
 
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR = 15,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL = 16,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL = 17,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION = 18,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION = 19,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE = 20,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA = 21,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID = 22,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION = 23,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE = 24,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE = 25,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT = 26,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST,
@@ -7971,6 +9080,30 @@
  * @QCA_WLAN_VENDOR_TWT_STATUS_DENIED: AP did not accept the request
  * @QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR: Adding TWT dialog failed due to an
  * unknown reason
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: TWT session already in
+ * suspend state
+ * @QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: FW has dropped the frame due to
+ * invalid IE in the received TWT frame
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: Parameters received from
+ * the responder are not in the specified range
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to request from the responder. Used on the TWT_TERMINATE
+ * notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to roaming. Used on the TWT_TERMINATE notification from the
+ * firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE: FW terminated the
+ * TWT session due to SCC (Single Channel Concurrency) and MCC (Multi Channel
+ * Concurrency). Used on the TWT_TERMINATE notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS: FW rejected the TWT setup
+ * request due to roaming in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS: FW rejected the TWT
+ * setup request due to channel switch in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS: FW rejected the TWT setup
+ * request due to scan in progress.
+ * QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE: The driver requested to
+ * terminate an existing TWT session on power save exit request from userspace.
+ * Used on the TWT_TERMINATE notification from the driver/firmware.
  */
 enum qca_wlan_vendor_twt_status {
 	QCA_WLAN_VENDOR_TWT_STATUS_OK = 0,
@@ -7986,6 +9119,16 @@
 	QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE = 10,
 	QCA_WLAN_VENDOR_TWT_STATUS_DENIED = 11,
 	QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR = 12,
+	QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED = 13,
+	QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID = 14,
+	QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE = 15,
+	QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE = 16,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE = 17,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE = 18,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS = 19,
+	QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS = 20,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS = 21,
+	QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE = 22,
 };
 
 /**
@@ -8012,6 +9155,10 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID: Required (u8).
  * Flow ID is the unique identifier for each TWT session. This attribute
  * represents the respective TWT session to resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer to which TWT Resume is
@@ -8034,6 +9181,231 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_twt_nudge - Represents attributes for
+ * TWT (Target Wake Time) nudge request. TWT nudge is a combination of suspend
+ * and resume in a single request. These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session to suspend and resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in TWT NUDGE request
+ * and response.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME: Required (u32)
+ * This attribute is used as the SP offset which is the offset from
+ * TSF after which the wake happens. The units are in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE: Required (u32)
+ * This attribute represents the next TWT subfield size.
+ * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits,
+ * and 4 for 64 bits.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer to which TWT Suspend and Resume is
+ * being sent. This is used in AP mode to represent the respective
+ * client and is a required parameter. In STA mode, this is an optional
+ * parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF: Optional (u64)
+ * This field contains absolute TSF value of the time at which the TWT
+ * session will be resumed.
+ */
+enum qca_wlan_vendor_attr_twt_nudge {
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE = 3,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_stats: Represents attributes for
+ * TWT (Target Wake Time) get statistics and clear statistics request.
+ * These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session for get and clear TWT statistics.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which TWT Statistics
+ * is required.
+ * In AP mode this is used to represent the respective
+ * client and is a required parameter for
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request and response
+ * In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION: Required (u32)
+ * This is the duration of the service period in microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION: Required (u32)
+ * Average of the actual wake duration observed so far. Unit is microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS: Required (u32)
+ * The number of TWT service periods elapsed so far.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION: Required (u32)
+ * This is the minimum value of the wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION: Required (u32)
+ * This is the maximum value of wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU: Required (u32)
+ * Average number of MPDUs transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU: Required (u32)
+ * Average number of MPDUs received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE: Required (u32)
+ * Average number of bytes transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE: Required (u32)
+ * Average number of bytes received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS: Required (u32)
+ * Status of the TWT GET STATISTICS request.
+ * This contains status values in enum qca_wlan_vendor_twt_status
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ */
+enum qca_wlan_vendor_attr_twt_stats {
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION = 3,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS = 5,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION = 6,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION = 7,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU = 8,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU = 9,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE = 10,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE = 11,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS = 12,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_twt_get_capa  - Represents the bitmap of TWT capabilities
+ * supported by the device and the peer.
+ * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_GET_CAPABILITIES
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by
+ * TWT non-scheduling STA. This capability is advertised in the HE
+ * Capability/Extended Capabilities information element in the
+ * Association Request frame by the device.
+ *
+ * @QCA_WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by
+ * the TWT scheduling AP. This capability is advertised in the Extended
+ * Capabilities/HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_BROADCAST: On the requestor side, this indicates support
+ * for the broadcast TWT functionality. On the responder side, this indicates
+ * support for the role of broadcast TWT scheduling functionality. This
+ * capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_TWT_FLEXIBLE: The device supports flexible TWT schedule.
+ * This capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate
+ * that it mandates the associated HE STAs to support TWT. This capability is
+ * advertised by AP in the HE Operation Parameters field of the HE Operation
+ * information element.
+ */
+enum qca_wlan_twt_capa {
+	QCA_WLAN_TWT_CAPA_REQUESTOR = BIT(0),
+	QCA_WLAN_TWT_CAPA_RESPONDER = BIT(1),
+	QCA_WLAN_TWT_CAPA_BROADCAST = BIT(2),
+	QCA_WLAN_TWT_CAPA_FLEXIBLE =  BIT(3),
+	QCA_WLAN_TWT_CAPA_REQUIRED =  BIT(4),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_capability  - Represents attributes for TWT
+ * get capabilities request type. Used by QCA_WLAN_TWT_GET_CAPABILITIES TWT
+ * operation.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which the TWT capabilities
+ * are being queried. This is used in AP mode to represent the respective
+ * client. In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF: (u16).
+ * Self TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER: (u16).
+ * Peer TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ */
+enum qca_wlan_vendor_attr_twt_capability {
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER = 3,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_set_param: Represents attributes for
+ * TWT (Target Wake Time) related parameters. It is used when
+ * %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to %QCA_WLAN_TWT_SET_PARAM.
+ * These attributes are sent as part of %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE: Optional (u8)
+ * This attribute configures AC parameters to be used for all TWT
+ * sessions in AP mode.
+ * Uses the enum qca_wlan_ac_type values.
+ */
+enum qca_wlan_vendor_attr_twt_set_param {
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST - 1,
+};
+
+/**
  * enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by
  * the TWT responder
  *
@@ -8124,6 +9496,22 @@
 };
 
 /**
+ * enum qca_wlan_vendor_cfr_data_transport_modes - Defines QCA vendor CFR data
+ * transport modes and is used by the attribute
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE as a part of the vendor
+ * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
+ * @QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS: Use relayfs to send CFR data.
+ * @QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS: Use netlink events to send CFR
+ * data. The data shall be encapsulated within
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA along with the vendor sub command
+ * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an asynchronous event.
+ */
+enum qca_wlan_vendor_cfr_data_transport_modes {
+	QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS = 0,
+	QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS = 1,
+};
+
+/**
  * enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by
  * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor
  * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
@@ -8313,6 +9701,27 @@
  * MAC for CFR capture. This is a bitmask in which each bit represents the
  * corresponding Data frame subtype value per IEEE Std 802.11-2016,
  * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE: Optional (u8)
+ * Userspace can use this attribute to specify the driver about which transport
+ * mode shall be used by the driver to send CFR data to userspace. Uses values
+ * from enum qca_wlan_vendor_cfr_data_transport_modes. When this attribute is
+ * not present, the driver shall use the default transport mechanism which is
+ * QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID: Optional (u32)
+ * Userspace can use this attribute to specify the nl port id of the application
+ * which receives the CFR data and processes it further so that the drivers can
+ * unicast the netlink events to a specific application. Optionally included
+ * when QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE is set to
+ * QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS, not required otherwise. The drivers
+ * shall multicast the netlink events when this attribute is not included.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA: Required (NLA_BINARY).
+ * This attribute will be used by the driver to encapsulate and send CFR data
+ * to userspace along with QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an
+ * asynchronous event when the driver is configured to send CFR data using
+ * netlink events with %QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS.
  */
 enum qca_wlan_vendor_peer_cfr_capture_attr {
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0,
@@ -8341,6 +9750,9 @@
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE = 26,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID = 27,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA = 28,
 
 	/* Keep last */
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST,
@@ -8562,7 +9974,6 @@
  *		has priority over BT_A2DP and ZB_HIGH.
  *	3: BT_A2DP has priority over ZB_HIGH.
  */
-
 enum qca_vendor_attr_coex_config_three_way {
 	QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_INVALID = 0,
 	QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE = 1,
@@ -9027,20 +10438,48 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE: Required
  * Nested attribute containing multiple ranges with following attributes:
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START,
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, and
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START: Required (u32)
  * Starting center frequency in MHz.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END: Required (u32)
  * Ending center frequency in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM:
+ * s32 attribute, optional. It is a per frequency range attribute.
+ * The maximum TX power limit from user space is to be applied on an
+ * unrestricted interface for corresponding frequency range. It is also
+ * possible that the actual TX power may be even lower than this cap due to
+ * other considerations such as regulatory compliance, SAR, etc. In absence of
+ * this attribute the driver shall follow current behavior which means
+ * interface (SAP/P2P) function can keep operating on an unsafe channel with TX
+ * power derived by the driver based on regulatory/SAR during interface up.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK:
+ * u32 attribute, optional. Indicates all the interface types which are
+ * restricted for all frequency ranges provided in
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ * This attribute encapsulates bitmasks of interface types defined in
+ * enum nl80211_iftype. If an interface is marked as restricted the driver must
+ * move to a safe channel and if no safe channel is available the driver shall
+ * terminate that interface functionality. In absence of this attribute,
+ * interface (SAP/P2P) can still continue operating on an unsafe channel with
+ * TX power limit derived from either
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM or based on
+ * regulatory/SAE limits if %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM
+ * is not provided.
  */
 enum qca_wlan_vendor_attr_avoid_frequency_ext {
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE = 1,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START = 2,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END = 3,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM = 4,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK = 5,
 
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_MAX =
@@ -9366,7 +10805,56 @@
  * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT: u32, used in STA mode
  * only. This represents number of Beacon frames received from this station with
  * the packet number less than or equal to the last received packet number when
- * beacon protection is enabled. 
+ * beacon protection is enabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE: u32, used in
+ * STA mode only. The driver uses this attribute to populate the connection
+ * failure reason codes and the values are defined in
+ * enum qca_sta_connect_fail_reason_codes. Userspace applications can send
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command after receiving
+ * a connection failure indication from the driver. The driver shall not
+ * include this attribute in response to the
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no connection
+ * failure observed in the last attempted connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE: u32, latest TX rate (Kbps)
+ * used by the station in its last TX frame while communicating to the AP in the
+ * connected state. When queried in the disconnected state, this represents the
+ * rate used by the STA in the last TX frame to the AP when it was connected.
+ * This attribute is used for STA mode only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX: u32, used in STA mode only.
+ * This represents the rate index used by the STA for the last TX frame to the
+ * AP. When queried in the disconnected state, this gives the last RIX used by
+ * the STA in the last TX frame to the AP when it was connected.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT: u32, used in STA
+ * mode only. This represents the number of times the STA TSF goes out of sync
+ * from the AP after the connection. If queried in the disconnected state, this
+ * gives the count of TSF out of sync for the last connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. This can be queried either in connected state or
+ * disconnected state. Each bit of this attribute represents the different
+ * roam trigger reason code which are defined in enum qca_vendor_roam_triggers.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON: u32, used in STA mode
+ * only. This represents the roam fail reason for the last failed roaming
+ * attempt by the firmware. Different roam failure reason codes are specified
+ * in enum qca_vendor_roam_fail_reasons. This can be queried either in
+ * connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be
+ * queried either in connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY: u32, used in STA mode only.
+ * This represents the average congestion duration of uplink frames in MAC
+ * queue in unit of ms. This can be queried either in connected state or
+ * disconnected state.
  */
 enum qca_wlan_vendor_attr_get_sta_info {
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0,
@@ -9412,6 +10900,14 @@
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT = 40,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE = 44,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX = 45,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT = 46,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY = 50,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST,
@@ -9842,4 +11338,718 @@
 	QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_wlan_vendor_attr_mbssid_tx_vdev_status - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL:
+ * u8 attribute. Notify the TX VDEV status. Possible values 0, 1
+ * belonging to MBSSID/EMA_AP configuration. 0 means Non-Tx VDEV,
+ * 1 means Tx VDEV. Mandatory attribute for all MBSSID VDEV status events.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT:
+ * u8 attribute, required. 1 means Tx VDEV up event. 0 means Tx VDEV down event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID:
+ * u8 attribute, required. Indicates group id of Tx VDEV.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * group information. The attributes defined in enum
+ * qca_wlan_vendor_attr_mbssid_tx_vdev_group_info
+ * are nested in this attribute.
+ */
+enum qca_wlan_vendor_attr_mbssid_tx_vdev_status {
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT = 2,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID = 3,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_MAX =
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX:
+ * u32 attribute, required. Contains interface index.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS:
+ * u8 attribute, required. 0 - means vdev is in down state.
+ * 1 - means vdev is in up state.
+ */
+enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info {
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS = 2,
+
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO - 1,
+};
+
+/**
+ * enum qca_wlan_concurrent_sta_policy_config - Concurrent STA policies
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY: Preference to the primary
+ * STA interface has to be given while selecting the connection policies
+ * (e.g., BSSID, band, TX/RX chains, etc.) for the subsequent STA interface.
+ * An interface is set as primary through the attribute
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY. This policy is not
+ * applicable if the primary interface has not been set earlier.
+ *
+ * The intention is not to downgrade the primary STA performance, such as:
+ * - Do not reduce the number of TX/RX chains of primary connection.
+ * - Do not optimize DBS vs. MCC/SCC, if DBS ends up reducing the number of
+ *   chains.
+ * - If using MCC, should set the MCC duty cycle of the primary connection to
+ *   be higher than the secondary connection.
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED: The connection policies for the
+ * subsequent STA connection shall be chosen to balance with the existing
+ * concurrent STA's performance.
+ * Such as
+ * - Can choose MCC or DBS mode depending on the MCC efficiency and hardware
+ *   capability.
+ * - If using MCC, set the MCC duty cycle of the primary connection to be equal
+ *   to the secondary.
+ * - Prefer BSSID candidates which will help provide the best "overall"
+ *   performance for all the STA connections.
+ */
+enum qca_wlan_concurrent_sta_policy_config {
+	QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY = 0,
+	QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_concurrent_sta_policy - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG:
+ * u8 attribute. Configures the concurrent STA policy configuration.
+ * Possible values are defined in enum qca_wlan_concurrent_sta_policy_config.
+ */
+enum qca_wlan_vendor_attr_concurrent_sta_policy {
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_MAX =
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST - 1,
+
+};
+
+/**
+ * enum qca_sta_connect_fail_reason_codes - Defines values carried
+ * by QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE vendor
+ * attribute.
+ * @QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND: No Probe Response frame received
+ *	for unicast Probe Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL: STA failed to send auth request.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED: AP didn't send ACK for
+ *	auth request.
+ * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED: Auth response is not
+ *	received from AP.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL: STA failed to send
+ *	Association Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED: AP didn't send ACK for
+ *	Association Request frame.
+ * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED: Association Response
+ *	frame is not received from AP.
+ */
+enum qca_sta_connect_fail_reason_codes {
+	QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND = 1,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL = 2,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED = 3,
+	QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED = 4,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL = 5,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED = 6,
+	QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED = 7,
+};
+
+/**
+ * enum qca_wlan_vendor_usable_channels_filter - Bitmask of different
+ * filters defined in this enum are used in attribute
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK.
+ *
+ * @QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX: When this bit is set, the driver
+ * shall filter the channels which are not usable because of coexistence with
+ * cellular radio.
+ * @QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY: When this bit is set, the driver
+ * shall filter the channels which are not usable because of existing active
+ * interfaces in the driver and will result in Multi Channel Concurrency, etc.
+ *
+ */
+enum qca_wlan_vendor_usable_channels_filter {
+	QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX = 0,
+	QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_chan_info - Attributes used inside
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ:
+ * u32 attribute, required. Indicates the center frequency of the primary
+ * channel in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ:
+ * u32 attribute. Indicates the center frequency of the primary segment of the
+ * channel in MHz. This attribute is required when reporting 40 MHz, 80 MHz,
+ * 160 MHz, and 320 MHz channels.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ:
+ * u32 attribute. Indicates the center frequency of the secondary segment of
+ * 80+80 channel in MHz. This attribute is required only when
+ * QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH is set to NL80211_CHAN_WIDTH_80P80.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH:
+ * u32 attribute, required. Indicates the bandwidth of the channel, possible
+ * values are defined in enum nl80211_chan_width.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK:
+ * u32 attribute, required. Indicates all the interface types for which this
+ * channel is usable. This attribute encapsulates bitmasks of interface types
+ * defined in enum nl80211_iftype.
+ *
+ */
+enum qca_wlan_vendor_attr_chan_info {
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ = 1,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH = 4,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_usable_channels - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK:
+ * u32 attribute. Indicates the bands from which the channels should be reported
+ * in response. This attribute encapsulates bit masks of bands defined in enum
+ * nl80211_band. Optional attribute, if not present in the request the driver
+ * shall return channels from all supported bands.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK:
+ * u32 attribute. Indicates all the interface types for which the usable
+ * channels information is requested. This attribute encapsulates bitmasks of
+ * interface types defined in enum nl80211_iftype. Optional attribute, if not
+ * present in the request the driver shall send information of all supported
+ * interface modes.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK:
+ * u32 attribute. This attribute carries information of all filters that shall
+ * be applied while populating usable channels information by the driver. This
+ * attribute carries bit masks of different filters defined in enum
+ * qca_wlan_vendor_usable_channels_filter. Optional attribute, if not present
+ * in the request the driver shall send information of channels without applying
+ * any of the filters that can be configured through this attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * usability information of each channel. The attributes defined in enum
+ * qca_wlan_vendor_attr_chan_info are used inside this attribute.
+ */
+enum qca_wlan_vendor_attr_usable_channels {
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK = 1,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK = 2,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK = 3,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX =
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_radar_history: Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY to get DFS radar history.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES: Nested attribute to carry
+ *	the list of radar history entries.
+ *	Each entry contains freq, timestamp, and radar signal detect flag.
+ *	The driver shall add an entry when CAC has finished, or radar signal
+ *	has been detected post AP beaconing. The driver shall maintain at least
+ *	8 entries in order to save CAC result for a 160 MHz channel.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ: u32 attribute.
+ *	Channel frequency in MHz.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP: u64 nanoseconds.
+ *	CLOCK_BOOTTIME timestamp when this entry is updated due to CAC
+ *	or radar detection.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED: NLA_FLAG attribute.
+ *	This flag indicates radar signal has been detected.
+ */
+enum qca_wlan_vendor_attr_radar_history {
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_INVALID = 0,
+
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES = 1,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP = 3,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX =
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_mcc_quota_type: MCC channel time quota type
+ *
+ * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR: In the event, it indicates that the
+ *	target exited MCC state and cleared the quota information. In the
+ *	command it clears MCC quota setting and restores adaptive scheduling.
+ * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED: Channel time quota is fixed and
+ *      will not be changed.
+ * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC: Channel time quota is dynamic
+ *      and the target may change the quota based on the data activity.
+ */
+enum qca_wlan_vendor_mcc_quota_type {
+	QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR = 0,
+	QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED = 1,
+	QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mcc_quota: Used by the vendor event
+ * QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA to indicate MCC channel
+ * quota information or as a command to set the required MCC quota for an
+ * interface.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE: u32 attribute.
+ * The type is defined in enum qca_wlan_vendor_mcc_quota_type.
+ * In a command this specifies the MCC quota type to be set for the interface.
+ * In an event this provides the current quota type in force.
+ * This is required in a command and an event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES: Nested attribute to carry
+ * the list of channel quota entries.
+ * In an event each entry contains the frequency and respective time quota for
+ * all the MCC interfaces.
+ * In a command it specifies the interface index and respective time quota.
+ * In a command only one entry (ifindex, quota pair) may be specified.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ: u32 attribute.
+ * Channel frequency in MHz. This is present only in an event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE: u32 attribute.
+ * Channel time quota expressed as percentage.
+ * This is present in an event and a command.
+ * In an command, the user shall specify the quota to be allocated for the
+ * interface represented by %QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX.
+ * In an event this provides the existing quota for the channel.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX: u32 attribute.
+ * Specifies the interface index (netdev) for which the corresponding
+ * configurations are applied. This is required in a command only. Only one
+ * interface index may be specified. If not specified, the configuration is
+ * rejected.
+ */
+enum qca_wlan_vendor_attr_mcc_quota {
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE = 1,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES = 2,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE = 4,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST,
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX =
+	QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mdns_offload - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE: Required (flag)
+ * Enable mDNS offload. This attribute is mandatory to enable
+ * mDNS offload feature. If this attribute is not present, mDNS offload
+ * is disabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE: Nested attribute containing
+ * one or more %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY attributes. This
+ * attribute is mandatory when enabling the feature, and not required when
+ * disabling the feature.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY: Nested attribute containing
+ * the following attributes:
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN: Required string attribute.
+ * It consists of a hostname and ".local" as the domain name. The character
+ * set is limited to UTF-8 encoding. The maximum allowed size is 63 bytes.
+ * It is used to compare the domain in the "QU" query. Only 1 FQDN is
+ * supported per vdev.
+ * For example: myphone.local
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT: Required
+ * u16 attribute. It specifies the total number of resource records present
+ * in the answer section of the answer payload. This attribute is needed by the
+ * firmware to populate the mDNS response frame for mDNS queries without having
+ * to parse the answer payload.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD: Required binary blob
+ * attribute sent by the mdnsResponder from userspace. It contains resource
+ * records of various types (e.g., A, AAAA, PTR, TXT) and service list. This
+ * payload is passed down to the firmware and is transmitted in response to
+ * mDNS queries.
+ * The maximum supported size of the answer payload is 512 bytes.
+ */
+enum qca_wlan_vendor_attr_mdns_offload {
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE = 1,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE = 2,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY = 3,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN = 4,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT = 5,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD = 6,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_MAX =
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_vendor_monitor_data_frame_type - Represent the various
+ * Data frame types to be sent over the monitor interface.
+ */
+enum qca_wlan_vendor_monitor_data_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17),
+};
+
+/**
+ * qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various
+ * Management frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the Management Frames.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the Management frames
+ * except the Beacon frame.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected
+ * BSSID Beacon frames. Valid only in the connected state.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents
+ * the Beacon frames obtained during the scan (off channel and connected
+ * channel), when in connected state.
+ */
+enum qca_wlan_vendor_monitor_mgmt_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_MGMT_NO_BEACON = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3),
+};
+
+/**
+ * qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various
+ * Control frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the Control frames
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger frame
+ */
+enum qca_wlan_vendor_monitor_ctrl_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_set_monitor_mode - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the
+ * monitor mode.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL: u32
+ * attribute.
+ * Represents the interval in milliseconds only for the connected Beacon frames,
+ * expecting the connected BSS's Beacon frames to be sent on the monitor
+ * interface at this specific interval.
+ */
+enum qca_wlan_vendor_attr_set_monitor_mode {
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX =
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_roam_scan_state - Roam scan state flags.
+ * Bits will be set to 1 if the corresponding state is enabled.
+ *
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start.
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end.
+ */
+enum qca_wlan_vendor_roam_scan_state {
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_roam_event_type - Roam event type flags.
+ * Bits will be set to 1 if the corresponding event is notified.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event
+ * carries the trigger reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries
+ * the BSSID, RSSI, frequency info of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event
+ * carries the roam fail reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the
+ * BSSID, RSSI, frequency info of the AP to which the roam was attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam
+ * event carries the roam invoke fail reason. When set, it is expected that
+ * the roam event carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event
+ * carries the roam scan state. When set, it is expected that the roam event
+ * carries the respective scan state via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding
+ * frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST.
+ */
+enum qca_wlan_vendor_roam_event_type {
+	QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1),
+	QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2),
+	QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info.
+ * Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address
+ * representing the BSSID of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value
+ * in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is
+ * attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, frequency in MHz
+ * on which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam fail reason for the last failed
+ * roaming attempt by the firmware for the specific BSSID. Different roam
+ * failure reason codes are specified in enum qca_vendor_roam_fail_reasons.
+ */
+enum qca_wlan_vendor_attr_roam_events_candidate_info {
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the
+ * roam events to the driver or notify these events from the driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the
+ * driver/firmware to enable/disable the notification of roam events. It's a
+ * mandatory attribute and used only in the request from the userspace to the
+ * host driver. 1-Enable, 0-Disable.
+ * If the roaming is totally offloaded to the firmware, this request when
+ * enabled shall mandate the firmware to notify all the relevant roam events
+ * represented by the below attributes. If the host is in the suspend mode,
+ * the behavior of the firmware to notify these events is guided by
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get
+ * these events in the suspend state, the firmware is expected to wake up the
+ * host before the respective events are notified. Please note that such a
+ * request to get the events in the suspend state will have a definite power
+ * implication.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents
+ * that the roam events need to be notified in the suspend state too. By
+ * default, these roam events are notified in the resume state. With this flag,
+ * the roam events are notified in both resume and suspend states.
+ * This attribute is used in the request from the userspace to the host driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only.
+ * Represents the different roam event types, signified by the enum
+ * qca_wlan_vendor_roam_event_type.
+ * Each bit of this attribute represents the different roam even types reported
+ * through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. Each bit of this attribute represents the
+ * different roam trigger reason code which are defined in enum
+ * qca_vendor_roam_triggers.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info
+ * for which the roam is attempted. Each entry is a nested attribute defined
+ * by enum qca_wlan_vendor_attr_roam_events_candidate_info.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents
+ * the scan state on which the roam events need to be notified. The values for
+ * this attribute are referred from enum qca_wlan_vendor_roam_scan_state.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of
+ * u32 values. List of frequencies in MHz considered for a roam scan.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ */
+enum qca_wlan_vendor_attr_roam_events {
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST -1,
+};
+
+/**
+ * enum qca_wlan_ratemask_params_type - Rate mask config type
+ *
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM: CCK/OFDM rate mask config
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HT: HT rate mask config
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT: VHT rate mask config
+ * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HE: HE rate mask config
+ */
+enum qca_wlan_ratemask_params_type {
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM = 0,
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_HT = 1,
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT = 2,
+	QCA_WLAN_RATEMASK_PARAMS_TYPE_HE = 3,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ratemask_params - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG.
+ * This is used to set the rate mask value to be used in rate selection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST:
+ * Array of nested containing attributes
+ * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE and
+ * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE: u8, represents
+ * the different PHY types to which the rate mask config is to be applied.
+ * The values for this attribute are referred from enum
+ * qca_wlan_vendor_ratemask_params_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP: binary, rate mask bitmap.
+ * A bit value of 1 represents rate is enabled and a value of 0
+ * represents rate is disabled.
+ * For HE targets, 12 bits correspond to one NSS setting.
+ * b0-13  => NSS1, MCS 0-13
+ * b14-27 => NSS2, MCS 0-13 and so on for other NSS.
+ * For VHT targets, 10 bits correspond to one NSS setting.
+ * b0-9   => NSS1, MCS 0-9
+ * b10-19 => NSS2, MCS 0-9 and so on for other NSS.
+ * For HT targets, 8 bits correspond to one NSS setting.
+ * b0-7  => NSS1, MCS 0-7
+ * b8-15 => NSS2, MCS 0-7 and so on for other NSS.
+ * For OFDM/CCK targets, 8 bits correspond to one NSS setting.
+ */
+enum qca_wlan_vendor_attr_ratemask_params {
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST = 1,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE = 2,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP = 3,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_MAX =
+	QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST - 1,
+};
+
 #endif /* QCA_VENDOR_H */
diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/wpa_driver_common_lib.h b/wcn6740/qcwcn/wpa_supplicant_8_lib/wpa_driver_common_lib.h
new file mode 100644
index 0000000..054d840
--- /dev/null
+++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/wpa_driver_common_lib.h
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WPA_DRIVER_COMMON_LIB
+#define WPA_DRIVER_COMMON_LIB
+
+#include "android_drv.h"
+#define OUI_LEN		3
+#define MAX_CMD_LEN	32
+#define MAC_ADDR_LEN	6
+#define COUNTRY_LEN	4
+
+#define IEEE80211_HE_OPERATION_VHT_OPER_MASK 0x00004000
+#define IEEE80211_HE_OPERATION_CO_LOC_BSS_MASK 0x00008000
+#define IEEE80211_HE_OPERATION_6G_OPER_MASK 0x00020000
+
+#define HE_OPER_VHT_CH_WIDTH_OFFSET 0
+#define HE_OPER_VHT_CENTER_FRQ_SEG0_OFFSET 1
+#define HE_OPER_VHT_CENTER_FRQ_SEG1_OFFSET 2
+#define HE_OPER_VHT_MAX_OFFSET 2
+
+#define HE_OPER_CO_LOCATED_MAX_OFFSET 0
+
+#define HE_OPER_6G_PARAMS_OFFSET 1
+
+#define HE_OPER_6G_PARAMS_SUB_CH_BW_MASK 0X03
+
+#define CHANNEL_BW_INVALID 255
+
+/* Define short names */
+#define GET_STATION_INFO_AKM \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
+#define GET_STATION_INFO_HT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
+#define GET_STATION_INFO_VHT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
+#define GET_STATION_INFO_REMOTE_LAST_RX_RATE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_RX_RATE
+#define GET_STATION_INFO_REMOTE_SUPPORTED_MODE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SUPPORTED_MODE
+#define GET_STATION_INFO_REMOTE_CH_WIDTH \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH
+#define GET_STATION_INFO_REMOTE_RX_RETRY_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT
+#define GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT
+#define GET_STATION_INFO_BEACON_IES \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES
+#define GET_STATION_INFO_DRIVER_DISCONNECT_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON
+#define GET_STATION_INFO_ASSOC_REQ_IES \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES
+#define GET_STATION_INFO_HE_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION
+#define GET_STATION_INFO_MAX \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX
+
+#define GET_STA_INFO_MAC \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC
+#define GET_STA_INFO_RX_RETRY_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT
+#define GET_STA_INFO_RX_BC_MC_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT
+#define GET_STA_INFO_TX_RETRY_SUCCEED \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED
+#define GET_STA_INFO_TX_RETRY_EXHAUSTED \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED
+#define GET_STA_INFO_TARGET_TX_TOTAL \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL
+#define GET_STA_INFO_TARGET_TX_RETRY \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY
+#define GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED
+#define GET_STA_INFO_ANI_LEVEL \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL
+#define GET_STA_INFO_LATEST_TX_RATE \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE
+#define GET_STA_INFO_LATEST_RIX \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX
+#define GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT
+#define GET_STA_INFO_LATEST_TX_POWER \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER
+#define GET_STA_INFO_ROAM_TRIGGER_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON
+#define GET_STA_INFO_TARGET_POWER_24G_1MBPS \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS
+#define GET_STA_INFO_TARGET_POWER_24G_6MBPS \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS
+#define GET_STA_INFO_TARGET_POWER_5G_6MBPS \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS
+#define GET_STA_INFO_ROAM_FAIL_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON
+#define GET_STA_INFO_ROAM_INVOKE_FAIL_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON
+#define GET_STA_INFO_MAX \
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX
+
+struct bss_info {
+	uint8_t oui[OUI_LEN];
+	char ssid[MAX_SSID_LEN + 1];
+	int channel;
+	int bw;
+	int rssi;
+	int data_rate;
+	/* 0 : 11b, 1 : 11g, 2 : 11n, 3 : 11a, 4 : 11ac */
+	int mode_80211;
+	/* 0 : SISO, 1 : MIMO (2X2), 2 : MIMO (3X3), 3 : MIMO (4X4) */
+	int snr;
+	int noise;
+	int akm;
+	int roaming_count;
+	/* 0: None, 1: 11k, 2: 11v, 3: 11kv */
+	int mode_11kv;
+	/* Bit mask value of 11kv support */
+	int mask_11kv;
+	u32 disc_reasn_code;
+	u32 ani_level;
+	u32 roam_trigger_reason;
+	u32 roam_fail_reason;
+	u32 roam_invoke_fail_reason;
+	u32 tsf_out_of_sync_count;
+	u32 latest_tx_power;
+	u32 latest_tx_rate;
+	u32 target_power_24g_1mbps;
+	u32 target_power_24g_6mbps;
+	u32 target_power_5g_6mbps;
+};
+
+enum get_info_cmd {
+	GETSTATSBSSINFO = 1,
+	SETCELLSWITCHMODE = 2,
+	GET_DRIVER_SUPPORTED_FEATURES = 3,
+};
+
+struct resp_info {
+	u32 subcmd;
+	char *reply_buf;
+	int reply_buf_len;
+	enum get_info_cmd cmd_type;
+	uint8_t mac_addr[MAC_ADDR_LEN];
+	u32 freq;
+	uint8_t country[COUNTRY_LEN];
+};
+
+#define QCA_NL80211_VENDOR_SUBCMD_GET_STATION 121
+
+#ifndef CHANWIDTH_USE_HT
+#define CHANWIDTH_USE_HT VHT_CHANWIDTH_USE_HT
+#endif /* CHANWIDTH_USE_HT */
+#ifndef CHANWIDTH_80MHZ
+#define CHANWIDTH_80MHZ VHT_CHANWIDTH_80MHZ
+#endif /* CHANWIDTH_80MHZ */
+#ifndef CHANWIDTH_160MHZ
+#define CHANWIDTH_160MHZ VHT_CHANWIDTH_160MHZ
+#endif /* CHANWIDTH_160MHZ */
+#ifndef CHANWIDTH_80P80MHZ
+#define CHANWIDTH_80P80MHZ VHT_CHANWIDTH_80P80MHZ
+#endif /* CHANWIDTH_80P80MHZ */
+
+/* HE channel widths */
+
+#define HE_CHANWIDTH_20MHZ     0
+#define HE_CHANWIDTH_40MHZ     1
+#define HE_CHANWIDTH_80MHZ     2
+#define HE_CHANWIDTH_160MHZ    3
+
+/**
+ * enum qca_wlan_vendor_attr_get_station - Sub commands used by
+ * QCA_NL80211_VENDOR_SUBCMD_GET_STATION to get the corresponding
+ * station information. The information obtained through these
+ * commands signify the current info in connected state and
+ * latest cached information during the connected state , if queried
+ * when in disconnected state.
+ */
+enum qca_wlan_vendor_attr_get_station {
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX =
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_get_station_info - Station Info queried
+ * through QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
+ */
+enum qca_wlan_vendor_attr_get_station_info {
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_INVALID = 0,
+	/*
+	 * Get the standard NL attributes Nested with this attribute.
+	 * Ex : Query BW , BITRATE32 , NSS , Signal , Noise of the Link -
+	 * NL80211_ATTR_SSID / NL80211_ATTR_SURVEY_INFO (Connected Channel) /
+	 * NL80211_ATTR_STA_INFO
+	 */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR,
+	/*
+	 * Get the standard NL attributes Nested with this attribute.
+	 * Ex : Query HT/VHT Capability advertized by the AP.
+	 * NL80211_ATTR_VHT_CAPABILITY / NL80211_ATTR_HT_CAPABILITY
+	 */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_AP_INFO_ATTR,
+
+	/* Number of successful Roam attempts before a disconnect,
+	 * Unsigned 32 bit value
+	 */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT,
+
+	/* Authentication Key Management Type used for the connected session.
+	 * Signified by enum qca_wlan_auth_type
+	 */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM,
+
+	/* 802.11 Mode of the connected Session,
+	 * signified by enum qca_wlan_802_11_mode
+	 */
+	QCA_WLAN_VENDOR_ATTR_802_11_MODE,
+
+	/* HS20 Indication Element */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_AP_INFO_HS20_INDICATION,
+
+	/* HT/VHT operation elements */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION,
+
+	/* Status Code Corresponding to the Association Failure.
+	 * Unsigned 32 bit value
+	 */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSSOC_FAIL_REASON,
+
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_MAX_PHY_RATE,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_PACKETS,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_BYTES,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_PACKETS,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BYTES,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_TX_RATE,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_RX_RATE,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_WMM,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SUPPORTED_MODE,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AMPDU,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_STBC,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_FAILURE,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AVG_RSSI_PER_CHAIN,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_SUCCEED,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_LAST_PKT_RSSI,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_EXHAUST,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_TOTAL_FW,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_FW,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_EXHAUST_FW,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST - 1,
+};
+
+#define NOISE_FLOOR_DBM (96)
+
+#define WMI_MAX_CHAINS (3)
+
+enum qca_vendor_wlan_chan_width {
+	QCA_VENDOR_WLAN_CHAN_WIDTH_20 = 0,
+	QCA_VENDOR_WLAN_CHAN_WIDTH_40 = 1,
+	QCA_VENDOR_WLAN_CHAN_WIDTH_80 = 2,
+	QCA_VENDOR_WLAN_CHAN_WIDTH_80_80 = 3,
+	QCA_VENDOR_WLAN_CHAN_WIDTH_160 = 4,
+};
+
+enum qca_vendor_wlan_802_11_mode {
+	QCA_VENDOR_WLAN_802_11_MODE_B = 0,
+	QCA_VENDOR_WLAN_802_11_MODE_G = 1,
+	QCA_VENDOR_WLAN_802_11_MODE_N = 2,
+	QCA_VENDOR_WLAN_802_11_MODE_A = 3,
+	QCA_VENDOR_WLAN_802_11_MODE_AC = 4,
+	QCA_VENDOR_WLAN_802_11_MODE_AX = 5,
+};
+
+enum qca_vendor_wlan_phy_mode {
+	QCA_VENDOR_WLAN_PHY_MODE_LEGACY = 0,
+	QCA_VENDOR_WLAN_PHY_MODE_HT = 1,
+	QCA_VENDOR_WLAN_PHY_MODE_VHT = 2,
+	QCA_VENDOR_WLAN_PHY_MODE_HE = 3,
+};
+
+struct assoc_req_ie_flags {
+	u8 ht_supported:1;
+	u8 vht_supported:1;
+	u8 he_supported:1;
+};
+
+struct remote_sta_info {
+	u8 num_sta;
+	u8 num_request_vendor_sta_info;
+	u8 num_received_vendor_sta_info;
+	u8 num_request_nl80211_sta_info;
+	u8 num_received_nl80211_sta_info;
+	u8 mac_addr[MAC_ADDR_LEN];
+	u32 rx_retry_pkts;
+	u32 rx_bcmc_pkts;
+	u16 cap;
+	u32 freq;
+	u8 bandwidth;
+	s8 rssi;
+	u32 data_rate;
+	u32 dot11_mode;
+	u32 reason;
+	u8 supported_mode;
+	u32 tx_pckts;
+	u32 tx_failures;
+	u32 tx_rate;
+	s32 avg_rssi_per_chain[WMI_MAX_CHAINS];
+	u32 tx_pkts_retried;
+	u32 tx_pkts_retry_exhausted;
+	s32 rx_lastpkt_rssi;
+	u32 tx_pkts_total;
+	u32 tx_pkts_retries;
+	u32 tx_pkts_fw_total;
+	u32 tx_pkts_fw_retries;
+	u32 tx_pkts_fw_retry_exhausted;
+	u32 ani_level;
+	u32 roam_trigger_reason;
+	u32 roam_fail_reason;
+	u32 roam_invoke_fail_reason;
+	u32 tsf_out_of_sync_count;
+	u32 latest_tx_power;
+	u32 latest_tx_rate;
+	u32 latest_rix;
+	u32 target_power_24g_1mbps;
+	u32 target_power_24g_6mbps;
+	u32 target_power_5g_6mbps;
+	u8 *supp_op_classes; /* Supported Operating Classes element, if
+			      * received, starting from the Length field */
+	u8 *supp_channels;
+	u32 supported_band;
+	bool show_band;
+	struct assoc_req_ie_flags flags;
+	uint8_t country[COUNTRY_LEN];
+};
+
+#endif
diff --git a/wcn6740/wcnss-service/Android.mk b/wcn6740/wcnss-service/Android.mk
new file mode 100644
index 0000000..42d83e1
--- /dev/null
+++ b/wcn6740/wcnss-service/Android.mk
@@ -0,0 +1,30 @@
+ifneq (,$(filter arm aarch64 arm64, $(TARGET_ARCH)))
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+LOCAL_VENDOR_MODULE := true
+endif
+LOCAL_MODULE := wcnss_service
+LOCAL_HEADER_LIBRARIES += vendor_common_inc
+LOCAL_SRC_FILES := wcnss_service.c
+LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog
+ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true)
+LOCAL_CFLAGS += -DWCNSS_QMI
+ifeq ($(filter 10% Q% q%,$(TARGET_PLATFORM_VERSION)),)
+#For Android R and above, assuming not compiling on Q and lower
+LOCAL_HEADER_LIBRARIES += libqmi_common_headers
+else
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/inc
+endif
+LOCAL_SRC_FILES += wcnss_qmi_client.c
+LOCAL_SHARED_LIBRARIES += libqmiservices libqmi_cci
+LOCAL_HEADER_LIBRARIES += libmdmdetect_headers
+LOCAL_SHARED_LIBRARIES += libmdmdetect
+LOCAL_HEADER_LIBRARIES += libril-qc-qmi-services-headers
+endif #TARGET_USES_QCOM_WCNSS_QMI
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/wcn6740/wcnss-service/wcnss_qmi_client.c b/wcn6740/wcnss-service/wcnss_qmi_client.c
new file mode 100644
index 0000000..3e1fb0e
--- /dev/null
+++ b/wcn6740/wcnss-service/wcnss_qmi_client.c
@@ -0,0 +1,135 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of The Linux Foundation nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+
+#ifdef WCNSS_QMI
+#define LOG_TAG "wcnss_qmi"
+#include <cutils/log.h>
+#include "wcnss_qmi_client.h"
+#include "qmi_client.h"
+#include "device_management_service_v01.h"
+#include <cutils/properties.h>
+#include <string.h>
+
+#define SUCCESS 0
+#define FAILED -1
+
+#define WLAN_ADDR_SIZE   6
+#define DMS_QMI_TIMEOUT (2000)
+
+static qmi_client_type dms_qmi_client;
+static int dms_init_done = FAILED;
+
+int wcnss_init_qmi()
+{
+	qmi_client_error_type qmi_client_err;
+
+	ALOGE("%s: Initialize wcnss QMI Interface", __func__);
+        qmi_client_os_params dms_os_params;
+
+	memset(&dms_os_params, 0, sizeof(qmi_client_os_params));
+	qmi_client_err = qmi_client_init_instance(dms_get_service_object_v01(),
+			QMI_CLIENT_INSTANCE_ANY, NULL, NULL,
+			&dms_os_params, 5000, &dms_qmi_client);
+
+	if (qmi_client_err != QMI_NO_ERR){
+		ALOGE("%s: Error while Initializing QMI Client: %d",
+			__func__, qmi_client_err);
+		goto exit;
+	}
+
+	dms_init_done = SUCCESS;
+	return SUCCESS;
+
+exit:
+	return FAILED;
+}
+
+int wcnss_qmi_get_wlan_address(unsigned char *pBdAddr)
+{
+	qmi_client_error_type qmi_client_err;
+	dms_get_mac_address_req_msg_v01 addr_req;
+	dms_get_mac_address_resp_msg_v01 addr_resp;
+
+	if ((dms_init_done == FAILED) || (pBdAddr == NULL)) {
+		ALOGE("%s: DMS init fail or pBdAddr is NULL", __func__);
+		return FAILED;
+	}
+
+	/* clear the request content */
+	memset(&addr_req, 0, sizeof(addr_req));
+
+	/*Request to get the WLAN MAC address */
+	addr_req.device = DMS_DEVICE_MAC_WLAN_V01;
+
+	qmi_client_err = qmi_client_send_msg_sync(dms_qmi_client,
+		QMI_DMS_GET_MAC_ADDRESS_REQ_V01, &addr_req, sizeof(addr_req),
+		&addr_resp, sizeof(addr_resp), DMS_QMI_TIMEOUT);
+
+	if (qmi_client_err != QMI_NO_ERR){
+		ALOGE("%s: Failed to get Rsp from Modem Error:%d",
+				__func__, qmi_client_err);
+		return FAILED;
+	}
+
+	ALOGE("%s: Mac Address_valid: %d Mac Address Len: %d",
+				__func__, addr_resp.mac_address_valid,
+				addr_resp.mac_address_len);
+
+	if (addr_resp.mac_address_valid &&
+		(addr_resp.mac_address_len == WLAN_ADDR_SIZE)) {
+		memcpy(pBdAddr, addr_resp.mac_address,
+			addr_resp.mac_address_len);
+		ALOGE("%s: Succesfully Read WLAN MAC Address", __func__);
+		return SUCCESS;
+	} else {
+		ALOGE("%s: Failed to Read WLAN MAC Address", __func__);
+		return FAILED;
+	}
+}
+
+void wcnss_qmi_deinit()
+{
+	qmi_client_error_type qmi_client_err;
+
+	ALOGE("%s: Deinitialize wcnss QMI Interface", __func__);
+
+	if (dms_init_done == FAILED) {
+		ALOGE("%s: DMS Service was not Initialized", __func__);
+		return;
+	}
+
+	qmi_client_err = qmi_client_release(dms_qmi_client);
+
+	if (qmi_client_err != QMI_NO_ERR){
+		ALOGE("%s: Error while releasing qmi_client: %d",
+			__func__, qmi_client_err);
+	}
+
+	dms_init_done = FAILED;
+}
+#endif
diff --git a/qcwcn/wcnss-service/wcnss_qmi_client.h b/wcn6740/wcnss-service/wcnss_qmi_client.h
similarity index 100%
copy from qcwcn/wcnss-service/wcnss_qmi_client.h
copy to wcn6740/wcnss-service/wcnss_qmi_client.h
diff --git a/wcn6740/wcnss-service/wcnss_service.c b/wcn6740/wcnss-service/wcnss_service.c
new file mode 100644
index 0000000..c817be1
--- /dev/null
+++ b/wcn6740/wcnss-service/wcnss_service.c
@@ -0,0 +1,815 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of The Linux Foundation nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <grp.h>
+#include <utime.h>
+#include <sys/stat.h>
+#include <sys/sendfile.h>
+#define LOG_TAG "wcnss_service"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#ifdef WCNSS_QMI
+#include "wcnss_qmi_client.h"
+#include "mdm_detect.h"
+#endif
+
+#define SUCCESS 0
+#define FAILED -1
+#define BYTE_0  0
+#define BYTE_1  8
+#define BYTE_2  16
+#define BYTE_3  24
+#define UNUSED(x)	(void)(x)
+
+#define MAX_FILE_LENGTH    (1024)
+#define WCNSS_MAX_CMD_LEN  (128)
+
+/* control messages to wcnss driver */
+#define WCNSS_USR_CTRL_MSG_START    0x00000000
+#define WCNSS_USR_SERIAL_NUM        (WCNSS_USR_CTRL_MSG_START + 1)
+#define WCNSS_USR_HAS_CAL_DATA      (WCNSS_USR_CTRL_MSG_START + 2)
+#define WCNSS_USR_WLAN_MAC_ADDR     (WCNSS_USR_CTRL_MSG_START + 3)
+
+
+#define WCNSS_CAL_CHUNK (3*1024)
+#define WCNSS_CAL_FILE  "/data/vendor/wifi/WCNSS_qcom_wlan_cal.bin"
+#define WCNSS_FACT_FILE "/data/vendor/wifi/WCN_FACTORY"
+#define WCNSS_DEVICE    "/dev/wcnss_wlan"
+#define WCNSS_CTRL      "/dev/wcnss_ctrl"
+#define WLAN_INI_FILE_DEST   "/data/vendor/wifi/WCNSS_qcom_cfg.ini"
+#define WLAN_INI_FILE_SOURCE "/vendor/etc/wifi/WCNSS_qcom_cfg.ini"
+#define WCNSS_HAS_CAL_DATA\
+		"/sys/module/wcnsscore/parameters/has_calibrated_data"
+#define WLAN_DRIVER_ATH_DEFAULT_VAL "0"
+
+#define ASCII_A		65
+#define ASCII_a		97
+#define ASCII_0		48
+#define HEXA_A		10
+#define HEX_BASE		16
+
+#ifdef WCNSS_QMI
+#define WLAN_ADDR_SIZE   6
+unsigned char wlan_nv_mac_addr[WLAN_ADDR_SIZE];
+#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+/* As we Want to write in 00:0a:f5:11:22:33 format in sysfs file
+   so taking mac length as 12 char + 5 for ":" + NULL
+ */
+#define WLAN_MAC_ADDR_STRING 18
+#endif
+
+#define MAX_SOC_INFO_NAME_LEN (15)
+#define MAX_DATA_NVBIN_PATH_LEN (64)
+#define QRD_DYNAMIC_NV_PROP  "persist.sys.dynamic.nv"
+#define QRD_HW_PLATFORM  "QRD"
+#define QRD_PLATFORM_SUBTYPE_ID  0
+#define PERSIST_NVFILE    "/persist/WCNSS_qcom_wlan_nv.bin"
+#define DATA_NVFILE_DIR   "/data/misc/wifi/nvbin/"
+#define SYSFS_SOCID_PATH1   "/sys/devices/soc0/soc_id"
+#define SYSFS_SOCID_PATH2   "/sys/devices/system/soc/soc0/id"
+#define SYSFS_HW_PLATFORM_PATH1  "/sys/devices/soc0/hw_platform"
+#define SYSFS_HW_PLATFORM_PATH2   "/sys/devices/system/soc/soc0/hw_platform"
+#define SYSFS_PLATFORM_SUBTYPE_PATH1   "/sys/devices/soc0/platform_subtype_id"
+#define SYSFS_PLATFORM_SUBTYPE_PATH2    "/sys/devices/system/soc/soc0/platform_subtype_id"
+#define SYSFS_PLATFORM_VERSION_PATH1  "/sys/devices/soc0/platform_version"
+#define SYSFS_PLATFORM_VERSION_PATH2   "/sys/devices/system/soc/soc0/platform_version"
+#define SOCINFO_HWVER_MAJOR(ver) (((ver) & 0x00ff0000) >> 16)
+#define SOCINFO_HWVER_MINOR(ver) ((ver) & 0x000000ff)
+#define GET_SOC_INFO(buf, soc_node_path1, soc_node_path2, info_got) \
+		{  if (get_soc_info(buf, soc_node_path1, soc_node_path2) < 0) \
+		    { \
+		        ALOGE("get_soc_info failed!\n"); \
+		        return FAILED; \
+		    } \
+		    info_got = atoi(buf); \
+		}
+
+int wcnss_write_cal_data(int fd_dev)
+{
+	int rcount = 0;
+	int size = 0;
+	int rc = 0;
+	int wcount = 0;
+	int fd_file;
+	struct stat st;
+
+	char buf[WCNSS_CAL_CHUNK];
+
+	ALOGI("wcnss_write_cal_data trying to write cal");
+
+	rc = stat(WCNSS_CAL_FILE, &st);
+	if (rc < 0) {
+		ALOGE("Failed to stat cal file : %s",
+				strerror(errno));
+		goto exit;
+	}
+
+	size = st.st_size;
+
+	fd_file = open(WCNSS_CAL_FILE, O_RDONLY);
+	if (fd_file < 0) {
+		ALOGE("cal file doesn't exist: %s",
+				strerror(errno));
+		rc = fd_file;
+		goto exit;
+	}
+
+	/* write the file size first, so that platform driver knows
+	 * when it recieves the full data */
+	wcount = write(fd_dev, (void *)&size, 4);
+	if (wcount != 4) {
+		ALOGE("Failed to write to wcnss device : %s",
+				strerror(errno));
+		rc = wcount;
+		goto exit_close;
+	}
+
+	do {
+		rcount = read(fd_file, (void *)buf, sizeof(buf));
+		if (rcount < 0) {
+			ALOGE("Failed to read from cal file ; %s",
+					strerror(errno));
+			rc = rcount;
+			goto exit_remove;
+		}
+
+		if (!rcount)
+			break;
+
+		wcount = write(fd_dev, buf, rcount);
+		if (wcount < 0) {
+			ALOGE("Failed to write to wcnss device : %s",
+				strerror(errno));
+			rc = wcount;
+			goto exit_close;
+		}
+
+	} while (rcount);
+	close(fd_file);
+
+	return SUCCESS;
+
+exit_remove:
+	close(fd_file);
+	remove("WCNSS_CAL_FILE");
+	return rc;
+
+exit_close:
+	close(fd_file);
+
+exit:
+	return rc;
+}
+
+
+int wcnss_read_and_store_cal_data(int fd_dev)
+{
+	int rcount = 0;
+	int wcount = 0;
+	int fd_file = -1;
+	int rc = 0;
+
+	char buf[WCNSS_CAL_CHUNK];
+
+	ALOGI("wcnss_read_and_store_cal_data trying to read cal");
+
+	do {
+		/* wait on this read until data comes from fw */
+		rcount = read(fd_dev, (void *)buf, sizeof(buf));
+		if (rcount < 0) {
+			ALOGE("Failed to read from wcnss device : %s",
+					strerror(errno));
+			rc = rcount;
+			goto exit;
+		}
+
+		/* truncate the file only if there is fw data, this read
+		 * may never return if the fw decides that no more cal is
+		 * required; and the data we have now is good enough.
+		 */
+		if (fd_file < 0) {
+			fd_file = open(WCNSS_CAL_FILE, O_WRONLY
+					| O_CREAT | O_TRUNC, 0664);
+			if (fd_file < 0) {
+				ALOGE("Failed to open cal file : %s",
+						strerror(errno));
+				rc = fd_file;
+				goto exit;
+			}
+		}
+
+		if (!rcount)
+			break;
+
+		wcount = write(fd_file, buf, rcount);
+		if (wcount < 0) {
+			ALOGE("Failed to write to cal file : %s",
+				strerror(errno));
+			rc = wcount;
+			goto exit_remove;
+		}
+
+	} while (rcount);
+
+	close(fd_file);
+
+	return SUCCESS;
+
+exit_remove:
+	close(fd_file);
+	remove(WCNSS_CAL_FILE);
+
+exit:
+	return rc;
+}
+
+
+void find_full_path(char *cur_dir, char *file_to_find, char *full_path)
+{
+	DIR *dir;
+	struct stat st;
+	struct dirent *dr;
+	char cwd[1024];
+	int rc;
+
+	chdir(cur_dir);
+
+	dir = opendir(".");
+
+	if (dir != NULL) {
+		while ((dr = readdir(dir))) {
+
+			rc = lstat(dr->d_name, &st);
+			if (rc < 0) {
+				ALOGE("lstat failed %s", strerror(errno));
+				return;
+			}
+			if (S_ISDIR(st.st_mode)) {
+				if ((strcmp(dr->d_name, ".")) &&
+					(strcmp(dr->d_name, ".."))) {
+				find_full_path(dr->d_name,
+						file_to_find, full_path);
+				}
+			} else if (!strcmp(file_to_find, dr->d_name)) {
+				getcwd(cwd, sizeof(cwd));
+				snprintf(full_path, MAX_FILE_LENGTH, "%s/%s",
+					cwd, file_to_find);
+			}
+		}
+		closedir(dir);
+	}
+
+	chdir("..");
+}
+
+void setup_wlan_config_file()
+{
+	int rfd;
+	int wfd;
+	struct stat st_dest, st_src;
+	int rc_dest;
+	int rc;
+	struct group *grp;
+	struct utimbuf new_time;
+
+	rc = stat(WLAN_INI_FILE_SOURCE, &st_src);
+	if (rc != 0) {
+		ALOGE("source file do not exist %s", WLAN_INI_FILE_SOURCE);
+		return;
+	}
+
+	rc_dest = stat(WLAN_INI_FILE_DEST, &st_dest);
+	if (rc_dest == 0 && st_dest.st_size &&
+			(st_dest.st_mtime > st_src.st_mtime)) {
+		ALOGE("wlan ini file exists %s and is newer than %s",
+				WLAN_INI_FILE_DEST, WLAN_INI_FILE_SOURCE);
+		goto out_nocopy;
+	}
+
+	rfd = open(WLAN_INI_FILE_SOURCE, O_RDONLY);
+	if (rfd < 0) {
+		ALOGE("Failed to open ini source file: %s", strerror(errno));
+		return;
+	}
+
+	wfd = open(WLAN_INI_FILE_DEST, O_WRONLY | O_CREAT | O_TRUNC, 0660);
+	if (wfd < 0) {
+		ALOGE("Failed to open ini dest file: %s", strerror(errno));
+		close(rfd);
+		return;
+	}
+
+	rc = sendfile(wfd, rfd, 0, st_src.st_size);
+	if (rc != st_src.st_size) {
+		ALOGE("Failed to copy ini file: %s", strerror(errno));
+		goto out;
+	}
+
+	new_time.actime = st_src.st_atime;
+	new_time.modtime = st_src.st_mtime;
+
+	rc = utime(WLAN_INI_FILE_DEST, &new_time);
+	if (rc != 0)
+		ALOGE("could not preserve the timestamp %s", strerror(errno));
+
+	grp = getgrnam("wifi");
+	if (grp != NULL) {
+		rc = chown(WLAN_INI_FILE_DEST, -1, grp->gr_gid);
+		if (rc != 0)
+			ALOGE("Failed change group of ini file %s", strerror(errno));
+	} else {
+			ALOGE("Failed to get group wifi %s", strerror(errno));
+	}
+
+	property_set("vendor.wlan.driver.config", WLAN_INI_FILE_DEST);
+
+out:
+	close(rfd);
+	close(wfd);
+	return;
+
+out_nocopy:
+	property_set("vendor.wlan.driver.config", WLAN_INI_FILE_DEST);
+	return;
+}
+unsigned int convert_string_to_hex(char* string)
+{
+	int idx;
+	unsigned long int hex_num = 0;
+	for(idx = 0; string[idx] != '\0'; idx++){
+		if(isalpha(string[idx])) {
+			if(string[idx] >='a' && string[idx] <='f') {
+				hex_num = hex_num * HEX_BASE + ((int)string[idx]
+					       - ASCII_a + HEXA_A);
+			} else if ( string[idx] >='A' && string[idx] <='F') {
+				hex_num = hex_num * HEX_BASE + ((int)string[idx]
+						- ASCII_A + HEXA_A);
+			} else
+				hex_num = hex_num * HEX_BASE + (int)string[idx];
+		} else {
+			hex_num = hex_num * HEX_BASE + (string[idx]- ASCII_0);
+		}
+	}
+	hex_num = hex_num & 0xFFFFFFFF;
+	return hex_num;
+}
+
+
+#ifdef WCNSS_QMI
+void setup_wcnss_parameters(int *cal, int nv_mac_addr)
+#else
+void setup_wcnss_parameters(int *cal)
+#endif
+{
+	char msg[WCNSS_MAX_CMD_LEN];
+	char serial[PROPERTY_VALUE_MAX];
+	int fd, rc, pos = 0;
+	struct stat st;
+	unsigned int serial_num = 0;
+
+	fd = open(WCNSS_CTRL, O_WRONLY);
+	if (fd < 0) {
+		ALOGE("Failed to open %s : %s", WCNSS_CTRL, strerror(errno));
+		return;
+	}
+
+	rc = property_get("ro.serialno", serial, "");
+	if (rc) {
+		serial_num = convert_string_to_hex(serial);
+		ALOGE("Serial Number is  %x", serial_num);
+
+		msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_1;
+		msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_0;
+		msg[pos++] = serial_num >> BYTE_3;
+		msg[pos++] = serial_num >> BYTE_2;
+		msg[pos++] = serial_num >> BYTE_1;
+		msg[pos++] = serial_num >> BYTE_0;
+
+		if (write(fd, msg, pos) < 0) {
+			ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
+					strerror(errno));
+			goto fail;
+		}
+	}
+
+#ifdef WCNSS_QMI
+	if (SUCCESS == nv_mac_addr)
+	{
+		pos = 0;
+		msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_1;
+		msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_0;
+		msg[pos++] = wlan_nv_mac_addr[0];
+		msg[pos++] = wlan_nv_mac_addr[1];
+		msg[pos++] = wlan_nv_mac_addr[2];
+		msg[pos++] = wlan_nv_mac_addr[3];
+		msg[pos++] = wlan_nv_mac_addr[4];
+		msg[pos++] = wlan_nv_mac_addr[5];
+
+		ALOGI("WLAN MAC Addr:" MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(wlan_nv_mac_addr));
+
+		if (write(fd, msg, pos) < 0) {
+			ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
+						strerror(errno));
+			goto fail;
+		}
+	}
+#endif
+
+	pos = 0;
+	msg[pos++] = WCNSS_USR_HAS_CAL_DATA >> BYTE_1;
+	msg[pos++] = WCNSS_USR_HAS_CAL_DATA >> BYTE_0;
+
+	rc = stat(WCNSS_FACT_FILE, &st);
+	if (rc == 0) {
+		ALOGE("Factory file found, deleting cal file");
+		unlink(WCNSS_CAL_FILE);
+		goto fail_resp;
+	}
+
+	rc = stat(WCNSS_CAL_FILE, &st);
+	if (rc != 0) {
+		ALOGE("CAL file not found");
+		goto fail_resp;
+	}
+
+	/* has cal data */
+	msg[pos++] = 1;
+
+	if (write(fd, msg, pos) < 0) {
+		ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
+				strerror(errno));
+		goto fail;
+	}
+
+	ALOGI("Correctly triggered cal file");
+	*cal = SUCCESS;
+	close(fd);
+	return;
+
+fail_resp:
+	msg[pos++] = 0;
+	if (write(fd, msg, pos) < 0)
+		ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
+				strerror(errno));
+
+fail:
+	*cal = FAILED;
+	close(fd);
+	return;
+}
+
+void setup_wlan_driver_ath_prop()
+{
+	property_set("vendor.wlan.driver.ath", WLAN_DRIVER_ATH_DEFAULT_VAL);
+}
+
+#ifdef WCNSS_QMI
+int check_modem_compatability(struct dev_info *mdm_detect_info)
+{
+	char args[MODEM_BASEBAND_PROPERTY_SIZE] = {0};
+	int ret = 0;
+	/* Get the hardware property */
+	ret = property_get(MODEM_BASEBAND_PROPERTY, args, "");
+	if (ret > MODEM_BASEBAND_PROPERTY_SIZE) {
+		ALOGE("property [%s] has size [%d] that exceeds max [%d]",
+				MODEM_BASEBAND_PROPERTY, ret, MODEM_BASEBAND_PROPERTY_SIZE);
+		return 0;
+	}
+	/* This will check for the type of hardware, and if the
+	   hardware type needs external modem, it will check if the
+	   modem type is external*/
+	if(!strncmp(MODEM_BASEBAND_VALUE_APQ, args, 3)) {
+
+		for (ret = 0; ret < mdm_detect_info->num_modems; ret++) {
+			if (mdm_detect_info->mdm_list[ret].type == MDM_TYPE_EXTERNAL) {
+				ALOGE("Hardware supports external modem");
+				return 1;
+			}
+		}
+		ALOGE("Hardware does not support external modem");
+		return 0;
+	}
+	return 1;
+}
+#endif
+
+static int read_line_from_file(const char *path, char *buf, size_t count)
+{
+	char * fgets_ret;
+	FILE * fd;
+	int rv;
+
+	fd = fopen(path, "r");
+	if (fd == NULL)
+	return -1;
+
+	fgets_ret = fgets(buf, (int)count, fd);
+	if (NULL != fgets_ret) {
+	    rv = (int)strlen(buf);
+	} else {
+	    rv = ferror(fd);
+	}
+
+	fclose(fd);
+
+	return rv;
+}
+
+static int get_soc_info(char *buf, char *soc_node_path1,
+			char *soc_node_path2)
+{
+	int ret = 0;
+
+	ret = read_line_from_file(soc_node_path1, buf,
+					MAX_SOC_INFO_NAME_LEN);
+	if (ret < 0) {
+		ret = read_line_from_file(soc_node_path2, buf,
+					MAX_SOC_INFO_NAME_LEN);
+		if (ret < 0) {
+		    ALOGE("getting socinfo(%s, %d) failed.\n",
+					soc_node_path1, ret);
+		    return ret;
+		}
+	}
+	if (ret && buf[ret - 1] == '\n')
+		buf[ret - 1] = '\0';
+
+	return ret;
+}
+
+static int get_data_nvfile_path(char *data_nvfile_path,
+	struct stat *pdata_nvfile_stat)
+{
+	char target_board_platform[PROP_VALUE_MAX] = {'\0'};
+	char buf[MAX_SOC_INFO_NAME_LEN] = {'\0'};
+	int  soc_id, platform_subtype_id, platform_version;
+	int  major_hwver, minor_hwver;
+	int  rc;
+
+	rc = property_get("ro.board.platform", target_board_platform, "");
+	if (!rc)
+	{
+		ALOGE("get ro.board.platform fail, rc=%d(%s)\n",
+				rc, strerror(errno));
+		return FAILED;
+	}
+
+	GET_SOC_INFO(buf, SYSFS_SOCID_PATH1, SYSFS_SOCID_PATH2, soc_id);
+	GET_SOC_INFO(buf, SYSFS_PLATFORM_SUBTYPE_PATH1,
+			SYSFS_PLATFORM_SUBTYPE_PATH2, platform_subtype_id);
+	GET_SOC_INFO(buf, SYSFS_PLATFORM_VERSION_PATH1,
+			SYSFS_PLATFORM_VERSION_PATH2, platform_version);
+
+	major_hwver = SOCINFO_HWVER_MAJOR(platform_version);
+	minor_hwver = SOCINFO_HWVER_MINOR(platform_version);
+
+	snprintf(data_nvfile_path, MAX_DATA_NVBIN_PATH_LEN,
+		"%s%s_%d_0x%02x_0x%02x_0x%02x_nv.bin", DATA_NVFILE_DIR,
+		target_board_platform, soc_id, platform_subtype_id&0xff,
+		major_hwver&0xff, minor_hwver&0xff);
+	ALOGI("data_nvfile_path %s\n",
+			data_nvfile_path);
+
+	if (stat(data_nvfile_path, pdata_nvfile_stat) != 0)
+	{
+		ALOGE("source file do not exist %s\n",
+				data_nvfile_path);
+		return FAILED;
+	}
+
+	return SUCCESS;
+}
+
+static int nvbin_sendfile(const char *dst, const char *src,
+	struct stat *src_stat)
+{
+	struct utimbuf new_time;
+	int fp_src, fp_dst;
+	int rc;
+	if ((fp_src = open(src, O_RDONLY)) < 0)
+	{
+		ALOGE("open %s failed(%s).\n",
+				src, strerror(errno));
+		return FAILED;
+	}
+
+	if ((fp_dst = open(dst, O_WRONLY |O_TRUNC)) < 0)
+	{
+		close(fp_src);
+		ALOGE("open %s failed(%s).\n",
+				dst, strerror(errno));
+		return FAILED;
+	}
+
+	if (sendfile(fp_dst, fp_src, 0, src_stat->st_size) == -1)
+	{
+		ALOGE("dynamic nv sendfile failed: (%s).\n",
+				strerror(errno));
+		rc = FAILED;
+		goto exit;
+	}
+
+	new_time.actime  = src_stat->st_atime;
+	new_time.modtime = src_stat->st_mtime;
+	if (utime(dst, &new_time) != 0)
+	{
+		ALOGE("could not preserve the timestamp %s",
+				strerror(errno));
+		rc = FAILED;
+		goto exit;
+	}
+
+	rc = SUCCESS;
+exit:
+	close(fp_dst);
+	close(fp_src);
+	return rc;
+}
+void dynamic_nv_replace()
+{
+	char data_nvfile_path[MAX_DATA_NVBIN_PATH_LEN] = {'\0'};
+	char property_nv_replaced_status [PROPERTY_VALUE_MAX] = { '\0' };
+	char buf[MAX_SOC_INFO_NAME_LEN] = {'\0'};
+	struct stat  data_nvfile_stat;
+	int rc;
+
+	if (property_get(QRD_DYNAMIC_NV_PROP, property_nv_replaced_status, NULL)
+		&& strcmp(property_nv_replaced_status, "done") == 0) {
+		ALOGI("dynamic nv have been replaced. leave\n");
+		return;
+	}
+
+	rc = get_soc_info(buf, SYSFS_HW_PLATFORM_PATH1, SYSFS_HW_PLATFORM_PATH2);
+	if (rc < 0)
+	{
+		ALOGE("get_soc_info(HW_PLATFORM) fail!\n");
+		return;
+	} else {
+		if( 0 != strncmp(buf, QRD_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN))
+		{
+			ALOGI("dynamic nv only for QRD platform, current platform:%s.\n",
+					buf);
+			return;
+		}
+	}
+
+	rc = get_data_nvfile_path(data_nvfile_path, &data_nvfile_stat);
+	if (rc != SUCCESS)
+	{
+		ALOGE("Get source file path fail !\n");
+		return;
+	}
+
+	if (property_set(QRD_DYNAMIC_NV_PROP, "replacing") < 0)
+	{
+		ALOGE("set %s to replacing failed (%s).\n",
+				QRD_DYNAMIC_NV_PROP, strerror(errno));
+		return;
+	}
+
+	rc = nvbin_sendfile(PERSIST_NVFILE, data_nvfile_path, &data_nvfile_stat);
+	if ( rc != SUCCESS)
+	{
+		ALOGE("nvbin_sendfile failed.\n");
+		return;
+	}
+
+	if (property_set(QRD_DYNAMIC_NV_PROP, "done") < 0)
+	{
+		ALOGE("set %s to done failed(%s).\n",
+				QRD_DYNAMIC_NV_PROP, strerror(errno));
+		return;
+	}
+
+	ALOGI("dynamic nv replace sucessfully!\n");
+
+}
+
+int main(int argc, char *argv[])
+{
+	UNUSED(argc), UNUSED(argv);
+	int rc;
+	int fd_dev, ret_cal;
+#ifdef WCNSS_QMI
+	int nv_mac_addr = FAILED;
+	struct dev_info mdm_detect_info;
+	int nom = 0;
+#endif
+
+	setup_wlan_config_file();
+
+#ifdef WCNSS_QMI
+	/* Call ESOC API to get the number of modems.
+	   If the number of modems is not zero, only then proceed
+	   with the eap_proxy intialization.*/
+
+	nom = get_system_info(&mdm_detect_info);
+
+	if (nom > 0)
+		ALOGE("Failed to get system info, ret %d", nom);
+
+	if (mdm_detect_info.num_modems == 0) {
+		ALOGE("wcnss_service: No Modem support for this target"
+				" number of modems is %d", mdm_detect_info.num_modems);
+		goto nomodem;
+	}
+
+	ALOGE("wcnss_service: num_modems = %d", mdm_detect_info.num_modems);
+
+	if(!check_modem_compatability(&mdm_detect_info)) {
+		ALOGE("wcnss_service: Target does not have external modem");
+		goto nomodem;
+	}
+
+	/* initialize the DMS client and request the wlan mac address */
+
+	if (SUCCESS == wcnss_init_qmi()) {
+
+		rc = wcnss_qmi_get_wlan_address(wlan_nv_mac_addr);
+
+		if (rc == SUCCESS) {
+			nv_mac_addr = SUCCESS;
+			ALOGE("WLAN MAC Addr:" MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(wlan_nv_mac_addr));
+		} else
+			ALOGE("Failed to Get MAC addr from modem");
+
+		wcnss_qmi_deinit();
+	}
+	else
+		ALOGE("Failed to Initialize wcnss QMI Interface");
+
+nomodem:
+#endif
+
+	dynamic_nv_replace();
+
+#ifdef WCNSS_QMI
+	setup_wcnss_parameters(&ret_cal, nv_mac_addr);
+#else
+	setup_wcnss_parameters(&ret_cal);
+#endif
+
+	fd_dev = open(WCNSS_DEVICE, O_RDWR);
+	if (fd_dev < 0) {
+		ALOGE("Failed to open wcnss device : %s",
+				strerror(errno));
+		return fd_dev;
+	}
+
+	if (ret_cal != FAILED) {
+		rc = wcnss_write_cal_data(fd_dev);
+		if (rc != SUCCESS)
+			ALOGE("No cal data is written to WCNSS %d", rc);
+		else
+			ALOGE("Cal data is successfully written to WCNSS");
+	}
+
+	setup_wlan_driver_ath_prop();
+
+	rc = wcnss_read_and_store_cal_data(fd_dev);
+	if (rc != SUCCESS)
+		ALOGE("Failed to read and save cal data %d", rc);
+	else
+		ALOGI("Calibration data was successfull written to %s",
+			WCNSS_CAL_FILE);
+
+	close(fd_dev);
+
+	return rc;
+}