Merge pi-dev-plus-aosp-without-vendor into stage-aosp-master

Bug: 79597307
Change-Id: I8c6a456e983f4afe0e95fa6d121371d011695f48
diff --git a/cld80211-lib/Android.mk b/cld80211-lib/Android.mk
index 1c51224..f2b93f7 100644
--- a/cld80211-lib/Android.mk
+++ b/cld80211-lib/Android.mk
@@ -11,6 +11,6 @@
 LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
 LOCAL_COPY_HEADERS_TO := cld80211-lib
 LOCAL_COPY_HEADERS := cld80211_lib.h
-LOCAL_PROPRIETARY_MODULE := true
+LOCAL_VENDOR_MODULE := true
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/cld80211-lib/cld80211_lib.h b/cld80211-lib/cld80211_lib.h
index 16b3f20..3dd53bb 100644
--- a/cld80211-lib/cld80211_lib.h
+++ b/cld80211-lib/cld80211_lib.h
@@ -55,11 +55,16 @@
  * CLD80211_ATTR_VENDOR_DATA: Embed all other attributes in this nested
  *                            attribute.
  * CLD80211_ATTR_DATA: Embed driver/application data in this attribute
+ * 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.
+ *
  * Any new message in future can be added as another attribute
  */
 enum cld80211_attr {
 	CLD80211_ATTR_VENDOR_DATA = 1,
 	CLD80211_ATTR_DATA,
+	CLD80211_ATTR_META_DATA,
 
 	__CLD80211_ATTR_AFTER_LAST,
 	CLD80211_ATTR_MAX = __CLD80211_ATTR_AFTER_LAST - 1
diff --git a/qcwcn/wcnss-service/wcnss_service.c b/qcwcn/wcnss-service/wcnss_service.c
index 4eb3403..f3eacb9 100644
--- a/qcwcn/wcnss-service/wcnss_service.c
+++ b/qcwcn/wcnss-service/wcnss_service.c
@@ -66,7 +66,7 @@
 #define WCNSS_DEVICE    "/dev/wcnss_wlan"
 #define WCNSS_CTRL      "/dev/wcnss_ctrl"
 #define WLAN_INI_FILE_DEST   "/data/misc/wifi/WCNSS_qcom_cfg.ini"
-#define WLAN_INI_FILE_SOURCE "/system/etc/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"
diff --git a/qcwcn/wifi_hal/Android.mk b/qcwcn/wifi_hal/Android.mk
index 25aeae3..0f82f9c 100644
--- a/qcwcn/wifi_hal/Android.mk
+++ b/qcwcn/wifi_hal/Android.mk
@@ -57,10 +57,11 @@
 	ring_buffer.cpp \
 	rb_wrapper.cpp \
 	rssi_monitor.cpp \
-	roam.cpp
+	roam.cpp \
+	radio_mode.cpp
 
 LOCAL_MODULE := libwifi-hal-qcom
-LOCAL_PROPRIETARY_MODULE := true
+LOCAL_VENDOR_MODULE := true
 LOCAL_CLANG := true
 LOCAL_SHARED_LIBRARIES += libnetutils liblog libwpa_client libcld80211
 
@@ -118,11 +119,12 @@
 	ring_buffer.cpp \
 	rb_wrapper.cpp \
 	rssi_monitor.cpp \
-	roam.cpp
+	roam.cpp \
+	radio_mode.cpp
 
 LOCAL_CFLAGS += -Wall -Werror
 LOCAL_MODULE := libwifi-hal-qcom
-LOCAL_PROPRIETARY_MODULE := true
+LOCAL_VENDOR_MODULE := true
 LOCAL_CLANG := true
 LOCAL_SHARED_LIBRARIES += libnetutils liblog
 LOCAL_SHARED_LIBRARIES += libdl libwpa_client libcld80211
diff --git a/qcwcn/wifi_hal/common.cpp b/qcwcn/wifi_hal/common.cpp
index 31e441c..c54577c 100644
--- a/qcwcn/wifi_hal/common.cpp
+++ b/qcwcn/wifi_hal/common.cpp
@@ -189,53 +189,6 @@
 }
 
 
-wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
-{
-    hal_info *info = (hal_info *)handle;
-
-    if (info->num_cmd < info->alloc_cmd) {
-        info->cmd[info->num_cmd].id   = id;
-        info->cmd[info->num_cmd].cmd  = cmd;
-        info->num_cmd++;
-        ALOGV("Successfully added command %d: %p", id, cmd);
-        return WIFI_SUCCESS;
-    } else {
-        return WIFI_ERROR_OUT_OF_MEMORY;
-    }
-}
-
-WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
-{
-    hal_info *info = (hal_info *)handle;
-
-    for (int i = 0; i < info->num_cmd; i++) {
-        if (info->cmd[i].id == id) {
-            WifiCommand *cmd = info->cmd[i].cmd;
-            memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
-            info->num_cmd--;
-            ALOGV("Successfully removed command %d: %p", id, cmd);
-            return cmd;
-        }
-    }
-
-    return NULL;
-}
-
-void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
-{
-    hal_info *info = (hal_info *)handle;
-
-    for (int i = 0; i < info->num_cmd; i++) {
-        if (info->cmd[i].cmd == cmd) {
-            int id = info->cmd[i].id;
-            memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
-            info->num_cmd--;
-            ALOGV("Successfully removed command %d: %p", id, cmd);
-            return;
-        }
-    }
-}
-
 #ifdef __cplusplus
 extern "C"
 {
@@ -449,12 +402,12 @@
     return LowiWifiHalApi;
 }
 
-wifi_error mapErrorKernelToWifiHAL(int error)
+wifi_error mapKernelErrortoWifiHalError(int kern_err)
 {
-    if (error >= 0)
-        return WIFI_ERROR_NONE;
+    if (kern_err >= 0)
+        return WIFI_SUCCESS;
 
-    switch (error) {
+    switch (kern_err) {
         case -EOPNOTSUPP:
             return WIFI_ERROR_NOT_SUPPORTED;
         case -EAGAIN:
@@ -467,8 +420,6 @@
             return WIFI_ERROR_OUT_OF_MEMORY;
         case -EBUSY:
             return WIFI_ERROR_BUSY;
-        default:
-            return WIFI_ERROR_UNKNOWN;
     }
     return WIFI_ERROR_UNKNOWN;
 }
diff --git a/qcwcn/wifi_hal/common.h b/qcwcn/wifi_hal/common.h
index c3ac14e..a67ef83 100644
--- a/qcwcn/wifi_hal/common.h
+++ b/qcwcn/wifi_hal/common.h
@@ -50,7 +50,6 @@
 #define SOCKET_BUFFER_SIZE      (32768U)
 #define RECV_BUF_SIZE           (4096)
 #define DEFAULT_EVENT_CB_SIZE   (64)
-#define DEFAULT_CMD_SIZE        (64)
 #define NUM_RING_BUFS           5
 
 #define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
@@ -111,14 +110,11 @@
     int alloc_event_cb;                             // number of allocated callback objects
     pthread_mutex_t cb_lock;                        // mutex for the event_cb access
 
-    cmd_info *cmd;                                  // Outstanding commands
-    int num_cmd;                                    // number of commands
-    int alloc_cmd;                                  // number of commands allocated
-
     interface_info **interfaces;                    // array of interfaces
     int num_interfaces;                             // number of interfaces
 
     feature_set supported_feature_set;
+    u32 supported_logger_feature_set;
     // add other details
     int user_sock_arg;
     struct rb_info rb_infos[NUM_RING_BUFS];
@@ -148,6 +144,7 @@
     struct rssi_monitor_event_handler_s *rssi_handlers;
     wifi_capa capa;
     struct cld80211_ctx *cldctx;
+    bool apf_enabled;
 } hal_info;
 
 wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg);
@@ -157,10 +154,6 @@
 void wifi_unregister_handler(wifi_handle handle, int cmd);
 void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd);
 
-wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd);
-WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id);
-void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd);
-
 interface_info *getIfaceInfo(wifi_interface_handle);
 wifi_handle getWifiHandle(wifi_interface_handle handle);
 hal_info *getHalInfo(wifi_handle handle);
@@ -182,7 +175,9 @@
 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 wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface);
-wifi_error mapErrorKernelToWifiHAL(int error);
+wifi_error wifi_set_radio_mode_change_handler(wifi_request_id id, wifi_interface_handle
+        iface, wifi_radio_mode_change_handler eh);
+wifi_error mapKernelErrortoWifiHalError(int kern_err);
 // some common macros
 
 #define min(x, y)       ((x) < (y) ? (x) : (y))
diff --git a/qcwcn/wifi_hal/cpp_bindings.cpp b/qcwcn/wifi_hal/cpp_bindings.cpp
index 36befed..6efec5a 100644
--- a/qcwcn/wifi_hal/cpp_bindings.cpp
+++ b/qcwcn/wifi_hal/cpp_bindings.cpp
@@ -543,7 +543,7 @@
     return result;
 }
 
-int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
+wifi_error WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
 
     destroy();
 
@@ -557,25 +557,21 @@
     }
 }
 
-int WifiRequest::create(uint32_t id, int subcmd) {
-    int res = create(NL80211_CMD_VENDOR);
-    if (res < 0) {
+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 < 0) {
+    if (res != WIFI_SUCCESS)
         return res;
-    }
 
     res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
-    if (res < 0) {
+    if (res != WIFI_SUCCESS)
         return res;
-    }
 
-    if (mIface != -1) {
+    if (mIface != -1)
         res = set_iface_id(mIface);
-    }
 
     return res;
 }
@@ -586,16 +582,17 @@
     return NL_OK;
 }
 
-int WifiCommand::requestResponse() {
-    int err = create();                 /* create the message */
-    if (err < 0) {
+wifi_error WifiCommand::requestResponse()
+{
+    wifi_error err = create();                 /* create the message */
+    if (err != WIFI_SUCCESS)
         return err;
-    }
 
     return requestResponse(mMsg);
 }
 
-int WifiCommand::requestResponse(WifiRequest& request) {
+wifi_error WifiCommand::requestResponse(WifiRequest& request)
+{
     int err = 0;
 
     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
@@ -623,26 +620,30 @@
 out:
     nl_cb_put(cb);
     mMsg.destroy();
-    return err;
+    return mapKernelErrortoWifiHalError(err);
 }
 
-int WifiCommand::requestEvent(int cmd) {
+wifi_error WifiCommand::requestEvent(int cmd)
+{
 
-    int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
-    if (res < 0) {
+    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 < 0)
+    if (res != WIFI_SUCCESS)
         goto out;
 
-    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
-    if (res < 0)
+    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 < 0)
+    if (res != WIFI_SUCCESS)
         goto out;
 
 out:
@@ -650,23 +651,25 @@
     return res;
 }
 
-int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
-
-    int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
-    if (res < 0) {
+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 < 0)
+    if (res != WIFI_SUCCESS)
         goto out;
 
-    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
-    if (res < 0)
+    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 < 0)
+    if (res != WIFI_SUCCESS)
         goto out;
 
 out:
@@ -794,85 +797,91 @@
     return NL_SKIP;
 }
 
-int WifiVendorCommand::create() {
+wifi_error WifiVendorCommand::create() {
     int ifindex;
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+    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 < 0)
+    if (ret != WIFI_SUCCESS)
         goto out;
 
     // insert the subcmd in the msg
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
+    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");
-    mMsg.set_iface_id(ifindex);
+    ret = mMsg.set_iface_id(ifindex);
 out:
     return ret;
-
 }
 
-int WifiVendorCommand::requestResponse()
+wifi_error WifiVendorCommand::requestResponse()
 {
     return WifiCommand::requestResponse(mMsg);
 }
 
-int WifiVendorCommand::requestEvent()
+wifi_error WifiVendorCommand::requestEvent()
 {
-    int res = requestVendorEvent(mVendor_id, mSubcmd);
+    wifi_error res = requestVendorEvent(mVendor_id, mSubcmd);
     return res;
-
 }
 
-int WifiVendorCommand::put_u8(int attribute, uint8_t value)
+wifi_error WifiVendorCommand::put_u8(int attribute, uint8_t value)
 {
     return mMsg.put_u8(attribute, value);
 }
 
-int WifiVendorCommand::put_u16(int attribute, uint16_t value)
+wifi_error WifiVendorCommand::put_u16(int attribute, uint16_t value)
 {
     return mMsg.put_u16(attribute, value);
 }
 
-int WifiVendorCommand::put_u32(int attribute, uint32_t value)
+wifi_error WifiVendorCommand::put_u32(int attribute, uint32_t value)
 {
     return mMsg.put_u32(attribute, value);
 }
 
-int WifiVendorCommand::put_u64(int attribute, uint64_t value)
+wifi_error WifiVendorCommand::put_u64(int attribute, uint64_t value)
 {
     return mMsg.put_u64(attribute, value);
 }
 
-int WifiVendorCommand::put_s8(int attribute, s8 value)
+wifi_error WifiVendorCommand::put_s8(int attribute, s8 value)
 {
     return mMsg.put_s8(attribute, value);
 }
 
-int WifiVendorCommand::put_s16(int attribute, s16 value)
+wifi_error WifiVendorCommand::put_s16(int attribute, s16 value)
 {
     return mMsg.put_s16(attribute, value);
 }
 
-int WifiVendorCommand::put_s32(int attribute, s32 value) {
+wifi_error WifiVendorCommand::put_s32(int attribute, s32 value)
+{
     return mMsg.put_s32(attribute, value);
 }
 
-int WifiVendorCommand::put_s64(int attribute, s64 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);
@@ -913,12 +922,12 @@
     return mMsg.get_s64(nla);
 }
 
-int WifiVendorCommand::put_string(int attribute, const char *value)
+wifi_error WifiVendorCommand::put_string(int attribute, const char *value)
 {
     return mMsg.put_string(attribute, value);
 }
 
-int WifiVendorCommand::put_addr(int attribute, mac_addr value)
+wifi_error WifiVendorCommand::put_addr(int attribute, mac_addr value)
 {
     return mMsg.put_addr(attribute, value);
 }
@@ -933,13 +942,15 @@
     return mMsg.attr_end(attribute);
 }
 
-int WifiVendorCommand::set_iface_id(const char* name)
+wifi_error WifiVendorCommand::set_iface_id(const char* name)
 {
     unsigned ifindex = if_nametoindex(name);
     return mMsg.set_iface_id(ifindex);
 }
 
-int WifiVendorCommand::put_bytes(int attribute, const char *data, int len)
+wifi_error WifiVendorCommand::put_bytes(int attribute,
+                                        const char *data,
+                                        int len)
 {
     return mMsg.put_bytes(attribute, data, len);
 }
@@ -973,7 +984,7 @@
                                  u32 subcmd,
                                  WifiVendorCommand **vCommand)
 {
-    int ret = 0;
+    wifi_error ret;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
 
@@ -992,16 +1003,16 @@
 
     /* Create the message */
     ret = (*vCommand)->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = (*vCommand)->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     return WIFI_SUCCESS;
 
 cleanup:
     delete *vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/cpp_bindings.h b/qcwcn/wifi_hal/cpp_bindings.h
index e862602..71d8da9 100644
--- a/qcwcn/wifi_hal/cpp_bindings.h
+++ b/qcwcn/wifi_hal/cpp_bindings.h
@@ -183,41 +183,61 @@
     }
 
     /* Command assembly helpers */
-    int create(int family, uint8_t cmd, int flags, int hdrlen);
-    int create(uint8_t cmd, int flags, int hdrlen) {
+    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);
     }
-    int create(uint8_t cmd) {
+    wifi_error create(uint8_t cmd) {
         return create(mFamily, cmd, 0, 0);
     }
 
-    int create(uint32_t id, int subcmd);
+    wifi_error create(uint32_t id, int subcmd);
 
-    int put_u8(int attribute, uint8_t value) {
-        return nla_put(mMsg, attribute, sizeof(value), &value);
+    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);
     }
-    int put_u16(int attribute, uint16_t value) {
-        return nla_put(mMsg, attribute, sizeof(value), &value);
+    wifi_error put_u8(int attribute, uint8_t value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
     }
-    int put_u32(int attribute, uint32_t value) {
-        return 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);
     }
 
-    int put_u64(int attribute, uint64_t value) {
-        return 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);
     }
 
-    int put_s8(int attribute, s8 value) {
-        return nla_put(mMsg, attribute, sizeof(int8_t), &value);
+    wifi_error put_s8(int attribute, s8 value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(int8_t), &value);
     }
-    int put_s16(int attribute, s16 value) {
-        return nla_put(mMsg, attribute, sizeof(int16_t), &value);
+    wifi_error put_s16(int attribute, s16 value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(int16_t), &value);
     }
