/*
 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/**=============================================================================
*     wlan_hdd_early_suspend.c
*
*     \brief      power management functions
*
*     Description

*
==============================================================================**/
/* $HEADER$ */

/**-----------------------------------------------------------------------------
*   Include files
* ----------------------------------------------------------------------------*/

#include <net/addrconf.h>
#include <linux/pm.h>
#include <linux/wait.h>
#include <linux/cpu.h>
#include <wlan_hdd_includes.h>
#include <wlan_qct_driver.h>
#include "halTypes.h"
#include "sme_Api.h"
#include <vos_api.h>
#include <vos_sched.h>
#include <macInitApi.h>
#include <wlan_qct_sys.h>
#include <wlan_nlink_common.h>
#include <wlan_hdd_main.h>
#include <wlan_hdd_assoc.h>
#include <wlan_hdd_dev_pwr.h>
#include <wlan_nlink_srv.h>
#include <wlan_hdd_misc.h>
#include <dbglog_host.h>

#include <linux/semaphore.h>
#include <wlan_hdd_hostapd.h>
#include "cfgApi.h"


#include <wcnss_api.h>
#include <linux/inetdevice.h>
#include <wlan_hdd_cfg.h>
#include <wlan_hdd_cfg80211.h>
#ifdef IPA_OFFLOAD
#include <wlan_hdd_ipa.h>
#endif
#include <wlan_logging_sock_svc.h>
#include <wlan_hdd_p2p.h>

/**-----------------------------------------------------------------------------
*   Preprocessor definitions and constants
* ----------------------------------------------------------------------------*/

/**-----------------------------------------------------------------------------
*   Type declarations
* ----------------------------------------------------------------------------*/

/**-----------------------------------------------------------------------------
*   Function and variables declarations
* ----------------------------------------------------------------------------*/
#include "wlan_hdd_power.h"
#include "wlan_hdd_packet_filtering.h"

#include <wlan_qct_wda.h>
#if defined(HIF_PCI)
#include "if_pci.h"
#elif defined(HIF_USB)
#include "if_usb.h"
#elif defined(HIF_SDIO)
#include "if_ath_sdio.h"
#endif

#include "ol_fw.h"
#include "wlan_hdd_host_offload.h"

/* Time in msec.
 * Time includes 60sec timeout of request_firmware for various binaries
 * (OTP, BDWLAN, QWLAN) and other cleanup and re-init sequence
 */
#ifdef CONFIG_SLUB_DEBUG_ON
#define HDD_SSR_BRING_UP_TIME 250000
#else
#define HDD_SSR_BRING_UP_TIME 240000
#endif

static eHalStatus g_full_pwr_status;
static eHalStatus g_standby_status;

extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
extern void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);

extern struct notifier_block hdd_netdev_notifier;
extern tVOS_CON_MODE hdd_get_conparam ( void );

static struct timer_list ssr_timer;
static bool ssr_timer_started;

#ifdef FEATURE_WLAN_DIAG_SUPPORT
/**
 * hdd_wlan_offload_event()- send offloads event
 * @type: offload type
 * @state: enabled or disabled
 *
 * This Function send offloads enable/disable diag event
 *
 * Return: void.
 */

void hdd_wlan_offload_event(uint8_t type, uint8_t state)
{
	WLAN_VOS_DIAG_EVENT_DEF(host_offload, struct vos_event_offload_req);
	vos_mem_zero(&host_offload, sizeof(host_offload));

	host_offload.offload_type = type;
	host_offload.state = state;

	WLAN_VOS_DIAG_EVENT_REPORT(&host_offload, EVENT_WLAN_OFFLOAD_REQ);
}

#endif

//Callback invoked by PMC to report status of standby request
void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
{
   hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
   hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
   g_standby_status = status;

   if(eHAL_STATUS_SUCCESS == status)
   {
      pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
   }

   complete(&pHddCtx->standby_comp_var);
}

//Callback invoked by PMC to report status of full power request
void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
{
   hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
   hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
   g_full_pwr_status = status;

   if(eHAL_STATUS_SUCCESS == status)
   {
      pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
   }

   complete(&pHddCtx->full_pwr_comp_var);
}

eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
{
    eHalStatus status = VOS_STATUS_SUCCESS;
    unsigned long rc;

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
    INIT_COMPLETION(pHddCtx->full_pwr_comp_var);

   g_full_pwr_status = eHAL_STATUS_FAILURE;
    status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
      eSME_FULL_PWR_NEEDED_BY_HDD);

   if(status == eHAL_STATUS_PMC_PENDING)
   {
      //Block on a completion variable. Can't wait forever though
      rc = wait_for_completion_timeout(
                 &pHddCtx->full_pwr_comp_var,
                 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
      if (!rc) {
          hddLog(VOS_TRACE_LEVEL_ERROR,
             FL("wait on full_pwr_comp_var failed"));
      }
      status = g_full_pwr_status;
      if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
         VOS_ASSERT(0);
         goto failure;
      }
    }
    else if(status != eHAL_STATUS_SUCCESS)
    {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
         __func__, status);
      VOS_ASSERT(0);
      goto failure;
    }
    else
      pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;

failure:
    //No blocking to reduce latency. No other device should be depending on WLAN
    //to finish resume and WLAN won't be instantly on after resume
    return status;
}


//Helper routine to put the chip into standby
VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
{
   eHalStatus halStatus = eHAL_STATUS_SUCCESS;
   VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
   unsigned long rc;

   //Disable IMPS/BMPS as we do not want the device to enter any power
   //save mode on its own during suspend sequence
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);

   //Note we do not disable queues unnecessarily. Queues should already be disabled
   //if STA is disconnected or the queue will be disabled as and when disconnect
   //happens because of standby procedure.

   //Ensure that device is in full power first. There is scope for optimization
   //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
   //Core s/w needs to be optimized to handle this. Until then we request full
   //power before issuing request for standby.
   INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
   g_full_pwr_status = eHAL_STATUS_FAILURE;
   halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
       pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);

   if(halStatus == eHAL_STATUS_PMC_PENDING)
   {
      //Block on a completion variable. Can't wait forever though
      rc = wait_for_completion_timeout(
                 &pHddCtx->full_pwr_comp_var,
                 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
      if (!rc) {
          hddLog(VOS_TRACE_LEVEL_ERROR,
                 FL("wait on full_pwr_comp_var failed"));
      }

      if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
         VOS_ASSERT(0);
         vosStatus = VOS_STATUS_E_FAILURE;
         goto failure;
      }
   }
   else if(halStatus != eHAL_STATUS_SUCCESS)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
         __func__, halStatus);
      VOS_ASSERT(0);
      vosStatus = VOS_STATUS_E_FAILURE;
      goto failure;
   }

   if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
         hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
         pHddCtx->hdd_mcastbcast_filter_set = FALSE;
   }

   //Request standby. Standby will cause the STA to disassociate first. TX queues
   //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
   //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
   //will send this failure code in case of concurrent sessions. Power Save cannot be supported
   //when there are concurrent sessions.
   INIT_COMPLETION(pHddCtx->standby_comp_var);
   g_standby_status = eHAL_STATUS_FAILURE;
   halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);

   if (halStatus == eHAL_STATUS_PMC_PENDING)
   {
      //Wait till WLAN device enters standby mode
      rc = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
         msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
      if (!rc) {
          hddLog(VOS_TRACE_LEVEL_ERROR,
                 FL("wait on standby_comp_var failed"));
      }

      if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
         VOS_ASSERT(0);
         vosStatus = VOS_STATUS_E_FAILURE;
         goto failure;
      }
   }
   else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
         __func__, halStatus);
      VOS_ASSERT(0);
      vosStatus = VOS_STATUS_E_FAILURE;
      goto failure;
   }
   else
      pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;

failure:
   //Restore IMPS config
   if(pHddCtx->cfg_ini->fIsImpsEnabled)
      sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);

   //Restore BMPS config
   if(pHddCtx->cfg_ini->fIsBmpsEnabled)
      sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);

   return vosStatus;
}


