Merge 2c9ea9435a0db28c4d107f8f8b5a8f7ebddfd980 on remote branch

Change-Id: I04697954666d16875b54b6f4f4961cc38372543e
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 75263f1..0b5b8fe 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -3317,6 +3317,11 @@
 #define CFG_ENABLE_SAE_FOR_SAP_MIN     (0)
 #define CFG_ENABLE_SAE_FOR_SAP_MAX     (1)
 
+#define CFG_SW_PTA_ENABLE_NAME         "sw_pta_enable"
+#define CFG_SW_PTA_ENABLE_DEFAULT      (0)
+#define CFG_SW_PTA_ENABLE_MIN          (0)
+#define CFG_SW_PTA_ENABLE_MAX          (1)
+
 /*--------------------------------------------------------------------------- 
   Type declarations
   -------------------------------------------------------------------------*/ 
@@ -3940,6 +3945,9 @@
 #ifdef FEATURE_WLAN_LFR
    uint8_t                     bssid_blacklist_timeout;
 #endif
+#ifdef FEATURE_WLAN_SW_PTA
+   bool                        is_sw_pta_enabled;
+#endif
 } hdd_config_t;
 
 /*--------------------------------------------------------------------------- 
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 2135cdd..ad479c9 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -2314,6 +2314,24 @@
  */
 void hdd_restore_roaming(hdd_context_t *hdd_ctx);
 
+/**
+ * hdd_chan_change_notify() - Function to notify about channel change
+ * @adapter: pointer to adapter
+ * @dev: Net device structure
+ * @oper_chan: New operating channel
+ * @phy_mode: phy mode
+ *
+ * This function is used to notify hostapd/supplicant about the channel change
+ *
+ * Return: Success on intimating userspace
+ *
+ */
+VOS_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter,
+        struct net_device *dev,
+        uint8_t oper_chan,
+        eCsrPhyMode phy_mode);
+
+
 int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait);
 
 /**
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index b8b2d9a..07c7b38 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -4414,6 +4414,7 @@
        case eCSR_ROAM_STA_CHANNEL_SWITCH:
          {
              hdd_adapter_t *pHostapdAdapter = NULL;
+             eCsrPhyMode phy_mode = 0;
              pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
              pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
@@ -4428,6 +4429,24 @@
              pHddStaCtx->conn_info.operationChannel =
                  pRoamInfo->chan_info.chan_id;
 
+             if(pRoamInfo->pProfile) {
+                 phy_mode = pRoamInfo->pProfile->phyMode;
+             }
+
+             status = hdd_chan_change_notify(pAdapter,
+                                             pAdapter->dev,
+                                             pRoamInfo->chan_info.chan_id,
+                                             phy_mode);
+
+             if(status != VOS_STATUS_SUCCESS) {
+                 hddLog(VOS_TRACE_LEVEL_ERROR,
+                        "%s: hdd_chan_change_notify failed", __func__);
+             }
+
+             hddLog(VOS_TRACE_LEVEL_ERROR,
+                    "%s: Channel switch event updated to upper layer to %d",
+                    __func__, pRoamInfo->chan_info.chan_id);
+
              pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
              if (pHostapdAdapter &&
                     (test_bit(SOFTAP_BSS_STARTED,
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index e3c7d18..02586ab 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -4056,6 +4056,15 @@
                CFG_ENABLE_SAE_FOR_SAP_MIN,
                CFG_ENABLE_SAE_FOR_SAP_MAX),
 #endif
+
+#ifdef FEATURE_WLAN_SW_PTA
+  REG_VARIABLE(CFG_SW_PTA_ENABLE_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, is_sw_pta_enabled,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_SW_PTA_ENABLE_DEFAULT,
+               CFG_SW_PTA_ENABLE_MIN,
+               CFG_SW_PTA_ENABLE_MAX)
+#endif
 };
 
 /*
@@ -4295,6 +4304,19 @@
 }
 #endif
 
+#ifdef FEATURE_WLAN_SW_PTA
+static void hdd_cfg_print_sw_pta(hdd_context_t* hdd_ctx)
+{
+   hddLog(LOG2, "Name = [%s] value = [%u]",
+          CFG_SW_PTA_ENABLE_NAME,
+          hdd_ctx->cfg_ini->is_sw_pta_enabled);
+}
+#else
+static void hdd_cfg_print_sw_pta(hdd_context_t* hdd_ctx)
+{
+}
+#endif
+
 static void print_hdd_cfg(hdd_context_t *pHddCtx)
 {
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "*********Config values in HDD Adapter*******");
@@ -4757,6 +4779,7 @@
             pHddCtx->cfg_ini->enabledefaultSAP);
     hdd_cfg_print_sae(pHddCtx);
     hdd_cfg_print_sae_sap(pHddCtx);
+    hdd_cfg_print_sw_pta(pHddCtx);
 }
 
 
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 07ce96c..dc3c428 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -12314,6 +12314,7 @@
                                              params->auth_type);
     }
 
+    wlan_hdd_cfg80211_register_frames(pAdapter);
     EXIT();
     return status;
 }
@@ -12491,6 +12492,7 @@
     eMib_dot11DesiredBssType connectedBssType;
     VOS_STATUS status;
     long ret;
+    bool iff_up = ndev->flags & IFF_UP;
 
     ENTER();
 
@@ -12763,13 +12765,21 @@
                          return -EINVAL;
                     }
                 }
-                status = hdd_init_ap_mode(pAdapter, false);
-                if(status != VOS_STATUS_SUCCESS)
-                {
-                    hddLog(VOS_TRACE_LEVEL_FATAL,
-                           "%s: Error initializing the ap mode", __func__);
-                    return -EINVAL;
-                }
+		if (iff_up) {
+			hddLog(VOS_TRACE_LEVEL_DEBUG,
+			       "%s: SAP interface is already up", __func__);
+			status = hdd_init_ap_mode(pAdapter, false);
+			if(status != VOS_STATUS_SUCCESS)
+			{
+				hddLog(VOS_TRACE_LEVEL_FATAL,
+				       "%s: Error initializing the ap mode",
+				       __func__);
+				return -EINVAL;
+			}
+		} else {
+			hddLog(VOS_TRACE_LEVEL_DEBUG,
+			       "%s: SAP interface is down", __func__);
+		}
                 hdd_set_conparam(1);
 
                 status = hdd_sta_id_hash_attach(pAdapter);
@@ -12855,9 +12865,16 @@
 #ifdef FEATURE_WLAN_TDLS
                 mutex_unlock(&pHddCtx->tdls_lock);
 #endif
-                status = hdd_init_station_mode( pAdapter );
-                if( VOS_STATUS_SUCCESS != status )
-                    return -EOPNOTSUPP;
+		if (iff_up) {
+			hddLog(VOS_TRACE_LEVEL_DEBUG,
+			       "%s: STA interface is already up", __func__);
+			status = hdd_init_station_mode( pAdapter );
+			if( VOS_STATUS_SUCCESS != status )
+				return -EOPNOTSUPP;
+		} else {
+			hddLog(VOS_TRACE_LEVEL_DEBUG,
+			       "%s: STA interface is down", __func__);
+		}
                 /* In case of JB, for P2P-GO, only change interface will be called,
                  * This is the right place to enable back bmps_imps()
                  */
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 80adfde..0cce477 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -223,21 +223,26 @@
        }
    }
 
-   status = hdd_init_ap_mode( pAdapter, false);
-   if( VOS_STATUS_SUCCESS != status ) {
-          hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to create session for station mode",
-                 __func__);
-          return -EINVAL;
+   if (!test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) {
+	   status = hdd_init_ap_mode( pAdapter, false);
+	   if( VOS_STATUS_SUCCESS != status ) {
+		   hddLog(VOS_TRACE_LEVEL_ERROR,
+			  "%s: Failed to create session for station mode",
+			  __func__);
+		   return -EINVAL;
+	   }
+	   set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
+
+	   //Turn ON carrier state
+	   netif_carrier_on(dev);
+	   //Enable all Tx queues
+	   hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
+	   netif_tx_start_all_queues(dev);
+   } else {
+	   hddLog(VOS_TRACE_LEVEL_DEBUG,
+		  "%s: session already exist for AP mode", __func__);
    }
 