-    int put_s32(int attribute, s32 value) {
-        return nla_put(mMsg, attribute, sizeof(int32_t), &value);
+    wifi_error put_s32(int attribute, s32 value) {
+        return wifi_nla_put(mMsg, attribute, sizeof(int32_t), &value);
     }
-    int put_s64(int attribute, s64 value) {
-        return nla_put(mMsg, attribute, sizeof(int64_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)
@@ -255,11 +275,11 @@
         return *(s64 *) nla_data(nla);
     }
 
-    int put_string(int attribute, const char *value) {
-        return nla_put(mMsg, attribute, strlen(value) + 1, value);
+    wifi_error put_string(int attribute, const char *value) {
+        return wifi_nla_put(mMsg, attribute, strlen(value) + 1, value);
     }
-    int put_addr(int attribute, mac_addr value) {
-        return nla_put(mMsg, attribute, sizeof(mac_addr), 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) {
@@ -269,12 +289,12 @@
         nla_nest_end(mMsg, attr);
     }
 
-    int set_iface_id(int ifindex) {
+    wifi_error set_iface_id(int ifindex) {
         return put_u32(NL80211_ATTR_IFINDEX, ifindex);
     }
 
-    int put_bytes(int attribute, const char *data, int len) {
-        return nla_put(mMsg, attribute, len, data);
+    wifi_error put_bytes(int attribute, const char *data, int len) {
+        return wifi_nla_put(mMsg, attribute, len, data);
     }
 
 private:
@@ -312,20 +332,20 @@
         return mId;
     }
 
-    virtual int create() {
+    virtual wifi_error create() {
         /* by default there is no way to cancel */
         return WIFI_ERROR_NOT_SUPPORTED;
     }
 
-    virtual int cancel() {
+    virtual wifi_error cancel() {
         /* by default there is no way to cancel */
         return WIFI_ERROR_NOT_SUPPORTED;
     }
 
-    int requestResponse();
-    int requestEvent(int cmd);
-    int requestVendorEvent(uint32_t id, int subcmd);
-    int requestResponse(WifiRequest& request);
+    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() {
@@ -364,7 +384,7 @@
         wifi_unregister_handler(wifiHandle(), cmd);
     }
 
-    int registerVendorHandler(uint32_t id, int subcmd) {
+    wifi_error registerVendorHandler(uint32_t id, int subcmd) {
         return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
     }
 
@@ -405,27 +425,29 @@
 
     virtual ~WifiVendorCommand();
 
-    virtual int create();
+    virtual wifi_error create();
 
-    virtual int requestResponse();
+    virtual wifi_error requestResponse();
 
-    virtual int requestEvent();
+    virtual wifi_error requestEvent();
 
-    virtual int put_u8(int attribute, uint8_t value);
+    virtual wifi_error put_u8(int attribute, uint8_t value);
 
-    virtual int put_u16(int attribute, uint16_t value);
+    virtual wifi_error put_u16(int attribute, uint16_t value);
 
-    virtual int put_u32(int attribute, uint32_t value);
+    virtual wifi_error put_u32(int attribute, uint32_t value);
 
-    virtual int put_u64(int attribute, uint64_t value);
+    virtual wifi_error put_u64(int attribute, uint64_t value);
 
-    virtual int put_s8(int attribute, s8 value);
+    virtual wifi_error put_s8(int attribute, s8 value);
 
-    virtual int put_s16(int attribute, s16 value);
+    virtual wifi_error put_s16(int attribute, s16 value);
 
-    virtual int put_s32(int attribute, s32 value);
+    virtual wifi_error put_s32(int attribute, s32 value);
 
-    virtual int put_s64(int attribute, s64 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);
@@ -437,17 +459,17 @@
     virtual s32 get_s32(const struct nlattr *nla);
     virtual s64 get_s64(const struct nlattr *nla);
 
-    virtual int put_string(int attribute, const char *value);
+    virtual wifi_error put_string(int attribute, const char *value);
 
-    virtual int put_addr(int attribute, mac_addr 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 int set_iface_id(const char* name);
+    virtual wifi_error set_iface_id(const char* name);
 
-    virtual int put_bytes(int attribute, const char *data, int len);
+    virtual wifi_error put_bytes(int attribute, const char *data, int len);
 
     virtual wifi_error get_mac_addr(struct nlattr **tb_vendor,
                                 int attribute,
diff --git a/qcwcn/wifi_hal/gscan.cpp b/qcwcn/wifi_hal/gscan.cpp
index db5f140..46e0f89 100644
--- a/qcwcn/wifi_hal/gscan.cpp
+++ b/qcwcn/wifi_hal/gscan.cpp
@@ -82,6 +82,8 @@
             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__);
@@ -92,7 +94,8 @@
 wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
        int band, int max_channels, wifi_channel *channels, int *num_channels)
 {
-    int requestId, ret = 0;
+    int requestId;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(handle);
@@ -122,12 +125,12 @@
     }
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -155,19 +158,17 @@
 
     /* Send the msg and wait for a response. */
     ret = gScanCommand->requestResponse();
-    if (ret) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
 
 cleanup:
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
                                  wifi_gscan_capabilities *capabilities)
 {
-    wifi_error ret = WIFI_SUCCESS;
     wifi_handle wifiHandle = getWifiHandle(handle);
     hal_info *info = getHalInfo(wifiHandle);
 
@@ -183,7 +184,7 @@
 
     memcpy(capabilities, &info->capa.gscan_capa, sizeof(wifi_gscan_capabilities));
 
-    return mapErrorKernelToWifiHAL(ret);
+    return WIFI_SUCCESS;
 }
 
 wifi_error wifi_start_gscan(wifi_request_id id,
@@ -191,7 +192,7 @@
                             wifi_scan_cmd_params params,
                             wifi_scan_result_handler handler)
 {
-    int ret = 0;
+    wifi_error ret;
     u32 i, j;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
@@ -232,12 +233,12 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -378,7 +379,7 @@
     }
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s : requestResponse Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
@@ -391,19 +392,19 @@
 cleanup:
     delete gScanCommand;
     /* Disable Event Handling if ret != 0 */
-    if (ret && gScanStartCmdEventHandler) {
+    if ((ret != WIFI_SUCCESS) && gScanStartCmdEventHandler) {
         ALOGI("%s: Error ret:%d, disable event handling",
             __FUNCTION__, ret);
         gScanStartCmdEventHandler->disableEventHandling();
     }
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 
 }
 
 wifi_error wifi_stop_gscan(wifi_request_id id,
                             wifi_interface_handle iface)
 {
-    int ret = 0;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
 
@@ -441,12 +442,12 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -457,15 +458,14 @@
     ret = gScanCommand->put_u32(
             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
             id);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     gScanCommand->attr_end(nlData);
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
 
     /* Disable Event Handling. */
     if (gScanStartCmdEventHandler) {
@@ -474,7 +474,7 @@
 
 cleanup:
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* Set the GSCAN BSSID Hotlist. */
@@ -483,7 +483,8 @@
                                     wifi_bssid_hotlist_params params,
                                     wifi_hotlist_ap_found_handler handler)
 {
-    int i, numAp, ret = 0;
+    int i, numAp;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData, *nlApThresholdParamList;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -523,12 +524,12 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -619,7 +620,7 @@
     }
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
@@ -632,18 +633,18 @@
 cleanup:
     delete gScanCommand;
     /* Disable Event Handling if ret != 0 */
-    if (ret && gScanSetBssidHotlistCmdEventHandler) {
+    if ((ret != WIFI_SUCCESS) && gScanSetBssidHotlistCmdEventHandler) {
         ALOGI("%s: Error ret:%d, disable event handling",
             __FUNCTION__, ret);
         gScanSetBssidHotlistCmdEventHandler->disableEventHandling();
     }
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_reset_bssid_hotlist(wifi_request_id id,
                             wifi_interface_handle iface)
 {
-    int ret = 0;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -683,12 +684,12 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -698,15 +699,14 @@
 
     ret = gScanCommand->put_u32(
             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     gScanCommand->attr_end(nlData);
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
 
     /* Disable Event Handling. */
     if (gScanSetBssidHotlistCmdEventHandler) {
@@ -715,7 +715,7 @@
 
 cleanup:
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* Set the GSCAN Significant AP Change list. */
@@ -724,7 +724,8 @@
                                     wifi_significant_change_params params,
                                     wifi_significant_change_handler handler)
 {
-    int i, numAp, ret = 0;
+    int i, numAp;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData, *nlApThresholdParamList;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -763,12 +764,12 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -871,7 +872,7 @@
     }
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
@@ -883,20 +884,20 @@
 
 cleanup:
     /* Disable Event Handling if ret != 0 */
-    if (ret && gScanSetSignificantChangeCmdEventHandler) {
+    if ((ret != WIFI_SUCCESS) && gScanSetSignificantChangeCmdEventHandler) {
         ALOGI("%s: Error ret:%d, disable event handling",
             __FUNCTION__, ret);
         gScanSetSignificantChangeCmdEventHandler->disableEventHandling();
     }
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* Clear the GSCAN Significant AP change list. */
 wifi_error wifi_reset_significant_change_handler(wifi_request_id id,
                                             wifi_interface_handle iface)
 {
-    int ret = 0;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -937,12 +938,12 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -953,15 +954,14 @@
     ret = gScanCommand->put_u32(
                     QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
                     id);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     gScanCommand->attr_end(nlData);
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
 
     /* Disable Event Handling. */
     if (gScanSetSignificantChangeCmdEventHandler) {
@@ -970,7 +970,7 @@
 
 cleanup:
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* Get the GSCAN cached scan results. */
@@ -979,7 +979,8 @@
                                             wifi_cached_scan_results *results,
                                             int *num)
 {
-    int requestId, ret = 0, retRequestRsp = 0;
+    int requestId, retRequestRsp = 0;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
 
@@ -1014,14 +1015,14 @@
     }
 
     ret = gScanCommand->allocRspParams(eGScanGetCachedResultsRspParams);
-    if (ret != 0) {
+    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 != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to allocate memory for temp gscan cached list. "
             "Error:%d", __FUNCTION__, ret);
         goto cleanup;
@@ -1032,12 +1033,12 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = gScanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -1045,9 +1046,6 @@
     if (!nlData)
         goto cleanup;
 
-    if (ret < 0)
-        goto cleanup;
-
     if (gScanCommand->put_u32(
          QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
             requestId) ||
@@ -1068,6 +1066,9 @@
     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 */
             goto cleanup;
@@ -1094,13 +1095,13 @@
 cleanup:
     gScanCommand->freeRspParams(eGScanGetCachedResultsRspParams);
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* Random MAC OUI for PNO */
 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
 {
-    int ret = 0;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
     interface_info *iinfo = getIfaceInfo(handle);
@@ -1116,11 +1117,11 @@
 
     /* create the message */
     ret = vCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = vCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -1136,20 +1137,20 @@
             QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI,
             (char *)scan_oui,
             WIFI_SCANNING_MAC_OUI_LENGTH);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     vCommand->attr_end(nlData);
 
     ret = vCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
 
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 
@@ -1174,35 +1175,38 @@
 
 
 /* This function implements creation of Vendor command */
-int GScanCommand::create() {
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+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 < 0)
-        goto out;
+    if (ret != WIFI_SUCCESS)
+        return ret;
+
     /* Insert the subcmd in the msg */
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
-        goto out;
+    if (ret != WIFI_SUCCESS)
+        return ret;
 
      ALOGV("%s: mVendor_id = %d, Subcmd = %d.",
         __FUNCTION__, mVendor_id, mSubcmd);
-out:
+
     return ret;
 }
 
-int GScanCommand::requestResponse()
+wifi_error GScanCommand::requestResponse()
 {
     return WifiCommand::requestResponse(mMsg);
 }
 
-int GScanCommand::handleResponse(WifiEvent &reply) {
+int GScanCommand::handleResponse(WifiEvent &reply)
+{
     int i = 0;
-    int ret = WIFI_SUCCESS;
+    wifi_error ret = WIFI_SUCCESS;
     u32 val;
 
     WifiVendorCommand::handleResponse(reply);
@@ -1374,7 +1378,7 @@
 }
 
 /* Called to parse and extract cached results. */
-int GScanCommand:: gscan_get_cached_results(
+wifi_error GScanCommand:: gscan_get_cached_results(
                                       wifi_cached_scan_results *cached_results,
                                       struct nlattr **tb_vendor)
 {
@@ -1654,7 +1658,8 @@
                                 const wifi_epno_params *epno_params,
                                 wifi_epno_handler handler)
 {
-    int i, ret = 0, num_networks;
+    int i, num_networks;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData, *nlPnoParamList;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -1694,14 +1699,14 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0) {
+    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 < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
@@ -1815,7 +1820,7 @@
     }
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
@@ -1828,18 +1833,18 @@
 cleanup:
     delete gScanCommand;
     /* Disable Event Handling if ret != 0 */
-    if (ret && gScanSetPnoListCmdEventHandler) {
+    if ((ret != WIFI_SUCCESS) && gScanSetPnoListCmdEventHandler) {
         ALOGI("%s: Error ret:%d, disable event handling",
             __FUNCTION__, ret);
         gScanSetPnoListCmdEventHandler->disableEventHandling();
     }
-    return mapErrorKernelToWifiHAL(ret);
+    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)
 {
-    int ret = 0;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -1863,14 +1868,14 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0) {
+    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 < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
@@ -1897,13 +1902,12 @@
     gScanCommand->attr_end(nlData);
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
 
 cleanup:
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* Set the ePNO Passpoint List. */
@@ -1912,7 +1916,8 @@
                                    wifi_passpoint_network *networks,
                                    wifi_passpoint_event_handler handler)
 {
-    int i, ret = 0;
+    int i;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData, *nlPasspointNetworksParamList;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -1951,14 +1956,14 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0) {
+    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 < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
@@ -2054,7 +2059,7 @@
     }
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
@@ -2067,18 +2072,18 @@
 cleanup:
     delete gScanCommand;
     /* Disable Event Handling if ret != 0 */
-    if (ret && gScanPnoSetPasspointListCmdEventHandler) {
+    if ((ret != WIFI_SUCCESS) && gScanPnoSetPasspointListCmdEventHandler) {
         ALOGI("%s: Error ret:%d, disable event handling",
             __FUNCTION__, ret);
         gScanPnoSetPasspointListCmdEventHandler->disableEventHandling();
     }
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_reset_passpoint_list(wifi_request_id id,
                             wifi_interface_handle iface)
 {
-    int ret = 0;
+    wifi_error ret;
     GScanCommand *gScanCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -2118,14 +2123,14 @@
 
     /* Create the NL message. */
     ret = gScanCommand->create();
-    if (ret < 0) {
+    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 < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
@@ -2140,7 +2145,7 @@
 
     ret = gScanCommand->put_u32(
             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to add vendor data attributes. Error:%d",
             __FUNCTION__, ret);
         goto cleanup;
@@ -2149,9 +2154,8 @@
     gScanCommand->attr_end(nlData);
 
     ret = gScanCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
 
     /* Disable Event Handling. */
     if (gScanPnoSetPasspointListCmdEventHandler) {
@@ -2160,10 +2164,10 @@
 
 cleanup:
     delete gScanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
-int GScanCommand::allocCachedResultsTemp(int max,
+wifi_error GScanCommand::allocCachedResultsTemp(int max,
                                      wifi_cached_scan_results *cached_results)
 {
     /* Alloc memory for "max" number of cached results. */
@@ -2187,31 +2191,29 @@
 /*
  * Allocates memory for the subCmd response struct and initializes status = -1
  */
-int GScanCommand::allocRspParams(eGScanRspRarams cmd)
+wifi_error GScanCommand::allocRspParams(eGScanRspRarams cmd)
 {
-    int ret = 0;
     switch(cmd)
     {
         case eGScanGetCachedResultsRspParams:
             mGetCachedResultsRspParams = (GScanGetCachedResultsRspParams *)
                 malloc(sizeof(GScanGetCachedResultsRspParams));
             if (!mGetCachedResultsRspParams)
-                ret = -1;
-            else {
-                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;
-            }
+                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__);
-            ret = -1;
+            return WIFI_ERROR_NOT_SUPPORTED;
     }
-    return ret;
+    return WIFI_SUCCESS;
 }
 
 void GScanCommand::freeRspParams(eGScanRspRarams cmd)
diff --git a/qcwcn/wifi_hal/gscan_event_handler.cpp b/qcwcn/wifi_hal/gscan_event_handler.cpp
index a68f2e6..7475a32 100644
--- a/qcwcn/wifi_hal/gscan_event_handler.cpp
+++ b/qcwcn/wifi_hal/gscan_event_handler.cpp
@@ -21,22 +21,19 @@
 #include "vendor_definitions.h"
 
 /* This function implements creation of Vendor command event handler. */
-int GScanCommandEventHandler::create() {
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+wifi_error GScanCommandEventHandler::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 < 0)
-        goto out;
+    if (ret != WIFI_SUCCESS)
+        return ret;
 
     /* Insert the subcmd in the msg */
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
-        goto out;
-out:
+
     return ret;
 }
 
diff --git a/qcwcn/wifi_hal/gscan_event_handler.h b/qcwcn/wifi_hal/gscan_event_handler.h
index cc828f9..5384db8 100644
--- a/qcwcn/wifi_hal/gscan_event_handler.h
+++ b/qcwcn/wifi_hal/gscan_event_handler.h
@@ -66,7 +66,7 @@
     GScanCommandEventHandler(wifi_handle handle, int id, u32 vendor_id,
                                     u32 subcmd, GScanCallbackHandler nHandler);
     virtual ~GScanCommandEventHandler();
-    virtual int create();
+    virtual wifi_error create();
     virtual int get_request_id();
     virtual void set_request_id(int request_id);
     virtual int handleEvent(WifiEvent &event);
diff --git a/qcwcn/wifi_hal/gscancommand.h b/qcwcn/wifi_hal/gscancommand.h
index 7c1bd36..6fb488d 100644
--- a/qcwcn/wifi_hal/gscancommand.h
+++ b/qcwcn/wifi_hal/gscancommand.h
@@ -115,22 +115,22 @@
     /* This function implements creation of GSCAN specific Request
      * based on  the request type.
      */
-    virtual int create();
-    virtual int requestResponse();
+    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 int allocRspParams(eGScanRspRarams cmd);
+    virtual wifi_error allocRspParams(eGScanRspRarams cmd);
     virtual void freeRspParams(eGScanRspRarams cmd);
     virtual wifi_error copyCachedScanResults(int *numResults,
                                              wifi_cached_scan_results *cached_results);
-    virtual int gscan_get_cached_results(wifi_cached_scan_results *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 int allocCachedResultsTemp(int max,
+    virtual wifi_error allocCachedResultsTemp(int max,
                                        wifi_cached_scan_results *results);
 };
 
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.cpp b/qcwcn/wifi_hal/ifaceeventhandler.cpp
index 9e11ce1..54845c0 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.cpp
+++ b/qcwcn/wifi_hal/ifaceeventhandler.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* 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
@@ -30,6 +30,7 @@
 #define LOG_TAG  "WifiHAL"
 #include <utils/Log.h>
 #include <time.h>
+#include <errno.h>
 
 #include "ifaceeventhandler.h"
 
@@ -41,7 +42,6 @@
                                         wifi_interface_handle iface,
                                         wifi_event_handler eh)
 {
-    int ret = 0;
     wifi_handle wifiHandle = getWifiHandle(iface);
 
     /* Check if a similar request to set iface event handler was made earlier.
@@ -72,15 +72,13 @@
     }
     mwifiEventHandler->setCallbackHandler(eh);
 
-    return mapErrorKernelToWifiHAL(ret);
+    return WIFI_SUCCESS;
 }
 
 /* Reset monitoring for the NL event*/
 wifi_error wifi_reset_iface_event_handler(wifi_request_id id,
                                           wifi_interface_handle iface)
 {
-    int ret = 0;
-
     if (mwifiEventHandler)
     {
         if (id == mwifiEventHandler->get_request_id()) {
@@ -96,7 +94,7 @@
         ALOGV("Object mwifiEventHandler for id = %d already Deleted", id);
     }
 
-    return mapErrorKernelToWifiHAL(ret);
+    return WIFI_SUCCESS;
 }
 
 /* This function will be the main handler for the registered incoming
@@ -205,6 +203,8 @@
     filterLength = 0;
     firmware_bus_max_size = 0;
     mCapa = &(info->capa);
+    mfilter_packet_read_buffer = NULL;
+    mfilter_packet_length = 0;
 }
 
 WifihalGeneric::~WifihalGeneric()
@@ -212,7 +212,7 @@
     mCapa = NULL;
 }
 
-int WifihalGeneric::requestResponse()
+wifi_error WifihalGeneric::requestResponse()
 {
     return WifiCommand::requestResponse(mMsg);
 }
@@ -236,7 +236,7 @@
                 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET])
                 {
                     ALOGE("%s: QCA_WLAN_VENDOR_ATTR_FEATURE_SET not found", __func__);
-                    return WIFI_ERROR_INVALID_ARGS;
+                    return -EINVAL;
                 }
                 mSet = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]);
                 ALOGV("Supported feature set : %x", mSet);
@@ -289,31 +289,69 @@
             break;
         case QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER:
             {
+                int subCmd;
                 struct nlattr *tb_vendor[
                         QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX + 1];
                 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX,
                         (struct nlattr *)mVendorData,
                         mDataLen, NULL);
 
-                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION])
+                if (tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD])
                 {
-                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION"
-                          " not found", __FUNCTION__);
-                    return WIFI_ERROR_INVALID_ARGS;
+                    subCmd = nla_get_u32(
+                           tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD]);
+                } else {
+                    /*
+                     * The older drivers may not send PACKET_FILTER_SUB_CMD as
+                     * they support QCA_WLAN_GET_PACKET_FILTER_SIZE only.
+                     */
+                    subCmd = QCA_WLAN_GET_PACKET_FILTER_SIZE;
                 }
-                filterVersion = nla_get_u32(
-                       tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION]);
-                ALOGV("Current version : %u", filterVersion);
+                if (subCmd == QCA_WLAN_GET_PACKET_FILTER_SIZE) {
+                    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION])
+                    {
+                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION"
+                              " not found", __FUNCTION__);
+                        return -EINVAL;
+                    }
+                    filterVersion = nla_get_u32(
+                           tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION]);
+                    ALOGV("Current version : %u", filterVersion);
 
-                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH])
-                {
-                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH"
-                          " not found", __FUNCTION__);
-                    return WIFI_ERROR_INVALID_ARGS;
+                    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH])
+                    {
+                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH"
+                              " not found", __FUNCTION__);
+                        return -EINVAL;
+                    }
+                    filterLength = nla_get_u32(
+                        tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH]);
+                    ALOGV("Max filter length Supported : %u", filterLength);
+                } else if (subCmd == QCA_WLAN_READ_PACKET_FILTER) {
+
+                   if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM])
+                   {
+                       ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM"
+                             " not found", __FUNCTION__);
+                       return -EINVAL;
+                   }
+                   if (nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM])
+                           < mfilter_packet_length)
+                   {
+                       ALOGE("%s: Expected packet filter length :%d but received only: %d bytes",
+                             __FUNCTION__, mfilter_packet_length,
+                             nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]));
+                       return -EINVAL;
+                   }
+                   memcpy(mfilter_packet_read_buffer,
+                      nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]),
+                      mfilter_packet_length);
+                   ALOGV("Filter Program length : %u", mfilter_packet_length);
+                } else {
+                       ALOGE("%s: Unknown APF sub command received",
+                             __FUNCTION__);
+                       return -EINVAL;
                 }