//Helper routine for Deep sleep entry
VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
{
   eHalStatus halStatus;
   VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
   unsigned long rc;

   //Stop the Interface TX queue.
   hddLog(LOG1, FL("Disabling queues"));
   wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
        WLAN_CONTROL_PATH);

   //Disable IMPS,BMPS as we do not want the device to enter any power
   //save mode on it own during suspend sequence
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);

   //Ensure that device is in full power as we will touch H/W during vos_Stop
   INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
   g_full_pwr_status = eHAL_STATUS_FAILURE;
   halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
       pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);

   if(halStatus == eHAL_STATUS_PMC_PENDING)
   {
      //Block on a completion variable. Can't wait forever though
      rc = wait_for_completion_timeout(
                 &pHddCtx->full_pwr_comp_var,
                 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
      if (!rc) {
          hddLog(VOS_TRACE_LEVEL_ERROR,
              FL("wait on full_pwr_comp_var failed"));
      }

      if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
         VOS_ASSERT(0);
      }
   }
   else if(halStatus != eHAL_STATUS_SUCCESS)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
      VOS_ASSERT(0);
   }

   //Issue a disconnect. This is required to inform the supplicant that
   //STA is getting disassociated and for GUI to be updated properly
   INIT_COMPLETION(pAdapter->disconnect_comp_var);
   halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);

   //Success implies disconnect command got queued up successfully
   if(halStatus == eHAL_STATUS_SUCCESS)
   {
      //Block on a completion variable. Can't wait forever though.
      rc = wait_for_completion_timeout(
                 &pAdapter->disconnect_comp_var,
                 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
      if (!rc) {
          hddLog(VOS_TRACE_LEVEL_ERROR,
             FL("wait on disconnect_comp_var failed"));
      }
   }
   //None of the steps should fail after this. Continue even in case of failure
   vosStatus = vos_stop( pHddCtx->pvosContext );
   if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
             __func__, vosStatus);
      VOS_ASSERT(0);
   }

   pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;

   //Restore IMPS config
   if(pHddCtx->cfg_ini->fIsImpsEnabled)
      sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);

   //Restore BMPS config
   if(pHddCtx->cfg_ini->fIsBmpsEnabled)
      sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);

   return vosStatus;
}

VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
{
   VOS_STATUS vosStatus;
   eHalStatus halStatus;
   tANI_U32 type, subType;

   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
      "%s: calling hdd_set_sme_config",__func__);
   vosStatus = hdd_set_sme_config( pHddCtx );
   VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed in hdd_set_sme_config",__func__);
      goto err_deep_sleep;
   }

   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
      "%s: calling vos_start",__func__);
   vosStatus = vos_start( pHddCtx->pvosContext );
   VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed in vos_start",__func__);
      goto err_deep_sleep;
   }

   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
      "%s: calling hdd_post_voss_start_config",__func__);
   vosStatus = hdd_post_voss_start_config( pHddCtx );
   VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed in hdd_post_voss_start_config",__func__);
      goto err_voss_stop;
   }

   vosStatus = vos_get_vdev_types(pAdapter->device_mode, &type, &subType);
   if (VOS_STATUS_SUCCESS != vosStatus)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "failed to get vdev type");
      goto err_voss_stop;
   }

   //Open a SME session for future operation
   halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
         (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId,
         type, subType);
   if ( !HAL_STATUS_SUCCESS( halStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
                    halStatus, halStatus );
      goto err_voss_stop;

   }

   pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;

   //Trigger the initial scan
   hdd_wlan_initial_scan(pAdapter);

   return VOS_STATUS_SUCCESS;

err_voss_stop:
   vos_stop(pHddCtx->pvosContext);
err_deep_sleep:
   return VOS_STATUS_E_FAILURE;

}

#ifdef WLAN_FEATURE_GTK_OFFLOAD
void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
{
    eHalStatus ret;
    tSirGtkOffloadParams hddGtkOffloadReqParams;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if(fenable)
    {
        if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
           (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
        {
            vos_mem_copy(&hddGtkOffloadReqParams,
                 &pHddStaCtx->gtkOffloadReqParams,
                 sizeof (tSirGtkOffloadParams));

            ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                          &hddGtkOffloadReqParams, pAdapter->sessionId);
            if (eHAL_STATUS_SUCCESS != ret)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_SetGTKOffload failed, returned %d",
                       __func__, ret);
                return;
            }

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s: sme_SetGTKOffload successful", __func__);
        }

    }
    else
    {
        if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
            (0 ==  memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
                     &pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE)) &&
            (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
        {

            /* Host driver has previously  offloaded GTK rekey  */
            ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                wlan_hdd_cfg80211_update_replayCounterCallback,
                                pAdapter, pAdapter->sessionId);
            if (eHAL_STATUS_SUCCESS != ret)

            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_GetGTKOffload failed, returned %d",
                       __func__, ret);
                return;
            }
            else
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                       "%s: sme_GetGTKOffload successful",
                       __func__);

                /* Sending GTK offload disable */
                memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
                      sizeof (tSirGtkOffloadParams));
                hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
                ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                &hddGtkOffloadReqParams, pAdapter->sessionId);
                if (eHAL_STATUS_SUCCESS != ret)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                            "%s: failed to disable GTK offload, returned %d",
                            __func__, ret);
                    return;
                }
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        "%s: successfully disabled GTK offload request to HAL",
                        __func__);
            }
        }
    }
    return;
}
#endif /*WLAN_FEATURE_GTK_OFFLOAD*/

#ifdef WLAN_NS_OFFLOAD

static int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
				   unsigned long data, void *arg)
{
	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
	struct net_device *ndev = ifa->idev->dev;
	hdd_context_t *hdd_ctx;
	hdd_adapter_t *adapter;
	int status;

	hdd_ctx = container_of(nb, hdd_context_t, ipv6_notifier);
	status = wlan_hdd_validate_context(hdd_ctx);
	if (0 != status)
		return NOTIFY_DONE;

	adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) return NOTIFY_DONE;
	if (adapter->dev != ndev) return NOTIFY_DONE;
	if (WLAN_HDD_GET_CTX(adapter) != hdd_ctx) return NOTIFY_DONE;

	if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
	    adapter->device_mode == WLAN_HDD_P2P_CLIENT ||
	    adapter->device_mode == WLAN_HDD_NDI) {

		if (eConnectionState_Associated ==
			WLAN_HDD_GET_STATION_CTX_PTR
			(adapter)->conn_info.connState)
				sme_dhcp_done_ind(hdd_ctx->hHal,
				adapter->sessionId);

		if (hdd_ctx->cfg_ini->nEnableSuspend ==
			WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER &&
			hdd_ctx->ns_offload_enable)
			schedule_work(&adapter->ipv6NotifierWorkQueue);
		else
			hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend: %d"),
				hdd_ctx->cfg_ini->nEnableSuspend);
	}

	return NOTIFY_DONE;
}

/**
 * wlan_hdd_ipv6_changed() - IPv6 change notifier callback
 * @nb: pointer to notifier block
 * @data: data
 * @arg: arg
 *
 * This is the IPv6 notifier callback function gets invoked
 * if any change in IP and then invoke the function @__wlan_hdd_ipv6_changed
 * to reconfigure the offload parameters.
 *
 * Return: 0 on success, error number otherwise.
 */
int wlan_hdd_ipv6_changed(struct notifier_block *nb,
				unsigned long data, void *arg)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_ipv6_changed(nb, data, arg);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_fill_ipv6_uc_addr() - fill IPv6 unicast addresses
 * @idev: pointer to net device
 * @ipv6addr: destination array to fill IPv6 addresses
 * @ipv6addr_type: IPv6 Address type
 * @count: number of IPv6 addresses
 *
 * This is the IPv6 utility function to populate unicast addresses.
 *
 * Return: 0 on success, error number otherwise.
 */
static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev,
				uint8_t ipv6_uc_addr[][SIR_MAC_IPV6_ADDR_LEN],
				uint8_t *ipv6addr_type, uint32_t *count)
{
	struct inet6_ifaddr *ifa;
	struct list_head *p;
	uint32_t scope;

	read_lock_bh(&idev->lock);
	list_for_each(p, &idev->addr_list) {
		if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
			read_unlock_bh(&idev->lock);
			return -EINVAL;
		}
		ifa = list_entry(p, struct inet6_ifaddr, if_list);
		if (ifa->flags & IFA_F_DADFAILED)
			continue;
		scope = ipv6_addr_src_scope(&ifa->addr);
		switch (scope) {
		case IPV6_ADDR_SCOPE_GLOBAL:
		case IPV6_ADDR_SCOPE_LINKLOCAL:
			vos_mem_copy(ipv6_uc_addr[*count], &ifa->addr.s6_addr,
				sizeof(ifa->addr.s6_addr));
			ipv6addr_type[*count] = SIR_IPV6_ADDR_UC_TYPE;
			hddLog (LOG1,
				FL("Index %d scope = %s UC-Address: %pI6"),
				*count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ?
				"LINK LOCAL": "GLOBAL", ipv6_uc_addr[*count]);
			*count += 1;
			break;
		default:
			hddLog(LOGE, "The Scope %d is not supported", scope);
		}
	}

	read_unlock_bh(&idev->lock);
	return 0;
}

/**
 * hdd_fill_ipv6_ac_addr() - fill IPv6 anycast addresses
 * @idev: pointer to net device
 * @ipv6addr: destination array to fill IPv6 addresses
 * @ipv6addr_type: IPv6 Address type
 * @count: number of IPv6 addresses
 *
 * This is the IPv6 utility function to populate anycast addresses.
 *
 * Return: 0 on success, error number otherwise.
 */