-   set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
-
-   //Turn ON carrier state
-   netif_carrier_on(dev);
-   //Enable all Tx queues
-   hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
-   netif_tx_start_all_queues(dev);
-
    EXIT();
    return 0;
 }
@@ -1024,149 +1029,6 @@
 }
 
 /**
- * hdd_update_chandef() - Function to update channel width and center freq
- * @chandef: cfg80211 chan def
- * @cb_mode: chan offset
- *
- * This function will be called to update channel width and center freq
- *
- * Return: None
- */
-static void
-hdd_update_chandef(struct cfg80211_chan_def *chandef,
-                   ePhyChanBondState cb_mode)
-{
-   uint8_t  center_chan, chan;
-
-   if (cb_mode <= PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
-       return;
-
-   chan = vos_freq_to_chan(chandef->chan->center_freq);
-   chandef->width = NL80211_CHAN_WIDTH_80;
-   switch (cb_mode) {
-   case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
-   case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
-        center_chan = chan + 2;
-        break;
-   case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
-        center_chan = chan + 6;
-        break;
-   case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
-   case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
-        center_chan = chan - 2;
-        break;
-   case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
-        center_chan = chan - 6;
-        break;
-   default:
-        center_chan = chan;
-        break;
-   }
-
-   chandef->center_freq1 = vos_chan_to_freq(center_chan);
-}
-
-/**
- * hdd_chan_change_notify() - Function to notify hostapd about channel change
- * @hostapd_adapter: hostapd adapter
- * @dev: Net device structure
- * @oper_chan: New operating channel
- *
- * This function is used to notify hostapd about the channel change
- *
- * Return: Success on intimating userspace
- *
- */
-static VOS_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
-   struct net_device *dev, uint8_t oper_chan)
-{
-   struct ieee80211_channel *chan;
-   struct cfg80211_chan_def chandef;
-   enum nl80211_channel_type channel_type;
-   eCsrPhyMode phy_mode;
-   ePhyChanBondState cb_mode;
-   uint32_t freq;
-   tHalHandle  hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter);
-   tSmeConfigParams sme_config;
-
-   if (!hal) {
-       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                 "%s: hal is NULL", __func__);
-       return VOS_STATUS_E_FAILURE;
-   }
-
-   freq = vos_chan_to_freq(oper_chan);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0))
-   chan = ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq);
-#else
-   chan = __ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq);
-#endif
-
-   if (!chan) {
-       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                "%s: Invalid input frequency for channel conversion", __func__);
-       return VOS_STATUS_E_FAILURE;
-   }
-
-   phy_mode = wlansap_get_phymode(
-                          (WLAN_HDD_GET_CTX(hostapd_adapter))->pvosContext);
-   sme_GetConfigParam(hal, &sme_config);
-   if (oper_chan <= 14)
-       cb_mode = sme_get_cb_phy_mode_from_cb_ini_mode(
-                    sme_config.csrConfig.channelBondingMode24GHz);
-   else
-       cb_mode = sme_get_cb_phy_mode_from_cb_ini_mode(
-                    sme_config.csrConfig.channelBondingMode5GHz);
-
-   switch (phy_mode) {
-   case eCSR_DOT11_MODE_11n:
-   case eCSR_DOT11_MODE_11n_ONLY:
-   case eCSR_DOT11_MODE_11ac:
-   case eCSR_DOT11_MODE_11ac_ONLY:
-        switch (cb_mode) {
-        case PHY_SINGLE_CHANNEL_CENTERED:
-             channel_type = NL80211_CHAN_HT20;
-             break;
-        case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
-        case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
-        case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
-        case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
-             channel_type = NL80211_CHAN_HT40MINUS;
-             break;
-        case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
-        case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
-        case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
-        case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
-             channel_type = NL80211_CHAN_HT40PLUS;
-             break;
-        default:
-             channel_type = NL80211_CHAN_HT20;
-             break;
-        }
-        break;
-   default:
-        channel_type = NL80211_CHAN_NO_HT;
-        break;
-   }
-
-   cfg80211_chandef_create(&chandef, chan, channel_type);
-   if ((phy_mode == eCSR_DOT11_MODE_11ac) ||
-       (phy_mode == eCSR_DOT11_MODE_11ac_ONLY))
-        hdd_update_chandef(&chandef, cb_mode);
-
-   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-             "%s: phy_mode %d cb_mode %d chann_type %d oper_chan %d width %d freq_1 %d",
-             __func__, phy_mode, cb_mode, channel_type, oper_chan,
-             chandef.width, chandef.center_freq1);
-
-
-   cfg80211_ch_switch_notify(dev, &chandef);
-
-   return VOS_STATUS_SUCCESS;
-}
-
-/**
  * hdd_convert_dot11mode_from_phymode() - get dot11mode to phymode
  * @phymode: phy mode
  *
@@ -1734,12 +1596,17 @@
                 hddLog(LOGW, FL("hdd_stop_bss_link failed %d"), vos_status);
             }
             return VOS_STATUS_SUCCESS;
-       case eSAP_CHANNEL_CHANGED_EVENT:
+        case eSAP_CHANNEL_CHANGED_EVENT:
+        {
+            eCsrPhyMode phy_mode = wlansap_get_phymode(
+                          (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext);
+
             hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGED_EVENT event"));
 
             return hdd_chan_change_notify(pHostapdAdapter, dev,
-                           pSapEvent->sapevt.sap_chan_selected.new_chan);
-    case eSAP_STA_LOSTLINK_DETECTED:
+                           pSapEvent->sapevt.sap_chan_selected.new_chan, phy_mode);
+        }
+        case eSAP_STA_LOSTLINK_DETECTED:
         {
             tSap_StationDisassocCompleteEvent *disassoc_comp =
                     &pSapEvent->sapevt.sapStationDisassocCompleteEvent;
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 6a92340..d39b65d 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -214,6 +214,9 @@
 //wait time for beacon miss rate.
 #define BCN_MISS_RATE_TIME 500
 
+//max size for BT profile indication cmd
+#define MAX_USER_COMMAND_SIZE_BT_PROFILE_IND_CMD 24
+
 /*
  * Android DRIVER command structures
  */
@@ -247,6 +250,19 @@
 static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
 
 #endif /* WLAN_FEATURE_RMC */
+
+#ifdef FEATURE_WLAN_SW_PTA
+/* BT profile sysfile entry obj */
+static struct kobject *driver_kobject;
+static ssize_t hdd_sysfs_bt_profile_ind_cmd_store(struct kobject *kobj,
+                                                  struct kobj_attribute *attr,
+                                                  const char *buf,
+                                                  size_t count);
+static struct kobj_attribute bt_profile_attribute =
+    __ATTR(bt_profile, 0220, NULL,
+           hdd_sysfs_bt_profile_ind_cmd_store);
+#endif
+
 void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
 void hdd_set_wlan_suspend_mode(bool suspend);
 void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
@@ -3892,6 +3908,135 @@
 	return len;
 }
 
