prima: WLAN Driver Release 3.2.0.9
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 9e64d20..9f59945 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -144,11 +144,25 @@
 module_param_string(fwpath, fwpath, BUF_LEN,
                     S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
+/*
+ * The rate at which the driver sends RESTART event to supplicant
+ * once the function 'vos_wlanRestart()' is called
+ *
+ */
+#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000  /* 5 second */
+#define WLAN_HDD_RESTART_RETRY_MAX_CNT  5     /* 5 retries */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
 static struct wake_lock wlan_wake_lock;
+#endif
 /* set when SSR is needed after unload */
 static v_U8_t      isSsrRequired;
 
 //internal function declaration
+static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
+static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
+static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
+void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
+
 v_U16_t hdd_select_queue(struct net_device *dev,
     struct sk_buff *skb);
 
@@ -173,7 +187,7 @@
 
    //Make sure that this callback corresponds to our device.
    if((strncmp( dev->name, "wlan", 4 )) && 
-      (strncmp( dev->name, "p2p-wlan", 8))
+      (strncmp( dev->name, "p2p", 3))
      )
       return NOTIFY_DONE;
 
@@ -207,11 +221,8 @@
         break;
 
    case NETDEV_CHANGE:
-        if(VOS_STA_MODE == hdd_get_conparam()) 
-        {
-            if(TRUE == pAdapter->isLinkUpSvcNeeded)
-               complete(&pAdapter->linkup_event_var);
-           }
+        if(TRUE == pAdapter->isLinkUpSvcNeeded)
+           complete(&pAdapter->linkup_event_var);
         break;
 
    case NETDEV_GOING_DOWN:
@@ -342,7 +353,7 @@
       goto exit; 
    }
 
-   if ((!ifr) && (!ifr->ifr_data))
+   if ((!ifr) || (!ifr->ifr_data))
    {
        ret = -EINVAL;
        goto exit; 
@@ -1268,65 +1279,6 @@
    return status;
 }
 
