/*
 * 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;
}