+#ifdef FEATURE_WLAN_SW_PTA
+static void hdd_sysfs_bt_profile_create(hdd_context_t* hdd_ctx)
+{
+	if(!hdd_ctx->cfg_ini->is_sw_pta_enabled)
+		return;
+
+	driver_kobject = kobject_create_and_add(WLAN_MODULE_NAME, kernel_kobj);
+	if (!driver_kobject) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s:could not allocate driver kobject",
+		       __func__);
+		return;
+	}
+
+	if(sysfs_create_file(driver_kobject, &bt_profile_attribute.attr))
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s:Failed to create BT profile sysfs entry", __func__);
+}
+
+static void hdd_sysfs_bt_profile_destroy(hdd_context_t* hdd_ctx)
+{
+	if(!hdd_ctx->cfg_ini->is_sw_pta_enabled)
+		return;
+
+	sysfs_remove_file(driver_kobject, &bt_profile_attribute.attr);
+	if (driver_kobject) {
+		kobject_put(driver_kobject);
+		driver_kobject = NULL;
+	}
+}
+
+static int hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size,
+					   char const *source_buf,
+					   size_t source_buf_size)
+{
+	if (source_buf_size > (dest_buf_size - 1)) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s:Command length is larger than %zu bytes",
+			   __func__, dest_buf_size);
+		return -EINVAL;
+	}
+
+	/* sysfs already provides kernel space buffer so copy from user
+	 * is not needed. Doing this extra copy operation just to ensure
+	 * the local buf is properly null-terminated.
+	 */
+	strlcpy(dest_buf, source_buf, dest_buf_size);
+
+	/* default 'echo' cmd takes new line character to here */
+	if (dest_buf[source_buf_size - 1] == '\n')
+		dest_buf[source_buf_size - 1] = '\0';
+
+	return 0;
+}
+
+static ssize_t __hdd_sysfs_bt_profile_ind_cmd_store(hdd_context_t *hdd_ctx,
+						    const char *buf,
+						    size_t count)
+{
+	char buf_local[MAX_USER_COMMAND_SIZE_BT_PROFILE_IND_CMD + 1];
+	char *sptr, *token, *profile, *profile_mode;
+	int ret;
+
+	ENTER();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
+					      buf, count);
+	if (ret)
+		return -EINVAL;
+
+	sptr = buf_local;
+	/* Get BT profile */
+	token = strsep(&sptr, " ");
+
+	if (!token)
+		return -EINVAL;
+	profile = token;
+
+	token = NULL;
+	/* Get BT profile mode */
+	token = strsep(&sptr, " ");
+
+	if (!token)
+		return -EINVAL;
+
+	profile_mode = token;
+
+	hddLog(VOS_TRACE_LEVEL_INFO, "%s:profile = %s, profile_mode = %s",
+	       __func__, profile, profile_mode);
+
+	EXIT();
+	return count;
+}
+
+static ssize_t hdd_sysfs_bt_profile_ind_cmd_store(struct kobject *kobj,
+						  struct kobj_attribute *attr,
+						  const char *buf,
+						  size_t count)
+{
+	hdd_context_t *pHddCtx = NULL;
+	ssize_t err_size = 0;
+
+	pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD,
+			vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
+
+	if (!pHddCtx) {
+		hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
+		return -EINVAL;
+	}
+
+	err_size = __hdd_sysfs_bt_profile_ind_cmd_store(pHddCtx, buf, count);
+
+	return err_size;
+}
+#else
+static inline
+void hdd_sysfs_bt_profile_create(hdd_context_t* pHddCtx)
+{
+}
+
+static inline
+void hdd_sysfs_bt_profile_destroy(hdd_context_t* pHddCtx)
+{
+}
+#endif
+
 static int hdd_driver_command(hdd_adapter_t *pAdapter,
                               hdd_priv_data_t *ppriv_data)
 {
@@ -8119,13 +8264,21 @@
        }
    }
 
-   status = hdd_init_station_mode( pAdapter );
-   if( VOS_STATUS_SUCCESS != status ) {
-          hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to create session for station mode",
-                 __func__);
-          return -EINVAL;
+   if (!test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) {
+	   status = hdd_init_station_mode( pAdapter );
+	   if( VOS_STATUS_SUCCESS != status ) {
+		   hddLog(VOS_TRACE_LEVEL_ERROR,
+			  "%s: Failed to create session for station mode",
+			  __func__);
+		   return -EINVAL;
+	   }
+   } else {
+	   hddLog(VOS_TRACE_LEVEL_DEBUG,
+		  "%s: session already exist for station mode", __func__);
    }
 
+   hdd_sysfs_bt_profile_create(pHddCtx);
+
    set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
    if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) 
    {
@@ -8303,6 +8456,8 @@
        wlan_hdd_stop_mon(pHddCtx, true);
    }
 
+   hdd_sysfs_bt_profile_destroy(pHddCtx);
+
    hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
 
    /* Disable TX on the interface, after this hard_start_xmit() will not
@@ -10387,6 +10542,136 @@
 					CFG_LFR_FEATURE_ENABLED_MAX);
 }
 
+/**
+ * hdd_update_chandef() - Function to update channel width and center freq
+ * @chandef: cfg80211 chan def
+ * @cb_mode: chan offset
+ *
+ * This function will be called to update channel width and center freq
+ *
+ * Return: None
+ */
+static void
+hdd_update_chandef(struct cfg80211_chan_def *chandef,
+                   ePhyChanBondState cb_mode)
+{
+   uint8_t  center_chan, chan;
+
+   if (cb_mode <= PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+       return;
+
+   chan = vos_freq_to_chan(chandef->chan->center_freq);
+   chandef->width = NL80211_CHAN_WIDTH_80;
+   switch (cb_mode) {
+   case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+   case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+        center_chan = chan + 2;
+        break;
+   case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+        center_chan = chan + 6;
+        break;
+   case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+   case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+        center_chan = chan - 2;
+        break;
+   case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+        center_chan = chan - 6;
+        break;
+   default:
+        center_chan = chan;
+        break;
+   }
+
+   chandef->center_freq1 = vos_chan_to_freq(center_chan);
+}
+
+VOS_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter,
+   struct net_device *dev, uint8_t oper_chan, eCsrPhyMode phy_mode)
+{
+   struct ieee80211_channel *chan;
+   struct cfg80211_chan_def chandef;
+   enum nl80211_channel_type channel_type;
+   ePhyChanBondState cb_mode;
+   uint32_t freq;
+   tHalHandle  hal = WLAN_HDD_GET_HAL_CTX(adapter);
+   tSmeConfigParams sme_config;
+
+   if (!hal) {
+       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                 "%s: hal is NULL", __func__);
+       return VOS_STATUS_E_FAILURE;
+   }
+
+   freq = vos_chan_to_freq(oper_chan);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0))
+   chan = ieee80211_get_channel(adapter->wdev.wiphy, freq);
+#else
+   chan = __ieee80211_get_channel(adapter->wdev.wiphy, freq);
+#endif
+
+   if (!chan) {
+       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "%s: Invalid input frequency for channel conversion", __func__);
+       return VOS_STATUS_E_FAILURE;
+   }
+
+   sme_GetConfigParam(hal, &sme_config);
+   if (oper_chan <= 14)
+       cb_mode = sme_get_cb_phy_mode_from_cb_ini_mode(
+                    sme_config.csrConfig.channelBondingMode24GHz);
+   else
+       cb_mode = sme_get_cb_phy_mode_from_cb_ini_mode(
+                    sme_config.csrConfig.channelBondingMode5GHz);
+
+   switch (phy_mode) {
+   case eCSR_DOT11_MODE_11n:
+   case eCSR_DOT11_MODE_11n_ONLY:
+   case eCSR_DOT11_MODE_11ac:
+   case eCSR_DOT11_MODE_11ac_ONLY:
+        switch (cb_mode) {
+        case PHY_SINGLE_CHANNEL_CENTERED:
+             channel_type = NL80211_CHAN_HT20;
+             break;
+        case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+        case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+        case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+        case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+             channel_type = NL80211_CHAN_HT40MINUS;
+             break;
+        case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+        case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+        case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+        case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+             channel_type = NL80211_CHAN_HT40PLUS;
+             break;
+        default:
+             channel_type = NL80211_CHAN_HT20;
+             break;
+        }
+        break;
+   default:
+        channel_type = NL80211_CHAN_NO_HT;
+        break;
+   }
+
+   cfg80211_chandef_create(&chandef, chan, channel_type);
+   if ((phy_mode == eCSR_DOT11_MODE_11ac) ||
+       (phy_mode == eCSR_DOT11_MODE_11ac_ONLY))
+        hdd_update_chandef(&chandef, cb_mode);
+
+   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+             "%s: phy_mode %d cb_mode %d chann_type %d oper_chan %d width %d freq_1 %d",
+             __func__, phy_mode, cb_mode, channel_type, oper_chan,
+             chandef.width, chandef.center_freq1);
+
+
+   cfg80211_ch_switch_notify(dev, &chandef);
+
+   return VOS_STATUS_SUCCESS;
+}
+
+
 VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
                              const v_BOOL_t bCloseSession )
 {
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 601c91a..5eb95fe 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -6501,4 +6501,31 @@
     uint8_t sae_status;
     tSirMacAddr peer_mac_addr;
 };