-                filterLength = nla_get_u32(
-                    tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH]);
-                ALOGV("Max filter length Supported : %u", filterLength);
 
             }
             break;
@@ -328,7 +366,7 @@
                 {
                     ALOGE("%s: QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE"
                           " not found", __FUNCTION__);
-                    return WIFI_ERROR_INVALID_ARGS;
+                    return -EINVAL;
                 }
                 firmware_bus_max_size = nla_get_u32(
                        tb_vendor[QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE]);
@@ -524,6 +562,10 @@
 int WifihalGeneric::getFilterLength() {
     return filterLength;
 }
+void WifihalGeneric::setPacketBufferParams(u8 *host_packet_buffer, int packet_length) {
+    mfilter_packet_read_buffer = host_packet_buffer;
+    mfilter_packet_length = packet_length;
+}
 
 int WifihalGeneric::getBusSize() {
     return firmware_bus_max_size;
@@ -531,42 +573,40 @@
 
 wifi_error WifihalGeneric::wifiGetCapabilities(wifi_interface_handle handle)
 {
-    int ret;
+    wifi_error ret;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(handle);
 
     /* Create the NL message. */
     ret = create();
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to create NL message,  Error:%d", __FUNCTION__, ret);
-        return WIFI_ERROR_UNKNOWN;
+        return ret;
     }
 
     /* Set the interface Id of the message. */
     ret = set_iface_id(ifaceInfo->name);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to set interface Id of message, Error:%d", __FUNCTION__, ret);
-        return WIFI_ERROR_UNKNOWN;
+        return ret;
     }
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = attr_start(NL80211_ATTR_VENDOR_DATA);
     if (!nlData)
-        return WIFI_ERROR_UNKNOWN;
+        return WIFI_ERROR_OUT_OF_MEMORY;
 
     ret = put_u32(QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, mId);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to add request_ID to NL command, Error:%d", __FUNCTION__, ret);
-        return WIFI_ERROR_UNKNOWN;
+        return ret;
     }
 
     attr_end(nlData);
 
     ret = requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
-        return WIFI_ERROR_UNKNOWN;
-    }
 
-    return WIFI_SUCCESS;
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.h b/qcwcn/wifi_hal/ifaceeventhandler.h
index 53cf91a..cdbd59d 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.h
+++ b/qcwcn/wifi_hal/ifaceeventhandler.h
@@ -90,17 +90,20 @@
     int filterLength;
     int firmware_bus_max_size;
     wifi_capa *mCapa;
-
+    /* Packet Filter buffer and length */
+    u8 *mfilter_packet_read_buffer;
+    int mfilter_packet_length;
     virtual wifi_error wifiParseCapabilities(struct nlattr **tbVendor);
 
 public:
     WifihalGeneric(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
     virtual ~WifihalGeneric();
-    virtual int requestResponse();
+    virtual wifi_error requestResponse();
     virtual int handleResponse(WifiEvent &reply);
     virtual void getResponseparams(feature_set *pset);
     virtual void setMaxSetSize(int set_size_max);
     virtual void setSizePtr(int *set_size);
+    virtual void setPacketBufferParams(u8 *host_packet_buffer, int packet_length);
     virtual void setConcurrencySet(feature_set set[]);
     virtual int getFilterVersion();
     virtual int getFilterLength();
diff --git a/qcwcn/wifi_hal/llstats.cpp b/qcwcn/wifi_hal/llstats.cpp
index 9a0365e..578b7a8 100644
--- a/qcwcn/wifi_hal/llstats.cpp
+++ b/qcwcn/wifi_hal/llstats.cpp
@@ -31,22 +31,19 @@
 
 // This function implements creation of Vendor command
 // For LLStats just call base Vendor command create
-int LLStatsCommand::create() {
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+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 < 0)
-        goto out;
+    if (ret != WIFI_SUCCESS)
+        return ret;
 
     // insert the subcmd in the msg
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
-        goto out;
 
-out:
     return ret;
 }
 
@@ -851,7 +848,7 @@
     *stop_rsp = mClearRspParams.stop_rsp;
 }
 
-int LLStatsCommand::requestResponse()
+wifi_error LLStatsCommand::requestResponse()
 {
     return WifiCommand::requestResponse(mMsg);
 }
@@ -880,10 +877,15 @@
 {
     if(mResultsParams.radio_stat)
     {
-        if (mResultsParams.radio_stat->tx_time_per_levels)
-        {
-            free(mResultsParams.radio_stat->tx_time_per_levels);
-            mResultsParams.radio_stat->tx_time_per_levels = NULL;
+        wifi_radio_stat *radioStat = mResultsParams.radio_stat;
+        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;
@@ -1246,7 +1248,7 @@
 wifi_error wifi_set_link_stats(wifi_interface_handle iface,
                                wifi_link_layer_params params)
 {
-    int ret = 0;
+    wifi_error ret;
     LLStatsCommand *LLCommand;
     struct nlattr *nl_data;
     interface_info *iinfo = getIfaceInfo(iface);
@@ -1263,11 +1265,11 @@
 
     /* create the message */
     ret = LLCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = LLCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /*add the attributes*/
@@ -1277,23 +1279,22 @@
     /**/
     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD,
                                   params.mpdu_size_threshold);
-    if (ret < 0)
+    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 < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     LLCommand->attr_end(nl_data);
 
     ret = LLCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
 
 cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 //Implementation of the functions exposed in LLStats.h
@@ -1301,7 +1302,7 @@
                                wifi_interface_handle iface,
                                wifi_stats_result_handler handler)
 {
-    int ret = 0;
+    wifi_error ret;
     LLStatsCommand *LLCommand;
     struct nlattr *nl_data;
     interface_info *iinfo = getIfaceInfo(iface);
@@ -1320,11 +1321,11 @@
 
     /* create the message */
     ret = LLCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = LLCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     /*add the attributes*/
     nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
@@ -1332,31 +1333,30 @@
         goto cleanup;
     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID,
                                   id);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK,
                                   7);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /**/
     LLCommand->attr_end(nl_data);
 
     ret = LLCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
-    if (ret < 0) {
+
+    if (ret != WIFI_SUCCESS) {
         LLCommand->clearStats();
         goto cleanup;
     }
 
-    if (ret == 0) {
+    if (ret == WIFI_SUCCESS)
         ret = LLCommand->notifyResponse();
-    }
 
 cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 
@@ -1366,7 +1366,7 @@
                                  u32 *stats_clear_rsp_mask,
                                  u8 stop_req, u8 *stop_rsp)
 {
-    int ret = 0;
+    wifi_error ret;
     LLStatsCommand *LLCommand;
     struct nlattr *nl_data;
     interface_info *iinfo = getIfaceInfo(iface);
@@ -1382,11 +1382,11 @@
 
     /* create the message */
     ret = LLCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = LLCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     /*add the attributes*/
     nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
@@ -1395,23 +1395,22 @@
     /**/
     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK,
                                   stats_clear_req_mask);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     /**/
     ret = LLCommand->put_u8(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ,
                                    stop_req);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     LLCommand->attr_end(nl_data);
 
     ret = LLCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
-    }
 
     LLCommand->getClearRspParams(stats_clear_rsp_mask, stop_rsp);
 
 cleanup:
     delete LLCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/llstatscommand.h b/qcwcn/wifi_hal/llstatscommand.h
index aef0017..5d4c480 100644
--- a/qcwcn/wifi_hal/llstatscommand.h
+++ b/qcwcn/wifi_hal/llstatscommand.h
@@ -94,13 +94,13 @@
 
     // This function implements creation of LLStats specific Request
     // based on  the request type
-    virtual int create();
+    virtual wifi_error create();
 
     virtual void setSubCmd(u32 subcmd);
 
     virtual void initGetContext(u32 reqid);
 
-    virtual int requestResponse();
+    virtual wifi_error requestResponse();
 
     virtual wifi_error notifyResponse();
 
diff --git a/qcwcn/wifi_hal/nan.cpp b/qcwcn/wifi_hal/nan.cpp
index 894873a..fb0e2d3 100644
--- a/qcwcn/wifi_hal/nan.cpp
+++ b/qcwcn/wifi_hal/nan.cpp
@@ -43,7 +43,7 @@
                                 NanCallbackHandler handlers)
 {
     // Obtain the singleton instance
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     wifi_handle wifiHandle = getWifiHandle(iface);
 
@@ -54,7 +54,7 @@
     }
 
     ret = nanCommand->setCallbackHandler(handlers);
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error nan_get_version(wifi_handle handle,
@@ -69,7 +69,7 @@
                               wifi_interface_handle iface,
                               NanEnableRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -84,33 +84,34 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanEnable(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanEnable Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send disable request to the wifi driver.*/
 wifi_error nan_disable_request(transaction_id id,
                                wifi_interface_handle iface)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -125,26 +126,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanDisable(id);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanDisable Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send publish request to the wifi driver.*/
@@ -152,7 +154,7 @@
                                wifi_interface_handle iface,
                                NanPublishRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -167,26 +169,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanPublish(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanPublish Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send publish cancel to the wifi driver.*/
@@ -194,7 +197,7 @@
                                       wifi_interface_handle iface,
                                       NanPublishCancelRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -209,26 +212,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanPublishCancel(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanPublishCancel Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send Subscribe request to the wifi driver.*/
@@ -236,7 +240,7 @@
                                  wifi_interface_handle iface,
                                  NanSubscribeRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -251,26 +255,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanSubscribe(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanSubscribe Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to cancel subscribe to the wifi driver.*/
@@ -278,7 +283,7 @@
                                         wifi_interface_handle iface,
                                         NanSubscribeCancelRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -293,26 +298,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanSubscribeCancel(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanSubscribeCancel Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send NAN follow up request to the wifi driver.*/
@@ -320,7 +326,7 @@
                                          wifi_interface_handle iface,
                                          NanTransmitFollowupRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -335,26 +341,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanTransmitFollowup(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanTransmitFollowup Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send NAN statistics request to the wifi driver.*/
@@ -362,7 +369,7 @@
                              wifi_interface_handle iface,
                              NanStatsRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -377,26 +384,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanStats(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanStats Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send NAN configuration request to the wifi driver.*/
@@ -404,7 +412,7 @@
                               wifi_interface_handle iface,
                               NanConfigRequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -419,26 +427,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanConfig(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanConfig Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send NAN request to the wifi driver.*/
@@ -446,7 +455,7 @@
                            wifi_interface_handle iface,
                            NanTCARequest* msg)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -461,26 +470,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanTCA(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanTCA Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to send NAN Beacon sdf payload to the wifi driver.
@@ -491,7 +501,7 @@
                                          wifi_interface_handle iface,
                                          NanBeaconSdfPayloadRequest* msg)
 {
-    int ret = WIFI_ERROR_NOT_SUPPORTED;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -506,34 +516,34 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanBeaconSdfPayload(id, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanBeaconSdfPayload Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
 
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error nan_get_sta_parameter(transaction_id id,
                                  wifi_interface_handle iface,
                                  NanStaParameter* msg)
 {
-    int ret = WIFI_ERROR_NOT_SUPPORTED;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     wifi_handle wifiHandle = getWifiHandle(iface);
 
@@ -544,20 +554,20 @@
     }
 
     ret = nanCommand->getNanStaParameter(iface, msg);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: getNanStaParameter Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
 
 cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to get NAN capabilities */
 wifi_error nan_get_capabilities(transaction_id id,
                                 wifi_interface_handle iface)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -572,26 +582,27 @@
     }
 
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanCapabilities(id);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanCapabilities Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*  Function to get NAN capabilities */
@@ -600,11 +611,17 @@
                                    NanDebugParams debug,
                                    int debug_msg_length)
 {
-    int ret = 0;
+    wifi_error ret;
     NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
 
+    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,
@@ -614,40 +631,34 @@
         return WIFI_ERROR_UNKNOWN;
     }
 
-    if (debug_msg_length <= 0) {
-        ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
-                                                       debug_msg_length);
-        return WIFI_ERROR_UNKNOWN;
-    }
-
     ret = nanCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = nanCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = nanCommand->putNanDebugCommand(debug, debug_msg_length);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
 
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return (wifi_error)ret;
+    return ret;
 }
 
 wifi_error nan_initialize_vendor_cmd(wifi_interface_handle iface,
                                      NanCommand **nanCommand)
 {
-    int ret = 0;
+    wifi_error ret;
     interface_info *ifaceInfo = getIfaceInfo(iface);
     wifi_handle wifiHandle = getWifiHandle(iface);
 
@@ -667,17 +678,18 @@
 
     /* Create the message */
     ret = (*nanCommand)->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = (*nanCommand)->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     return WIFI_SUCCESS;
+
 cleanup:
     delete *nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error nan_data_interface_create(transaction_id id,
@@ -685,7 +697,7 @@
                                      char* iface_name)
 {
     ALOGV("NAN_DP_INTERFACE_CREATE");
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     NanCommand *nanCommand = NULL;
 
@@ -698,7 +710,7 @@
                                     &nanCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __FUNCTION__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     /* Add the vendor specific attributes for the NL command. */
@@ -719,13 +731,14 @@
     }
 
     nanCommand->attr_end(nlData);
+
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error nan_data_interface_delete(transaction_id id,
@@ -733,7 +746,7 @@
                                      char* iface_name)
 {
     ALOGV("NAN_DP_INTERFACE_DELETE");
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     NanCommand *nanCommand = NULL;
 
@@ -745,7 +758,7 @@
                                     &nanCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __FUNCTION__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     /* Add the vendor specific attributes for the NL command. */
@@ -768,12 +781,12 @@
     nanCommand->attr_end(nlData);
 
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error nan_data_request_initiator(transaction_id id,
@@ -781,7 +794,7 @@
                                       NanDataPathInitiatorRequest* msg)
 {
     ALOGV("NAN_DP_REQUEST_INITIATOR");
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
     NanCommand *nanCommand = NULL;
 
@@ -792,7 +805,7 @@
                                     &nanCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __FUNCTION__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
@@ -903,12 +916,12 @@
     nanCommand->attr_end(nlData);
 
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error nan_data_indication_response(transaction_id id,
@@ -916,7 +929,7 @@
                                         NanDataPathIndicationResponse* msg)
 {
     ALOGV("NAN_DP_INDICATION_RESPONSE");
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
     NanCommand *nanCommand = NULL;
 
@@ -927,7 +940,7 @@
                                     &nanCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __FUNCTION__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
@@ -1020,20 +1033,20 @@
     nanCommand->attr_end(nlData);
 
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error nan_data_end(transaction_id id,
                         wifi_interface_handle iface,
                         NanDataPathEndRequest* msg)
 {
+    wifi_error ret;
     ALOGV("NAN_DP_END");
-    int ret = WIFI_SUCCESS;
     struct nlattr *nlData;
     NanCommand *nanCommand = NULL;
 
@@ -1044,7 +1057,7 @@
                                     &nanCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __FUNCTION__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     /* Add the vendor specific attributes for the NL command. */
@@ -1067,12 +1080,12 @@
     nanCommand->attr_end(nlData);
 
     ret = nanCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete nanCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 // Implementation related to nan class common functions
@@ -1131,12 +1144,12 @@
     return NL_SKIP;
 }
 
-int NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
+wifi_error NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
 {
-    int res = WIFI_SUCCESS;
+    wifi_error res;
     mHandler = nHandler;
     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NAN);
-    if (res != 0) {
+    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);
@@ -1144,7 +1157,7 @@
     }
 
     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NDP);
-    if (res != 0) {
+    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);
@@ -1154,24 +1167,21 @@
 }
 
 /* This function implements creation of Vendor command */
-int NanCommand::create() {
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+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 < 0)
+    if (ret != WIFI_SUCCESS)
         goto out;
     /* Insert the subcmd in the msg */
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
-        goto out;
+
 out:
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS)
         mMsg.destroy();
-    }
     return ret;
 }
 
@@ -1238,6 +1248,7 @@
                 case QCA_WLAN_VENDOR_ATTR_NDP_DATA_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:
diff --git a/qcwcn/wifi_hal/nan_cert.h b/qcwcn/wifi_hal/nan_cert.h
index d84b806..040471a 100644
--- a/qcwcn/wifi_hal/nan_cert.h
+++ b/qcwcn/wifi_hal/nan_cert.h
@@ -36,8 +36,9 @@
 {
 #endif /* __cplusplus */
 
-#define NAN_CERT_VERSION                        2
+#define NAN_CERT_VERSION                        4
 #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 */
@@ -90,6 +91,12 @@
     NAN_SCHED_INVALID_BAD_IMMU = 3
 } NanSchedType;
 
+/* NAN device type */
+typedef enum {
+    NAN_DEVICE_TYPE_TEST_BED = 1,
+    NAN_DEVICE_TYPE_DUT = 2
+} NanDeviceType;
+
  /*
   * Definitions of debug subcommand type for the
   * generic debug command.
@@ -106,7 +113,9 @@
     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_NAN_AVAILABILITY_MAP_ORDER = 12,
+    NAN_TEST_MODE_CMD_CONFIG_QOS = 13,
+    NAN_TEST_MODE_CMD_DEVICE_TYPE = 14
 } NanDebugModeCmd;
 
 /*
diff --git a/qcwcn/wifi_hal/nan_i.h b/qcwcn/wifi_hal/nan_i.h
index 656fb7f..8cfd8b1 100644
--- a/qcwcn/wifi_hal/nan_i.h
+++ b/qcwcn/wifi_hal/nan_i.h
@@ -212,6 +212,9 @@
     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 */
@@ -963,6 +966,7 @@
     u32 amHopCountExpireCount;
     u32 ndpChannelFreq;
     u32 ndpChannelFreq2;
+    u32 schedUpdateChannelFreq;
 } FwNanSyncStats, *pFwNanSyncStats;
 
 /* NAN Misc DE Statistics */
@@ -1073,8 +1077,10 @@
     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 reserved:22;
+    u32 reserved2:15;
 } NanFWSdeaCtrlParams;
 
 /* NAN Ranging Configuration params */
diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/qcwcn/wifi_hal/nan_ind.cpp
index 75663d3..00e3410 100644
--- a/qcwcn/wifi_hal/nan_ind.cpp
+++ b/qcwcn/wifi_hal/nan_ind.cpp
@@ -886,21 +886,20 @@
     return 0;
 }
 
-int NanCommand::getNanStaParameter(wifi_interface_handle iface,
+wifi_error NanCommand::getNanStaParameter(wifi_interface_handle iface,
                                    NanStaParameter *pRsp)
 {
-    int ret = WIFI_ERROR_NONE;
-    int res = -1;
+    wifi_error ret = WIFI_ERROR_NONE;
     transaction_id id = 1;
     interface_info *ifaceInfo = getIfaceInfo(iface);
 
     ret = create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /*
@@ -914,7 +913,7 @@
 
     mStaParam = pRsp;
     ret = putNanStats(id, &syncStats);
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: putNanStats Error:%d",__func__, ret);
         goto cleanup;
     }
@@ -927,11 +926,10 @@
     struct timespec abstime;
     abstime.tv_sec = 4;
     abstime.tv_nsec = 0;
-    res = mCondition.wait(abstime);
-    if (res == ETIMEDOUT)
+    ret = mCondition.wait(abstime);
+    if (ret == WIFI_ERROR_TIMED_OUT)
     {
         ALOGE("%s: Time out happened.", __func__);
-        ret = WIFI_ERROR_TIMED_OUT;
         goto cleanup;
     }
     ALOGV("%s: NanStaparameter Master_pref:%x," \
@@ -942,7 +940,7 @@
           pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq);
 cleanup:
     mStaParam = NULL;
-    return (int)ret;
+    return ret;
 }
 
 int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event)
@@ -1021,6 +1019,47 @@
         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;
@@ -1071,6 +1110,10 @@
 {
     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",
@@ -1116,6 +1159,113 @@
             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_MAX + 1];
+
+             pChInfo =
+                 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
+             nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_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_MAX + 1];
+
+            pChInfo =
+                (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
+            nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_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;
 }
 
@@ -1210,7 +1360,7 @@
                 outputTlv.length = sizeof(NanFWRangeReportParams);
             }
             memcpy(&range_params, outputTlv.value, outputTlv.length);
-            event->range_measurement_cm = range_params.range_measurement;
+            event->range_measurement_mm = range_params.range_measurement;
             event->publish_id = range_params.publish_id;
 //          event->event_type = range_params.event_type;
             break;
diff --git a/qcwcn/wifi_hal/nan_req.cpp b/qcwcn/wifi_hal/nan_req.cpp
index ab94bfd..8ab3a51 100644
--- a/qcwcn/wifi_hal/nan_req.cpp
+++ b/qcwcn/wifi_hal/nan_req.cpp
@@ -20,8 +20,9 @@
 #include "nan_i.h"
 #include "nancommand.h"
 
-int NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *pReq)
+wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_ENABLE");
     size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
 
@@ -142,7 +143,24 @@
         (
           pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->subscribe_sid_beacon_val)) : 0 \
-        ) ;
+        ) + \
+        (
+           pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
+        ) + \
+        (
+           pReq->config_nss ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
+        ) + \
+        (
+           pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
+        ) + \
+        (
+           pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
+        );
+
     pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
     if (pFwReq == NULL) {
         cleanup();
@@ -303,13 +321,29 @@
                       sizeof(pReq->subscribe_sid_beacon_val),
                       (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
     }
+    if (pReq->config_discovery_beacon_int) {
+        tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
+                      (const u8*)&pReq->discovery_beacon_interval, tlvs);
+    }
+    if (pReq->config_nss) {
+        tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32),
+                      (const u8*)&pReq->nss, tlvs);
+    }
+    if (pReq->config_enable_ranging) {
+        tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32),
+                      (const u8*)&pReq->enable_ranging, tlvs);
+    }
+    if (pReq->config_dw_early_termination) {
+        tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
+                      (const u8*)&pReq->enable_dw_termination, tlvs);
+    }
 
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
     //Insert the vendor specific data
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -318,8 +352,9 @@
     return ret;
 }
 
-int NanCommand::putNanDisable(transaction_id id)
+wifi_error NanCommand::putNanDisable(transaction_id id)
 {
+    wifi_error ret;
     ALOGV("NAN_DISABLE");
     size_t message_len = sizeof(NanDisableReqMsg);
 
@@ -339,8 +374,8 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -349,8 +384,9 @@
     return ret;
 }
 
-int NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq)
+wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_CONFIG");
     size_t message_len = 0;
     int idx = 0;
@@ -423,6 +459,22 @@
         (
            /* Always include cfg discovery indication TLV */
            SIZEOF_TLV_HDR + sizeof(u32) \
+        ) + \
+        (
+           pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
+        ) + \
+        (
+           pReq->config_nss ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
+        ) + \
+        (
+           pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
+        ) + \
+        (
+           pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
+           sizeof(u32)) : 0 \
         );
 
     if (pReq->num_config_discovery_attr) {
@@ -543,6 +595,10 @@
                       sizeof(pReq->subscribe_sid_beacon_val),
                       (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
     }
+    if (pReq->config_discovery_beacon_int) {
+        tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
+                      (const u8*)&pReq->discovery_beacon_interval, tlvs);
+    }
 
     u32 config_discovery_indications;
     config_discovery_indications = (u32)(pReq->discovery_indication_cfg);
@@ -551,11 +607,24 @@
                   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);