static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
				uint8_t ipv6_ac_addr[][SIR_MAC_IPV6_ADDR_LEN],
				uint8_t *ipv6addr_type, uint32_t *count)
{
	struct ifacaddr6 *ifaca;
	uint32_t scope;

	read_lock_bh(&idev->lock);
	for (ifaca = idev->ac_list; ifaca; ifaca = ifaca->aca_next) {
		if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
			read_unlock_bh(&idev->lock);
			return -EINVAL;
		}
		/* For anycast addr no DAD */
		scope = ipv6_addr_src_scope(&ifaca->aca_addr);
		switch (scope) {
		case IPV6_ADDR_SCOPE_GLOBAL:
		case IPV6_ADDR_SCOPE_LINKLOCAL:
			vos_mem_copy(ipv6_ac_addr[*count], &ifaca->aca_addr,
				sizeof(ifaca->aca_addr));
			ipv6addr_type[*count] = SIR_IPV6_ADDR_AC_TYPE;
			hddLog (LOG1,
				FL("Index %d scope = %s AC-Address: %pI6"),
				*count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ?
				"LINK LOCAL": "GLOBAL", ipv6_ac_addr[*count]);
			*count += 1;
			break;
		default:
			hddLog(LOGE, "The Scope %d is not supported", scope);
		}
	}

	read_unlock_bh(&idev->lock);
	return 0;
}

/**----------------------------------------------------------------------------

  \brief hdd_conf_ns_offload() - Configure NS offload

  Called during SUSPEND to configure the NS offload (MC BC filter) which
  reduces power consumption.

  \param  - pAdapter - Adapter context for which NS offload is to be configured
  \param  - fenable - 0 - disable.
                      1 - enable. (with IPv6 notifier registration)
                      2 - enable. (without IPv6 notifier registration)

  \return - void

  ---------------------------------------------------------------------------*/
void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
{
    struct inet6_dev *in6_dev;
    uint8_t ipv6_addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
                                     [SIR_MAC_IPV6_ADDR_LEN] = {{0,}};
    uint8_t ipv6_addr_type[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0};
    tSirHostOffloadReq offLoadRequest;
    hdd_context_t *pHddCtx;

    int i = 0, ret;
    eHalStatus returnStatus;
    uint32_t count = 0;

    ENTER();
    hddLog(LOG1, FL(" fenable = %d"), fenable);

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    /* In SAP/P2PGo mode, ARP/NS offload feature capability
     * is controlled by one bit.
     */

     if ((WLAN_HDD_SOFTAP == pAdapter->device_mode ||
          WLAN_HDD_P2P_GO == pAdapter->device_mode) &&
          !pHddCtx->ap_arpns_support) {
           hddLog(LOG1, FL("NS Offload is not supported in SAP/P2PGO mode"));
           return;
    }

    if (fenable) {
        in6_dev = __in6_dev_get(pAdapter->dev);
        if (NULL != in6_dev) {
            /* Unicast Addresses */
            ret = hdd_fill_ipv6_uc_addr(in6_dev, ipv6_addr,
                                        ipv6_addr_type, &count);

            if (0 > ret) {
                if (pHddCtx->cfg_ini->active_mode_offload)
                    goto disable_ns;
                else {
                     hddLog(LOG1,
                            FL("Reached max supported addresses and not enabling NS offload"));
                     return;
                }
            }

            /* Anycast Addresses */
            ret = hdd_fill_ipv6_ac_addr(in6_dev, ipv6_addr,
                                        ipv6_addr_type, &count);

            if (0 > ret) {
                if (pHddCtx->cfg_ini->active_mode_offload)
                    goto disable_ns;
                else {
                    hddLog(LOG1,
                        FL("Reached max supported addresses and not enabling NS offload"));
                    return;
                }
            }

            vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
            for (i = 0; i < count; i++) {
                /* Filling up the request structure
                 * Filling the selfIPv6Addr with solicited address
                 * A Solicited-Node multicast address is created by
                 * taking the last 24 bits of a unicast or anycast
                 * address and appending them to the prefix
                 *
                 * FF02:0000:0000:0000:0000:0001:FFXX:XXXX
                 *
                 * here XX is the unicast/anycast bits
                 */
                offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][0] = 0xFF;
                offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][1] = 0x02;
                offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][11] = 0x01;
                offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][12] = 0xFF;
                offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][13] =
                                                       ipv6_addr[i][13];
                offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][14] =
                                                       ipv6_addr[i][14];
                offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][15] =
                                                       ipv6_addr[i][15];
                offLoadRequest.nsOffloadInfo.slotIdx = i;

                vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[i],
                   &ipv6_addr[i][0], SIR_MAC_IPV6_ADDR_LEN);

                offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[i] =
                                                    SIR_IPV6_ADDR_VALID;
                offLoadRequest.nsOffloadInfo.target_ipv6_addr_type[i] =
                                                       ipv6_addr_type[i];
                hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
                                               SIR_OFFLOAD_ENABLE);
                vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
                   &offLoadRequest.nsOffloadInfo.targetIPv6Addr[i],
                   sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);

                hddLog (LOG1,
                   FL("Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6, Index %d"),
                   &offLoadRequest.nsOffloadInfo.selfIPv6Addr[i],
                   &offLoadRequest.nsOffloadInfo.targetIPv6Addr[i], i);
            }

            hddLog (LOG1,
                FL("configuredMcastBcastFilter: %d"),
                pHddCtx->configuredMcastBcastFilter);

            offLoadRequest.offloadType =  SIR_IPV6_NS_OFFLOAD;
            offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
            vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
               &pAdapter->macAddressCurrent.bytes, SIR_MAC_ADDR_LEN);
            /* set number of ns offload address count */
            offLoadRequest.num_ns_offload_count = count;
            /* Configure the Firmware with this */
            returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                               pAdapter->sessionId, &offLoadRequest);
            if (eHAL_STATUS_SUCCESS != returnStatus) {
                 hddLog(LOGE,
                        FL("Failed to enable HostOffload feature with status: %d"),
                        returnStatus);
            }
        }
        else {
            hddLog(LOGE,
                    FL("IPv6 dev does not exist. Failed to request NSOffload"));
            return;
        }
    } else {
disable_ns:
        /* Disable NSOffload */
        hddLog(LOG1, FL("Disable NS Offload"));
        vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
        offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
        offLoadRequest.offloadType =  SIR_IPV6_NS_OFFLOAD;
        hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
                                           SIR_OFFLOAD_DISABLE);

        if (eHAL_STATUS_SUCCESS !=
             sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                 pAdapter->sessionId, &offLoadRequest)) {
             hddLog(LOGE, FL("Failed to disable NS Offload"));
        }
    }
    EXIT();
    return;
}

/**
 * __hdd_ipv6_notifier_work_queue() - IP V6 change notifier work handler
 * @work: Pointer to work context
 *
 * Return: none
 */