+
+#ifdef FEATURE_WLAN_SW_PTA
+/**
+ * enum sir_sw_pta_param_type - Type of sw pta coex param
+ * @SCO_STATUS: Enable/Disable SCO
+ * @NUD_STATUS: Enable/Disable NUD
+ * @BT_STATUS: Enable/Disable BT
+ */
+enum sir_sw_pta_param_type {
+	SCO_STATUS,
+	NUD_STATUS,
+	BT_STATUS,
+};
+
+#define SW_PTA_COEX_PARAMS_MAX_LEN 32
+/**
+ * struct sir_sw_pta_req - sw pta coex params request
+ * @param_type: sw pta coex param type
+ * @length: sw pta coex params value length
+ * @value: sw pta coex params value
+ */
+struct sir_sw_pta_req {
+	enum sir_sw_pta_param_type param_type;
+	uint8_t length;
+	uint8_t value[SW_PTA_COEX_PARAMS_MAX_LEN];
+};
+#endif
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 67839eb..e1ea5a5 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -404,6 +404,9 @@
     eWNI_SME_TRIGGER_SAE,
     eWNI_SME_SEND_MGMT_FRAME_TX,
     eWNI_SME_SEND_SAE_MSG,
+#ifdef FEATURE_WLAN_SW_PTA
+    eWNI_SME_SW_PTA_RESP,
+#endif
     eWNI_SME_MSG_TYPES_END
 };
 
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 51f6b0f..4f76572 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -832,6 +832,10 @@
 
 #define SIR_HAL_BLACKLIST_REQ              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 308)
 
+#ifdef FEATURE_WLAN_SW_PTA
+#define SIR_HAL_SW_PTA_REQ                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 309)
+#endif
+
 #define SIR_HAL_MSG_TYPES_END              (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 // CFG message types
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c
index f5bb4d3..640b47a 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.c
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.c
@@ -587,7 +587,8 @@
         limLog(pMac, LOGP, FL("AllocateMemory failed!"));
         goto err_timer;
     }
-
+    memset(pMac->lim.gLimPreAuthTimerTable.pTable,
+               0, cfgValue*sizeof(tLimPreAuthNode));
     limInitPreAuthTimerTable(pMac, &pMac->lim.gLimPreAuthTimerTable);
     PELOG1(limLog(pMac, LOG1, FL("alloc and init table for preAuth timers"));)
 
diff --git a/CORE/SME/inc/smeInside.h b/CORE/SME/inc/smeInside.h
index 38aa648..562dad3 100644
--- a/CORE/SME/inc/smeInside.h
+++ b/CORE/SME/inc/smeInside.h
@@ -211,6 +211,9 @@
         tpSirUpdateChanList chan_list;
         tpRoamParams RoamParams;
         bool olpc_mode_enable;
+#ifdef FEATURE_WLAN_SW_PTA
+	struct sir_sw_pta_req *sw_pta_req;
+#endif
     }u;
 }tSmeCmd;
 
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index 1a598ad..907f8d1 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -110,6 +110,9 @@
     eSmeCommandRemainOnChannel,
     eSmeCommandNoAUpdate,
     eSmeCommandBlackList,
+#ifdef FEATURE_WLAN_SW_PTA
+    eSmeCommandSwPTAReq,
+#endif
 } eSmeCommandType;
 
 
@@ -195,6 +198,9 @@
    void (*roaming_mbb_callback)(void* mac, tANI_U32 session_id,
           void* bss_description, void *reassoc_req, tANI_U32 csr_roam_op_code);
 #endif
+#ifdef FEATURE_WLAN_SW_PTA
+    void (*sw_pta_resp_cb)(uint8_t status);
+#endif
 } tSmeStruct, *tpSmeStruct;
 
 
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 04cc78b..cb6592c 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -4178,4 +4178,34 @@
  */
 eHalStatus sme_update_olpc_mode(tHalHandle hHal, bool enable);
 
+#ifdef FEATURE_WLAN_SW_PTA
+/**
+ * sme_sw_pta_req() - Send sw pta coex params request to sme
+ * @hal: The handle returned by mac_open
+ * @resp_callback: callback to indicate sw pta response to hdd
+ * @session_id: session id
+ * @type: sw pta coex param type
+ * @length: length of sw pta coex param value
+ * @value: sw pta coex params value
+ *
+ * Return: HAL_STATUS
+ */
+eHalStatus sme_sw_pta_req(tHalHandle hal,
+			  void (*resp_callback)(uint8_t resp_status),
+			  uint8_t session_id, enum sir_sw_pta_param_type type,
+			  uint8_t length, uint8_t *value);
+
+/**
+ * sme_sco_req() - Send sco request status to sme
+ * @hal: The handle returned by mac_open
+ * @resp_callback: callback to indicate sco response to hdd
+ * @session_id: session id
+ * @req_status: sco request status
+ *
+ * Return: HAL_STATUS
+ */
+eHalStatus sme_sco_req(tHalHandle hal,
+		       void (*resp_callback)(uint8_t resp_status),
+		       uint8_t session_id, uint8_t req_status);
+#endif /* FEATURE_WLAN_SW_PTA */
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 4f708ff..0fe9292 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -112,6 +112,9 @@
 static tANI_BOOLEAN bRoamScanOffloadStarted = VOS_FALSE;
 #endif
 
+#define MAX_PWR_FCC_CHAN_12 8
+#define MAX_PWR_FCC_CHAN_13 2
+
 #define LE_READ_4(p) \
         ((uint32_t)\
         ((((const uint8_t *)(p))[0]) |\
@@ -660,6 +663,21 @@
         pChanList->chanParam[num_channel].pwr =
           cfgGetRegulatoryMaxTransmitPower(pMac,
                                            pScan->defaultPowerTable[i].chanId);
+        if (pMac->scan.fcc_constraint)
+        {
+            if (pChanList->chanParam[num_channel].chanId == 12)
+            {
+                pChanList->chanParam[num_channel].pwr = MAX_PWR_FCC_CHAN_12;
+                smsLog(pMac, LOG1,
+                      "fcc_constraint is set, txpower for channel 12 is 8db ");
+            }
+            if (pChanList->chanParam[num_channel].chanId == 13)
+            {
+                pChanList->chanParam[num_channel].pwr = MAX_PWR_FCC_CHAN_13;
+                smsLog(pMac, LOG1,
+                      "fcc_constraint is set, txpower for channel 13 is 2db ");
+            }
+        }
 
         if (!pChanList->chanParam[num_channel].pwr)
         {
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index 72aecc0..db88dd4 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -4218,31 +4218,6 @@
     csrSetCfgCountryCode(pMac, countryCode);
 }
 
-void csrUpdateFCCChannelList(tpAniSirGlobal pMac)
-{
-    tCsrChannel ChannelList;
-    tANI_U8 chnlIndx = 0;
-    int i;
-
-    for ( i = 0; i < pMac->scan.base20MHzChannels.numChannels; i++ )
-    {
-        if (pMac->scan.fcc_constraint &&
-            ((pMac->scan.base20MHzChannels.channelList[i] == 12) ||
-            (pMac->scan.base20MHzChannels.channelList[i] == 13)))
-        {
-                    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
-                        FL("removing channel %d"),
-                        pMac->scan.base20MHzChannels.channelList[i]);
-            continue;
-        }
-        ChannelList.channelList[chnlIndx] =
-        pMac->scan.base20MHzChannels.channelList[i];
-        chnlIndx++;
-    }
-    csrSetCfgValidChannelList(pMac, ChannelList.channelList, chnlIndx);
-    csrScanFilterResults(pMac);
-}
-
 void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce, tANI_BOOLEAN updateRiva )
 {
     if( fForce || (csrIs11dSupported( pMac ) && (!pMac->scan.f11dInfoReset)))
diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h
index d888281..0ff58c4 100644
--- a/CORE/SME/src/csr/csrInsideApi.h
+++ b/CORE/SME/src/csr/csrInsideApi.h
@@ -458,7 +458,6 @@
 tANI_U32 csrTranslateToWNICfgDot11Mode(tpAniSirGlobal pMac, eCsrCfgDot11Mode csrDot11Mode);
 void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand );
 void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode, tANI_BOOLEAN updateRiva);