+    }
+    if (pReq->config_enable_ranging) {
+        tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32),
+                      (const u8*)&pReq->enable_ranging, tlvs);
+    }
+    if (pReq->config_dw_early_termination) {
+        tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
+                      (const u8*)&pReq->enable_dw_termination, tlvs);
+    }
+
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -564,8 +633,9 @@
     return ret;
 }
 
-int NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq)
+wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_PUBLISH");
     if (pReq == NULL) {
         cleanup();
@@ -581,10 +651,11 @@
         (SIZEOF_TLV_HDR + sizeof(NanServiceAcceptPolicy)) +
         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
-          pReq->sdea_params.ranging_state || pReq->sdea_params.range_report) ?
+          pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
+          pReq->sdea_params.qos_cfg) ?
           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
-          pReq->ranging_cfg.distance_ingress_cm || pReq->ranging_cfg.distance_egress_cm) ?
+          pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ?
           SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
         ((pReq->range_response_cfg.publish_id ||
           pReq->range_response_cfg.ranging_response) ?
@@ -688,7 +759,8 @@
     if (pReq->sdea_params.config_nan_data_path ||
         pReq->sdea_params.security_cfg ||
         pReq->sdea_params.ranging_state ||
-        pReq->sdea_params.range_report) {
+        pReq->sdea_params.range_report ||
+        pReq->sdea_params.qos_cfg) {
         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
 
@@ -712,14 +784,17 @@
             pNanFWSdeaCtrlParams.range_report =
                 (((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT) >> 1) ? 1 : 0);
         }
+        if (pReq->sdea_params.qos_cfg) {
+            pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
+        }
         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
     }
 
     if (pReq->ranging_cfg.ranging_interval_msec ||
         pReq->ranging_cfg.config_ranging_indications ||
-        pReq->ranging_cfg.distance_ingress_cm ||
-        pReq->ranging_cfg.distance_ingress_cm) {
+        pReq->ranging_cfg.distance_ingress_mm ||
+        pReq->ranging_cfg.distance_egress_mm) {
         NanFWRangeConfigParams pNanFWRangingCfg;
 
         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
@@ -733,10 +808,10 @@
         pNanFWRangingCfg.ranging_indication_event = pReq->ranging_cfg.config_ranging_indications;
         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
-                                        pReq->ranging_cfg.distance_ingress_cm;
+                                        pReq->ranging_cfg.distance_ingress_mm;
         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)
             pNanFWRangingCfg.geo_fence_threshold.outer_threshold =
-                                       pReq->ranging_cfg.distance_egress_cm;
+                                       pReq->ranging_cfg.distance_egress_mm;
         tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams),
                                                     (const u8*)&pNanFWRangingCfg, tlvs);
     }
@@ -766,8 +841,8 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -776,8 +851,9 @@
     return ret;
 }
 
-int NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq)
+wifi_error NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_PUBLISH_CANCEL");
     if (pReq == NULL) {
         cleanup();
@@ -803,8 +879,8 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -813,9 +889,10 @@
     return ret;
 }
 
-int NanCommand::putNanSubscribe(transaction_id id,
+wifi_error NanCommand::putNanSubscribe(transaction_id id,
                                 const NanSubscribeRequest *pReq)
 {
+    wifi_error ret;
 
     ALOGV("NAN_SUBSCRIBE");
     if (pReq == NULL) {
@@ -831,10 +908,11 @@
         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
-          pReq->sdea_params.ranging_state || pReq->sdea_params.range_report) ?
+          pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
+          pReq->sdea_params.qos_cfg) ?
           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
-          pReq->ranging_cfg.distance_ingress_cm || pReq->ranging_cfg.distance_egress_cm) ?
+          pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ?
           SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
         ((pReq->range_response_cfg.requestor_instance_id ||
           pReq->range_response_cfg.ranging_response) ?
@@ -946,7 +1024,8 @@
     if (pReq->sdea_params.config_nan_data_path ||
         pReq->sdea_params.security_cfg ||
         pReq->sdea_params.ranging_state ||
-        pReq->sdea_params.range_report) {
+        pReq->sdea_params.range_report ||
+        pReq->sdea_params.qos_cfg) {
         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
 
@@ -970,13 +1049,16 @@
             pNanFWSdeaCtrlParams.range_report =
                 ((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT >> 1) ? 1 : 0);
         }
+        if (pReq->sdea_params.qos_cfg) {
+            pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
+        }
         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
 
     }
 
-    if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || pReq->ranging_cfg.distance_ingress_cm
-        || pReq->ranging_cfg.distance_ingress_cm) {
+    if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || pReq->ranging_cfg.distance_ingress_mm
+        || pReq->ranging_cfg.distance_egress_mm) {
         NanFWRangeConfigParams pNanFWRangingCfg;
         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
         pNanFWRangingCfg.range_interval =
@@ -990,10 +1072,10 @@
                                           pReq->ranging_cfg.config_ranging_indications;
         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
-                                        pReq->ranging_cfg.distance_ingress_cm;
+                                        pReq->ranging_cfg.distance_ingress_mm;
         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)
             pNanFWRangingCfg.geo_fence_threshold.outer_threshold =
-                                       pReq->ranging_cfg.distance_egress_cm;
+                                       pReq->ranging_cfg.distance_egress_mm;
         tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams),
                                                     (const u8*)&pNanFWRangingCfg, tlvs);
     }
@@ -1021,8 +1103,8 @@
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -1031,9 +1113,10 @@
     return ret;
 }
 
-int NanCommand::putNanSubscribeCancel(transaction_id id,
+wifi_error NanCommand::putNanSubscribeCancel(transaction_id id,
                                       const NanSubscribeCancelRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_SUBSCRIBE_CANCEL");
     if (pReq == NULL) {
         cleanup();
@@ -1058,8 +1141,8 @@
 
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -1068,9 +1151,10 @@
     return ret;
 }
 
-int NanCommand::putNanTransmitFollowup(transaction_id id,
+wifi_error NanCommand::putNanTransmitFollowup(transaction_id id,
                                        const NanTransmitFollowupRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("TRANSMIT_FOLLOWUP");
     if (pReq == NULL) {
         cleanup();
@@ -1131,8 +1215,8 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -1141,8 +1225,9 @@
     return ret;
 }
 
-int NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq)
+wifi_error NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_STATS");
     if (pReq == NULL) {
         cleanup();
@@ -1171,8 +1256,8 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -1181,8 +1266,9 @@
     return ret;
 }
 
-int NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq)
+wifi_error NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_TCA");
     if (pReq == NULL) {
         cleanup();
@@ -1226,8 +1312,8 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -1236,9 +1322,10 @@
     return ret;
 }
 
-int NanCommand::putNanBeaconSdfPayload(transaction_id id,
+wifi_error NanCommand::putNanBeaconSdfPayload(transaction_id id,
                                        const NanBeaconSdfPayloadRequest *pReq)
 {
+    wifi_error ret;
     ALOGV("NAN_BEACON_SDF_PAYLAOD");
     if (pReq == NULL) {
         cleanup();
@@ -1292,8 +1379,8 @@
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -1343,39 +1430,44 @@
 //This will send the request message
 //We dont wait for any response back in case of Nan as it is asynchronous
 //thus no wait for condition.
-int NanCommand::requestEvent()
+wifi_error NanCommand::requestEvent()
 {
-    int res;
+    wifi_error res;
+    int status;
     struct nl_cb * cb;
 
     cb = nl_cb_alloc(NL_CB_DEFAULT);
     if (!cb) {
         ALOGE("%s: Callback allocation failed",__func__);
-        res = -1;
+        res = WIFI_ERROR_OUT_OF_MEMORY;
         goto out;
     }
 
     if (!mInfo->cmd_sock) {
         ALOGE("%s: Command socket is null",__func__);
-        res = -1;
+        res = WIFI_ERROR_OUT_OF_MEMORY;
         goto out;
     }
 
     /* send message */
     ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
-    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
-    if (res < 0)
+    status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
         goto out;
-    res = 1;
+    }
 
-    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res);
-    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res);
-    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res);
+    status = 1;
+
+    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &status);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &status);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &status);
 
     // err is populated as part of finish_handler
-    while (res > 0)
+    while (status > 0)
         nl_recvmsgs(mInfo->cmd_sock, cb);
 
+    res = mapKernelErrortoWifiHalError(status);
 out:
     //free the VendorData
     if (mVendorData) {
@@ -1535,8 +1627,9 @@
     return ret;
 }
 
-int NanCommand::putNanCapabilities(transaction_id id)
+wifi_error NanCommand::putNanCapabilities(transaction_id id)
 {
+    wifi_error ret;
     ALOGV("NAN_CAPABILITIES");
     size_t message_len = sizeof(NanCapabilitiesReqMsg);
 
@@ -1555,8 +1648,8 @@
     mVendorData = (char*)pFwReq;
     mDataLen = message_len;
 
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
@@ -1565,9 +1658,10 @@
     return ret;
 }
 
-int NanCommand::putNanDebugCommand(NanDebugParams debug,
+wifi_error NanCommand::putNanDebugCommand(NanDebugParams debug,
                                    int debug_msg_length)
 {
+    wifi_error ret;
     ALOGV("NAN_AVAILABILITY_DEBUG");
     size_t message_len = sizeof(NanTestModeReqMsg);
 
@@ -1598,8 +1692,8 @@
     mDataLen = message_len;
 
     /* Write the TLVs to the message. */
-    int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
-    if (ret < 0) {
+    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;
diff --git a/qcwcn/wifi_hal/nan_rsp.cpp b/qcwcn/wifi_hal/nan_rsp.cpp
index 1743293..4160ee1 100644
--- a/qcwcn/wifi_hal/nan_rsp.cpp
+++ b/qcwcn/wifi_hal/nan_rsp.cpp
@@ -703,7 +703,7 @@
         publish_stats.publishNewMatchCount = pPubStats->publishNewMatchCount;
         publish_stats.pubsubGlobalNewMatchCount =
                                pPubStats->pubsubGlobalNewMatchCount;
-        memcpy(&pRsp->data, &publish_stats, sizeof(NanPublishStats));
+        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)) {
@@ -746,7 +746,7 @@
         sub_stats.subscribeNewMatchCount = pSubStats->subscribeNewMatchCount;
         sub_stats.pubsubGlobalNewMatchCount =
                                       pSubStats->pubsubGlobalNewMatchCount;
-        memcpy(&pRsp->data, &sub_stats, sizeof(NanSubscribeStats));
+        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)) {
@@ -775,7 +775,7 @@
         dw_stats.completeByTp75DW = pMacStats->completeByTp75DW;
         dw_stats.completeByTendDW = pMacStats->completeByTendDW;
         dw_stats.lateActionFramesTx = pMacStats->lateActionFramesTx;
-        memcpy(&pRsp->data, &dw_stats, sizeof(NanDWStats));
+        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)) {
@@ -809,7 +809,7 @@
         mac_stats.twChanges = pMacStats->twChanges;
         mac_stats.twHighwater = pMacStats->twHighwater;
         mac_stats.bloomFilterIndex = pMacStats->bloomFilterIndex;
-        memcpy(&pRsp->data, &mac_stats, sizeof(NanMacStats));
+        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)) {
@@ -870,7 +870,8 @@
         sync_stats.amHopCountExpireCount = pSyncStats->amHopCountExpireCount;
         sync_stats.ndpChannelFreq = pSyncStats->ndpChannelFreq;
         sync_stats.ndpChannelFreq2 = pSyncStats->ndpChannelFreq2;
-        memcpy(&pRsp->data, &sync_stats, sizeof(NanSyncStats));
+        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)) {
@@ -910,7 +911,7 @@
         de_stats.invalidEnableReqMsgs = pDeStats->invalidEnableReqMsgs;
         de_stats.invalidDisableReqMsgs = pDeStats->invalidDisableReqMsgs;
         de_stats.invalidTcaReqMsgs = pDeStats->invalidTcaReqMsgs;
-        memcpy(&pRsp->data, &de_stats, sizeof(NanDeStats));
+        memcpy(&pRsp->data.de_stats, &de_stats, sizeof(NanDeStats));
     } else {
         ALOGE("Unknown stats_type:%d\n", stats_type);
     }
diff --git a/qcwcn/wifi_hal/nancommand.h b/qcwcn/wifi_hal/nancommand.h
index e009e0f..b25fec9 100644
--- a/qcwcn/wifi_hal/nancommand.h
+++ b/qcwcn/wifi_hal/nancommand.h
@@ -104,6 +104,7 @@
     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);
@@ -111,28 +112,28 @@
 
     // This function implements creation of NAN specific Request
     // based on  the request type
-    virtual int create();
-    virtual int requestEvent();
+    virtual wifi_error create();
+    virtual wifi_error requestEvent();
     virtual int handleResponse(WifiEvent &reply);
     virtual int handleEvent(WifiEvent &event);
-    int setCallbackHandler(NanCallbackHandler nHandler);
+    wifi_error setCallbackHandler(NanCallbackHandler nHandler);
 
 
     //Functions to fill the vendor data appropriately