static void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
{
    hdd_adapter_t* pAdapter =
             container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
    hdd_context_t *pHddCtx;
    int status;
    bool ndi_connected = false;

    ENTER();

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
        return;

   if (!pHddCtx->cfg_ini->active_mode_offload) {
       hddLog(LOG1, FL("Active mode offload is disabled"));
       return;
   }

    if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
    {
        pHddCtx->sus_res_mcastbcast_filter =
            pHddCtx->configuredMcastBcastFilter;
        pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
    }

    /* check if the device is in NAN data mode */
    if (WLAN_HDD_IS_NDI(pAdapter))
        ndi_connected = WLAN_HDD_IS_NDI_CONNECTED(pAdapter);

    if ((eConnectionState_Associated ==
            (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState ||
         ndi_connected)) {
        /*
         * This invocation being part of the IPv6 registration callback,
         * we are passing second parameter as 2 to avoid registration
         * of IPv6 notifier again
         */
        if (pHddCtx->cfg_ini->fhostNSOffload)
            hdd_conf_ns_offload(pAdapter, 2);
    }
    EXIT();
}

/**
 * hdd_ipv6_notifier_work_queue() - IP V6 change notifier work handler
 * @work: Pointer to work context
 *
 * Return: none
 */
void hdd_ipv6_notifier_work_queue(struct work_struct *work)
{
	vos_ssr_protect(__func__);
	__hdd_ipv6_notifier_work_queue(work);
	vos_ssr_unprotect(__func__);
}


#endif

/*
 * Function: hdd_conf_hostoffload
 *           Central function to configure the supported offloads,
 *           either enable or disable them.
 */
void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
{
    hdd_context_t *pHddCtx = NULL;
    v_CONTEXT_t *pVosContext = NULL;
    VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;

    ENTER();

    hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
            fenable);

    pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

    if (NULL == pVosContext) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
        return;
    }

    //Get the HDD context.
    pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );

    if (NULL == pHddCtx) {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
        return;
    }

    if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
           (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
               (WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
               (WLAN_HDD_P2P_GO == pAdapter->device_mode))
    {
        if (fenable) {
            if ((eConnectionState_Associated ==
                (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) ||
                (WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
                (WLAN_HDD_P2P_GO == pAdapter->device_mode)) {
                    if (!pHddCtx->cfg_ini->active_mode_offload) {
                         if ((pHddCtx->cfg_ini->fhostArpOffload)) {
                            /*
                             * Configure the ARP Offload.
                             * Even if it fails we have to reconfigure the MC/BC
                             * filter flag as we want RIVA not to drop BroadCast
                             * Packets
                             */
                             hddLog(VOS_TRACE_LEVEL_INFO,
                                FL("Calling ARP Offload with flag: %d"),
                                fenable);
                             vstatus = hdd_conf_arp_offload(pAdapter, fenable);
                             pHddCtx->configuredMcastBcastFilter &=
                                ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);

                             if (!VOS_IS_STATUS_SUCCESS(vstatus)) {
                                 hddLog(VOS_TRACE_LEVEL_INFO,
                                    "Failed to enable ARPOFfloadFeature %d",
                                    vstatus);
                             }
                         }
#ifdef WLAN_NS_OFFLOAD
                         if (pHddCtx->cfg_ini->fhostNSOffload &&
                             pHddCtx->ns_offload_enable) {
                             /*
                              * Configure the NS Offload.
                              * Even if it fails we have to reconfigure the
                              * MC/BC filter flag as we want RIVA not to
                              * drop Multicast Packets
                              */

                              hddLog(VOS_TRACE_LEVEL_INFO,
                                  FL("Calling NS Offload with flag: %d"),
                                  fenable);
                              hdd_conf_ns_offload(pAdapter, fenable);
                              pHddCtx->configuredMcastBcastFilter &=
                                  ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
                         }
#endif
                    }

                    /* Configure GTK_OFFLOAD */
#ifdef WLAN_FEATURE_GTK_OFFLOAD
                    hdd_conf_gtk_offload(pAdapter, fenable);
#endif

                    /*
                     * This variable saves the state if offload were configured
                     * or not. helps in recovering when pcie fails to suspend
                     * because of ongoing scan and state is no longer
                     * associated.
                     */
                     pAdapter->offloads_configured = TRUE;
            }
        } else {
            /* Disable offlaod features */
            if ((eConnectionState_Associated ==
                 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) ||
                 (pAdapter->offloads_configured == TRUE)) {

                  pAdapter->offloads_configured = FALSE;

                  /* Disable ARPOFFLOAD */
                  if (!pHddCtx->cfg_ini->active_mode_offload) {
                      if (pHddCtx->cfg_ini->fhostArpOffload) {
                          vstatus = hdd_conf_arp_offload(pAdapter, fenable);
                          if (!VOS_IS_STATUS_SUCCESS(vstatus)) {
                              hddLog(VOS_TRACE_LEVEL_ERROR,
                                 "Failed to disable ARPOffload Feature %d",
                                 vstatus);
                          }
                      }

#ifdef WLAN_NS_OFFLOAD
                      /* Disable NSOFFLOAD */
                      if (pHddCtx->cfg_ini->fhostNSOffload &&
                          pHddCtx->ns_offload_enable) {
                             hdd_conf_ns_offload(pAdapter, fenable);
                      }
#endif
                 }
                 /* Disable GTK_OFFLOAD*/
#ifdef WLAN_FEATURE_GTK_OFFLOAD
                 hdd_conf_gtk_offload(pAdapter, fenable);
#endif
            }
        }
    }

    EXIT();
    return;
}

/**
 * __hdd_ipv4_notifier_work_queue() - IP V4 change notifier work handler
 * @work: Pointer to work context
 *
 * Return: none
 */
static void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
{
    hdd_adapter_t* pAdapter =
             container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
    hdd_context_t *pHddCtx;
    int status;
    bool ndi_connected = false;

    hddLog(LOG1, FL("Reconfiguring ARP Offload"));
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
        return;

    if (!pHddCtx->cfg_ini->active_mode_offload) {
        hddLog(LOG1, FL("Active mode offload is disabled"));
        return;
    }

    if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
        pHddCtx->sus_res_mcastbcast_filter =
            pHddCtx->configuredMcastBcastFilter;
        pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
    }

    /* check if the device is in NAN data mode */
    if (WLAN_HDD_IS_NDI(pAdapter))
        ndi_connected = WLAN_HDD_IS_NDI_CONNECTED(pAdapter);

    if ((eConnectionState_Associated ==
            (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState ||
         ndi_connected)) {
        /*
         * This invocation being part of the IPv4 registration callback,
         * we are passing second parameter as 2 to avoid registration
         * of IPv4 notifier again.
         */
        hdd_conf_arp_offload(pAdapter, 2);
    }
}

/**
 * hdd_ipv4_notifier_work_queue() - IP V4 change notifier work handler
 * @work: Pointer to work context
 *
 * Return: none
 */
void hdd_ipv4_notifier_work_queue(struct work_struct *work)
{
	vos_ssr_protect(__func__);
	__hdd_ipv4_notifier_work_queue(work);
	vos_ssr_unprotect(__func__);
}

static int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
				   unsigned long data, void *arg)
{
	struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
	struct in_ifaddr **ifap = NULL;
	struct in_device *in_dev;
	struct net_device *ndev = ifa->ifa_dev->dev;
	hdd_context_t *hdd_ctx;
	hdd_adapter_t *adapter;
	int status;

	hdd_ctx = container_of(nb, hdd_context_t, ipv4_notifier);
	status = wlan_hdd_validate_context(hdd_ctx);
	if (0 != status)
		return NOTIFY_DONE;

	adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
	if (!adapter) return NOTIFY_DONE;
	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) return NOTIFY_DONE;
	if (adapter->dev != ndev) return NOTIFY_DONE;
	if (WLAN_HDD_GET_CTX(adapter) != hdd_ctx) return NOTIFY_DONE;
        if (!(adapter->device_mode == WLAN_HDD_INFRA_STATION ||
	      adapter->device_mode == WLAN_HDD_P2P_CLIENT ||
	      adapter->device_mode == WLAN_HDD_NDI))
		return NOTIFY_DONE;

	if (eConnectionState_Associated ==
		WLAN_HDD_GET_STATION_CTX_PTR(
		adapter)->conn_info.connState)
			sme_dhcp_done_ind(hdd_ctx->hHal,
			adapter->sessionId);

	if ((hdd_ctx->cfg_ini->nEnableSuspend !=
				WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER) ||
			(!hdd_ctx->cfg_ini->fhostArpOffload)) {
		hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
				hdd_ctx->cfg_ini->nEnableSuspend,
				hdd_ctx->cfg_ini->fhostArpOffload);

		return NOTIFY_DONE;
	}

	in_dev = __in_dev_get_rtnl(adapter->dev);
	if (in_dev != NULL) {
		for (ifap = &in_dev->ifa_list;
			(ifa = *ifap) != NULL;
			ifap = &ifa->ifa_next) {
			if (!strcmp(adapter->dev->name,
				ifa->ifa_label))
				break; /* found */
		}
	}

	if (ifa && ifa->ifa_local)
		schedule_work(&adapter->ipv4NotifierWorkQueue);

	return NOTIFY_DONE;
}

/**
 * wlan_hdd_ipv4_changed() - IPv4 change notifier callback
 * @nb: pointer to notifier block
 * @data: data
 * @arg: arg
 *
 * This is the IPv4 notifier callback function gets invoked
 * if any change in IP and then invoke the function @__wlan_hdd_ipv4_changed
 * to reconfigure the offload parameters.
 *
 * Return: 0 on success, error number otherwise.
 */
int wlan_hdd_ipv4_changed(struct notifier_block *nb,
				unsigned long data, void *arg)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_ipv4_changed(nb, data, arg);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**----------------------------------------------------------------------------

  \brief hdd_conf_arp_offload() - Configure ARP offload

  Called during SUSPEND to configure the ARP offload (MC BC filter) which
  reduces power consumption.

  \param  - pAdapter -Adapter context for which ARP offload is to be configured
  \param  - fenable - 0 - disable.
                      1 - enable. (with IPv4 notifier registration)
                      2 - enable. (without IPv4 notifier registration)

  \return -
            VOS_STATUS_SUCCESS - on successful operation
            VOS_STATUS_E_FAILURE - on failure of operation