-void csrUpdateFCCChannelList(tpAniSirGlobal pMac);
 void csrApplyPower2Current( tpAniSirGlobal pMac );
 void csrAssignRssiForCategory(tpAniSirGlobal pMac, tANI_S8 bestApRssi, tANI_U8 catOffset);
 tANI_BOOLEAN csrIsMacAddressZero( tpAniSirGlobal pMac, tCsrBssid *pMacAddr );
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index a8da6a6..7d83661 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1022,6 +1022,36 @@
     }
 }
 
+#ifdef FEATURE_WLAN_SW_PTA
+/**
+ * sme_process_sw_pta_req() - Process sw pta request
+ * @mac - context handler
+ * @sme_cmd: cmd param containing sw pta request
+ *
+ * The function sends sw pta request to firmware
+ */
+static void sme_process_sw_pta_req(tpAniSirGlobal mac, tSmeCmd *sme_cmd)
+{
+	tSirRetStatus ret = eSIR_SUCCESS;
+	tSirMsgQ msg;
+
+	msg.type = WDA_SW_PTA_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = sme_cmd->u.sw_pta_req;
+	msg.bodyval = 0;
+
+	ret = wdaPostCtrlMsg(mac, &msg);
+	if (ret != eSIR_SUCCESS) {
+		smsLog(mac, LOGE,
+		       FL("Posting WDA_SW_PTA_REQ to WDA failed, reason=%X"),
+		       ret);
+		vos_mem_free(sme_cmd->u.sw_pta_req);
+	} else {
+		smsLog(mac, LOG1, FL("posted WDA_SW_PTA_REQ command"));
+	}
+}
+#endif /* FEATURE_WLAN_SW_PTA */
+
 tANI_BOOLEAN smeProcessCommand( tpAniSirGlobal pMac )
 {
     tANI_BOOLEAN fContinue = eANI_BOOLEAN_FALSE;
@@ -1499,7 +1529,19 @@
                                       "sme_command_olpc_mode processed");
                             fContinue = eANI_BOOLEAN_TRUE;
                             break;
-
+#ifdef FEATURE_WLAN_SW_PTA
+                        case eSmeCommandSwPTAReq:
+                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
+                            sme_process_sw_pta_req(pMac, pCommand);
+                            if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
+                                &pCommand->Link, LL_ACCESS_LOCK)) {
+                                csrReleaseCommand(pMac, pCommand);
+                            }
+                            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                                      "eSmeCommandScoIndReq processed");
+                            fContinue = eANI_BOOLEAN_TRUE;
+                            break;
+#endif /* FEATURE_WLAN_SW_PTA */
                         default:
                             //something is wrong
                             //remove it from the active list
@@ -3182,6 +3224,20 @@
                          FL("Empty message for (eWNI_SME_ECSA_IE_BEACON_COMP_IND)"));
               }
               break;
+#ifdef FEATURE_WLAN_SW_PTA
+          case eWNI_SME_SW_PTA_RESP:
+                MTRACE(vos_trace(VOS_MODULE_ID_SME,
+                       TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type));
+
+                if (pMac->sme.sw_pta_resp_cb) {
+                   smsLog(pMac, LOGE, FL("sw pta response"));
+                   pMac->sme.sw_pta_resp_cb(pMsg->bodyval);
+                } else {
+                   smsLog(pMac, LOGE,
+                          FL("sw pta response is NULL"));
+                }
+              break;
+#endif
 
           default:
 
@@ -14402,7 +14458,7 @@
             pMac->scan.defer_update_channel_list = true;
         } else {
             /* update the channel list to the firmware */
-            csrUpdateFCCChannelList(pMac);
+            csrUpdateChannelList(pMac);
         }
     }
 
@@ -15586,4 +15642,73 @@
     return eHAL_STATUS_SUCCESS;
 }
 
+#ifdef FEATURE_WLAN_SW_PTA
+eHalStatus sme_sw_pta_req(tHalHandle hal,
+			  void (*resp_callback)(uint8_t resp_status),
+			  uint8_t session_id, enum sir_sw_pta_param_type type,
+			  uint8_t length, uint8_t *value)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct sir_sw_pta_req *sw_pta_req;
+	eHalStatus status;
+	tSmeCmd *sme_cmd;
 
+	if (length > SW_PTA_COEX_PARAMS_MAX_LEN) {
+		smsLog(mac, LOGE, FL("Invalid length"));
+		return eHAL_STATUS_FAILURE;
+	}
+
+	sme_cmd = csrGetCommandBuffer(mac);
+	if (!sme_cmd) {
+		smsLog(mac, LOGE, FL("Failed to get buffer for sw pta req"));
+		return eHAL_STATUS_RESOURCES;
+	}
+
+	sw_pta_req = vos_mem_malloc(sizeof(*sw_pta_req));
+	if (!sw_pta_req) {
+		smsLog(mac, LOGE, FL("Failed to allocate memory for sw pta"));
+		csrReleaseCommand(mac, sme_cmd);
+		return eHAL_STATUS_RESOURCES;
+	}
+
+	sw_pta_req->param_type = type;
+	sw_pta_req->length = length;
+	memcpy(sw_pta_req->value, value, length);
+
+	status = sme_AcquireGlobalLock(&mac->sme);
+	if (HAL_STATUS_SUCCESS(status)) {
+		mac->sme.sw_pta_resp_cb = resp_callback;
+
+		smsLog(mac, LOG1, "Posting sw pta request to csr queue");
+		sme_cmd->command = eSmeCommandSwPTAReq;
+		sme_cmd->sessionId = session_id;
+		sme_cmd->u.sw_pta_req = sw_pta_req;
+
+		if (!HAL_STATUS_SUCCESS(csrQueueSmeCommand(mac,
+					sme_cmd, TRUE))) {
+			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+				  FL("failed queueing sme command"));
+			sme_ReleaseGlobalLock(&mac->sme);
+			csrReleaseCommand(mac, sme_cmd);
+			vos_mem_free(sw_pta_req);
+			return eHAL_STATUS_FAILURE;
+		}
+	} else {
+		smsLog(mac, LOGE, FL("sme_AcquireGlobalLock failed"));
+		csrReleaseCommand(mac, sme_cmd);
+		vos_mem_free(sw_pta_req);
+		return eHAL_STATUS_FAILURE;
+	}
+
+	sme_ReleaseGlobalLock(&mac->sme);
+	return eHAL_STATUS_SUCCESS;
+}
+
+eHalStatus sme_sco_req(tHalHandle hal,
+		       void (*resp_callback)(uint8_t resp_status),
+		       uint8_t session_id, uint8_t req_status)
+{
+	return sme_sw_pta_req(hal, resp_callback, session_id,
+			      SCO_STATUS, sizeof(req_status), &req_status);
+}
+#endif /* FEATURE_WLAN_SW_PTA */
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index 4d98d99..6bd31ab 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -853,6 +853,9 @@
         CASE_RETURN_STRING(WDA_GET_ROAM_RSSI_RSP);
         CASE_RETURN_STRING(WDA_NAN_REQUEST);
         CASE_RETURN_STRING(WDA_BLACKLIST_REQ);