-#ifdef WLAN_FEATURE_P2P
-/**
- * hdd_init_p2p_device_mode
- *
- *FUNCTION:
- * This function is called from hdd_wlan_startup function when wlan 
- * driver module is loaded. 
- *
- *LOGIC:
- * Open New SME session with P2P Device Mac Address which is different 
- * from STA Mac Address SME session. When driver receive any frame on STA Mac 
- * Address then we divert all the frame using P2P Device Mac Address instaed of 
- * STA Mac address. 
- *
- *ASSUMPTIONS:
- *
- *
- *NOTE:
- *
- * @param  pAdapter   Pointer to pAdapter structure
- *
- * @return None
- */
-VOS_STATUS hdd_init_p2p_device_mode( hdd_adapter_t *pAdapter)
-{
-   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
-   eHalStatus halStatus = eHAL_STATUS_SUCCESS;
-   VOS_STATUS status = VOS_STATUS_E_FAILURE;
-   int rc = 0;
-
-   INIT_COMPLETION(pAdapter->session_open_comp_var);
-   //Open a SME session for future operation
-   halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
-               (tANI_U8 *)&pHddCtx->p2pDeviceAddress, &pAdapter->p2pSessionId);
-   if ( !HAL_STATUS_SUCCESS( halStatus ) )
-   {
-      hddLog(VOS_TRACE_LEVEL_FATAL,
-             "sme_OpenSession() failed with status code %08d [x%08lx]",
-                                                 halStatus, halStatus );
-      status = VOS_STATUS_E_FAILURE;
-      return status;
-   }
-   
-   //Block on a completion variable. Can't wait forever though.
-   rc = wait_for_completion_interruptible_timeout(
-                        &pAdapter->session_open_comp_var,
-                        msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
-   if (!rc)
-   {
-      hddLog(VOS_TRACE_LEVEL_FATAL,
-             "Session is not opened within timeout period code %08d", rc );
-      status = VOS_STATUS_E_FAILURE;
-      return status;
-   }
-
-   return VOS_STATUS_SUCCESS;
-}
-#endif
-
 #ifdef CONFIG_CFG80211
 void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
 {
@@ -1358,6 +1310,7 @@
    {
       case WLAN_HDD_INFRA_STATION:
       case WLAN_HDD_P2P_CLIENT:
+      case WLAN_HDD_P2P_DEVICE:
       {
          if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
          {
@@ -1598,6 +1551,7 @@
       case WLAN_HDD_INFRA_STATION:
 #ifdef WLAN_FEATURE_P2P
       case WLAN_HDD_P2P_CLIENT:
+      case WLAN_HDD_P2P_DEVICE:
 #endif
       {
          pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
@@ -1606,12 +1560,11 @@
             return NULL;
 
 #ifdef CONFIG_CFG80211
-         pAdapter->wdev.iftype = (session_type == WLAN_HDD_INFRA_STATION) ?
-                                  NL80211_IFTYPE_STATION :
-                                  NL80211_IFTYPE_P2P_CLIENT;
+         pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
+                                  NL80211_IFTYPE_P2P_CLIENT:
+                                  NL80211_IFTYPE_STATION;
 #endif
 
-
          pAdapter->device_mode = session_type;
 
          status = hdd_init_station_mode( pAdapter );
@@ -1900,6 +1853,7 @@
    {
       case WLAN_HDD_INFRA_STATION:
       case WLAN_HDD_P2P_CLIENT:
+      case WLAN_HDD_P2P_DEVICE:
          if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
          {
             if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
@@ -2085,6 +2039,7 @@
       {
          case WLAN_HDD_INFRA_STATION:
          case WLAN_HDD_P2P_CLIENT:
+         case WLAN_HDD_P2P_DEVICE:
             hdd_init_station_mode(pAdapter);
             /* Open the gates for HDD to receive Wext commands */
             pAdapter->isLinkUpSvcNeeded = FALSE; 
@@ -2677,6 +2632,9 @@
 
    ENTER();
 
+   // Unloading, restart logic is no more required.
+   wlan_hdd_restart_deinit(pHddCtx);
+
 #ifdef CONFIG_CFG80211
 #ifdef WLAN_SOFTAP_FEATURE
    if (VOS_STA_SAP_MODE != hdd_get_conparam())
@@ -2820,26 +2778,6 @@
    // Unregister the Net Device Notifier
    unregister_netdevice_notifier(&hdd_netdev_notifier);
    
-#ifdef WLAN_FEATURE_P2P
-   if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated)
-   {
-       hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
-                                    WLAN_HDD_INFRA_STATION);
-       if (pAdapter != NULL)
-       {
-          INIT_COMPLETION(pAdapter->session_close_comp_var);
-          if( eHAL_STATUS_SUCCESS == sme_CloseSession( pHddCtx->hHal,
-                                        pAdapter->p2pSessionId,
-                                        hdd_smeCloseSessionCallback, pAdapter ) )
-          {
-              //Block on a completion variable. Can't wait forever though.
-              wait_for_completion_interruptible_timeout(
-                         &pAdapter->session_close_comp_var,
-                         msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
-          }
-       }
-   }
-#endif
    hdd_stop_all_adapters( pHddCtx );
 
 #ifdef ANI_BUS_TYPE_SDIO
@@ -2939,7 +2877,11 @@
          "%s: Failed to close VOSS Scheduler",__func__);
       VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
    }
-   
+
+#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
+   /* Destroy the wake lock */
+   wake_lock_destroy(&pHddCtx->rx_wake_lock);
+#endif
 
    //Close VOSS
    //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
@@ -3182,12 +3124,20 @@
 /* wake lock APIs for HDD */
 void hdd_prevent_suspend(void)
 {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
     wake_lock(&wlan_wake_lock);
+#else
+    wcnss_prevent_suspend();
+#endif
 }
 
 void hdd_allow_suspend(void)
 {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
     wake_unlock(&wlan_wake_lock);
+#else
+    wcnss_allow_suspend();
+#endif
 }
 
 /**---------------------------------------------------------------------------
@@ -3206,6 +3156,7 @@
 {
    VOS_STATUS status;
    hdd_adapter_t *pAdapter = NULL;
+   hdd_adapter_t *pP2pAdapter = NULL;
    hdd_context_t *pHddCtx = NULL;
    v_CONTEXT_t pVosContext= NULL;
 #ifdef WLAN_BTAMP_FEATURE
@@ -3420,6 +3371,17 @@
       goto err_vosclose;
    }
 
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+      /* Vos preStart is calling */
+      /* vos preStart which does cfg download should be called before set sme config which accesses/sets some cfgs */
+      status = vos_preStart( pHddCtx->pvosContext );
+      if ( !VOS_IS_STATUS_SUCCESS( status ) )
+      {
+         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
+         goto err_vosclose;
+      }
+#endif
+
    // Set the SME configuration parameters...
    status = hdd_set_sme_config( pHddCtx );
 
@@ -3438,16 +3400,6 @@
    }
 
 #ifdef FEATURE_WLAN_INTEGRATED_SOC
-   /* Vos preStart is calling */
-   status = vos_preStart( pHddCtx->pvosContext );
-   if ( !VOS_IS_STATUS_SUCCESS( status ) )
-   {
-      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
-      goto err_vosclose;
-   }
-#endif
-
-#ifdef FEATURE_WLAN_INTEGRATED_SOC
    /* In the integrated architecture we update the configuration from
       the INI file and from NV before vOSS has been started so that
       the final contents are available to send down to the cCPU   */
@@ -3627,11 +3579,20 @@
       pr_info("%s: WCNSS hardware version %s\n",
               WLAN_MODULE_NAME, versionString);
 
-      /* Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message */
-      if ((versionReported.major>0) || (versionReported.minor>1) || ((versionReported.minor>=1) && (versionReported.version>=1)))
+      /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message 
+              2.Host-FW capability exchange message  is only present on riva 1.1 so 
+                send the message only if it the riva is 1.1
+                minor numbers for different riva branches:
+                0 -> (1.0)Mainline Build
+                1 -> (1.1)Mainline Build
+                2->(1.04) Stability Build
+         */
+      if (((versionReported.major>0) || (versionReported.minor>1) || 
+         ((versionReported.minor>=1) && (versionReported.version>=1)))
+         && ((versionReported.major == 1) && (versionReported.minor >= 1)))
          fwFeatCapsMsgSupported = 1;
       if (fwFeatCapsMsgSupported)
-        sme_featureCapsExchange(pHddCtx->hHal);
+         sme_featureCapsExchange(pHddCtx->hHal);
    } while (0);
 
 #endif // FEATURE_WLAN_INTEGRATED_SOC
@@ -3658,26 +3619,44 @@
      if (pAdapter != NULL)
      {
 #ifdef WLAN_FEATURE_P2P
-         vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes, 
-                       pHddCtx->cfg_ini->intfMacAddr[0].bytes,
-                       sizeof(tSirMacAddr));
          if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
          {
+             vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
+                       pHddCtx->cfg_ini->intfMacAddr[0].bytes,
+                       sizeof(tSirMacAddr));
              /* Generate the P2P Device Address.  This consists of the device's
               * primary MAC address with the locally administered bit set.
               */
              pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
-             status = hdd_init_p2p_device_mode(pAdapter);
-             if ( VOS_STATUS_SUCCESS != status )
+         }
+         else
+         {
+             tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
+             if (p2p_dev_addr != NULL)
              {
-                 hddLog(VOS_TRACE_LEVEL_FATAL,
-                         "%s: Init Session fail for P2P Device Address Mode ",
-                          __FUNCTION__);
-                 goto err_close_adapter;
+                vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
+                             p2p_dev_addr, VOS_MAC_ADDR_SIZE);
+             }
+             else
+             {
+                hddLog(VOS_TRACE_LEVEL_FATAL,
+                    "%s: Failed to allocate mac_address for p2p_device",
+                    __FUNCTION__);
+                goto err_close_adapter;
              }
          }
+
+         pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
+                           &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
+         if ( NULL == pP2pAdapter )
+         {
+             hddLog(VOS_TRACE_LEVEL_FATAL,
+                "%s: Failed to do hdd_open_adapter for P2P Device Interface",
+                __FUNCTION__);
+             goto err_close_adapter;
+         }
 #endif
-    }
+     }
 #ifdef WLAN_SOFTAP_FEATURE
    }
 #endif