-----------------------------------------------------------------------------*/
VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
{
   struct in_ifaddr **ifap = NULL;
   struct in_ifaddr *ifa = NULL;
   struct in_device *in_dev;
   int i = 0;
   tSirHostOffloadReq  offLoadRequest;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

   hddLog(LOG1, FL("fenable = %d"), fenable);


   /* In SAP/P2PGo mode, ARP/NS offload feature capability
    * is controlled by one bit.
    */
   if ((WLAN_HDD_SOFTAP == pAdapter->device_mode ||
       WLAN_HDD_P2P_GO == pAdapter->device_mode) &&
       !pHddCtx->ap_arpns_support) {
       hddLog(LOG1, FL("APR Offload is not supported in SAP/P2PGO mode"));
       return VOS_STATUS_SUCCESS;
   }

   if(fenable)
   {
       if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
       {
           for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
                   ifap = &ifa->ifa_next)
           {
               if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
               {
                   break; /* found */
               }
           }
       }
       if(ifa && ifa->ifa_local)
       {
           offLoadRequest.offloadType =  SIR_IPV4_ARP_REPLY_OFFLOAD;
           offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
           hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
                                           SIR_OFFLOAD_ENABLE);

           hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);

           if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
                pHddCtx->sus_res_mcastbcast_filter) ||
               (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
                pHddCtx->sus_res_mcastbcast_filter)) &&
               (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
           {
               offLoadRequest.enableOrDisable =
                   SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
               hddLog(VOS_TRACE_LEVEL_INFO,
                      "offload: inside arp offload conditional check");
           }
           hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
                                           SIR_OFFLOAD_ENABLE);
           hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
                  offLoadRequest.enableOrDisable);

           //converting u32 to IPV4 address
           for(i = 0 ; i < 4; i++)
           {
              offLoadRequest.params.hostIpv4Addr[i] =
                      (ifa->ifa_local >> (i*8) ) & 0xFF ;
           }
           hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
                  offLoadRequest.params.hostIpv4Addr[0],
                  offLoadRequest.params.hostIpv4Addr[1],
                  offLoadRequest.params.hostIpv4Addr[2],
                  offLoadRequest.params.hostIpv4Addr[3]);

          if (eHAL_STATUS_SUCCESS !=
                    sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                    pAdapter->sessionId, &offLoadRequest))
          {
              hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
                      "feature", __func__);
              return VOS_STATUS_E_FAILURE;
          }
       }
       else
       {
           hddLog(VOS_TRACE_LEVEL_INFO, FL("IP Address is not assigned\n"));
       }

       return VOS_STATUS_SUCCESS;
   }
   else
   {
       vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
       offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
       offLoadRequest.offloadType =  SIR_IPV4_ARP_REPLY_OFFLOAD;
       hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
                                           SIR_OFFLOAD_DISABLE);

       if (eHAL_STATUS_SUCCESS !=
                 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                 pAdapter->sessionId, &offLoadRequest))
       {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
                             "offload feature", __func__);
            return VOS_STATUS_E_FAILURE;
       }
       return VOS_STATUS_SUCCESS;
   }
}

/*
 * This function is called before setting mcbc filters
 * to modify filter value considering Different Offloads
 */

void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
                                  tANI_U8 *pMcBcFilter)
{
    if (NULL == pHddCtx)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
        return;
    }

    *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
    if (pHddCtx->cfg_ini->fhostArpOffload)
    {
        /* ARP offload is enabled, do not block bcast packets at RXP
         * Will be using Bitmasking to reset the filter. As we have
         * disable Broadcast filtering, Anding with the negation
         * of Broadcast BIT
         */
        hddLog(VOS_TRACE_LEVEL_INFO, FL("ARP offload is enabled"));
        *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
    }

#ifdef WLAN_NS_OFFLOAD
    if (pHddCtx->cfg_ini->fhostNSOffload)
    {
        /* NS offload is enabled, do not block mcast packets at RXP
         * Will be using Bitmasking to reset the filter. As we have
         * disable Multicast filtering, Anding with the negation
         * of Multicast BIT
         */
        hddLog(VOS_TRACE_LEVEL_INFO, FL("NS offload is enabled"));
        *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
    }
#endif

    pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
}

void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
{
    eHalStatus halStatus = eHAL_STATUS_FAILURE;
    tpSirWlanSetRxpFilters wlanRxpFilterParam =
                     vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
    if (NULL == wlanRxpFilterParam)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
           "%s: vos_mem_alloc failed ", __func__);
        return;
    }
    hddLog(VOS_TRACE_LEVEL_INFO,
        "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
    if (TRUE == setfilter)
    {
            hdd_mcbc_filter_modification(pHddCtx,
                  &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
    }
    else
    {
        /*Use the current configured value to clear*/
        wlanRxpFilterParam->configuredMcstBcstFilterSetting =
                              pHddCtx->configuredMcastBcastFilter;
    }

    wlanRxpFilterParam->setMcstBcstFilter = setfilter;
    halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);

    if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
       pHddCtx->hdd_mcastbcast_filter_set = TRUE;

    hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
           "lower mac with status %d"
           "configuredMcstBcstFilterSetting = %d"
           "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
           "Failed" : "Success", halStatus,
           wlanRxpFilterParam->configuredMcstBcstFilterSetting,
           wlanRxpFilterParam->setMcstBcstFilter);

    if (eHAL_STATUS_SUCCESS != halStatus)
        vos_mem_free(wlanRxpFilterParam);
}

static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
                                 hdd_adapter_t *pAdapter,
                                 void (*callback)(void *callbackContext,
                                                  boolean suspended),
                                 void *callbackContext)
{
    eHalStatus halStatus = eHAL_STATUS_FAILURE;
    tpSirWlanSuspendParam wlanSuspendParam =
      vos_mem_malloc(sizeof(tSirWlanSuspendParam));

    if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
        pHddCtx->sus_res_mcastbcast_filter =
            pHddCtx->configuredMcastBcastFilter;
        pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
        hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
        hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
               pHddCtx->configuredMcastBcastFilter);

    }


    if(NULL == wlanSuspendParam)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
           "%s: vos_mem_alloc failed ", __func__);
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO,
      "%s: send wlan suspend indication", __func__);

    if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
    {
        //Configure supported OffLoads
        hdd_conf_hostoffload(pAdapter, TRUE);
        wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
    }

    if ((eConnectionState_Associated ==
            (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) ||
        (eConnectionState_IbssConnected ==
            (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
                wlanSuspendParam->connectedState = TRUE;
    else
                wlanSuspendParam->connectedState = FALSE;

    wlanSuspendParam->sessionId = pAdapter->sessionId;
    halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam,
                                        callback, callbackContext);
    if(eHAL_STATUS_SUCCESS == halStatus)
    {
        pHddCtx->hdd_mcastbcast_filter_set = TRUE;
    } else {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);

        vos_mem_free(wlanSuspendParam);
    }
}

static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
{
    hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    eHalStatus halStatus = eHAL_STATUS_FAILURE;


    halStatus = sme_ConfigureResumeReq(pHddCtx->hHal,
                                       NULL
                                      );

    if (eHAL_STATUS_SUCCESS != halStatus)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: sme_ConfigureResumeReq return failure %d",
               __func__, halStatus);

    }

    hddLog(VOS_TRACE_LEVEL_INFO,
      "%s: send wlan resume indication", __func__);
    /* Disable supported OffLoads */
    hdd_conf_hostoffload(pAdapter, FALSE);
    pHddCtx->hdd_mcastbcast_filter_set = FALSE;

    if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
        pHddCtx->configuredMcastBcastFilter =
            pHddCtx->sus_res_mcastbcast_filter;
        pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
    }

    hddLog(VOS_TRACE_LEVEL_INFO,
           "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
    hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
                  pHddCtx->configuredMcastBcastFilter);
}

#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN
static void hdd_thermal_off_carrier(hdd_adapter_t *pAdapter)
{
	if (netif_carrier_ok(pAdapter->dev)) {
		pAdapter->netif_carrier_on = TRUE;
		wlan_hdd_netif_queue_control(pAdapter,
		  WLAN_NETIF_CARRIER_OFF, WLAN_CONTROL_PATH);
	} else {
		pAdapter->netif_carrier_on = FALSE;
	}
}

static void hdd_thermal_on_carrier(hdd_adapter_t *pAdapter)
{
	if (pAdapter->netif_carrier_on) {
	/* Thermal shutdown is an urgent accident visible to user space. */
		wlan_hdd_netif_queue_control(pAdapter,
			WLAN_NETIF_CARRIER_ON, WLAN_CONTROL_PATH);
	}
}
#else
static inline void hdd_thermal_off_carrier(hdd_adapter_t *pAdapter)
{
	return;
}

static inline void hdd_thermal_on_carrier(hdd_adapter_t *pAdapter)
{
	return;
}
#endif
//Suspend routine registered with Android OS
void hdd_suspend_wlan(void (*callback)(void *callbackContext, boolean suspended),
                      void *callbackContext, bool thermal)
{
   hdd_context_t *pHddCtx = NULL;
   v_CONTEXT_t pVosContext = NULL;

   VOS_STATUS status;
   hdd_adapter_t *pAdapter = NULL;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   bool hdd_enter_bmps = FALSE;

   hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);

   //Get the global VOSS context.
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if(!pVosContext) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
      return;
   }

   //Get the HDD context.
   pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );

   if(!pHddCtx) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
      return;
   }

   if (pHddCtx->isLogpInProgress) {
      hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: Ignore suspend wlan, LOGP in progress!", __func__);
      return;
   }

   hdd_set_pwrparams(pHddCtx);
   status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
       pAdapter = pAdapterNode->pAdapter;
       if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
         && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
         && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )

       {
           goto send_suspend_ind;
       }
       /* Avoid multiple enter/exit BMPS in this while loop using
        * hdd_enter_bmps flag
        */
       if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
       {
            hdd_enter_bmps = TRUE;

           /* If device was already in BMPS, and dynamic DTIM is set,
            * exit(set the device to full power) and enter BMPS again
            * to reflect new DTIM value */
           wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);

           wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);

           pHddCtx->hdd_ignore_dtim_enabled = TRUE;
       }