+#ifdef FEATURE_WLAN_SW_PTA
+        CASE_RETURN_STRING(WDA_SW_PTA_REQ);
+#endif
         CASE_RETURN_STRING(WDA_START_SCAN_OFFLOAD_REQ);
         CASE_RETURN_STRING(WDA_START_SCAN_OFFLOAD_RSP);
         CASE_RETURN_STRING(WDA_STOP_SCAN_OFFLOAD_REQ);
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 7ca2db4..2bd5594 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1244,6 +1244,10 @@
 
 #define WDA_BLACKLIST_REQ          SIR_HAL_BLACKLIST_REQ
 
+#ifdef FEATURE_WLAN_SW_PTA
+#define WDA_SW_PTA_REQ             SIR_HAL_SW_PTA_REQ
+#endif
+
 #define WDA_START_SCAN_OFFLOAD_REQ  SIR_HAL_START_SCAN_OFFLOAD_REQ
 #define WDA_START_SCAN_OFFLOAD_RSP  SIR_HAL_START_SCAN_OFFLOAD_RSP
 #define WDA_STOP_SCAN_OFFLOAD_REQ  SIR_HAL_STOP_SCAN_OFFLOAD_REQ
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 026bb27..314fbf7 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -16795,6 +16795,110 @@
 }
 #endif /* MDNS_OFFLOAD */
 
+#ifdef FEATURE_WLAN_SW_PTA
+/**
+ * WDA_sw_pta_resp_cb() - WDA callback api to get sw pta resp status
+ * @status: SW PTA response status
+ * @user_data: user data
+ *
+ * Retrun: None
+ */
+static void WDA_sw_pta_resp_cb(uint8_t status, void *user_data)
+{
+	tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+	vos_msg_t msg;
+
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+		  "<------ %s", __func__);
+
+	if (!wda_params) {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: wda_params received NULL", __func__);
+		VOS_ASSERT(0);
+		return;
+	}
+
+	if (!wda_params->wdaMsgParam) {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: wda_params->wdaMsgParam is NULL", __func__);
+		VOS_ASSERT(0);
+		vos_mem_free(wda_params->wdaWdiApiMsgParam);
+		vos_mem_free(wda_params);
+		return;
+	}
+
+	/* VOS message wrapper */
+	msg.type = eWNI_SME_SW_PTA_RESP;
+	msg.bodyptr = NULL;
+	msg.bodyval = status;
+
+	if (vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t *)&msg) !=
+	    VOS_STATUS_SUCCESS) {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: Failed to post message to SME", __func__);
+	}
+
+	vos_mem_free(wda_params->wdaWdiApiMsgParam);
+	vos_mem_free(wda_params->wdaMsgParam);
+	vos_mem_free(wda_params);
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+		  "EXIT <------ %s ", __func__);
+}
+
+/* WDA_process_sw_pta_req - Process sw pta request
+ * @wda: wda handle
+ * @sw_pta_req: sw pta coex params request
+ *
+ * Return: VOS_STATUS
+ */
+static VOS_STATUS
+WDA_process_sw_pta_req(tWDA_CbContext *wda,
+		       struct sir_sw_pta_req *sw_pta_req)
+{
+	struct wdi_sw_pta_req *wdi_sw_pta_req;
+	tWDA_ReqParams *wda_params;
+	WDI_Status wdi_status;
+
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, FL("Enter"));
+
+	wdi_sw_pta_req = (struct wdi_sw_pta_req *)
+		vos_mem_malloc(sizeof(tWDA_ReqParams));
+	if (!wdi_sw_pta_req) {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: VOS MEM Alloc Failure", __func__);
+		vos_mem_free(sw_pta_req);
+		return VOS_STATUS_E_NOMEM;
+	}
+
+	wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams));
+	if (!wda_params) {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: VOS MEM Alloc Failure", __func__);
+		vos_mem_free(wdi_sw_pta_req);
+		vos_mem_free(sw_pta_req);
+	}
+
+	memcpy(wdi_sw_pta_req, sw_pta_req, sizeof(*sw_pta_req));
+
+	/* Store Params pass it to WDI */
+	wda_params->wdaWdiApiMsgParam = (void *)wdi_sw_pta_req;
+	wda_params->pWdaContext = wda;
+	/* Store param pointer as passed in by caller */
+	wda_params->wdaMsgParam = sw_pta_req;
+
+	wdi_status = WDI_sw_pta_req(WDA_sw_pta_resp_cb, wdi_sw_pta_req,
+				    wda_params);
+	if (IS_WDI_STATUS_FAILURE(wdi_status)) {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+			  FL("Error in WDA sw pta request"));
+		vos_mem_free(wdi_sw_pta_req);
+		vos_mem_free(sw_pta_req);
+	}
+
+	return CONVERT_WDI2VOS_STATUS(wdi_status);
+}
+#endif
+
 /*
  * FUNCTION: WDA_McProcessMsg
  * Trigger DAL-AL to start CFG download 
@@ -17870,6 +17974,13 @@
          WDA_ProcessGetARPStatsReq(pWDA, (getArpStatsParams *)pMsg->bodyptr);
          break;
       }
+#ifdef FEATURE_WLAN_SW_PTA
+      case WDA_SW_PTA_REQ:
+      {
+         WDA_process_sw_pta_req(pWDA, (struct sir_sw_pta_req *)pMsg->bodyptr);
+         break;
+      }
+#endif
       default:
       {
          VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
@@ -20434,8 +20545,6 @@
 void WDA_PERRoamOffloadScanReqCallback(WDI_Status status, void* pUserData)
 {
    tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
-   vos_msg_t vosMsg;
-   wpt_uint8 reason = 0;
 
    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
                                           "<------ %s " ,__func__);
@@ -20451,18 +20560,9 @@
        vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
 
    vos_mem_free(pWdaParams) ;
-   vosMsg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP;
-   vosMsg.bodyptr = NULL;
    if (WDI_STATUS_SUCCESS != status)
-      reason = 0;
-
-   vosMsg.bodyval = reason;
-   if (VOS_STATUS_SUCCESS !=
-       vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) {
-      /* free the mem and return */
-      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
-                 "%s: Failed to post the rsp to UMAC", __func__);
-   }
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+	       "%s: wdi_status %d", __func__, status);
 
    return ;
 }
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 1af5b15..d635888 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -6680,6 +6680,34 @@
     wpt_uint32 tsf_hi;
 } wdi_cap_tsf_rsp_t;
 
+#ifdef FEATURE_WLAN_SW_PTA
+/**
+ * enum wdi_sw_pta_param_type - Type of sw pta coex param
+ * @WDI_SCO_STATUS: Enable/Disable SCO
+ * @WDI_NUD_STATUS: Enable/Disable NUD
+ * @WDI_BT_STATUS: Enable/Disable BT
+ */
+/* Copied from sirApi.h to avoid compile error */
+enum wdi_sw_pta_param_type {
+	WDI_SCO_STATUS,
+	WDI_NUD_STATUS,
+	WDI_BT_STATUS,
+};
+
+#define WDI_SW_PTA_COEX_PARAMS_MAX_LEN 32
+/**
+ * wdi_sw_pta_req - SW PTA coex params request
+ * @param_type: sw pta coex param type
+ * @length: sw pta coex params value length
+ * @value: sw pta coex params value
+ */
+struct wdi_sw_pta_req {
+	enum wdi_sw_pta_param_type param_type;
+	uint8_t length;
+	uint8_t value[WDI_SW_PTA_COEX_PARAMS_MAX_LEN];
+};
+#endif
+
 /*----------------------------------------------------------------------------
  *   WDI callback types
  *--------------------------------------------------------------------------*/