@@ -3691,15 +3670,14 @@
      goto err_clkvote;
 #endif
    }
-   
-     
+
 #ifdef WLAN_BTAMP_FEATURE
    vStatus = WLANBAP_Open(pVosContext);
    if(!VOS_IS_STATUS_SUCCESS(vStatus))
    {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to open BAP",__func__);
-      goto err_p2psession_close;
+      goto err_close_adapter;
    }
 
    vStatus = BSL_Init(pVosContext);
@@ -3722,7 +3700,7 @@
    status = WLANBAP_SetConfig(&btAmpConfig);
 
 #endif //WLAN_BTAMP_FEATURE
- 
+
 #ifdef FEATURE_WLAN_SCAN_PNO
    /*SME must send channel update configuration to RIVA*/
    sme_UpdateChannelConfig(pHddCtx->hHal); 
@@ -3737,7 +3715,7 @@
 #ifdef WLAN_BTAMP_FEATURE
       goto err_bap_stop;
 #else
-      goto err_p2psession_close; 
+      goto err_close_adapter; 
 #endif //WLAN_BTAMP_FEATURE
    }
 
@@ -3813,7 +3791,7 @@
    if (VOS_STA_SAP_MODE != hdd_get_conparam())
 #endif
    {
-      wlan_hdd_cfg80211_post_voss_start(pAdapter);
+      wlan_hdd_cfg80211_post_voss_start(pP2pAdapter);
    }
 #endif
 