#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
       if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
       {
          //stop the interface before putting the chip to standby
          hddLog(LOG1, FL("Disabling queues"));
          wlan_hdd_netif_queue_control(pAdapter,
            WLAN_NETIF_TX_DISABLE_N_CARRIER,
            WLAN_CONTROL_PATH);
       }
       else if (pHddCtx->cfg_ini->nEnableSuspend ==
               WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
       {
          //Execute deep sleep procedure
          hdd_enter_deep_sleep(pHddCtx, pAdapter);
       }
#endif

send_suspend_ind:
       //stop all TX queues before suspend
       hddLog(LOG1, FL("Disabling queues"));

      /* Thermal shutdown is an urgent accident visible to user space. */
        if (thermal) {
            hdd_thermal_off_carrier(pAdapter);
        }

       wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE,
                      WLAN_CONTROL_PATH);


       WLANTL_PauseUnPauseQs(pVosContext, true);

      /* Keep this suspend indication at the end (before processing next adaptor)
       * for discrete. This indication is considered as trigger point to start
       * WOW (if wow is enabled). */
       /*Suspend notification sent down to driver*/
       hdd_conf_suspend_ind(pHddCtx, pAdapter, callback, callbackContext);

       status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
       pAdapterNode = pNext;
   }

   pHddCtx->hdd_wlan_suspended = TRUE;
   hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
  if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
  {
      hdd_enter_standby(pHddCtx);
  }
#endif

   return;
}

static void hdd_PowerStateChangedCB
(
   v_PVOID_t callbackContext,
   tPmcState newState
)
{
   hdd_context_t *pHddCtx = callbackContext;
   /* if the driver was not in BMPS during early suspend,
    * the dynamic DTIM is now updated at Riva */
   if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
           && pHddCtx->cfg_ini->enableDynamicDTIM
           && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
   {
       pHddCtx->hdd_ignore_dtim_enabled = TRUE;
   }
   spin_lock(&pHddCtx->filter_lock);
   if ((newState == BMPS) &&  pHddCtx->hdd_wlan_suspended)
   {
      spin_unlock(&pHddCtx->filter_lock);
      if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
      {
          pHddCtx->sus_res_mcastbcast_filter =
              pHddCtx->configuredMcastBcastFilter;
          pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;

          hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
          hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
                 pHddCtx->configuredMcastBcastFilter);
          hddLog(VOS_TRACE_LEVEL_INFO,
                 "offload: calling hdd_conf_mcastbcast_filter");

      }

      hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
      if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
   }
   else
   {
      /* Android framework can send resume request when the WCN chip is
       * in IMPS mode. When the chip exits IMPS mode the firmware will
       * restore all the registers to the state they were before the chip
       * entered IMPS and so our hardware filter settings configured by the
       * resume request will be lost. So reconfigure the filters on detecting
       * a change in the power state of the WCN chip.
       */
      spin_unlock(&pHddCtx->filter_lock);
      if (IMPS != newState)
      {
           spin_lock(&pHddCtx->filter_lock);
           if (FALSE == pHddCtx->hdd_wlan_suspended)
           {
                spin_unlock(&pHddCtx->filter_lock);
                hddLog(VOS_TRACE_LEVEL_INFO,
                          "Not in IMPS/BMPS and suspended state");
                hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
           }
           else
           {
                spin_unlock(&pHddCtx->filter_lock);
           }
      }
   }
}



void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
{
   v_CONTEXT_t pVosContext;
   tHalHandle smeContext;

   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if (NULL == pVosContext)
   {
      hddLog(LOGE, "%s: Invalid pContext", __func__);
      return;
   }
   smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
   if (NULL == smeContext)
   {
      hddLog(LOGE, "%s: Invalid smeContext", __func__);
      return;
   }

   spin_lock_init(&pHddCtx->filter_lock);
   if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
                                            pHddCtx->cfg_ini->nEnableSuspend)
   {
      if(!pHddCtx->cfg_ini->enablePowersaveOffload)
      {
         pmcRegisterDeviceStateUpdateInd(smeContext,
                   hdd_PowerStateChangedCB, pHddCtx);
      }
      /* TODO: For Power Save Offload case */
   }
}

void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
{
   v_CONTEXT_t pVosContext;
   tHalHandle smeContext;

   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if (NULL == pVosContext)
   {
      hddLog(LOGE, "%s: Invalid pContext", __func__);
      return;
   }
   smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
   if (NULL == smeContext)
   {
      hddLog(LOGE, "%s: Invalid smeContext", __func__);
      return;
   }

   if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
                                            pHddCtx->cfg_ini->nEnableSuspend)
   {
      if(!pHddCtx->cfg_ini->enablePowersaveOffload)
      {
         pmcDeregisterDeviceStateUpdateInd(smeContext,
                             hdd_PowerStateChangedCB);
      }
      /* TODO: For Power Save Offload case */
   }
}

void hdd_resume_wlan(bool thermal)
{
   hdd_context_t *pHddCtx = NULL;
   hdd_adapter_t *pAdapter = NULL;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   v_CONTEXT_t pVosContext = NULL;

   hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);

   //Get the global VOSS context.
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if(!pVosContext) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
      return;
   }

   //Get the HDD context.
   pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );

   if(!pHddCtx) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
      return;
   }

   if (pHddCtx->isLogpInProgress)
   {
      hddLog(VOS_TRACE_LEVEL_INFO,
             "%s: Ignore resume wlan, LOGP in progress!", __func__);
      return;
   }

   pHddCtx->hdd_wlan_suspended = FALSE;
   hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
   /*loop through all adapters. Concurrency */
   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
       pAdapter = pAdapterNode->pAdapter;
       if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
         && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
         && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
       {
            goto send_resume_ind;
       }


#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
       if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
       {
          hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
          hdd_exit_deep_sleep(pAdapter);
       }
#endif

      if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
      {
         /*Switch back to DTIM 1*/
         tSirSetPowerParamsReq powerRequest = { 0 };

         powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
         powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
         powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;

         /*Disabled ModulatedDTIM if enabled on suspend*/
         if(pHddCtx->cfg_ini->enableModulatedDTIM)
             powerRequest.uDTIMPeriod = 0;

         /* Update ignoreDTIM and ListedInterval in CFG with default values */
         ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
                          NULL, eANI_BOOLEAN_FALSE);
         ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
                          NULL, eANI_BOOLEAN_FALSE);

         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        "Switch to DTIM%d",powerRequest.uListenInterval);
         sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);

         if (BMPS == pmcGetPmcState(pHddCtx->hHal))
         {
             /* put the device into full power */
             wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);

             /* put the device back into BMPS */
             wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);

             pHddCtx->hdd_ignore_dtim_enabled = FALSE;
         }
      }

send_resume_ind:
      //wake the tx queues
      hddLog(LOG1, FL("Enabling queues"));

      WLANTL_PauseUnPauseQs(pVosContext, false);

      wlan_hdd_netif_queue_control(pAdapter,
                WLAN_WAKE_ALL_NETIF_QUEUE,
                WLAN_CONTROL_PATH);

      if (thermal) {
        hdd_thermal_on_carrier(pAdapter);
      }

      hdd_conf_resume_ind(pAdapter);

      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

#ifdef IPA_OFFLOAD
   hdd_ipa_resume(pHddCtx);
#endif

#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
   if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
   {
       hdd_exit_standby(pHddCtx);
   }
#endif

   return;
}

VOS_STATUS hdd_wlan_reset_initialization(void)
{
   v_CONTEXT_t pVosContext = NULL;

   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);

   //Get the global VOSS context.
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if(!pVosContext)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);

   // Prevent the phone from going to sleep
   hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);

   return VOS_STATUS_SUCCESS;
}

static void hdd_ssr_timer_init(void)
{
    init_timer(&ssr_timer);
}

static void hdd_ssr_timer_del(void)
{
    del_timer(&ssr_timer);
    ssr_timer_started = false;
}

static void hdd_ssr_timer_cb(unsigned long data)
{
    hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired!", __func__);
    VOS_BUG(0);
}

static void hdd_ssr_timer_start(int msec)
{
    if(ssr_timer_started)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Trying to start SSR timer when "
               "it's running!", __func__);
    }
    ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
    ssr_timer.function = hdd_ssr_timer_cb;
    add_timer(&ssr_timer);
    ssr_timer_started = true;
}

/**
 * hdd_svc_fw_shutdown_ind() - API to send FW SHUTDOWN IND to Userspace
 *
 * @dev: Device Pointer
 *
 * Return: None
 */
void hdd_svc_fw_shutdown_ind(struct device *dev)
{
	v_CONTEXT_t g_context;
	hdd_context_t *hdd_ctx;

	g_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

	if(!g_context)
		return;

	hdd_ctx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD,
						   g_context);

	hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
					      WLAN_SVC_FW_SHUTDOWN_IND,
					      NULL, 0) : 0;
}