-    int putNanEnable(transaction_id id, const NanEnableRequest *pReq);
-    int putNanDisable(transaction_id id);
-    int putNanPublish(transaction_id id, const NanPublishRequest *pReq);
-    int putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq);
-    int putNanSubscribe(transaction_id id, const NanSubscribeRequest *pReq);
-    int putNanSubscribeCancel(transaction_id id, const NanSubscribeCancelRequest *pReq);
-    int putNanTransmitFollowup(transaction_id id, const NanTransmitFollowupRequest *pReq);
-    int putNanStats(transaction_id id, const NanStatsRequest *pReq);
-    int putNanConfig(transaction_id id, const NanConfigRequest *pReq);
-    int putNanTCA(transaction_id id, const NanTCARequest *pReq);
-    int putNanBeaconSdfPayload(transaction_id id, const NanBeaconSdfPayloadRequest *pReq);
-    int getNanStaParameter(wifi_interface_handle iface, NanStaParameter *pRsp);
-    int putNanCapabilities(transaction_id id);
-    int putNanDebugCommand(NanDebugParams debug, int debug_msg_length);
+    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,
diff --git a/qcwcn/wifi_hal/radio_mode.cpp b/qcwcn/wifi_hal/radio_mode.cpp
new file mode 100644
index 0000000..96a2176
--- /dev/null
+++ b/qcwcn/wifi_hal/radio_mode.cpp
@@ -0,0 +1,255 @@
+/* Copyright (c) 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.
+ */
+
+#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 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)
+{
+    RADIOModeCommand* mRADIOModeCommandInstance;
+
+    if (handle == NULL) {
+        ALOGE("Interface Handle is invalid");
+        return NULL;
+    }
+    hal_info *info = getHalInfo(handle);
+    if (!info) {
+        ALOGE("hal_info is invalid");
+        return NULL;
+    }
+    mRADIOModeCommandInstance = new RADIOModeCommand(handle, id,
+                OUI_QCA,
+                QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_MODE);
+    return mRADIOModeCommandInstance;
+}
+
+/* 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_SUCCESS;
+    int num_of_mac = 0;
+    wifi_mac_info mode_info;
+
+    WifiVendorCommand::handleEvent(event);
+
+    /* Parse the vendordata and get the attribute */
+    switch(mSubcmd)
+    {
+        case QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_MODE:
+        {
+            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__);
+                        return WIFI_ERROR_INVALID_ARGS;
+                     }
+                     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__);
+                         return WIFI_ERROR_INVALID_ARGS;
+                     }
+                     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_ID])
+                            {
+                                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_ID"
+                                      " NOT FOUND", __FUNCTION__);
+                                return WIFI_ERROR_INVALID_ARGS;
+                            }
+                            if (if_indextoname(nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_ID]),
+                                               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_ID]));
+                            }
+                            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__);
+                                return WIFI_ERROR_INVALID_ARGS;
+                            }
+                            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));
+
+                            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)));
+
+                    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);
+                free(mwifi_iface_mac_info);
+                mwifi_iface_mac_info = NULL;
+            }
+            else {
+                  ALOGE("No Callback registered: on radio mode change");
+                  free(mwifi_iface_mac_info);
+                  mwifi_iface_mac_info = NULL;
+            }
+        }
+        break;
+
+        default:
+            /* Error case should not happen print log */
+            ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd);
+    }
+
+    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_MODE,
+                                &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/qcwcn/wifi_hal/radio_mode.h b/qcwcn/wifi_hal/radio_mode.h
new file mode 100644
index 0000000..4bb83f1
--- /dev/null
+++ b/qcwcn/wifi_hal/radio_mode.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 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 __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/roam.cpp b/qcwcn/wifi_hal/roam.cpp
index d6a8aa9..53a26ef 100644
--- a/qcwcn/wifi_hal/roam.cpp
+++ b/qcwcn/wifi_hal/roam.cpp
@@ -30,28 +30,26 @@
 }
 
 /* This function implements creation of Vendor command */
-int RoamCommand::create() {
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+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 < 0)
-        goto out;
+    if (ret != WIFI_SUCCESS)
+        return ret;
     /* Insert the subcmd in the msg */
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
-        goto out;
+    if (ret != WIFI_SUCCESS)
+        return ret;
 
      ALOGV("%s: mVendor_id = %d, Subcmd = %d.",
         __FUNCTION__, mVendor_id, mSubcmd);
-out:
     return ret;
 }
 
-int RoamCommand::requestResponse()
+wifi_error RoamCommand::requestResponse()
 {
     return WifiCommand::requestResponse(mMsg);
 }
@@ -60,7 +58,8 @@
                                     wifi_interface_handle iface,
                                     wifi_bssid_params params)
 {
-    int ret = 0, i;
+    wifi_error ret;
+    int i;
     RoamCommand *roamCommand;
     struct nlattr *nlData, *nlBssids;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -92,12 +91,12 @@
 
     /* Create the NL message. */
     ret = roamCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = roamCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -105,27 +104,31 @@
     if (!nlData)
         goto cleanup;
 
-    if (roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
-            QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID) ||
-        roamCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID,
-            id) ||
-        roamCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID,
-            params.num_bssid)) {
+    ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
+                          QCA_WLAN_VENDOR_ATTR_ROAM_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);
 
-        if (roamCommand->put_addr(
-                QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID,
-                (u8 *)params.bssids[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);
     }
@@ -134,21 +137,20 @@
     roamCommand->attr_end(nlData);
 
     ret = roamCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("wifi_set_bssid_blacklist(): requestResponse Error:%d", ret);
-    }
 
 cleanup:
     delete roamCommand;
-    return (wifi_error)ret;
+    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 result = WIFI_SUCCESS;
-    int ret = 0, i;
+    wifi_error ret;
+    int i;
     RoamCommand *roamCommand;
     struct nlattr *nlData, *nlSsids;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -169,36 +171,35 @@
 
     /* Create the NL message. */
     ret = roamCommand->create();
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to create NL message,  Error: %d", __FUNCTION__, ret);
-        result = WIFI_ERROR_UNKNOWN;
         goto cleanup;
     }
 
     /* Set the interface Id of the message. */
     ret = roamCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to set interface Id of message, Error: %d", __FUNCTION__, ret);
-        result = WIFI_ERROR_UNKNOWN;
         goto cleanup;
     }
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
     if (!nlData) {
-        result = WIFI_ERROR_UNKNOWN;
         goto cleanup;
     }
 
-    if (roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
-                             QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SSID_WHITE_LIST) ||
-        roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID, id) ||
-        roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS,
-                             num_networks)) {
-        ALOGE("%s: Failed to add vendor atributes, Error: %d", __FUNCTION__, ret);
-        result = WIFI_ERROR_UNKNOWN;
+    ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
+                              QCA_WLAN_VENDOR_ATTR_ROAM_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++) {
@@ -208,10 +209,10 @@
         ssid[ssid_list[i].length] = '\0';
         ALOGV("ssid[%d] : %s", i, ssid);
 
-        if (roamCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID, ssid,
-                                   (ssid_list[i].length + 1))) {
+        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);
-            result = WIFI_ERROR_UNKNOWN;
             goto cleanup;
         }
 
@@ -222,14 +223,12 @@
     roamCommand->attr_end(nlData);
 
     ret = roamCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
-        result = WIFI_ERROR_UNKNOWN;
-    }
 
 cleanup:
     delete roamCommand;
-    return result;
+    return ret;
 }
 
 wifi_error wifi_get_roaming_capabilities(wifi_interface_handle iface,
@@ -307,8 +306,8 @@
 /* Enable/disable firmware roaming */
 wifi_error wifi_enable_firmware_roaming(wifi_interface_handle iface, fw_roaming_state_t state)
 {
-    wifi_error result = WIFI_SUCCESS;
-    int requestId, ret;
+    int requestId;
+    wifi_error ret;
     RoamCommand *roamCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -343,45 +342,38 @@
 
     /* Create the NL message. */
     ret = roamCommand->create();
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to create NL message,  Error: %d", __FUNCTION__, ret);
-        result = WIFI_ERROR_UNKNOWN;
         goto cleanup;
     }
 
     /* Set the interface Id of the message. */
     ret = roamCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Failed to set interface Id of message, Error: %d", __FUNCTION__, ret);
-        result = WIFI_ERROR_UNKNOWN;
         goto cleanup;
     }
 
     /* Add the vendor specific attributes for the NL command. */
     nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
     if (!nlData) {
-        result = WIFI_ERROR_UNKNOWN;
+        ret = WIFI_ERROR_UNKNOWN;
         goto cleanup;
     }
 
-    if (roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY, policy)) {
+    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);
-        result = WIFI_ERROR_UNKNOWN;
         goto cleanup;
     }
 
     roamCommand->attr_end(nlData);
 
     ret = roamCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
-        if (ret == -EBUSY)
-            result = WIFI_ERROR_BUSY;
-        else
-            result = WIFI_ERROR_UNKNOWN;
-    }
 
 cleanup:
     delete roamCommand;
-    return result;
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/roamcommand.h b/qcwcn/wifi_hal/roamcommand.h
index 1704675..9de90b2 100644
--- a/qcwcn/wifi_hal/roamcommand.h
+++ b/qcwcn/wifi_hal/roamcommand.h
@@ -39,8 +39,8 @@
     RoamCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
     virtual ~RoamCommand();
 
-    virtual int create();
-    virtual int requestResponse();
+    virtual wifi_error create();
+    virtual wifi_error requestResponse();
 };
 
 #ifdef __cplusplus
diff --git a/qcwcn/wifi_hal/rssi_monitor.cpp b/qcwcn/wifi_hal/rssi_monitor.cpp
index b4df331..20d5aa3 100644
--- a/qcwcn/wifi_hal/rssi_monitor.cpp
+++ b/qcwcn/wifi_hal/rssi_monitor.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* 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
@@ -67,6 +67,8 @@
             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__);
@@ -253,7 +255,7 @@
                                       s8 min_rssi,
                                       wifi_rssi_event_handler eh)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -264,7 +266,7 @@
                                 &vCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __FUNCTION__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     ALOGV("%s: Max RSSI:%d Min RSSI:%d", __FUNCTION__,
@@ -274,47 +276,49 @@
     if (!nlData)
         goto cleanup;
 
-    if (vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL,
-            QCA_WLAN_RSSI_MONITORING_START) ||
-        vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
-            id) ||
-        vCommand->put_s8(
-            QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI,
-            max_rssi) ||
-        vCommand->put_s8(
-            QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI,
-            min_rssi))
-    {
+    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__);
-        return WIFI_ERROR_OUT_OF_MEMORY;
+        ret = WIFI_ERROR_OUT_OF_MEMORY;
+        goto cleanup;
     }
 
     rssiCommand->setCallbackHandler(eh);
 
     ret = vCommand->requestResponse();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     rssiCommand->enableEventHandling();
 
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_stop_rssi_monitoring(wifi_request_id id,
                                      wifi_interface_handle iface)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
     wifi_handle wifiHandle = getWifiHandle(iface);
@@ -322,7 +326,7 @@
     rssi_monitor_event_handlers* event_handlers;
     hal_info *info = getHalInfo(wifiHandle);
 
-    event_handlers = (rssi_monitor_event_handlers*)info->rssi_handlers;
+    event_handlers = info->rssi_handlers;
     rssiCommand = event_handlers->mRSSIMonitorCommandInstance;
 
     if (rssiCommand == NULL ||
@@ -337,7 +341,7 @@
                                 &vCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __FUNCTION__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     /* Add the vendor specific attributes for the NL command. */
@@ -345,26 +349,24 @@
     if (!nlData)
         goto cleanup;
 
-    if (vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL,
-            QCA_WLAN_RSSI_MONITORING_STOP) ||
-        vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
-            id))
-    {
+    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 < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     rssiCommand->disableEventHandling();
 
-
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/rtt.cpp b/qcwcn/wifi_hal/rtt.cpp
index c3d9e69..b295ab6 100644
--- a/qcwcn/wifi_hal/rtt.cpp
+++ b/qcwcn/wifi_hal/rtt.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* 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
@@ -43,7 +43,7 @@
 wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
                                      wifi_rtt_capabilities *capabilities)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL) {
@@ -68,19 +68,15 @@
         lowiWifiHalApi->get_rtt_capabilities == NULL) {
         ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.");
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        return WIFI_ERROR_NOT_SUPPORTED;
     }
 
-    ret = lowiWifiHalApi->get_rtt_capabilities(iface, capabilities);
-    if (ret != WIFI_SUCCESS) {
+    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);
-        goto cleanup;
-    }
 
-cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* API to request RTT measurement */
@@ -90,7 +86,7 @@
                                     wifi_rtt_config rtt_config[],
                                     wifi_rtt_event_handler handler)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL) {
@@ -127,23 +123,17 @@
         lowiWifiHalApi->rtt_range_request == NULL) {
         ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.");
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        return WIFI_ERROR_NOT_SUPPORTED;
     }
 
-    ret = lowiWifiHalApi->rtt_range_request(id,
-                                            iface,
-                                            num_rtt_config,
-                                            rtt_config,
-                                            handler);
-    if (ret != WIFI_SUCCESS) {
+    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);
-        goto cleanup;
-    }
 
-cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* API to cancel RTT measurements */
@@ -152,7 +142,7 @@
                                    unsigned num_devices,
                                    mac_addr addr[])
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL) {
@@ -183,26 +173,22 @@
         lowiWifiHalApi->rtt_range_cancel == NULL) {
         ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.");
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        return WIFI_ERROR_NOT_SUPPORTED;
     }
 
-    ret = lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr);
-    if (ret != WIFI_SUCCESS) {
+    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);
-        goto cleanup;
-    }
 
-cleanup:
-    return mapErrorKernelToWifiHAL(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)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL) {
@@ -227,26 +213,21 @@
         lowiWifiHalApi->rtt_set_lci == NULL) {
         ALOGE("%s: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.", __FUNCTION__);
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        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);
-        goto cleanup;
-    }
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
 
-cleanup:
-    return mapErrorKernelToWifiHAL(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)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL) {
@@ -271,19 +252,14 @@
         lowiWifiHalApi->rtt_set_lcr == NULL) {
         ALOGE("%s: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.", __FUNCTION__);
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        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);
-        goto cleanup;
-    }
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
 
-cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /*
@@ -292,7 +268,7 @@
 wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
                                       wifi_rtt_responder *responder_info)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL || responder_info == NULL) {
@@ -308,19 +284,14 @@
         lowiWifiHalApi->rtt_get_responder_info == NULL) {
         ALOGE("%s: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.", __FUNCTION__);
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        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);
-        goto cleanup;
-    }
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
 
-cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /**
@@ -337,7 +308,7 @@
                                  unsigned max_duration_seconds,
                                  wifi_rtt_responder *responder_info)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL || responder_info == NULL) {
@@ -352,21 +323,16 @@
         lowiWifiHalApi->enable_responder == NULL) {
         ALOGE("%s: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.", __FUNCTION__);
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        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);
-        goto cleanup;
-    }
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
 
-cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 
@@ -377,7 +343,7 @@
                                   wifi_interface_handle iface)
 
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     lowi_cb_table_t *lowiWifiHalApi = NULL;
 
     if (iface == NULL) {
@@ -392,17 +358,12 @@
         lowiWifiHalApi->disable_responder == NULL) {
         ALOGE("%s: getLowiCallbackTable returned NULL or "
             "the function pointer is NULL. Exit.", __FUNCTION__);
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto cleanup;
+        return WIFI_ERROR_NOT_SUPPORTED;
     }
 
     ret = lowiWifiHalApi->disable_responder(id, iface);
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s: returned error:%d. Exit.",
-              __FUNCTION__, ret);
-        goto cleanup;
-    }
+    if (ret != WIFI_SUCCESS)
+        ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
 
-cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/sync.h b/qcwcn/wifi_hal/sync.h
index 57080df..eaa9f11 100644
--- a/qcwcn/wifi_hal/sync.h
+++ b/qcwcn/wifi_hal/sync.h
@@ -15,6 +15,8 @@
  */
 
 #include <pthread.h>
+#include "wifi_hal.h"
+#include "common.h"
 
 #ifndef __WIFI_HAL_SYNC_H__
 #define __WIFI_HAL_SYNC_H__
@@ -57,13 +59,15 @@
         pthread_mutex_destroy(&mMutex);
     }
 
-    int wait() {
-        return pthread_cond_wait(&mCondition, &mMutex);
+    wifi_error wait() {
+        int status = pthread_cond_wait(&mCondition, &mMutex);
+        return mapKernelErrortoWifiHalError(status);
     }
 
-    int wait(struct timespec abstime)
+    wifi_error wait(struct timespec abstime)
     {
         struct timeval now;
+        int status;
 
         gettimeofday(&now,NULL);
 
@@ -78,7 +82,8 @@
         {
             abstime.tv_nsec += now.tv_usec * 1000;
         }
-        return pthread_cond_timedwait(&mCondition, &mMutex, &abstime);
+        status = pthread_cond_timedwait(&mCondition, &mMutex, &abstime);
+        return mapKernelErrortoWifiHalError(status);
     }
 
     void signal() {
diff --git a/qcwcn/wifi_hal/tdls.cpp b/qcwcn/wifi_hal/tdls.cpp
index 64d5a63..f12816f 100644
--- a/qcwcn/wifi_hal/tdls.cpp
+++ b/qcwcn/wifi_hal/tdls.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* 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
@@ -282,12 +282,13 @@
 }
 
 
-int TdlsCommand::setCallbackHandler(wifi_tdls_handler nHandler, u32 event)
+wifi_error TdlsCommand::setCallbackHandler(wifi_tdls_handler nHandler, u32 event)
 {
-    int res = 0;
+    wifi_error res;
     mHandler = nHandler;
+
     res = registerVendorHandler(mVendor_id, event);
-    if (res != 0) {
+    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);
@@ -309,7 +310,7 @@
     status->reason = mTDLSgetStatusRspParams.reason;
 }
 
-int TdlsCommand::requestResponse()
+wifi_error TdlsCommand::requestResponse()
 {
     return WifiCommand::requestResponse(mMsg);
 }
@@ -349,7 +350,7 @@
                             wifi_tdls_params *params,
                             wifi_tdls_handler handler)
 {
-    int ret = 0;
+    wifi_error ret;
     TdlsCommand *pTdlsCommand;
     struct nlattr *nl_data;
     interface_info *iinfo = getIfaceInfo(iface);
@@ -364,11 +365,11 @@
 
     /* Create the message */
     ret = pTdlsCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = pTdlsCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the attributes */
@@ -378,7 +379,7 @@
     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 < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     if (params != NULL) {
@@ -388,34 +389,39 @@
             params->max_latency_ms, params->min_bandwidth_kbps);
         ret = pTdlsCommand->put_u32(
                             QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL,
-                            params->channel) |
-              pTdlsCommand->put_u32(
+                            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) |
-              pTdlsCommand->put_u32(
+                            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) |
-              pTdlsCommand->put_u32(
+                            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 < 0)
-            goto cleanup;
+        if (ret != WIFI_SUCCESS)
+                goto cleanup;
     }
 
     pTdlsCommand->attr_end(nl_data);
 
     ret = pTdlsCommand->setCallbackHandler(handler,
                         QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = pTdlsCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
-    }
 
 cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* wifi_disable_tdls - disables TDLS-auto mode for a specific route