@@ -3821,11 +3799,21 @@
 
    pHddCtx->isLoadUnloadInProgress = FALSE;
 
+#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
+   /* Initialize the wake lcok */
+   wake_lock_init(&pHddCtx->rx_wake_lock,
+           WAKE_LOCK_SUSPEND,
+           "qcom_rx_wakelock");
+#endif
+
    vos_event_init(&pAdapter->scan_info.scan_finished_event);
    pAdapter->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
 
    vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
    hdd_allow_suspend();
+   
+   // Initialize the restart logic
+   wlan_hdd_restart_init(pHddCtx);
   
    goto success;
 
@@ -3852,29 +3840,6 @@
    WLANBAP_Close(pVosContext);
 #endif
 
-err_p2psession_close:
-#ifdef WLAN_FEATURE_P2P
-   if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated)
-   {
-       hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
-                                    WLAN_HDD_INFRA_STATION);
-
-       if (pAdapter != NULL)
-       {
-          INIT_COMPLETION(pAdapter->session_close_comp_var);
-          if( eHAL_STATUS_SUCCESS == sme_CloseSession( pHddCtx->hHal,
-                                        pAdapter->p2pSessionId,
-                                        hdd_smeCloseSessionCallback, pAdapter ) )
-          {
-              //Block on a completion variable. Can't wait forever though.
-              wait_for_completion_interruptible_timeout(
-                         &pAdapter->session_close_comp_var,
-                         msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
-          }
-       }
-   }
-#endif
-
 err_close_adapter:
    hdd_close_all_adapters( pHddCtx );
 
@@ -3968,7 +3933,9 @@
 
    ENTER();
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
    wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
+#endif
 
    pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
            QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
@@ -4146,7 +4113,9 @@
       vos_mem_exit();
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
       wake_lock_destroy(&wlan_wake_lock);
+#endif
       pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
    }
    else
@@ -4179,7 +4148,6 @@
 {
    hdd_context_t *pHddCtx = NULL;
    v_CONTEXT_t pVosContext = NULL;
-   int attempts = 0;
 
    pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
 
@@ -4201,13 +4169,10 @@
    }
    else
    {
+      /* module exit should never proceed if SSR is not completed */
       while(isWDresetInProgress()){
-         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Reset in Progress by LOGP. Block rmmod for 500ms!!!",__func__);
-         VOS_ASSERT(0);
-         msleep(500);
-         attempts++;
-         if(attempts==MAX_EXIT_ATTEMPTS_DURING_LOGP)
-           break;
+         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:SSR in Progress; block rmmod for 1 second!!!",__func__);
+         msleep(1000);
        }
 
       pHddCtx->isLoadUnloadInProgress = TRUE;
@@ -4231,7 +4196,9 @@
 #endif
 
 done:
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,5))
    wake_lock_destroy(&wlan_wake_lock);
+#endif
    pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
 }
 
@@ -4426,8 +4393,8 @@
        case WLAN_HDD_P2P_GO:
 #endif
        case WLAN_HDD_SOFTAP:
-    pHddCtx->concurrency_mode |= (1 << mode);
-    pHddCtx->no_of_sessions[mode]++;
+            pHddCtx->concurrency_mode |= (1 << mode);
+            pHddCtx->no_of_sessions[mode]++;
             break;
        default:
             break;
@@ -4459,6 +4426,189 @@
     __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
 }
 