#ifdef FEATURE_WLAN_DIAG_SUPPORT
/**
* hdd_wlan_ssr_shutdown_event() - Send ssr shutdown status
*
* This function sends ssr shutdown status diag event
*
* Return: - Void.
*/
static void hdd_wlan_ssr_shutdown_event(void)
{
	WLAN_VOS_DIAG_EVENT_DEF(ssr_shutdown,
					struct host_event_wlan_ssr_shutdown);
	vos_mem_zero(&ssr_shutdown, sizeof(ssr_shutdown));
	ssr_shutdown.status = SSR_SUB_SYSTEM_SHUTDOWN;
	WLAN_VOS_DIAG_EVENT_REPORT(&ssr_shutdown,
					EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM);
}
#else
static inline void hdd_wlan_ssr_shutdown_event(void)
{

};
#endif

/* the HDD interface to WLAN driver shutdown,
 * the primary shutdown function in SSR
 */
VOS_STATUS hdd_wlan_shutdown(void)
{
   VOS_STATUS       vosStatus;
   v_CONTEXT_t      pVosContext = NULL;
   hdd_context_t    *pHddCtx = NULL;
   pVosSchedContext vosSchedContext = NULL;

   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);

   /* If SSR never completes, then do kernel panic. */
   hdd_ssr_timer_init();
   hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);

   /* Get the global VOSS context. */
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if(!pVosContext) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }
   /* Get the HDD context. */
   pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
   if(!pHddCtx) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
      return VOS_STATUS_E_FAILURE;
   }

   pHddCtx->isLogpInProgress = TRUE;
   pHddCtx->isWiphySuspended = FALSE;
   pHddCtx->isSchedScanUpdatePending = FALSE;

   vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE);

   vos_clear_concurrent_session_count();

   hddLog(VOS_TRACE_LEVEL_INFO,
           FL("Invoking packetdump deregistration API"));
   wlan_deregister_txrx_packetdump();

   if (VOS_TIMER_STATE_RUNNING ==
            vos_timer_getCurrentState(&pHddCtx->tdls_source_timer))
      vos_timer_stop(&pHddCtx->tdls_source_timer);

#ifdef FEATURE_BUS_BANDWIDTH
   if (VOS_TIMER_STATE_RUNNING ==
           vos_timer_getCurrentState(&pHddCtx->bus_bw_timer))
   {
      vos_timer_stop(&pHddCtx->bus_bw_timer);
      hdd_rst_tcp_delack(pHddCtx);

      if (pHddCtx->hbw_requested) {
          vos_remove_pm_qos();
          pHddCtx->hbw_requested = false;
      }
   }
#endif

#ifdef IPA_UC_OFFLOAD
   hdd_ipa_uc_ssr_deinit();
#endif

   hdd_reset_all_adapters(pHddCtx);
   vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
   }

   /* Disable IMPS/BMPS as we do not want the device to enter any power
    * save mode on its own during reset sequence
    */
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);

   vosSchedContext = get_vos_sched_ctxt();

   /* Wakeup all driver threads */
   if(TRUE == pHddCtx->isMcThreadSuspended){
      complete(&vosSchedContext->ResumeMcEvent);
      pHddCtx->isMcThreadSuspended= FALSE;
   }
#ifdef QCA_CONFIG_SMP
   if (TRUE == pHddCtx->isTlshimRxThreadSuspended) {
      complete(&vosSchedContext->ResumeTlshimRxEvent);
      pHddCtx->isTlshimRxThreadSuspended = FALSE;
    }
#endif

   /* Reset the Suspend Variable */
   pHddCtx->isWlanSuspended = FALSE;

   /* Stop all the threads; we do not want any messages to be a processed,
    * any more and the best way to ensure that is to terminate the threads
    * gracefully.
    */
   /* Wait for MC to exit */
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
   set_bit(MC_SHUTDOWN_EVENT, &vosSchedContext->mcEventFlag);
   set_bit(MC_POST_EVENT, &vosSchedContext->mcEventFlag);
   wake_up_interruptible(&vosSchedContext->mcWaitQueue);
   wait_for_completion(&vosSchedContext->McShutdown);

#ifdef QCA_CONFIG_SMP
   /* Wait for TLshim RX to exit */
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TLshim RX thread",
          __func__);
   //unregister_hotcpu_notifier(vosSchedContext->cpuHotPlugNotifier);
   set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->tlshimRxEvtFlg);
   set_bit(RX_POST_EVENT, &vosSchedContext->tlshimRxEvtFlg);
   wake_up_interruptible(&vosSchedContext->tlshimRxWaitQueue);
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Waiting for TLshim RX thread to exit",
          __func__);
   wait_for_completion(&vosSchedContext->TlshimRxShutdown);
   vosSchedContext->TlshimRxThread = NULL;
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Waiting for dropping RX packets",
          __func__);
   vos_drop_rxpkt_by_staid(vosSchedContext, WLAN_MAX_STA_COUNT);
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Waiting for freeing freeQ", __func__);
   vos_free_tlshim_pkt_freeq(vosSchedContext);
#endif

   tl_shim_flush_cache_rx_queue();

   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing WDA STOP", __func__);
   vosStatus = WDA_stop(pVosContext, HAL_STOP_TYPE_RF_KILL);

   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: Failed to stop WDA", __func__);
      VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
      WDA_setNeedShutdown(pVosContext);
   }

   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
   /* Stop SME - Cannot invoke vos_stop as vos_stop relies
    * on threads being running to process the SYS Stop
    */
   vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to stop sme %d", __func__, vosStatus);
       VOS_ASSERT(0);
   }

   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
   /* Stop MAC (PE and HAL) */
   vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to stop mac %d", __func__, vosStatus);
       VOS_ASSERT(0);
   }

   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
   /* Stop TL */
   vosStatus = WLANTL_Stop(pVosContext);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to stop TL %d", __func__, vosStatus);
       VOS_ASSERT(0);
   }

   hdd_unregister_mcast_bcast_filter(pHddCtx);

   hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
   /* Clean up message queues of TX, RX and MC thread */
   vos_sched_flush_mc_mqs(vosSchedContext);

   /* Deinit all the TX, RX and MC queues */
   vos_sched_deinit_mqs(vosSchedContext);

   hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
   /* shutdown VOSS */
   vos_shutdown(pVosContext);

   /*mac context has already been released in mac_close call
     so setting it to NULL in hdd context*/
   pHddCtx->hHal = (tHalHandle)NULL;

   if (free_riva_power_on_lock("wlan"))
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
                                           __func__);
   }

#ifdef WLAN_FEATURE_LPSS
   wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
#endif

   hdd_wlan_ssr_shutdown_event();
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
                                   ,__func__);
   return VOS_STATUS_SUCCESS;
}

/**
 * hdd_ssr_restart_sap() - restart sap on SSR
 * @hdd_ctx:   hdd context
 *
 * Return:     nothing
 */
static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx)
{
	VOS_STATUS       status;
	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
	hdd_adapter_t *adapter;

	ENTER();

	status =  hdd_get_front_adapter (hdd_ctx, &adapter_node);
	while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
		adapter = adapter_node->pAdapter;
		if (adapter && adapter->device_mode == WLAN_HDD_SOFTAP) {
			if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) {
				hddLog(VOS_TRACE_LEVEL_INFO, FL("Restart prev SAP session"));
				wlan_hdd_start_sap(adapter, true);
			}
		}
		status = hdd_get_next_adapter ( hdd_ctx, adapter_node, &next );
		adapter_node = next;
	}

	EXIT();
}

#ifdef FEATURE_WLAN_DIAG_SUPPORT
/**
 * hdd_wlan_ssr_reinit_event - Send ssr reinit status
 *
 * This function sends ssr reinit status diag event
 *
 * Return: void.
 */
static void hdd_wlan_ssr_reinit_event(void)
{
	WLAN_VOS_DIAG_EVENT_DEF(ssr_reinit, struct host_event_wlan_ssr_reinit);
	vos_mem_zero(&ssr_reinit, sizeof(ssr_reinit));
	ssr_reinit.status = SSR_SUB_SYSTEM_REINIT;
	WLAN_VOS_DIAG_EVENT_REPORT(&ssr_reinit,
					EVENT_WLAN_SSR_REINIT_SUBSYSTEM);
}
#else
static void hdd_wlan_ssr_reinit_event(void)
{

};
#endif

/* the HDD interface to WLAN driver re-init.
 * This is called to initialize/start WLAN driver after a shutdown.
 */