@@ -428,7 +434,7 @@
  */
 wifi_error wifi_disable_tdls(wifi_interface_handle iface, mac_addr addr)
 {
-    int ret = 0;
+    wifi_error ret;
     TdlsCommand *pTdlsCommand;
     struct nlattr *nl_data;
     interface_info *iinfo = getIfaceInfo(iface);
@@ -443,11 +449,11 @@
 
     /* Create the message */
     ret = pTdlsCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = pTdlsCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    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));
@@ -458,18 +464,17 @@
         goto cleanup;
     ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR,
                                   (char *)addr, 6);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     pTdlsCommand->attr_end(nl_data);
 
     ret = pTdlsCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
-    }
 
 cleanup:
     delete pTdlsCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* wifi_get_tdls_status - allows getting the status of TDLS for a specific
@@ -478,7 +483,7 @@
 wifi_error wifi_get_tdls_status(wifi_interface_handle iface, mac_addr addr,
                                 wifi_tdls_status *status)
 {
-    int ret = 0;
+    wifi_error ret;
     TdlsCommand *pTdlsCommand;
     struct nlattr *nl_data;
     interface_info *iinfo = getIfaceInfo(iface);
@@ -493,11 +498,11 @@
 
     /* Create the message */
     ret = pTdlsCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = pTdlsCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     ALOGV("%s: ifindex obtained:%d", __FUNCTION__, ret);
 
@@ -507,25 +512,25 @@
         goto cleanup;
     ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR,
                                   (char *)addr, 6);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
     pTdlsCommand->attr_end(nl_data);
 
     ret = pTdlsCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
-    }
+
     pTdlsCommand->getStatusRspParams(status);
 
 cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    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)
 {
-    int ret = 0;
+    wifi_error ret;
     TdlsCommand *pTdlsCommand;
 
     if (capabilities == NULL) {
@@ -545,23 +550,23 @@
 
     /* Create the message */
     ret = pTdlsCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = pTdlsCommand->set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = pTdlsCommand->requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
     pTdlsCommand->getCapsRspParams(capabilities);
 
 cleanup:
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         memset(capabilities, 0, sizeof(wifi_tdls_capabilities));
     delete pTdlsCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/tdlsCommand.h b/qcwcn/wifi_hal/tdlsCommand.h
index d6e3f0f..565e9b3 100755
--- a/qcwcn/wifi_hal/tdlsCommand.h
+++ b/qcwcn/wifi_hal/tdlsCommand.h
@@ -90,13 +90,13 @@
 
     virtual void setSubCmd(u32 subcmd);
 
-    virtual int requestResponse();
+    virtual wifi_error requestResponse();
 
     virtual int handleEvent(WifiEvent &event);
 
     virtual int handleResponse(WifiEvent &reply);
 
-    virtual int setCallbackHandler(wifi_tdls_handler nHandler, u32 event);
+    virtual wifi_error setCallbackHandler(wifi_tdls_handler nHandler, u32 event);
 
     virtual void unregisterHandler(u32 subCmd);
 
diff --git a/qcwcn/wifi_hal/vendor_definitions.h b/qcwcn/wifi_hal/vendor_definitions.h
index ea105fa..928a159 100644
--- a/qcwcn/wifi_hal/vendor_definitions.h
+++ b/qcwcn/wifi_hal/vendor_definitions.h
@@ -106,6 +106,8 @@
 #define QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE 84
 /* Get wake reason stats */
 #define QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS 85
+/* Radio Mode change */
+#define QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_MODE 165
 #endif
 
 enum qca_wlan_vendor_attr_tdls_enable
@@ -369,7 +371,17 @@
     QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
     /* Array of u8: len = NAN_MAX_SERVICE_NAME_LEN */
     QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+    /* Unsigned 32-bit value indicating schedule update */
+    QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON,
+    /* Unsigned 32-bit value for NSS */
+    QCA_WLAN_VENDOR_ATTR_NDP_NSS,
+    /* Unsigned 32-bit value for NUMBER NDP CHANNEL */
+    QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS,
+    /* Unsigned 32-bit value for CHANNEL BANDWIDTH */
+    QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH,
 
+    /* Array of channel/band width */
+    QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO,
 
     /* KEEP LAST */
     QCA_WLAN_VENDOR_ATTR_NDP_AFTER_LAST,
@@ -406,7 +418,8 @@
    QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE = 8,
    QCA_WLAN_VENDOR_ATTR_NDP_DATA_REQUEST_IND = 9,
    QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND = 10,
-   QCA_WLAN_VENDOR_ATTR_NDP_END_IND = 11
+   QCA_WLAN_VENDOR_ATTR_NDP_END_IND = 11,
+   QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND = 12
 };
 
 #define PACKET_FILTER_ID 0
@@ -415,6 +428,14 @@
 {
     QCA_WLAN_SET_PACKET_FILTER = 1,
     QCA_WLAN_GET_PACKET_FILTER_SIZE = 2,
+    /* For writing packet filter program + data */
+    QCA_WLAN_WRITE_PACKET_FILTER = 3,
+    /* For reading packet filter data */
+    QCA_WLAN_READ_PACKET_FILTER = 4,
+    /* Enable APF faeature */
+    QCA_WLAN_ENABLE_PACKET_FILTER = 5,
+    /* Disable APF faeature */
+    QCA_WLAN_DISABLE_PACKET_FILTER = 6,
 };
 
 enum qca_wlan_vendor_attr_packet_filter
@@ -427,6 +448,10 @@
     QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
     QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET,
     QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM,
+    /* The length of the program in the write buffer,
+     * the write buffer may have program+data
+     */
+    QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH,
 
     /* keep last */
     QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST,
@@ -490,4 +515,60 @@
     QCA_WLAN_VENDOR_ATTR_WAKE_STATS_MAX =
         QCA_WLAN_VENDOR_ATTR_WAKE_STATS_AFTER_LAST - 1,
 };
+
+/**
+ * enum qca_wlan_vendor_attr_mac - Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO.
+ */
+enum qca_wlan_vendor_attr_mac {
+    QCA_WLAN_VENDOR_ATTR_MAC_INVALID = 0,
+    /* MAC mode info list which has an array of nested values as
+     * per attributes in enum qca_wlan_vendor_attr_mac_info.
+     */
+    QCA_WLAN_VENDOR_ATTR_MAC_INFO = 1,
+    /* keep last */
+    QCA_WLAN_VENDOR_ATTR_MAC_AFTER_LAST,
+    QCA_WLAN_VENDOR_ATTR_MAC_MAX =
+    QCA_WLAN_VENDOR_ATTR_MAC_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mac_iface_info - Information of the connected
+ * WiFi netdev interface on a respective MAC.
+ * Used by the attribute QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO.
+ */
+enum qca_wlan_vendor_attr_mac_iface_info {
+    QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_INVALID = 0,
+    /* Wi-Fi Netdev's interface id.u32. */
+    QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_ID = 1,
+    /* Associated frequency in MHz of the connected Wi-Fi interface. u32 */
+    QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ = 2,
+    /* keep last */
+    QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_AFTER_LAST,
+    QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_MAX =
+    QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mac_info - Points to MAC the information.
+ * Used by the attribute QCA_WLAN_VENDOR_ATTR_MAC_INFO of the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO.
+ */
+enum qca_wlan_vendor_attr_mac_info {
+    QCA_WLAN_VENDOR_ATTR_MAC_INFO_INVALID = 0,
+    /* Hardware MAC ID associated for the MAC (u32) */
+    QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID = 1,
+    /* Band supported by the respective MAC at a given point.
+     * Represented by enum qca_wlan_vendor_mac_info_band.
+     */
+    QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND = 2,
+    /* Refers to list of WLAN net dev interfaces associated with this MAC.
+     * Represented by enum qca_wlan_vendor_attr_mac_iface_info.
+     */
+    QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO = 3,
+    /* keep last */
+    QCA_WLAN_VENDOR_ATTR_MAC_INFO_AFTER_LAST,
+    QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAX =
+    QCA_WLAN_VENDOR_ATTR_MAC_INFO_AFTER_LAST - 1,
+};
 #endif
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index fcd2b4d..1a5811c 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -66,6 +66,13 @@
 #define WIFI_HAL_CMD_SOCK_PORT       644
 #define WIFI_HAL_EVENT_SOCK_PORT     645
 
+/*
+ * Defines for wifi_wait_for_driver_ready()
+ * Specify durations between polls and max wait time
+ */
+#define POLL_DRIVER_DURATION_US (100000)
+#define POLL_DRIVER_MAX_TIME_MS (10000)
+
 static void internal_event_handler(wifi_handle handle, int events,
                                    struct nl_sock *sock);
 static int internal_valid_message_handler(nl_msg *msg, void *arg);
@@ -78,6 +85,8 @@
                                          const u8 *program, u32 len);
 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
                                               u32 *version, u32 *max_len);
+static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
+                                   u32 src_offset, u8 *host_dst, u32 length);
 static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface,
                                             u8 enable);
 wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
@@ -157,7 +166,7 @@
 static wifi_error acquire_supported_features(wifi_interface_handle iface,
         feature_set *set)
 {
-    int ret = 0;
+    wifi_error ret;
     interface_info *iinfo = getIfaceInfo(iface);
     wifi_handle handle = getWifiHandle(iface);
     *set = 0;
@@ -168,15 +177,15 @@
 
     /* create the message */
     ret = supportedFeatures.create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = supportedFeatures.set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = supportedFeatures.requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d",__func__, ret);
         goto cleanup;
     }
@@ -184,7 +193,7 @@
     supportedFeatures.getResponseparams(set);
 
 cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 static wifi_error wifi_get_capabilities(wifi_interface_handle handle)
@@ -212,7 +221,7 @@
                             QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES);
     if (!wifihalGeneric) {
         ALOGE("%s: Failed to create object of WifihalGeneric class", __FUNCTION__);
-        return WIFI_ERROR_UNKNOWN;
+        return WIFI_ERROR_OUT_OF_MEMORY;
     }
 
     ret = wifihalGeneric->wifiGetCapabilities(handle);
@@ -224,7 +233,7 @@
 static wifi_error get_firmware_bus_max_size_supported(
                                                 wifi_interface_handle iface)
 {
-    int ret = 0;
+    wifi_error ret;
     interface_info *iinfo = getIfaceInfo(iface);
     wifi_handle handle = getWifiHandle(iface);
     hal_info *info = (hal_info *)handle;
@@ -235,22 +244,22 @@
 
     /* create the message */
     ret = busSizeSupported.create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = busSizeSupported.set_iface_id(iinfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = busSizeSupported.requestResponse();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
         goto cleanup;
     }
     info->firmware_bus_max_size = busSizeSupported.getBusSize();
 
 cleanup:
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 static wifi_error wifi_init_user_sock(hal_info *info)
@@ -326,6 +335,7 @@
     }
 
     fn->wifi_initialize = wifi_initialize;
+    fn->wifi_wait_for_driver_ready = wifi_wait_for_driver_ready;
     fn->wifi_cleanup = wifi_cleanup;
     fn->wifi_event_loop = wifi_event_loop;
     fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
@@ -396,6 +406,7 @@
     fn->wifi_nan_get_version = nan_get_version;
     fn->wifi_set_packet_filter = wifi_set_packet_filter;
     fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
+    fn->wifi_read_packet_filter = wifi_read_packet_filter;
     fn->wifi_nan_get_capabilities = nan_get_capabilities;
     fn->wifi_nan_data_interface_create = nan_data_interface_create;
     fn->wifi_nan_data_interface_delete = nan_data_interface_delete;
@@ -413,6 +424,7 @@
     fn->wifi_enable_firmware_roaming = wifi_enable_firmware_roaming;
     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;
 
     return WIFI_SUCCESS;
 }
@@ -431,6 +443,15 @@
     info->cldctx = NULL;
 }
 
+static int wifi_get_iface_id(hal_info *info, const char *iface)
+{
+    int i;
+    for (i = 0; i < info->num_interfaces; i++)
+        if (!strcmp(info->interfaces[i]->name, iface))
+            return i;
+    return -1;
+}
+
 wifi_error wifi_initialize(wifi_handle *handle)
 {
     int err = 0;
@@ -440,6 +461,7 @@
     struct nl_sock *event_sock = NULL;
     struct nl_cb *cb = NULL;
     int status = 0;
+    int index;
 
     ALOGI("Initializing wifi");
     hal_info *info = (hal_info *)malloc(sizeof(hal_info));
@@ -511,15 +533,6 @@
     info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE;
     info->num_event_cb = 0;
 
-    info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE);
-    if (info->cmd == NULL) {
-        ALOGE("Could not allocate cmd info");
-        ret = WIFI_ERROR_OUT_OF_MEMORY;
-        goto unload;
-    }
-    info->alloc_cmd = DEFAULT_CMD_SIZE;
-    info->num_cmd = 0;
-
     info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211");
     if (info->nl80211_family_id < 0) {
         ALOGE("Could not resolve nl80211 familty id");
@@ -591,17 +604,17 @@
         goto unload;
     }
 
-    iface_handle = wifi_get_iface_handle((info->interfaces[0])->handle,
-            (info->interfaces[0])->name);
-    if (iface_handle == NULL) {
+    index = wifi_get_iface_id(info, "wlan0");
+    if (index == -1) {
         int i;
         for (i = 0; i < info->num_interfaces; i++)
         {
             free(info->interfaces[i]);
         }
-        ALOGE("%s no iface with %s\n", __func__, info->interfaces[0]->name);
+        ALOGE("%s no iface with wlan0", __func__);
         goto unload;
     }
+    iface_handle = (wifi_interface_handle)info->interfaces[index];
 
     ret = acquire_supported_features(iface_handle,
             &info->supported_feature_set);
@@ -613,6 +626,11 @@
         ret = WIFI_SUCCESS;
     }
 
+    ret =  wifi_get_logger_supported_feature_set(iface_handle,
+                         &info->supported_logger_feature_set);
+    if (ret != WIFI_SUCCESS)
+        ALOGE("Failed to get supported logger feature set: %d", ret);
+
     ret = get_firmware_bus_max_size_supported(iface_handle);
     if (ret != WIFI_SUCCESS) {
         ALOGE("Failed to get supported bus size, error : %d", ret);
@@ -620,10 +638,8 @@
     }
 
     ret = wifi_logger_ring_buffers_init(info);
-    if (ret != WIFI_SUCCESS) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("Wifi Logger Ring Initialization Failed");
-        goto unload;
-    }
 
     ret = wifi_get_capabilities(iface_handle);
     if (ret != WIFI_SUCCESS)
@@ -688,8 +704,6 @@
         if (event_sock)
             nl_socket_free(event_sock);
         if (info) {
-            if (info->cmd) free(info->cmd);
-            if (info->event_cb) free(info->event_cb);
             if (info->cldctx) {
                 cld80211lib_cleanup(info);
             } else if (info->user_sock) {
@@ -697,8 +711,10 @@
             }
             if (info->pkt_stats) free(info->pkt_stats);
             if (info->rx_aggr_pkts) free(info->rx_aggr_pkts);
+            wifi_logger_ring_buffers_deinit(info);
             cleanupGscanHandlers(info);
             cleanupRSSIMonitorHandler(info);
+            free(info->event_cb);
             free(info);
         }
     }
@@ -706,6 +722,25 @@
     return ret;
 }
 
+wifi_error wifi_wait_for_driver_ready(void)
+{
+    // This function will wait to make sure basic client netdev is created
+    // Function times out after 10 seconds
+    int count = (POLL_DRIVER_MAX_TIME_MS * 1000) / POLL_DRIVER_DURATION_US;
+    FILE *fd;
+
+    do {
+        if ((fd = fopen("/sys/class/net/wlan0", "r")) != NULL) {
+            fclose(fd);
+            return WIFI_SUCCESS;
+        }
+        usleep(POLL_DRIVER_DURATION_US);
+    } while(--count > 0);
+
+    ALOGE("Timed out wating on Driver ready ... ");
+    return WIFI_ERROR_TIMED_OUT;
+}
+
 static int wifi_add_membership(wifi_handle handle, const char *group)
 {
     hal_info *info = getHalInfo(handle);
@@ -736,6 +771,12 @@
         info->event_sock = NULL;
     }
 
+    if (info->interfaces) {
+        for (int i = 0; i < info->num_interfaces; i++)
+            free(info->interfaces[i]);
+        free(info->interfaces);
+    }
+
     if (info->cldctx != NULL) {
         cld80211lib_cleanup(info);
     } else if (info->user_sock != 0) {
@@ -751,6 +792,11 @@
     cleanupGscanHandlers(info);
     cleanupRSSIMonitorHandler(info);
 
+    if (info->num_event_cb)
+        ALOGE("%d events were leftover without being freed",
+              info->num_event_cb);
+    free(info->event_cb);
+
     if (info->exit_sockets[0] >= 0) {
         close(info->exit_sockets[0]);
         info->exit_sockets[0] = -1;
@@ -955,13 +1001,13 @@
         return mId;
     }
 
-    virtual int create() {
+    virtual wifi_error create() {
         int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
         // ALOGI("ctrl family = %d", nlctrlFamily);
-        int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
-        if (ret < 0) {
+        wifi_error ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
+        if (ret != WIFI_SUCCESS)
             return ret;
-        }
+
         ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
         return ret;
     }
@@ -1148,7 +1194,7 @@
                                        int set_size_max,
                                        feature_set set[], int *set_size)
 {
-    int ret = 0;
+    wifi_error ret;
     struct nlattr *nlData;
     WifihalGeneric *vCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(handle);
@@ -1170,11 +1216,11 @@
 
     /* Create the message */
     ret = vCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = vCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -1182,12 +1228,12 @@
     if (!nlData)
         goto cleanup;
 
-    if (vCommand->put_u32(
-        QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX,
-        set_size_max))
-    {
+    ret = vCommand->put_u32(
+          QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX,
+          set_size_max);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
+
     vCommand->attr_end(nlData);
 
     /* Populate the input received from caller/framework. */
@@ -1196,22 +1242,20 @@
     vCommand->setConcurrencySet(set);
 
     ret = vCommand->requestResponse();
-    if (ret) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: requestResponse() error: %d", __func__, ret);
-    }
 
 cleanup:
     delete vCommand;
-    if (ret) {
+    if (ret)
         *set_size = 0;
-    }
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 
 wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
 {
-    int ret = 0;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(handle);
@@ -1227,11 +1271,11 @@
 
     /* Create the message */
     ret = vCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = vCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -1240,9 +1284,9 @@
         goto cleanup;
 
     /* Add the fixed part of the mac_oui to the nl command */
-    if (vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG, nodfs)) {
+    ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG, nodfs);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
 
     vCommand->attr_end(nlData);
 
@@ -1251,7 +1295,7 @@
 
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id,
@@ -1262,7 +1306,7 @@
                                                u8 *dst_mac_addr,
                                                u32 period_msec)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
 
@@ -1271,7 +1315,7 @@
                                 &vCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __func__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     ALOGV("ip packet length : %u\nIP Packet:", ip_packet_len);
@@ -1285,43 +1329,57 @@
     if (!nlData)
         goto cleanup;
 
-    if (vCommand->put_u32(
+    ret = vCommand->put_u32(
             QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL,
-            QCA_WLAN_OFFLOADED_PACKETS_SENDING_START) ||
-        vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID,
-            id) ||
-        vCommand->put_bytes(
-            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET,
-            (const char *)ip_packet, ip_packet_len) ||
-        vCommand->put_addr(
-            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR,
-            src_mac_addr) ||
-        vCommand->put_addr(
-            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR,
-            dst_mac_addr) ||
-        vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD,
-            period_msec))
-    {
+            QCA_WLAN_OFFLOADED_PACKETS_SENDING_START);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
+
+    ret = vCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID,
+            id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = vCommand->put_bytes(
+            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET,
+            (const char *)ip_packet, ip_packet_len);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = vCommand->put_addr(
+            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR,
+            src_mac_addr);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = vCommand->put_addr(
+            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR,
+            dst_mac_addr);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
+
+    ret = vCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD,
+            period_msec);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
 
     vCommand->attr_end(nlData);
 
     ret = vCommand->requestResponse();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id,
                                               wifi_interface_handle iface)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
 