@@ -12563,5 +12591,21 @@
                          wdi_tsf_rsp_cb wdi_tsf_rsp_callback,
                          void *user_data);
 
+#ifdef FEATURE_WLAN_SW_PTA
+typedef void (*WDI_sw_pta_resp_cb)(uint8_t status, void *user_data);
 
+/**
+ * @WDI_sw_pta_req - SW PTA request
+ *
+ * @wdi_sw_pta_resp_cb: WDI sw pta response callback
+ * @wdi_sw_pta_req: sw pta request params
+ * @user_data: user data
+ *
+ * @Return: WDI_Status
+ */
+WDI_Status
+WDI_sw_pta_req(WDI_sw_pta_resp_cb wdi_sw_pta_resp_cb,
+	       struct wdi_sw_pta_req *wdi_sw_pta_req,
+	       void *user_data);
+#endif /* FEATURE_WLAN_SW_PTA */
 #endif /* #ifndef WLAN_QCT_WDI_H */
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index 17c0dbd..50aae4d 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -508,6 +508,12 @@
   /* BLACKLIST Request */
   WDI_BLACKLIST_REQ                              = 127,
   WDI_SET_LOW_POWER_REQ                          = 128,
+
+#ifdef FEATURE_WLAN_SW_PTA
+  /* SW PTA coex params request */
+  WDI_SW_PTA_COEX_PARAMS_REQ                     = 129,
+#endif
+
   WDI_MAX_REQ,
 
   /*Send a suspend Indication down to HAL*/
@@ -901,6 +907,10 @@
   WDI_BLACKLIST_RSP                              = 126,
   WDI_SET_LOW_POWER_RSP                          = 127,
 
+#ifdef FEATURE_WLAN_SW_PTA
+  /* SW PTA coex params response */
+  WDI_SW_PTA_COEX_PARAMS_RSP                    = 128,
+#endif
   /*-------------------------------------------------------------------------
     Indications
      !! Keep these last in the enum if possible
@@ -6931,5 +6941,31 @@
   WDI_EventInfoType*     pEventData
 );
 
+#ifdef FEATURE_WLAN_SW_PTA
+/**
+ * WDI_process_sw_pta_req() - process sw pta coex params request
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ * @return Result of the function call
+ */
+WDI_Status
+WDI_process_sw_pta_req(WDI_ControlBlockType *pWDICtx,
+		       WDI_EventInfoType *pEventData);
+
+/**
+ * WDI_process_sw_pta_resp() - process sw pta coex params response
+ *
+ * @pWDICtx: pointer to the WLAN DAL context
+ * @pEventData: pointer to the event information structure
+ *
+ * @return Result of the function call
+ */
+WDI_Status
+WDI_process_sw_pta_resp(WDI_ControlBlockType *pWDICtx,
+			WDI_EventInfoType *pEventData);
+#endif /* FEATURE_WLAN_SW_PTA */
+
 #endif /*WLAN_QCT_WDI_I_H*/
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 275f55a..327f9fc 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -551,6 +551,10 @@
   WDI_ProcessBlackListReq,            /* WDI_BLACKLIST_REQ*/
   WDI_process_low_power_request,      /* WDI_SET_LOW_POWER_REQ */
 
+#ifdef FEATURE_WLAN_SW_PTA
+  WDI_process_sw_pta_req,            /* WDI_SW_PTA_COEX_PARAMS_REQ */
+#endif
+
   /*-------------------------------------------------------------------------
     Indications
   -------------------------------------------------------------------------*/
@@ -906,7 +910,12 @@
    WDI_ProcessGetArpStatsResp,          /* WDI_FW_GET_ARP_STATS_RSP */
    WDI_low_power_rsp_callback,          /* WDI_SET_LOW_POWER_RSP */
 
-   WDI_ProcessBlackListResp,              /* WDI_BLACKLIST_RSP */
+   WDI_ProcessBlackListResp,            /* WDI_BLACKLIST_RSP */
+
+#ifdef FEATURE_WLAN_SW_PTA
+   WDI_process_sw_pta_resp,             /* WDI_SW_PTA_COEX_PARAMS_RESP */
+#endif
+
   /*---------------------------------------------------------------------
     Indications
   ---------------------------------------------------------------------*/
@@ -1386,6 +1395,9 @@
 #endif
     CASE_RETURN_STRING( WDI_FW_ARP_STATS_REQ );
     CASE_RETURN_STRING( WDI_FW_GET_ARP_STATS_REQ );
+#ifdef FEATURE_WLAN_SW_PTA
+    CASE_RETURN_STRING(WDI_SW_PTA_COEX_PARAMS_REQ);
+#endif
 
     default:
         return "Unknown WDI MessageId";
@@ -1817,6 +1829,9 @@
     CASE_RETURN_STRING (WDI_CAPTURE_GET_TSF_TSTAMP_RSP);
     CASE_RETURN_STRING (WDI_BLACKLIST_RSP);
     CASE_RETURN_STRING (WDI_SET_LOW_POWER_RSP);
+#ifdef FEATURE_WLAN_SW_PTA
+    CASE_RETURN_STRING(WDI_SW_PTA_COEX_PARAMS_RSP);
+#endif
     default:
         return "Unknown WDI MessageId";
   }
@@ -25544,6 +25559,10 @@
       return WLAN_HAL_FW_SET_CLEAR_ARP_STATS_REQ;
   case WDI_FW_GET_ARP_STATS_REQ:
       return WLAN_HAL_FW_GET_ARP_STATS_REQ;
+#ifdef FEATURE_WLAN_SW_PTA
+  case WDI_SW_PTA_COEX_PARAMS_REQ:
+       return WLAN_HAL_HOST_SW_PTA_COEX_PARAMS_REQ;
+#endif
   default:
     return WLAN_HAL_MSG_MAX;
   }
@@ -25935,6 +25954,10 @@
        return WDI_FW_GET_ARP_STATS_RSP;
   case WLAN_HAL_POWER_CONTROL_MODE_CHANGE_RSP:
        return WDI_SET_LOW_POWER_RSP;
+#ifdef FEATURE_WLAN_SW_PTA
+  case WLAN_HAL_HOST_SW_PTA_COEX_PARAMS_RSP:
+       return WDI_SW_PTA_COEX_PARAMS_RSP;
+#endif
   default:
     return eDRIVER_TYPE_MAX;
   }
@@ -40092,4 +40115,107 @@
 
         return WDI_STATUS_SUCCESS;
 }