VOS_STATUS hdd_wlan_re_init(void *hif_sc)
{
   VOS_STATUS       vosStatus;
   v_CONTEXT_t      pVosContext = NULL;
   hdd_context_t    *pHddCtx = NULL;
   eHalStatus       halStatus;
   bool             bug_on_reinit_failure = 0;
   hdd_adapter_t *pAdapter;
   int i;
   hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);

   vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);

   /* Get the VOS context */
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if(pVosContext == NULL)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed vos_get_global_context",
             __func__);
      goto err_re_init;
   }

   /* Get the HDD context */
   pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
   if(!pHddCtx)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is Null", __func__);
      goto err_re_init;
   }
   bug_on_reinit_failure = pHddCtx->cfg_ini->bug_on_reinit_failure;

   if (!hif_sc) {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hif_sc is NULL", __func__);
      goto err_re_init;
   }

   ((VosContextType*)pVosContext)->pHIFContext = hif_sc;

   /* The driver should always be initialized in STA mode after SSR */
   if (VOS_STA_SAP_MODE != hdd_get_conparam())
       hdd_set_conparam(0);

   /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
   vosStatus = vos_open(&pVosContext, 0);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
      goto err_re_init;
   }

#if  !defined(REMOVE_PKT_LOG)
      hif_init_pdev_txrx_handle(hif_sc,
      vos_get_context(VOS_MODULE_ID_TXRX, pVosContext));
#endif

   /* Save the hal context in Adapter */
   pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
   if ( NULL == pHddCtx->hHal )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
      goto err_vosclose;
   }

   /* Set the SME configuration parameters. */
   vosStatus = hdd_set_sme_config(pHddCtx);
   if ( VOS_STATUS_SUCCESS != vosStatus )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
      goto err_vosclose;
   }

   vosStatus = vos_preStart( pHddCtx->pvosContext );
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
      goto err_vosclose;
   }

   hdd_set_dfs_regdomain(pHddCtx,true);

   vosStatus = hdd_set_sme_chan_list(pHddCtx);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
      hddLog(VOS_TRACE_LEVEL_FATAL,
             "%s: Failed to init channel list", __func__);
      goto err_vosclose;
   }

   /* 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   */
   /* Apply the cfg.ini to cfg.dat */
   if (FALSE == hdd_update_config_dat(pHddCtx))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
      goto err_vosclose;
   }

   /* Set the MAC Address, currently this is used by HAL to add self sta.
    * Remove this once self sta is added as part of session open. */
   halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
         (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
           sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
   if (!HAL_STATUS_SUCCESS(halStatus))
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
            "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
      goto err_vosclose;
   }

   /*
    * Invoke ipa reinit before vos_start so that doorbell registers are
    * updated
    */
#ifdef IPA_UC_OFFLOAD
   if (hdd_ipa_uc_ssr_reinit(pHddCtx))
      hddLog(LOGE, "%s: HDD IPA UC reinit failed", __func__);
#endif

   /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
      Note: Firmware image will be read and downloaded inside vos_start API */
   vosStatus = vos_start( pVosContext );
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
      goto err_vosclose;
   }

   vosStatus = hdd_post_voss_start_config( pHddCtx );
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
         __func__);
      goto err_vosstop;
   }

   /* Try to get an adapter from mode ID */
   pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
   if (!pAdapter) {
      pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
      if (!pAdapter) {
        pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
        if (!pAdapter) {
           hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to get Adapter!",
                  __func__);
        }
     }
   }

   /* Get WLAN Host/FW/HW version */
   if (pAdapter)
      hdd_wlan_get_version(pAdapter, NULL, NULL);

   /* Pass FW version to HIF layer */
   hif_set_fw_info(hif_sc, pHddCtx->target_fw_version);

   wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
                               WLAN_SVC_FW_CRASHED_IND, NULL, 0);

   /* Restart all adapters */
   hdd_start_all_adapters(pHddCtx);

   /* Reconfigure FW logs after SSR */
   if (pAdapter) {
      if (pHddCtx->fw_log_settings.enable != 0) {
         process_wma_set_command(pAdapter->sessionId,
                                 WMI_DBGLOG_MODULE_ENABLE,
                                 pHddCtx->fw_log_settings.enable , DBG_CMD);
      } else {
         process_wma_set_command(pAdapter->sessionId,
                                 WMI_DBGLOG_MODULE_DISABLE,
                                 pHddCtx->fw_log_settings.enable, DBG_CMD);
      }

      if (pHddCtx->fw_log_settings.dl_report != 0) {
         process_wma_set_command(pAdapter->sessionId,
                                 WMI_DBGLOG_REPORT_ENABLE,
                                 pHddCtx->fw_log_settings.dl_report, DBG_CMD);

         process_wma_set_command(pAdapter->sessionId,
                                 WMI_DBGLOG_TYPE,
                                 pHddCtx->fw_log_settings.dl_type, DBG_CMD);

         process_wma_set_command(pAdapter->sessionId,
                                 WMI_DBGLOG_LOG_LEVEL,
                                 pHddCtx->fw_log_settings.dl_loglevel, DBG_CMD);

         for (i = 0; i < MAX_MOD_LOGLEVEL; i++) {
            if (pHddCtx->fw_log_settings.dl_mod_loglevel[i] != 0) {
               process_wma_set_command(pAdapter->sessionId,
                                 WMI_DBGLOG_MOD_LOG_LEVEL,
                                 pHddCtx->fw_log_settings.dl_mod_loglevel[i],
                                 DBG_CMD);
            }
         }
      }
   }

   /* Register TM level change handler function to the platform */
   hddDevTmRegisterNotifyCallback(pHddCtx);

   pHddCtx->last_scan_reject_session_id = 0xFF;
   pHddCtx->last_scan_reject_reason = 0;
   pHddCtx->last_scan_reject_timestamp = 0;
   pHddCtx->scan_reject_cnt = 0;

   pHddCtx->hdd_mcastbcast_filter_set = FALSE;
   pHddCtx->btCoexModeSet = false;
   hdd_register_mcast_bcast_filter(pHddCtx);

   /* Allow the phone to go to sleep */
   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
   /* register for riva power on lock */
   if (req_riva_power_on_lock("wlan"))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
                                        __func__);
      goto err_unregister_pmops;
   }
   vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);

   sme_register_mgmt_frame_ind_callback(pHddCtx->hHal, hdd_indicate_mgmt_frame);

   /* Register for p2p ack indication */
   sme_register_p2p_ack_ind_callback(pHddCtx->hHal, hdd_send_action_cnf_cb);

#ifdef FEATURE_WLAN_EXTSCAN
   sme_ExtScanRegisterCallback(pHddCtx->hHal,
                               wlan_hdd_cfg80211_extscan_callback);
#endif /* FEATURE_WLAN_EXTSCAN */
   sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached);
   wlan_hdd_cfg80211_link_layer_stats_init(pHddCtx);
   sme_bpf_offload_register_callback(pHddCtx->hHal, hdd_get_bpf_offload_cb);

#ifdef WLAN_FEATURE_LPSS
   wlan_hdd_send_all_scan_intf_info(pHddCtx);
   wlan_hdd_send_version_pkg(pHddCtx->target_fw_version,
                             pHddCtx->target_hw_version,
                             pHddCtx->target_hw_name);
#endif
   /* set chip power save failure detected callback */
   sme_set_chip_pwr_save_fail_cb(pHddCtx->hHal,
                                 hdd_chip_pwr_save_fail_detected_cb);

   ol_pktlog_init(hif_sc);
   goto success;

err_unregister_pmops:
#ifdef CONFIG_HAS_EARLYSUSPEND
   hdd_unregister_mcast_bcast_filter(pHddCtx);
#endif

err_vosstop:
   vos_stop(pVosContext);

err_vosclose:
   vos_close(pVosContext);
   vos_sched_close(pVosContext);

#ifdef MEMORY_DEBUG
   adf_net_buf_debug_exit();
   vos_mem_exit();
#endif

err_re_init:
   if (bug_on_reinit_failure)
      VOS_BUG(0);
   else {
      pr_err("SSR fails during reinit hence doing cleanup");
      /* Stop SSR timer */
      hdd_ssr_timer_del();
      if (pHddCtx) {
         /* Unregister all Net Device Notifiers */
         wlan_hdd_netdev_notifiers_cleanup(pHddCtx);
         /* Clean up HDD Nlink Service */
         nl_srv_exit();
         hdd_runtime_suspend_deinit(pHddCtx);
         hdd_close_all_adapters(pHddCtx);
         /* Free up dynamically allocated members
          * inside HDD Adapter
          */
         vos_mem_free(pHddCtx->cfg_ini);
         pHddCtx->cfg_ini= NULL;
         /* Destroy all wakelocks */
         wlan_hdd_wakelocks_destroy(pHddCtx);
         wlan_hdd_deinit_tx_rx_histogram(pHddCtx);
         wiphy_unregister(pHddCtx->wiphy);
         wiphy_free(pHddCtx->wiphy);
      }
   }
   vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
   vos_preClose(&pVosContext);
   /* Allow the phone to go to sleep */
   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
   hdd_wlan_wakelock_destroy();
   return -EPERM;
success:
   hdd_wlan_ssr_reinit_event();
   if (pHddCtx->cfg_ini->sap_internal_restart)
       hdd_ssr_restart_sap(pHddCtx);
   pHddCtx->isLogpInProgress = FALSE;
   hdd_ssr_timer_del();
   return VOS_STATUS_SUCCESS;
}