@@ -1330,7 +1388,7 @@
                                 &vCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __func__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     /* Add the vendor specific attributes for the NL command. */
@@ -1338,32 +1396,33 @@
     if (!nlData)
         goto cleanup;
 
-    if (vCommand->put_u32(
+    ret = vCommand->put_u32(
             QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL,
-            QCA_WLAN_OFFLOADED_PACKETS_SENDING_STOP) ||
-        vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID,
-            id))
-    {
+            QCA_WLAN_OFFLOADED_PACKETS_SENDING_STOP);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
 
+    ret = vCommand->put_u32(
+            QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID,
+            id);
+    if (ret != WIFI_SUCCESS)
+        goto cleanup;
 
     vCommand->attr_end(nlData);
 
     ret = vCommand->requestResponse();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 static wifi_error wifi_set_packet_filter(wifi_interface_handle iface,
                                          const u8 *program, u32 len)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
     u32 current_offset = 0;
@@ -1383,7 +1442,7 @@
                                     &vCommand);
         if (ret != WIFI_SUCCESS) {
             ALOGE("%s: Initialization failed", __FUNCTION__);
-            return mapErrorKernelToWifiHAL(ret);
+            return ret;
         }
 
         /* Add the vendor specific attributes for the NL command. */
@@ -1391,28 +1450,32 @@
         if (!nlData)
             goto cleanup;
 
-        if (vCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
-                QCA_WLAN_SET_PACKET_FILTER) ||
-            vCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID,
-                PACKET_FILTER_ID) ||
-            vCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
-                len) ||
-            vCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET,
-                current_offset)) {
-            ALOGE("%s: failed to put subcmd/program", __FUNCTION__);
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
+                                QCA_WLAN_SET_PACKET_FILTER);
+        if (ret != WIFI_SUCCESS)
             goto cleanup;
-        }
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID,
+                                PACKET_FILTER_ID);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
+                                len);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+        ret = vCommand->put_u32(
+                            QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET,
+                            current_offset);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
 
         if (len) {
-            if(vCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM,
-                                   (char *)&program[current_offset],
-                                   min(info->firmware_bus_max_size,
-                                   len-current_offset))) {
-                ALOGE("%s: failed to put subcmd", __FUNCTION__);
+            ret = vCommand->put_bytes(
+                                     QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM,
+                                     (char *)&program[current_offset],
+                                     min(info->firmware_bus_max_size,
+                                     len-current_offset));
+            if (ret!= WIFI_SUCCESS) {
+                ALOGE("%s: failed to put program", __FUNCTION__);
                 goto cleanup;
             }
         }
@@ -1420,7 +1483,7 @@
         vCommand->attr_end(nlData);
 
         ret = vCommand->requestResponse();
-        if (ret < 0) {
+        if (ret != WIFI_SUCCESS) {
             ALOGE("%s: requestResponse Error:%d",__func__, ret);
             goto cleanup;
         }
@@ -1432,16 +1495,18 @@
         current_offset += min(info->firmware_bus_max_size, len);
     } while (current_offset < len);
 
+    info->apf_enabled = !!len;
+
 cleanup:
     if (vCommand)
         delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 static wifi_error wifi_get_packet_filter_capabilities(
                 wifi_interface_handle handle, u32 *version, u32 *max_len)
 {
-    int ret = 0;
+    wifi_error ret;
     struct nlattr *nlData;
     WifihalGeneric *vCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(handle);
@@ -1463,11 +1528,11 @@
 
     /* Create the message */
     ret = vCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     ret = vCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Add the vendor specific attributes for the NL command. */
@@ -1475,18 +1540,17 @@
     if (!nlData)
         goto cleanup;
 
-    if (vCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
-            QCA_WLAN_GET_PACKET_FILTER_SIZE))
-    {
+    ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
+                            QCA_WLAN_GET_PACKET_FILTER_SIZE);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
+
     vCommand->attr_end(nlData);
 
     ret = vCommand->requestResponse();
-    if (ret) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret);
-        if (ret == -ENOTSUP) {
+        if (ret == WIFI_ERROR_NOT_SUPPORTED) {
             /* Packet filtering is not supported currently, so return version
              * and length as 0
              */
@@ -1502,14 +1566,14 @@
     *max_len = vCommand->getFilterLength();
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 
 static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface,
                                             u8 enable)
 {
-    int ret = WIFI_SUCCESS;
+    wifi_error ret;
     struct nlattr *nlData;
     WifiVendorCommand *vCommand = NULL;
 
@@ -1518,7 +1582,7 @@
                                 &vCommand);
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s: Initialization failed", __func__);
-        return mapErrorKernelToWifiHAL(ret);
+        return ret;
     }
 
     ALOGV("ND offload : %s", enable?"Enable":"Disable");
@@ -1528,12 +1592,9 @@
     if (!nlData)
         goto cleanup;
 
-    if (vCommand->put_u8(
-            QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG,
-            enable))
-    {
+    ret = vCommand->put_u8(QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG, enable);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
 
     vCommand->attr_end(nlData);
 
@@ -1541,5 +1602,285 @@
 
 cleanup:
     delete vCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
+}
+
+/**
+ * Copy 'len' bytes of raw data from host memory at source address 'program'
+ * to APF (Android Packet Filter) working memory starting at offset 'dst_offset'.
+ * The size of the program lenght passed to the interpreter is set to
+ * 'progaram_lenght'
+ *
+ * The implementation is allowed to tranlate this wrtie into a series of smaller
+ * writes,but this function is not allowed to return untill all write operations
+ * have been completed
+ * additionally visible memory not targeted by this function must remain
+ * unchanged
+
+ * @param dst_offset write offset in bytes relative to the beginning of the APF
+ * working memory with logical address 0X000. Must be a multiple of 4
+ *
+ * @param program host memory to copy bytes from. Must be 4B aligned
+ *
+ * @param len the number of bytes to copy from the bost into the APF working
+ * memory
+ *
+ * @param program_length new length of the program instructions in bytes to pass
+ * to the interpreter
+ */
+
+wifi_error wifi_write_packet_filter(wifi_interface_handle iface,
+                                         u32 dst_offset, const u8 *program,
+                                         u32 len, u32 program_length)
+{
+    wifi_error ret;
+    struct nlattr *nlData;
+    WifiVendorCommand *vCommand = NULL;
+    u32 current_offset = 0;
+    wifi_handle wifiHandle = getWifiHandle(iface);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    /* len=0 clears the filters in driver/firmware */
+    if (len != 0 && program == NULL) {
+        ALOGE("%s: No valid program provided. Exit.",
+            __func__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    do {
+        ret = initialize_vendor_cmd(iface, get_requestid(),
+                                    QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER,
+                                    &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)
+             goto cleanup;
+
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
+                                 QCA_WLAN_WRITE_PACKET_FILTER);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID,
+                                PACKET_FILTER_ID);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
+                                len);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+        ret = vCommand->put_u32(
+                            QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET,
+                            dst_offset + current_offset);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+        ret = vCommand->put_u32(
+                           QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH,
+                            program_length);
+        if (ret != WIFI_SUCCESS)
+            goto cleanup;
+
+        ret = vCommand->put_bytes(
+                                 QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM,
+                                 (char *)&program[current_offset],
+                                 min(info->firmware_bus_max_size,
+                                 len - current_offset));
+        if (ret!= WIFI_SUCCESS) {
+            ALOGE("%s: failed to put program", __FUNCTION__);
+            goto cleanup;
+        }
+
+        vCommand->attr_end(nlData);
+
+        ret = vCommand->requestResponse();
+       if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: requestResponse Error:%d",__func__, ret);
+            goto cleanup;
+        }
+
+        /* destroy the object after sending each fragment to driver */
+        delete vCommand;
+        vCommand = NULL;
+
+        current_offset += min(info->firmware_bus_max_size,
+                                         len - current_offset);
+    } while (current_offset < len);
+
+cleanup:
+    if (vCommand)
+        delete vCommand;
+    return ret;
+}
+
+wifi_error wifi_enable_packet_filter(wifi_interface_handle handle,
+                                        u32 enable)
+{
+    wifi_error ret;
+    struct nlattr *nlData;
+    WifiVendorCommand *vCommand = NULL;
+    u32 subcmd;
+    wifi_handle wifiHandle = getWifiHandle(handle);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    ret = initialize_vendor_cmd(handle, get_requestid(),
+                                QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER,
+                                &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)
+        goto cleanup;
+
+    subcmd = enable ? QCA_WLAN_ENABLE_PACKET_FILTER :
+                      QCA_WLAN_DISABLE_PACKET_FILTER;
+    ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
+                            subcmd);
+    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;
+    }
+
+    info->apf_enabled = !!enable;
+
+cleanup:
+    if (vCommand)
+        delete vCommand;
+    return ret;
+
+}
+
+/**
+ * Copy 'length' bytes of raw data from APF (Android Packet Filter) working
+ * memory  to host memory starting at offset src_offset into host memory
+ * pointed to by host_dst.
+ * Memory can be text, data or some combination of the two. The implementiion is
+ * allowed to translate this read into a series of smaller reads, but this
+ * function is not allowed to return untill all the reads operations
+ * into host_dst have been completed.
+ *
+ * @param src_offset offset in bytes of destination memory within APF working
+ * memory
+ *
+ * @param host_dst host memory to copy into. Must be 4B aligned.
+ *
+ * @param length the number of bytes to copy from the APF working memory to the
+ * host.
+ */
+
+static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
+                                          u32 src_offset, u8 *host_dst, u32 length)
+{
+    wifi_error ret;
+    struct nlattr *nlData;
+    WifihalGeneric *vCommand = NULL;
+    interface_info *ifaceInfo = getIfaceInfo(handle);
+    wifi_handle wifiHandle = getWifiHandle(handle);
+    hal_info *info = getHalInfo(wifiHandle);
+
+    /*Temporary varibles to support the read complete length in chunks */
+    u8 *temp_host_dst;
+    u32 remainingLengthToBeRead, currentLength;
+    u8 apf_locally_disabled = 0;
+
+    /*Initializing the temporary variables*/
+    temp_host_dst = host_dst;
+    remainingLengthToBeRead = length;
+
+    if (info->apf_enabled) {
+        /* Disable APF only when not disabled by framework before calling
+         * wifi_read_packet_filter()
+         */
+        ret = wifi_enable_packet_filter(handle, 0);
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: Failed to disable APF", __FUNCTION__);
+            return ret;
+        }
+        apf_locally_disabled = 1;
+    }
+    /**
+     * Read the complete length in chunks of size less or equal to firmware bus
+     * max size
+     */
+    while (remainingLengthToBeRead)
+    {
+        vCommand = new WifihalGeneric(wifiHandle, 0, OUI_QCA,
+                                      QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER);
+
+        if (vCommand == NULL) {
+            ALOGE("%s: Error vCommand NULL", __FUNCTION__);
+            ret = WIFI_ERROR_OUT_OF_MEMORY;
+            break;
+        }
+
+        /* Create the message */
+        ret = vCommand->create();
+        if (ret != WIFI_SUCCESS)
+            break;
+        ret = vCommand->set_iface_id(ifaceInfo->name);
+        if (ret != WIFI_SUCCESS)
+            break;
+        /* Add the vendor specific attributes for the NL command. */
+        nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!nlData)
+            break;
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD,
+                                QCA_WLAN_READ_PACKET_FILTER);
+        if (ret != WIFI_SUCCESS)
+            break;
+
+        currentLength = min(remainingLengthToBeRead, info->firmware_bus_max_size);
+
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH,
+                                currentLength);
+        if (ret != WIFI_SUCCESS)
+            break;
+        ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET,
+                                src_offset);
+        if (ret != WIFI_SUCCESS)
+            break;
+
+        vCommand->setPacketBufferParams(temp_host_dst, currentLength);
+        vCommand->attr_end(nlData);
+        ret = vCommand->requestResponse();
+
+        if (ret != WIFI_SUCCESS) {
+            ALOGE("%s: requestResponse() error: %d current_len = %u, src_offset = %u",
+                  __FUNCTION__, ret, currentLength, src_offset);
+            break;
+        }
+
+        remainingLengthToBeRead -= currentLength;
+        temp_host_dst += currentLength;
+        src_offset += currentLength;
+        delete vCommand;
+        vCommand = NULL;
+    }
+
+    /* Re enable APF only when disabled above within this API */
+    if (apf_locally_disabled) {
+        wifi_error status;
+        status = wifi_enable_packet_filter(handle, 1);
+        if (status != WIFI_SUCCESS)
+            ALOGE("%s: Failed to enable APF", __FUNCTION__);
+        /* Prefer to return read status if read fails */
+        if (ret == WIFI_SUCCESS)
+            ret = status;
+    }
+
+    delete vCommand;
+    return ret;
 }
diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/qcwcn/wifi_hal/wificonfig.cpp
index 2d26ba0..9d1fef2 100644
--- a/qcwcn/wifi_hal/wificonfig.cpp
+++ b/qcwcn/wifi_hal/wificonfig.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* 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
@@ -40,7 +40,7 @@
                                          wifi_interface_handle iface,
                                          int extended_dtim)
 {
-    int ret = 0;
+    wifi_error ret;
     WiFiConfigCommand *wifiConfigCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -61,7 +61,7 @@
 
     /* Create the NL message. */
     ret = wifiConfigCommand->create();
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_extended_dtim_config_set: failed to create NL msg. "
             "Error:%d", ret);
         goto cleanup;
@@ -69,7 +69,7 @@
 
     /* Set the interface Id of the message. */
     ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_extended_dtim_config_set: failed to set iface id. "
             "Error:%d", ret);
         goto cleanup;
@@ -83,8 +83,9 @@
         goto cleanup;
     }
 
-    if (wifiConfigCommand->put_u32(
-        QCA_WLAN_VENDOR_ATTR_WIFI_CONFIG_DYNAMIC_DTIM, extended_dtim)) {
+    ret = wifiConfigCommand->put_u32(
+                  QCA_WLAN_VENDOR_ATTR_WIFI_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;
@@ -94,21 +95,22 @@
     /* Send the NL msg. */
     wifiConfigCommand->waitForRsp(false);
     ret = wifiConfigCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_extended_dtim_config_set(): requestEvent Error:%d", ret);
         goto cleanup;
     }
 
 cleanup:
     delete wifiConfigCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 /* Set the country code to driver. */
 wifi_error wifi_set_country_code(wifi_interface_handle iface,
                                  const char* country_code)
 {
-    int requestId, ret = 0;
+    int requestId;
+    wifi_error ret;
     WiFiConfigCommand *wifiConfigCommand;
     wifi_handle wifiHandle = getWifiHandle(iface);
 
@@ -131,12 +133,13 @@
 
     /* Create the NL message with NL80211_CMD_REQ_SET_REG NL cmd. */
     ret = wifiConfigCommand->create_generic(NL80211_CMD_REQ_SET_REG);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_set_country_code: failed to create NL msg. Error:%d", ret);
         goto cleanup;
     }
 
-    if (wifiConfigCommand->put_string(NL80211_ATTR_REG_ALPHA2, country_code)) {
+    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;
     }
@@ -144,7 +147,7 @@
     /* Send the NL msg. */
     wifiConfigCommand->waitForRsp(false);
     ret = wifiConfigCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_set_country_code(): requestEvent Error:%d", ret);
         goto cleanup;
     }
@@ -152,7 +155,7 @@
 
 cleanup:
     delete wifiConfigCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor(
@@ -160,7 +163,7 @@
                                                 wifi_interface_handle iface,
                                                 u16 factor)
 {
-    int ret = 0;
+    wifi_error ret;
     WiFiConfigCommand *wifiConfigCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -179,7 +182,7 @@
 
     /* Create the NL message. */
     ret = wifiConfigCommand->create();
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
             "create NL msg. Error:%d", ret);
         goto cleanup;
@@ -187,7 +190,7 @@
 
     /* Set the interface Id of the message. */
     ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
             "set iface id. Error:%d", ret);
         goto cleanup;
@@ -212,7 +215,7 @@
     /* Send the NL msg. */
     wifiConfigCommand->waitForRsp(false);
     ret = wifiConfigCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): "
             "requestEvent Error:%d", ret);
         goto cleanup;
@@ -220,14 +223,14 @@
 
 cleanup:
     delete wifiConfigCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_set_guard_time(wifi_request_id id,
                                wifi_interface_handle iface,
                                u32 guard_time)
 {
-    int ret = 0;
+    wifi_error ret;
     WiFiConfigCommand *wifiConfigCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -247,14 +250,14 @@
 
     /* Create the NL message. */
     ret = wifiConfigCommand->create();
-    if (ret < 0) {
+    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 < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_set_guard_time: failed to set iface id. Error:%d", ret);
         goto cleanup;
     }
@@ -277,20 +280,20 @@
     /* Send the NL msg. */
     wifiConfigCommand->waitForRsp(false);
     ret = wifiConfigCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_set_guard_time(): requestEvent Error:%d", ret);
         goto cleanup;
     }
 
 cleanup:
     delete wifiConfigCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle,
                                          wifi_power_scenario scenario)
 {
-    int ret = 0;
+    wifi_error ret;
     WiFiConfigCommand *wifiConfigCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(handle);
@@ -311,14 +314,14 @@
 
     /* Create the NL message. */
     ret = wifiConfigCommand->create();
-    if (ret < 0) {
+    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 < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_select_tx_power_scenario: failed to set iface id. Error:%d", ret);
         goto cleanup;
     }
@@ -331,13 +334,30 @@
         goto cleanup;
     }
 