+
+#ifdef FEATURE_WLAN_SW_PTA
+WDI_Status
+WDI_sw_pta_req(WDI_sw_pta_resp_cb wdi_sw_pta_resp_cb,
+	      struct wdi_sw_pta_req *wdi_sw_pta_req,
+	      void *user_data)
+{
+	WDI_EventInfoType wdiEventData;
+
+	if (gWDIInitialized == eWLAN_PAL_FALSE) {
+		WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+			   "WDI API called before module is initialized");
+		return WDI_STATUS_E_NOT_ALLOWED;
+	}
+
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, "%s", __func__);
+
+	wdiEventData.wdiRequest      = WDI_SW_PTA_COEX_PARAMS_REQ;
+	wdiEventData.pEventData      = (void *)wdi_sw_pta_req;
+	wdiEventData.uEventDataSize  = sizeof(*wdi_sw_pta_req);
+	wdiEventData.pUserData       = user_data;
+	wdiEventData.pCBfnc          = wdi_sw_pta_resp_cb;
+
+	return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+
+WDI_Status
+WDI_process_sw_pta_req(WDI_ControlBlockType *pWDICtx,
+		       WDI_EventInfoType *pEventData)
+{
+	struct wdi_sw_pta_req *wdi_sw_pta_req;
+	wpt_uint8 *pSendBuffer = NULL;
+	tpHalSwPTAReq hal_sw_pta_req;
+	wpt_uint16 usDataOffset = 0;
+	wpt_uint16 usSendSize = 0;
+
+	WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+		   "WDI_process_sw_pta_req");
+
+	if (!pEventData) {
+		WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+			   "%s: Invalid parameters", __func__);
+		WDI_ASSERT(0);
+		return WDI_STATUS_E_FAILURE;
+	}
+
+	if (WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx,
+	     WDI_SW_PTA_COEX_PARAMS_REQ, sizeof(*hal_sw_pta_req),
+	     &pSendBuffer, &usDataOffset, &usSendSize) ||
+	     (usSendSize < (usDataOffset + sizeof(*hal_sw_pta_req)))) {
+		WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
+			   "Unable to get buffer in sw pta request %pK",
+			   pEventData);
+		WDI_ASSERT(0);
+		return WDI_STATUS_E_FAILURE;
+	}
+
+	wdi_sw_pta_req = (struct wdi_sw_pta_req *)pEventData->pEventData;
+
+	hal_sw_pta_req = (tpHalSwPTAReq) (pSendBuffer + usDataOffset);;
+	hal_sw_pta_req->param_type = wdi_sw_pta_req->param_type;
+	hal_sw_pta_req->length = wdi_sw_pta_req->length;
+	memcpy(hal_sw_pta_req->value, wdi_sw_pta_req->value,
+	       wdi_sw_pta_req->length);
+
+	return WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize,
+			   pEventData->pCBfnc, pEventData->pUserData,
+			   WDI_SW_PTA_COEX_PARAMS_RSP);
+}
+
+WDI_Status
+WDI_process_sw_pta_resp(WDI_ControlBlockType *wdi_ctx,
+			WDI_EventInfoType *pEventData)
+{
+	WDI_sw_pta_resp_cb wdi_sw_pta_resp_cb;
+	uint8_t sw_pta_status;
+
+	if ((!wdi_ctx) || (!pEventData) ||
+	    !pEventData->pEventData) {
+		WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+			   "%s: Invalid parameters", __func__);
+		WDI_ASSERT(0);
+		return WDI_STATUS_E_FAILURE;
+	}
+
+	sw_pta_status = *((uint8_t *)pEventData->pEventData);
+
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+		  "%s : Received SW PTA coex params response, status : %d",
+		  __func__, sw_pta_status);
+
+	wdi_sw_pta_resp_cb = (WDI_sw_pta_resp_cb)wdi_ctx->pfncRspCB;
+	if (wdi_sw_pta_resp_cb) {
+		wdi_sw_pta_resp_cb(sw_pta_status, wdi_ctx->pRspCBUserData);
+	} else {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+			  "%s : wdi_sw_pta_resp_cb is NULL", __func__);
+		return WDI_STATUS_E_FAILURE;
+	}
+
+	return WDI_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_SW_PTA */
 #endif
diff --git a/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c b/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c
index 9e80267..ff3abe2 100644
--- a/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c
+++ b/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c
@@ -242,16 +242,19 @@
    /* iterate until no more packets are available */
    while (1) {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
-      spin_lock(&pWCTSCb->wctsDataMsg.data_queue_lock);
+      unsigned long flags;
+
+      spin_lock_irqsave(&pWCTSCb->wctsDataMsg.data_queue_lock, flags);
       if (list_empty(&pWCTSCb->wctsDataMsg.data_queue)) {
-	      spin_unlock(&pWCTSCb->wctsDataMsg.data_queue_lock);
+	      spin_unlock_irqrestore(&pWCTSCb->wctsDataMsg.data_queue_lock,
+                                     flags);
 	      return;
       }
 
       msg = list_first_entry(&pWCTSCb->wctsDataMsg.data_queue,
                              struct data_msg, list);
       list_del(&msg->list);
-      spin_unlock(&pWCTSCb->wctsDataMsg.data_queue_lock);
+      spin_unlock_irqrestore(&pWCTSCb->wctsDataMsg.data_queue_lock, flags);
 
       buffer = msg->buffer;
       packet_size = msg->buf_len;
@@ -492,6 +495,12 @@
 	WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) priv;
 	struct data_msg *msg;
 
+	if (WCTS_CB_MAGIC != wcts_cb->wctsMagic) {
+		WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+			   "%s: Received smd data in invalid state", __func__);
+		return 0;
+	}
+
 	if (WCTS_STATE_REM_CLOSED == wcts_cb->wctsState) {
 		WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
 			"%s: received SMD data when wcts state is closed ",
@@ -512,6 +521,7 @@
 	msg->buf_len = len;
 	msg->buffer = wpalMemoryAllocate(len);
 	if (!msg->buffer) {
+		wpalMemoryFree(msg);
 		WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
 			   "WCTS_smd_resp_process: Memory allocation failure");
 		WPAL_ASSERT(0);
diff --git a/Kbuild b/Kbuild
index cf403ba..7414ebd 100644
--- a/Kbuild
+++ b/Kbuild
@@ -26,6 +26,9 @@
 #Flag to enable SAE
     CONFIG_WLAN_FEATURE_SAE := y
 
+#Flag to enable SW PTA
+    CONFIG_WLAN_FEATURE_SW_PTA := y
+
 #Flag to enable OWE
     CONFIG_WLAN_AKM_SUITE_OWE := y
 
@@ -691,6 +694,10 @@
 CDEFINES += -DWLAN_FEATURE_SAE
 endif
 
+ifeq ($(CONFIG_WLAN_FEATURE_SW_PTA),y)
+CDEFINES += -DFEATURE_WLAN_SW_PTA
+endif
+
 ifeq ($(CONFIG_WLAN_AKM_SUITE_OWE),y)
 CDEFINES += -DWLAN_AKM_SUITE_OWE
 endif
diff --git a/riva/inc/wlan_hal_msg.h b/riva/inc/wlan_hal_msg.h
index fef1636..8e038fb 100644
--- a/riva/inc/wlan_hal_msg.h
+++ b/riva/inc/wlan_hal_msg.h
@@ -635,6 +635,8 @@
    WLAN_HAL_QPOWER_ENABLE_BY_HOST_IND        = 361,
    WLAN_HAL_BLACK_LIST_SSID_REQ              = 362,
    WLAN_HAL_BLACK_LIST_SSID_RSP              = 363,
+   WLAN_HAL_HOST_SW_PTA_COEX_PARAMS_REQ      = 364,
+   WLAN_HAL_HOST_SW_PTA_COEX_PARAMS_RSP      = 365,
 
    WLAN_HAL_MSG_MAX = WLAN_HAL_MSG_TYPE_MAX_ENUM_SIZE
 }tHalHostMsgType;
@@ -9771,4 +9773,32 @@
 #else
 #endif
 
+#ifdef FEATURE_WLAN_SW_PTA
+/**
+ * enum hal_sw_pta_param_type - Type of sw pta coex param
+ * @WDI_SCO_STATUS: Enable/Disable SCO
+ * @WDI_NUD_STATUS: Enable/Disable NUD
+ * @WDI_BT_STATUS: Enable/Disable BT
+ */
+/* Copied from sirApi.h to avoid compile error */
+enum hal_sw_pta_param_type {
+	HAL_SW_PTA_SCO_STATUS = 0,
+	HAL_SW_PTA_NUD_STATUS = 1,
+	HAL_SW_PTA_BT_STATUS = 2,
+	HAL_SW_PTA_MAX = WLAN_HAL_MAX_ENUM_SIZE
+};
+
+#define HAL_SW_PTA_COEX_PARAMS_MAX_LEN 32
+/**
+ * hal_sw_pta_req - SW PTA coex params request
+ * @param_type: sw pta coex param type
+ * @length: sw pta coex params value length
+ * @value: sw pta coex params value
+ */
+typedef PACKED_PRE struct PACKED_POST {
+	enum hal_sw_pta_param_type param_type;
+	uint8_t length;
+	uint8_t value[HAL_SW_PTA_COEX_PARAMS_MAX_LEN];
+} tHalSwPTAReq, *tpHalSwPTAReq;
+#endif
 #endif /* _WLAN_HAL_MSG_H_ */