+/**---------------------------------------------------------------------------
+ *
+ *   \brief wlan_hdd_restart_init
+ *
+ *   This function initalizes restart timer/flag. An internal function.
+ *
+ *   \param  - pHddCtx
+ *
+ *   \return - None
+ *             
+ * --------------------------------------------------------------------------*/
+
+static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
+{
+   /* Initialize */
+   pHddCtx->hdd_restart_retries = 0;
+   atomic_set(&pHddCtx->isRestartInProgress, 0);
+   vos_timer_init(&pHddCtx->hdd_restart_timer, 
+                     VOS_TIMER_TYPE_SW, 
+                     wlan_hdd_restart_timer_cb,
+                     pHddCtx);
+}
+/**---------------------------------------------------------------------------
+ *
+ *   \brief wlan_hdd_restart_deinit
+ *
+ *   This function cleans up the resources used. An internal function.
+ *
+ *   \param  - pHddCtx
+ *
+ *   \return - None
+ *             
+ * --------------------------------------------------------------------------*/
+
+static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
+{
+ 
+   VOS_STATUS vos_status;
+   /* Block any further calls */
+   atomic_set(&pHddCtx->isRestartInProgress, 1);
+   /* Cleanup */
+   vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
+   if (!VOS_IS_STATUS_SUCCESS(vos_status))
+          hddLog(LOGE, FL("Failed to stop HDD restart timer\n"));
+   vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
+   if (!VOS_IS_STATUS_SUCCESS(vos_status))
+          hddLog(LOGE, FL("Failed to destroy HDD restart timer\n"));
+
+}
+
+/**---------------------------------------------------------------------------
+ *
+ *   \brief wlan_hdd_framework_restart
+ *
+ *   This function uses a cfg80211 API to start a framework initiated WLAN
+ *   driver module unload/load.
+ *
+ *   Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
+ *
+ *
+ *   \param  - pHddCtx
+ *
+ *   \return - VOS_STATUS_SUCCESS: Success
+ *             VOS_STATUS_E_EMPTY: Adapter is Empty
+ *             VOS_STATUS_E_NOMEM: No memory
+
+ * --------------------------------------------------------------------------*/
+
+static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx) 
+{
+   VOS_STATUS status = VOS_STATUS_SUCCESS;
+   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
+   int len = (sizeof (struct ieee80211_mgmt));
+   struct ieee80211_mgmt *mgmt = NULL; 
+   
+   /* Prepare the DEAUTH managment frame with reason code */
+   mgmt =  kzalloc(len, GFP_KERNEL);
+   if(mgmt == NULL) 
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, 
+            "%s: memory allocatoin failed (%d bytes)", __func__, len);
+      return VOS_STATUS_E_NOMEM;
+   }
+   mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
+
+   /* Iterate over all adapters/devices */
+   status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
+   do 
+   {
+      if( (status == VOS_STATUS_SUCCESS) && 
+                           pAdapterNode  && 
+                           pAdapterNode->pAdapter)
+      {
+         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, 
+               "restarting the driver(intf:\'%s\' mode:%d :try %d)",
+               pAdapterNode->pAdapter->dev->name,
+               pAdapterNode->pAdapter->device_mode,
+               pHddCtx->hdd_restart_retries + 1);
+         /* 
+          * CFG80211 event to restart the driver
+          * 
+          * 'cfg80211_send_unprot_deauth' sends a 
+          * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state 
+          * of SME(Linux Kernel) state machine.
+          *
+          * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
+          * the driver.
+          *
+          */
+         
+         cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );  
+      }
+      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
+      pAdapterNode = pNext;
+   } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
+
+
+   /* Free the allocated management frame */
+   kfree(mgmt);
+
+   /* Retry until we unload or reach max count */
+   if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT) 
+      vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
+
+   return status;
+
+}
+/**---------------------------------------------------------------------------
+ *
+ *   \brief wlan_hdd_restart_timer_cb
+ *
+ *   Restart timer callback. An internal function.
+ *
+ *   \param  - User data:
+ *
+ *   \return - None
+ *             
+ * --------------------------------------------------------------------------*/
+
+void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
+{
+   hdd_context_t *pHddCtx = usrDataForCallback;
+   wlan_hdd_framework_restart(pHddCtx);
+   return;
+
+}
+
+
+/**---------------------------------------------------------------------------
+ *
+ *   \brief wlan_hdd_restart_driver
+ *
+ *   This function sends an event to supplicant to restart the WLAN driver. 
+ *   
+ *   This function is called from vos_wlanRestart.
+ *
+ *   \param  - pHddCtx
+ *
+ *   \return - VOS_STATUS_SUCCESS: Success
+ *             VOS_STATUS_E_EMPTY: Adapter is Empty
+ *             VOS_STATUS_E_ALREADY: Request already in progress
+
+ * --------------------------------------------------------------------------*/
+VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx) 
+{
+   VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+   /* A tight check to make sure reentrancy */
+   if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, 
+            "%s: WLAN restart is already in progress", __func__);
+
+      return VOS_STATUS_E_ALREADY;
+   }
+
+   /* Restart API */
+   status = wlan_hdd_framework_restart(pHddCtx);
+   
+   return status;
+}
+
+
 //Register the module init/exit functions
 module_init(hdd_module_init);
 module_exit(hdd_module_exit);