-    if (scenario == WIFI_POWER_SCENARIO_VOICE_CALL) {
-        bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
-    } else {
-        ALOGE("wifi_select_tx_power_scenario: invalid scenario %d", scenario);
-        ret = WIFI_ERROR_INVALID_ARGS;
-        goto cleanup;
+    switch (scenario) {
+        case WIFI_POWER_SCENARIO_VOICE_CALL:
+        case WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON:
+            bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1;
+            break;
+
+        case WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF:
+            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;
+
+        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)) {
@@ -347,19 +367,19 @@
     wifiConfigCommand->attr_end(nlData);
 
     ret = wifiConfigCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_select_tx_power_scenario(): requestEvent Error:%d", ret);
         goto cleanup;
     }
 
 cleanup:
     delete wifiConfigCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
 {
-    int ret = 0;
+    wifi_error ret;
     WiFiConfigCommand *wifiConfigCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(handle);
@@ -377,14 +397,14 @@
 
     /* Create the NL message. */
     ret = wifiConfigCommand->create();
-    if (ret < 0) {
+    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 < 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_reset_tx_power_scenario: failed to set iface id. Error:%d", ret);
         goto cleanup;
     }
@@ -405,14 +425,14 @@
     wifiConfigCommand->attr_end(nlData);
 
     ret = wifiConfigCommand->requestEvent();
-    if (ret != 0) {
+    if (ret != WIFI_SUCCESS) {
         ALOGE("wifi_reset_tx_power_scenario(): requestEvent Error:%d", ret);
         goto cleanup;
     }
 
 cleanup:
     delete wifiConfigCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle,
@@ -431,27 +451,26 @@
 }
 
 /* This function implements creation of Vendor command */
-int WiFiConfigCommand::create() {
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+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 < 0)
-        goto out;
+    if (ret != WIFI_SUCCESS)
+        return ret;
     /* Insert the subcmd in the msg */
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
-        goto out;
-out:
+
     return ret;
 }
 
 /* This function implements creation of generic NL command */
-int WiFiConfigCommand::create_generic(u8 cmdId) {
-    int ret = mMsg.create(cmdId, 0, 0);
+wifi_error WiFiConfigCommand::create_generic(u8 cmdId)
+{
+    wifi_error ret = mMsg.create(cmdId, 0, 0);
     return ret;
 }
 
@@ -501,43 +520,49 @@
  * We don't wait for any response back in case of wificonfig,
  * thus no wait for condition.
  */
-int WiFiConfigCommand::requestEvent()
+wifi_error WiFiConfigCommand::requestEvent()
 {
-    int res = -1;
+    int status;
+    wifi_error res = WIFI_SUCCESS;
     struct nl_cb *cb;
 
     cb = nl_cb_alloc(NL_CB_DEFAULT);
     if (!cb) {
         ALOGE("%s: Callback allocation failed",__FUNCTION__);
-        res = -1;
+        res = WIFI_ERROR_OUT_OF_MEMORY;
         goto out;
     }
 
-    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
-    if (res < 0)
+    status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
         goto out;
-    res = 1;
+    }
+    status = 1;
 
-    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_config, &res);
+    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,
-        &res);
-    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_config, &res);
+        &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 (res > 0){
+    while (status > 0) {
          nl_recvmsgs(mInfo->cmd_sock, cb);
     }
 
-    /* Only wait for the asynchronous event if HDD returns success, res=0 */
-    if (!res && (mWaitforRsp == true)) {
+    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 == ETIMEDOUT)
-        {
+        if (res == WIFI_ERROR_TIMED_OUT)
             ALOGE("%s: Time out happened.", __FUNCTION__);
-        }
+
         ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d",
             __FUNCTION__, res, mWaitforRsp);
     }
diff --git a/qcwcn/wifi_hal/wificonfigcommand.h b/qcwcn/wifi_hal/wificonfigcommand.h
index f2bf329..53bb288 100644
--- a/qcwcn/wifi_hal/wificonfigcommand.h
+++ b/qcwcn/wifi_hal/wificonfigcommand.h
@@ -60,14 +60,14 @@
      * This function implements creation of WiFiConfigCommand specific Request
      * based on the QCA vendor specific request type.
      */
-    virtual int create();
+    virtual wifi_error create();
     /*
      * This function implements creation of WiFiConfigCommand specific Request
      * based on the generic NL request type.
      */
-    virtual int create_generic(u8 cmdId);
+    virtual wifi_error create_generic(u8 cmdId);
     virtual void waitForRsp(bool wait);
-    virtual int requestEvent();
+    virtual wifi_error requestEvent();
 };
 
 #ifdef __cplusplus
diff --git a/qcwcn/wifi_hal/wifihal_vendor.cpp b/qcwcn/wifi_hal/wifihal_vendor.cpp
new file mode 100644
index 0000000..33842f2
--- /dev/null
+++ b/qcwcn/wifi_hal/wifihal_vendor.cpp
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#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"
+#include "vendor_definitions.h"
+
+//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));
+}
+
+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;
+}
+
+wifi_error NUDStatsCommand::requestResponse()
+{
+    return WifiCommand::requestResponse(mMsg);
+}
+
+int NUDStatsCommand::handleResponse(WifiEvent &reply)
+{
+    int 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);
+        }
+    }
+cleanup:
+    if (status == WIFI_ERROR_INVALID_ARGS)
+       memset(&mStats,0,sizeof(nud_stats));
+
+    return status;
+}
+
+void NUDStatsCommand::copyStats(nud_stats *stats)
+{
+    memcpy(stats, &mStats, sizeof(nud_stats));
+}
+
+wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr)
+{
+    wifi_error ret;
+    NUDStatsCommand *NUDCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+
+    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;
+    /**/
+    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,
+                              nud_stats *stats)
+{
+    wifi_error ret;
+    NUDStatsCommand *NUDCommand;
+    struct nlattr *nl_data;
+    interface_info *iinfo = getIfaceInfo(iface);
+    wifi_handle handle = getWifiHandle(iface);
+
+    if (stats == NULL) {
+        ALOGE("%s: Error stats is NULL", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    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);
+
+    /* 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;
+    /**/
+    NUDCommand->attr_end(nl_data);
+
+    ret = NUDCommand->requestResponse();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    NUDCommand->copyStats(stats);
+
+cleanup:
+    return ret;
+}
+
+
+wifi_error wifi_clear_nud_stats(wifi_interface_handle iface)
+{
+    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_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;
+
+    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/qcwcn/wifi_hal/wifihal_vendorcommand.h b/qcwcn/wifi_hal/wifihal_vendorcommand.h
new file mode 100644
index 0000000..2a73902
--- /dev/null
+++ b/qcwcn/wifi_hal/wifihal_vendorcommand.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 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 __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;
+
+    nud_stats mStats;
+
+    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 int handleResponse(WifiEvent &reply);
+
+    void copyStats(nud_stats *stats);
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/qcwcn/wifi_hal/wifilogger.cpp
index a8423cf..11a6b6e 100644
--- a/qcwcn/wifi_hal/wifilogger.cpp
+++ b/qcwcn/wifi_hal/wifilogger.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* 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
@@ -68,7 +68,8 @@
                               u32 max_interval_sec, u32 min_data_size,
                               char *buffer_name)
 {
-    int requestId, ret = 0;
+    int requestId;
+    wifi_error ret;
     WifiLoggerCommand *wifiLoggerCommand = NULL;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -76,6 +77,11 @@
     hal_info *info = getHalInfo(wifiHandle);
     int ring_id = 0;
 
+    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.
@@ -105,56 +111,48 @@
     }
     /* Create the NL message. */
     ret = wifiLoggerCommand->create();
-
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
-
-    if (ret < 0)
+    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;
 
-    if (wifiLoggerCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID, ring_id))
-    {
+    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID,
+                                     ring_id);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
-    if (wifiLoggerCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL,
-                verbose_level))
-    {
+
+    ret = wifiLoggerCommand->put_u32(
+                             QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL,
+                             verbose_level);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
-    if (wifiLoggerCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS,
-                flags))
-    {
+
+    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) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
 
     ALOGV("%s: Logging Started for %s.", __FUNCTION__, buffer_name);
     rb_start_logging(&info->rb_infos[ring_id], verbose_level,
                     flags, max_interval_sec, min_data_size);
 cleanup:
-    if (wifiLoggerCommand)
-        delete wifiLoggerCommand;
-    return mapErrorKernelToWifiHAL(ret);
-
+    delete wifiLoggerCommand;
+    return ret;
 }
 
 /*  Function to get each ring related info */
@@ -162,13 +160,19 @@
                                         u32 *num_buffers,
                                         wifi_ring_buffer_status *status)
 {
-    int ret = 0;
     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,
@@ -183,7 +187,7 @@
         get_rb_status(rb_info, rbs);
     }
     *num_buffers = NUM_RING_BUFS;
-    return mapErrorKernelToWifiHAL(ret);
+    return WIFI_SUCCESS;
 }
 
 void push_out_all_ring_buffers(hal_info *info)
@@ -198,13 +202,13 @@
 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, NULL, 0, reason_code);
+        handler.on_alert(0, alert_msg, strlen(alert_msg), reason_code);
     }
 }
 
@@ -216,8 +220,8 @@
 wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
                                                  u32 *support)
 {
-
-    int requestId, ret = 0;
+    int requestId;
+    wifi_error ret;
     WifiLoggerCommand *wifiLoggerCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -240,48 +244,44 @@
     }
     /* Create the NL message. */
     ret = wifiLoggerCommand->create();
-
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
-
-    if (ret < 0)
+    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;
 
-    if (wifiLoggerCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_FEATURE_SET, requestId))
-    {
+    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_FEATURE_SET,
+                                     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) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
 
 cleanup:
     delete wifiLoggerCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    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, ret = 0;
+    int requestId;
+    wifi_error ret;
     WifiLoggerCommand *wifiLoggerCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -289,6 +289,13 @@
     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__);
@@ -308,19 +315,16 @@
     }
     /* Create the NL message. */
     ret = wifiLoggerCommand->create();
-
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
-
-    if (ret < 0)
+    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;
 
@@ -333,13 +337,12 @@
 
     /* Send the msg and wait for a response. */
     ret = wifiLoggerCommand->requestResponse();
-    if (ret) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
 
 cleanup:
     delete wifiLoggerCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 void WifiLoggerCommand::setVersionInfo(char *buffer, int buffer_size) {
@@ -351,7 +354,8 @@
 wifi_error wifi_get_firmware_version(wifi_interface_handle iface,
                                      char *buffer, int buffer_size)
 {
-    int requestId, ret = 0;
+    int requestId;
+    wifi_error ret;
     WifiLoggerCommand *wifiLoggerCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -373,39 +377,36 @@
     }
     /* Create the NL message. */
     ret = wifiLoggerCommand->create();
-
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
-
-    if (ret < 0)
+    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;
 
-    if (wifiLoggerCommand->put_u32(
-                QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION, requestId))
-    {
+    ret = wifiLoggerCommand->put_u32(
+                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) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete wifiLoggerCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 
 }
 
@@ -414,7 +415,8 @@
                                    char *buffer, int buffer_size)
 {
 
-    int requestId, ret = 0;
+    int requestId;
+    wifi_error ret;
     WifiLoggerCommand *wifiLoggerCommand;
     struct nlattr *nlData;
     interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -436,39 +438,36 @@
     }
     /* Create the NL message. */
     ret = wifiLoggerCommand->create();
-
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
-
-    if (ret < 0)
+    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;
 
-    if (wifiLoggerCommand->put_u32(
-            QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION, requestId))
-    {
+    ret = wifiLoggerCommand->put_u32(
+                      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) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
+
 cleanup:
     delete wifiLoggerCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 
@@ -476,11 +475,21 @@
 wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface,
                                 wifi_firmware_memory_dump_handler handler)
 {
-    int requestId, ret = 0;
+    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.
@@ -499,18 +508,17 @@
     /* Create the NL message. */
     ret = wifiLoggerCommand->create();
 
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
 
-    if (ret < 0)
+    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;
 
@@ -523,18 +531,17 @@
         handler.on_firmware_memory_dump;
 
     ret = wifiLoggerCommand->setCallbackHandler(callbackHandler);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Send the msg and wait for the memory dump response */
     ret = wifiLoggerCommand->requestResponse();
-    if (ret) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
 
 cleanup:
     delete wifiLoggerCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 wifi_error wifi_set_log_handler(wifi_request_id id,
@@ -606,6 +613,13 @@
     wifi_handle wifiHandle = getWifiHandle(iface);
     hal_info *info = getHalInfo(wifiHandle);
 
+    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;
@@ -786,19 +800,18 @@
 }
 
 /* This function implements creation of Vendor command */
-int WifiLoggerCommand::create() {
-    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
-    if (ret < 0) {
+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 < 0)
+    if (ret != WIFI_SUCCESS)
         goto out;
     /* Insert the subcmd in the msg */
     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto out;
 
      ALOGV("%s: mVendor_id = %d, Subcmd = %d.",
@@ -823,6 +836,12 @@
 {
     wifi_error ret;
 
+    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,
@@ -887,6 +906,9 @@
 {
     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]);
     }
@@ -930,44 +952,47 @@
   return NL_SKIP;
 }
 
-int WifiLoggerCommand::requestEvent()
+wifi_error WifiLoggerCommand::requestEvent()
 {
-    int res = -1;
+    int status;
+    wifi_error res = WIFI_SUCCESS;
     struct nl_cb *cb;
 
     cb = nl_cb_alloc(NL_CB_DEFAULT);
     if (!cb) {
         ALOGE("%s: Callback allocation failed",__FUNCTION__);
-        res = -1;
+        res = WIFI_ERROR_OUT_OF_MEMORY;
         goto out;
     }
 
     /* Send message */
-    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
-    if (res < 0)
+    status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
+    if (status < 0) {
+        res = mapKernelErrortoWifiHalError(status);
         goto out;
-    res = 1;
+    }
 
-    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_logger, &res);
-    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_logger, &res);
-    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_logger, &res);
+    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 (res > 0){
+    while (status > 0){
          nl_recvmsgs(mInfo->cmd_sock, cb);
     }
 
-    ALOGV("%s: Msg sent, res=%d, mWaitForRsp=%d", __FUNCTION__, res, mWaitforRsp);
+    ALOGV("%s: Msg sent, status=%d, mWaitForRsp=%d", __FUNCTION__, status, mWaitforRsp);
     /* Only wait for the asynchronous event if HDD returns success, res=0 */
-    if (!res && (mWaitforRsp == true)) {
+    if (!status && (mWaitforRsp == true)) {
         struct timespec abstime;
         abstime.tv_sec = 4;
         abstime.tv_nsec = 0;
         res = mCondition.wait(abstime);
-        if (res == ETIMEDOUT)
-        {
+        if (res == WIFI_ERROR_TIMED_OUT)
             ALOGE("%s: Time out happened.", __FUNCTION__);
-        }
+
         ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d",
             __FUNCTION__, res, mWaitforRsp);
     }
@@ -977,7 +1002,7 @@
     return res;
 }
 
-int WifiLoggerCommand::requestResponse()
+wifi_error WifiLoggerCommand::requestResponse()
 {
     return WifiCommand::requestResponse(mMsg);
 }
@@ -1323,12 +1348,12 @@
     return NL_SKIP;
 }
 
-int WifiLoggerCommand::setCallbackHandler(WifiLoggerCallbackHandler nHandler)
+wifi_error WifiLoggerCommand::setCallbackHandler(WifiLoggerCallbackHandler nHandler)
 {
-    int res = 0;
+    wifi_error res;
     mHandler = nHandler;
     res = registerVendorHandler(mVendor_id, mSubcmd);
-    if (res != 0) {
+    if (res != WIFI_SUCCESS) {
         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
               __FUNCTION__, mVendor_id, mSubcmd);
     }
@@ -1340,7 +1365,7 @@
     unregisterVendorHandler(mVendor_id, subCmd);
 }
 
-int WifiLoggerCommand::timed_wait(u16 wait_time)
+wifi_error WifiLoggerCommand::timed_wait(u16 wait_time)
 {
     struct timespec absTime;
     absTime.tv_sec = wait_time;
@@ -1361,7 +1386,16 @@
     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) {
@@ -1434,11 +1468,21 @@
 wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
                              WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
 {
-    int requestId, ret = WIFI_SUCCESS;
+    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);
+
+    /* 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.
@@ -1463,12 +1507,12 @@
 
     /* Create the NL message. */
     ret = wifiLoggerCommand->create();
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     /* Set the interface Id of the message. */
     ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);
-    if (ret < 0)
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
 
     wifiLoggerCommand->getWakeStatsRspParams(wifi_wake_reason_cnt);
@@ -1478,30 +1522,28 @@
     if (!nlData)
         goto cleanup;
 
-    if (wifiLoggerCommand->put_u32(
+    ret = wifiLoggerCommand->put_u32(
                 QCA_WLAN_VENDOR_ATTR_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ,
-                wifi_wake_reason_cnt->cmd_event_wake_cnt_sz))
-    {
+                wifi_wake_reason_cnt->cmd_event_wake_cnt_sz);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
 
-    if (wifiLoggerCommand->put_u32(
+    ret = wifiLoggerCommand->put_u32(
                 QCA_WLAN_VENDOR_ATTR_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ,
-                wifi_wake_reason_cnt->driver_fw_local_wake_cnt_sz))
-    {
+                wifi_wake_reason_cnt->driver_fw_local_wake_cnt_sz);
+    if (ret != WIFI_SUCCESS)
         goto cleanup;
-    }
+
     wifiLoggerCommand->attr_end(nlData);
 
     /* Send the msg and wait for a response. */
     ret = wifiLoggerCommand->requestResponse();
-    if (ret) {
+    if (ret != WIFI_SUCCESS)
         ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
-    }
 
 cleanup:
     delete wifiLoggerCommand;
-    return mapErrorKernelToWifiHAL(ret);
+    return ret;
 }
 
 void WifiLoggerCommand::getWakeStatsRspParams(
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index d131102..bbdeb7c 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* 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
@@ -136,6 +136,7 @@
 
     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);
 
@@ -701,6 +702,8 @@
             roam_candidate_found_vendor_data_t 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),
diff --git a/qcwcn/wifi_hal/wifiloggercmd.h b/qcwcn/wifi_hal/wifiloggercmd.h
index ba0d284..a5d3bbf 100644
--- a/qcwcn/wifi_hal/wifiloggercmd.h
+++ b/qcwcn/wifi_hal/wifiloggercmd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* 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
@@ -55,6 +55,10 @@
 #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,
@@ -90,16 +94,16 @@
 
     // This function implements creation of WifiLogger specific Request
     // based on  the request type
-    virtual int create();
-    virtual int requestEvent();
-    virtual int requestResponse();
+    virtual wifi_error create();
+    virtual wifi_error requestEvent();
+    virtual wifi_error requestResponse();
     virtual int handleResponse(WifiEvent &reply);
     virtual int handleEvent(WifiEvent &event);
-    int setCallbackHandler(WifiLoggerCallbackHandler nHandler);
+    wifi_error setCallbackHandler(WifiLoggerCallbackHandler nHandler);
     virtual void unregisterHandler(u32 subCmd);
 
     /* Takes wait time in seconds. */
-    virtual int timed_wait(u16 wait_time);
+    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);