/*
 * 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 <linux/pm.h>
#include <linux/wait.h>
#include <wlan_hdd_includes.h>
#include <wlan_qct_driver.h>

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && \
    defined(WLAN_OPEN_SOURCE)
#include <linux/device.h>
#include <linux/pm_wakeup.h>
#else
#include <linux/wakelock.h>
#endif

#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_btc_svc.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 "wlan_qct_wda.h"

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

#ifdef WLAN_BTAMP_FEATURE
#include "bapApi.h"
#include "bap_hdd_main.h"
#include "bap_hdd_misc.h"
#endif

#include <linux/wcnss_wlan.h>
#include <linux/inetdevice.h>
#include <wlan_hdd_cfg.h>
#include <wlan_hdd_cfg80211.h>
#include <net/addrconf.h>
/**-----------------------------------------------------------------------------
*   Preprocessor definitions and constants
* ----------------------------------------------------------------------------*/

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

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

#define HDD_SSR_BRING_UP_TIME 180000
#define NS_DEFAULT_SLOT_INDEX 4
#define NS_EXTENDED_SLOT_INDEX 18

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;

void inline check_and_set_suspend_resume_mcbc_filter(hdd_context_t *pHddCtx)
{
    hddLog(VOS_TRACE_LEVEL_INFO,
       FL("offload: sus_res_mcbc_filter_valid: %d sus_res_mcbc_filter: %d configuredMcBcFilter: %d"),
       pHddCtx->sus_res_mcastbcast_filter_valid,
       pHddCtx->sus_res_mcastbcast_filter,
       pHddCtx->configuredMcastBcastFilter);
    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,
           FL("offload: saving sus_res_mcastbcast_filter = %d"),
           pHddCtx->sus_res_mcastbcast_filter);
    }
}

#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_OFFLOAD_REQ);
}
#endif /* FEATURE_WLAN_DIAG_SUPPORT */

//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;
    long ret;

    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
      ret = wait_for_completion_interruptible_timeout(
                 &pHddCtx->full_pwr_comp_var,
                  msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
      if (0 >= ret)
      {
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
                 __func__, ret);
      }
      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;
   long ret;

   //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
      ret = wait_for_completion_interruptible_timeout(
                      &pHddCtx->full_pwr_comp_var,
                       msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
      if (0 >= ret)
      {
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
                __func__, ret);
      }

      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
      ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
         msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
      if (0 >= ret)
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                 FL("wait on standby_comp_var failed %ld"), ret);
      }
      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;
   long ret;

   //Stop the Interface TX queue.
   hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
   netif_tx_disable(pAdapter->dev);
   netif_carrier_off(pAdapter->dev);

   //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
      ret = wait_for_completion_interruptible_timeout(
                    &pHddCtx->full_pwr_comp_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
      if (0 >= ret)
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("wait on full_pwr_comp_var failed %ld"), ret);
      }
      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.
      ret = wait_for_completion_interruptible_timeout(
                     &pAdapter->disconnect_comp_var,
                      msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
      if (0 >= ret)
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("wait on disconnect_comp_var failed %ld"), ret);
      }
   }


   //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);
       if (isSsrPanicOnFailure())
           VOS_BUG(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;

   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__);
      if (isSsrPanicOnFailure())
          VOS_BUG(0);
      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;
   }


   //Open a SME session for future operation
   halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
                                (tANI_U8 *)&pAdapter->macAddressCurrent,
                                &pAdapter->sessionId);
   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;

}

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;

    ENTER();
    if (NULL == pAdapter)
    {
        hddLog(LOGE, FL("Adapter is invalid"));
        return;
    }

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

    if ((eConnectionState_Associated ==
                (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
        && (pHddCtx->hdd_wlan_suspended))
    {
        check_and_set_suspend_resume_mcbc_filter(pHddCtx);
        // This invocation being part of the IPv6 registration callback,
        // set the newly generated ip address to f/w in suspend mode.
#ifdef WLAN_NS_OFFLOAD
        if (pHddCtx->cfg_ini->fhostNSOffload)
        {
            hdd_conf_ns_offload(pAdapter, 1);
        }
#endif
    }
#ifdef WLAN_FEATURE_PACKET_FILTERING
    /* wlan_hdd_set_mc_addr_list() is called from the early suspend
     * only so when new ipv6 address is generated the screen may not
     * on so we need to call it here to update the list in f/w.
     */
    wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
#endif
    EXIT();
}

void hdd_ipv6_notifier_work_queue(struct work_struct *work)
{
     vos_ssr_protect(__func__);
     __hdd_ipv6_notifier_work_queue(work);
     vos_ssr_unprotect(__func__);
}
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_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_context_t *pHddCtx;
    VOS_STATUS vos_status;
    int status;

    ENTER();
    pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return NOTIFY_DONE;
    }

    vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
    while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
    {
        if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
             (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
              pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
        {

            if (eConnectionState_Associated ==
               WLAN_HDD_GET_STATION_CTX_PTR
               (pAdapterNode->pAdapter)->conn_info.connState)
                 sme_dhcp_done_ind(pHddCtx->hHal,
                       pAdapterNode->pAdapter->sessionId);
            if (pHddCtx->cfg_ini->nEnableSuspend ==
                  WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
            {
                schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
            }
            else
            {
                hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
                             pHddCtx->cfg_ini->nEnableSuspend);
            }
            break;
        }
        vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }
    EXIT();
    return NOTIFY_DONE;
}

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

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

    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) &&
       (pHddCtx->is_ap_mode_wow_supported)))
    {
        if (fenable)
        {
            if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
                (eConnectionState_Associated ==
                (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
                || (WLAN_HDD_SOFTAP == pAdapter->device_mode))
            {
                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);
                    }
                }
                //Configure GTK_OFFLOAD
#ifdef WLAN_FEATURE_GTK_OFFLOAD
                hdd_conf_gtk_offload(pAdapter, fenable);
#endif

#ifdef WLAN_NS_OFFLOAD
                if (pHddCtx->cfg_ini->fhostNSOffload)
                {
                    /*
                     * 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

            }
        }
        else
        {
            //Disable ARPOFFLOAD
            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);
                }
            }
            //Disable GTK_OFFLOAD
#ifdef WLAN_FEATURE_GTK_OFFLOAD
            hdd_conf_gtk_offload(pAdapter, fenable);
#endif

#ifdef WLAN_NS_OFFLOAD
            //Disable NSOFFLOAD
            if (pHddCtx->cfg_ini->fhostNSOffload)
            {
                hdd_conf_ns_offload(pAdapter, fenable);
            }
            else
            {
                hddLog(VOS_TRACE_LEVEL_INFO,
                    FL("ns offload ini is disabled"));
            }
#endif
        }
    }
    return;
}


#ifdef WLAN_NS_OFFLOAD
/**----------------------------------------------------------------------------

  \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;
    struct inet6_ifaddr *ifp;
    struct list_head *p;
    int slot_index = NS_DEFAULT_SLOT_INDEX;
    tANI_U8 **selfIPv6Addr = NULL;
    tANI_U8 *selfIPv6AddrValid = NULL;
    tSirHostOffloadReq offLoadRequest;
    hdd_context_t *pHddCtx;
    tHalHandle halHandle;

    int i = 0, slot = 0;
    int ret = 0;
    eHalStatus returnStatus;

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

    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
        return;
    }

    halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return;
    }

    if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
    {
        slot_index = NS_EXTENDED_SLOT_INDEX;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);

    selfIPv6AddrValid =
            (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);

    if (NULL == selfIPv6AddrValid)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
                                         " selfIPv6AddrValid"));
        goto end;
    }

    vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));

    selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);

    if (NULL == selfIPv6Addr)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
                                         " selfIPv6Addr"));
        goto end;
    }

    vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));

    for (slot = 0; slot < slot_index; slot++)
    {
        selfIPv6Addr[slot] =
           (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
        if (NULL == selfIPv6Addr[slot])
        {
            hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
                                              "for selfIPv6Addr"));
            goto end;
        }
        vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
    }

    i = 0;

    if (fenable)
    {
        in6_dev = __in6_dev_get(pAdapter->dev);
        if (NULL != in6_dev)
        {
            read_lock_bh(&in6_dev->lock);
            list_for_each(p, &in6_dev->addr_list)
            {
                if (i >= slot_index)
                {
                    hddLog (VOS_TRACE_LEVEL_ERROR,
                            FL("IPv6 address list is greater than IPv6"
                               "address supported by firmware"));
                    hddLog (VOS_TRACE_LEVEL_ERROR,
                            FL("FW supported IPv6 address = %d"), slot_index);
                    break;
                }
                ifp = list_entry(p, struct inet6_ifaddr, if_list);
                switch(ipv6_addr_src_scope(&ifp->addr))
                {
                    case IPV6_ADDR_SCOPE_LINKLOCAL:
                        vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
                                sizeof(ifp->addr.s6_addr));
                        selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
                        hddLog (VOS_TRACE_LEVEL_INFO,
                           FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
                               selfIPv6Addr[i]);
                        break;
                    case IPV6_ADDR_SCOPE_GLOBAL:
                        vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
                                sizeof(ifp->addr.s6_addr));
                        selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
                        hddLog (VOS_TRACE_LEVEL_INFO,
                           FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
                               selfIPv6Addr[i]);
                        break;
                    default:
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                           FL("The Scope %d is not supported"),
                               ipv6_addr_src_scope(&ifp->addr));
                }
                if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
                {
                    i++;
                }
            }
            /* store actual slots being used */
            pAdapter->ns_slots = i;
            read_unlock_bh(&in6_dev->lock);

            vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
            for (i =0; i < slot_index; i++)
            {
                if (selfIPv6AddrValid[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:XX
                     *
                     * here XX is the unicast/anycast bits
                     */
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
                                                          selfIPv6Addr[i][13];
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
                                                          selfIPv6Addr[i][14];
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
                                                          selfIPv6Addr[i][15];
                    offLoadRequest.nsOffloadInfo.slotIdx = i;

                    vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
                        selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
                    vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
                                &pAdapter->macAddressCurrent.bytes,
                                sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);

                    offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
                                                          SIR_IPV6_ADDR_VALID;
                    offLoadRequest.offloadType =  SIR_IPV6_NS_OFFLOAD;
                    offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
                    hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
                                                     SIR_OFFLOAD_ENABLE);

                    hddLog (VOS_TRACE_LEVEL_INFO,
                       FL("configuredMcastBcastFilter: %d"
                       "NSOffload Slot = %d"),
                       pHddCtx->configuredMcastBcastFilter, i);

                    if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
                        && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
                             pHddCtx->sus_res_mcastbcast_filter) ||
                            (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
                             pHddCtx->sus_res_mcastbcast_filter)) &&
                        (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
                         (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
                          !(pHddCtx->cfg_ini->fEnableMCAddrList))))
                    {
                        offLoadRequest.enableOrDisable =
                            SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
                    }
                    hdd_wlan_offload_event(
                                  SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE,
                                  SIR_OFFLOAD_ENABLE);
                    hddLog(VOS_TRACE_LEVEL_INFO,
                        FL("offload: NS filter programmed %d"),
                        offLoadRequest.enableOrDisable);
                    vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
                                &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
                                sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);

                    hddLog (VOS_TRACE_LEVEL_INFO,
                    FL("Setting NSOffload with solicitedIp: %pI6,"
                       "targetIp: %pI6"),
                    offLoadRequest.nsOffloadInfo.selfIPv6Addr,
                    offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);

                    //Configure the Firmware with this
                    returnStatus = sme_SetHostOffload(halHandle,
                                    pAdapter->sessionId, &offLoadRequest);
                    if(eHAL_STATUS_SUCCESS != returnStatus)
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                        FL("Failed to enable HostOffload feature with"
                           " status: %d"), returnStatus);
                    }
                    vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
                }
            }
        }
        else
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("IPv6 dev does not exist. Failed to request NSOffload"));
              goto end;
        }
    }
    else
    {
        //Disable NSOffload
        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);

        for (i = 0; i <  pAdapter->ns_slots; i++)
        {
            hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
            offLoadRequest.nsOffloadInfo.slotIdx = i;
            if (eHAL_STATUS_SUCCESS !=
                 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                 pAdapter->sessionId, &offLoadRequest))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
                                                 " %d Slot"), i);
            }
        }
        pAdapter->ns_slots = 0;
    }
end:
    while (slot > 0 && selfIPv6Addr[--slot])
    {
       vos_mem_free(selfIPv6Addr[slot]);
    }
    if (selfIPv6Addr)
    {
       vos_mem_free(selfIPv6Addr);
    }
    if (selfIPv6AddrValid)
    {
       vos_mem_free(selfIPv6AddrValid);
    }
    EXIT();
    return;
}
#endif

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;

    ENTER();
    if (NULL == pAdapter)
    {
        hddLog(LOGE, FL("Adapter is invalid"));
        return;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return;
    }

    if ((eConnectionState_Associated ==
                (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
        && (pHddCtx->hdd_wlan_suspended))
    {
        // This invocation being part of the IPv4 registration callback,
        // we are passing second parameter as 2 to avoid registration
        // of IPv4 notifier again.
        check_and_set_suspend_resume_mcbc_filter(pHddCtx);
        if (pHddCtx->cfg_ini->fhostArpOffload)
        {
            hdd_conf_arp_offload(pAdapter, 2);
        }
        else
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                    FL("offload: arp offload ini is disabled in host"));
        }
    }
    EXIT();
}

void hdd_ipv4_notifier_work_queue(struct work_struct *work)
{
    vos_ssr_protect(__func__);
    __hdd_ipv4_notifier_work_queue(work);
    vos_ssr_unprotect(__func__);
}

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_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_context_t *pHddCtx;
    VOS_STATUS vos_status;
    int status;

    ENTER();
    pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return NOTIFY_DONE;
    }

    vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
    while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
    {
        if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
             (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
              pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
        {

            if (eConnectionState_Associated ==
               WLAN_HDD_GET_STATION_CTX_PTR
               (pAdapterNode->pAdapter)->conn_info.connState)
                 sme_dhcp_done_ind(pHddCtx->hHal,
                       pAdapterNode->pAdapter->sessionId);
            if ((pHddCtx->cfg_ini->nEnableSuspend !=
                  WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
               || (!pHddCtx->cfg_ini->fhostArpOffload))
            {
                hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
                              pHddCtx->cfg_ini->nEnableSuspend,
                              pHddCtx->cfg_ini->fhostArpOffload);
                return NOTIFY_DONE;
            }

            if ((in_dev =
                  __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
            {
                for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
                       ifap = &ifa->ifa_next)
                {
                    if (!strcmp(pAdapterNode->pAdapter->dev->name,
                          ifa->ifa_label))
                    {
                        break; /* found */
                    }
                }
            }
            if(ifa && ifa->ifa_local)
            {
                schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
            }
            break;
        }
        vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }
    EXIT();
    return NOTIFY_DONE;
}

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(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);

   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_WARN, FL("IP Address is not assigned"));
           return VOS_STATUS_E_AGAIN;
       }

       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

    if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
    {
        *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
    }

    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);
}

/*
 * Enable/Disable McAddrList cfg item in fwr.
 */
eHalStatus hdd_set_mc_list_cfg_item(hdd_context_t* pHddCtx,
                bool value)
{
    eHalStatus ret_val;

    if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST,
        value, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
    {
       ret_val = eHAL_STATUS_FAILURE;
       hddLog(LOGE,
           FL("offload: can't pass WNI_CFG_ENABLE_MC_ADDR_LIST to CCM"));
       return ret_val;
    }

    ret_val = sme_update_cfg_int_param(pHddCtx->hHal,
                  WNI_CFG_ENABLE_MC_ADDR_LIST);
    if (!HAL_STATUS_SUCCESS(ret_val))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("Failed to toggle MC_ADDR_LIST_INI %d "),
               ret_val);
        return ret_val;
    }
    /* cache the value configured in fwr */
    pHddCtx->mc_list_cfg_in_fwr = value;
    return eHAL_STATUS_SUCCESS;
}

bool is_mc_list_cfg_disable_required(hdd_context_t* pHddCtx)
{
    hddLog(VOS_TRACE_LEVEL_INFO,
        FL("offload: fEnableMCList %d sus_res_mcbc_filter %d mc_list_in_fwr %d"),
        pHddCtx->cfg_ini->fEnableMCAddrList,
        pHddCtx->sus_res_mcastbcast_filter,
        pHddCtx->mc_list_cfg_in_fwr);

    /*
     * If MCAddrList is enabled in ini and MCBC filter is set to
     * Either Filter None or Filter all BC then, Fwr need to push
     * all MC to host. This can be achieved by disabling cfg MCAddrList
     * in fwr. As in driver load, firmware have this value to 1 we
     * need to set it to 0. Same needs to be reverted on resume.
     */
    if (pHddCtx->cfg_ini->fEnableMCAddrList &&
         WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
         ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)&&
            ((HDD_MCASTBCASTFILTER_FILTER_NONE ==
                 pHddCtx->sus_res_mcastbcast_filter) ||
              (HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
                 pHddCtx->sus_res_mcastbcast_filter)))
       )
    {
        hddLog(VOS_TRACE_LEVEL_INFO,
            FL("offload: cfg ini need to disable in fwr"));
        return true;
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_INFO,
            FL("offload: cfg ini disable not needed "));
        return false;
    }
}

/**
 * hdd_mc_addr_list_cfg_config() - To set mc list cfg configuration in fwr
 * @pHddCtx: hdd context handle
 * @action: true to disable MCAddrList  in fwr to get all MC pkt to host
 *          false to set ini value of MCAddrList in fwr if it was toggled
 * Return: none
 *
 * Ensure Below API is invoked always post modification
 * of sus_res_mcastbcast_filter.
 */
void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action)
{
    if (action)
    {
        /* check host need to disable mc list ini in fwr */
        if (is_mc_list_cfg_disable_required(pHddCtx))
        {
            /*
             * Yes Host should disable the mc list in fwr
             * But Ensure host might already disable it
             * This can happen when user issue set/clear MCBC
             * ioctl with 2 to 0 or vice versa.
             */
            if (pHddCtx->cfg_ini->fEnableMCAddrList ==
                   pHddCtx->mc_list_cfg_in_fwr)
            {
                hdd_set_mc_list_cfg_item(pHddCtx,
                    !pHddCtx->cfg_ini->fEnableMCAddrList);
                hddLog(VOS_TRACE_LEVEL_INFO,
                    FL("offload: setting mc_list_cfg_in_fwr: %d"),
                    !pHddCtx->cfg_ini->fEnableMCAddrList);
            }
        }
        else
        {
           /* Host toggled mc list ini in fwr previosuly, set to ini value */
           if (pHddCtx->cfg_ini->fEnableMCAddrList !=
                  pHddCtx->mc_list_cfg_in_fwr)
           {
               hdd_set_mc_list_cfg_item(pHddCtx,
                   pHddCtx->cfg_ini->fEnableMCAddrList);
               hddLog(VOS_TRACE_LEVEL_INFO,
                   FL("offload: setting mc_list_cfg_in_fwr: %d"),
                   pHddCtx->cfg_ini->fEnableMCAddrList);
           }
        }
    }
    else
    {
       /* Host toggled mc list ini in fwr previosuly, set to ini value */
       if (pHddCtx->cfg_ini->fEnableMCAddrList !=
              pHddCtx->mc_list_cfg_in_fwr)
       {
           hdd_set_mc_list_cfg_item(pHddCtx,
               pHddCtx->cfg_ini->fEnableMCAddrList);
           hddLog(VOS_TRACE_LEVEL_INFO,
               FL("offload: setting mc_list_cfg_in_fwr: %d"),
               pHddCtx->cfg_ini->fEnableMCAddrList);
       }
    }
}

/**
 * hdd_suspend_ind_callback: This API will set completion event for suspend
 * @pAdapter: hdd_adapter_t
 * @status: suspend status
 *
 * Return: none
 */
static void hdd_suspend_ind_callback(void *context, VOS_STATUS status)
{
    hdd_adapter_t *adapter = (hdd_adapter_t *)context;
    if (NULL == adapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: HDD adapter is NULL",__func__);
        return;
    }
    hddLog(VOS_TRACE_LEVEL_INFO, FL("suspend status %d"), status);
    complete(&adapter->wlan_suspend_comp_var);
}

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

    check_and_set_suspend_resume_mcbc_filter(pHddCtx);
    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;
        hddLog(VOS_TRACE_LEVEL_INFO,
              FL("saving configuredMcastBcastFilterSetting = %d"),
              wlanSuspendParam->configuredMcstBcstFilterSetting);
#ifdef WLAN_FEATURE_PACKET_FILTERING
        /* During suspend, configure MC Addr list filter to the firmware
         * function takes care of checking necessary conditions before
         * configuring.
         */
        wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
#endif

        if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
        {

            hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
            pHddCtx->configuredMcastBcastFilter &=
                ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
        }

        wlanSuspendParam->configuredMcstBcstFilterSetting =
            pHddCtx->configuredMcastBcastFilter;

        wlanSuspendParam->wlan_sus_callback = hdd_suspend_ind_callback;
        wlanSuspendParam->context = pAdapter;
        /* mc add list cfg item configuration in fwr */
        hdd_mc_addr_list_cfg_config(pHddCtx, true);

    }

    halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
    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)
{
    eHalStatus halStatus = eHAL_STATUS_FAILURE;
    hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tpSirWlanResumeParam wlanResumeParam;

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

    wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));

    if (NULL == wlanResumeParam)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
             "%s: memory allocation failed for wlanResumeParam ", __func__);
        return;
    }

    //Disable supported OffLoads
    hdd_conf_hostoffload(pAdapter, FALSE);

    wlanResumeParam->configuredMcstBcstFilterSetting =
                               pHddCtx->configuredMcastBcastFilter;
    halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
    if (eHAL_STATUS_SUCCESS != halStatus)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
              "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
        vos_mem_free(wlanResumeParam);
    }

    pHddCtx->hdd_mcastbcast_filter_set = FALSE;
    /* mc add list cfg item configuration in fwr */
    hdd_mc_addr_list_cfg_config(pHddCtx, 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 WLAN_FEATURE_PACKET_FILTERING
    /* Filer was applied during suspend inditication
     * clear it when we resume.
     */
    wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
#endif
}

//Suspend routine registered with Android OS
void hdd_suspend_wlan(void)
{
   hdd_context_t *pHddCtx = NULL;
   v_CONTEXT_t pVosContext = NULL;
   long ret;
   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;
   }

   if (pHddCtx->hdd_wlan_suspended)
   {
      hddLog(VOS_TRACE_LEVEL_INFO,
             "%s: Ignore suspend wlan, Already suspended!", __func__);
      return;
   }

   pHddCtx->hdd_wlan_suspended = TRUE;
   hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
   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) )

       {  // we skip this registration for modes other than STA, SAP and P2P client modes.
           status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
           pAdapterNode = pNext;
           continue;
       }
       dev_hold(pAdapter->dev);
       /* 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(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
          netif_tx_disable(pAdapter->dev);
          netif_carrier_off(pAdapter->dev);
       }
       else if (pHddCtx->cfg_ini->nEnableSuspend ==
               WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
       {
          //Execute deep sleep procedure
          hdd_enter_deep_sleep(pHddCtx, pAdapter);
       }
#endif

       INIT_COMPLETION(pAdapter->wlan_suspend_comp_var);
       /*Suspend notification sent down to driver*/
       hdd_conf_suspend_ind(pHddCtx, pAdapter);
       ret = wait_for_completion_interruptible_timeout(
                   &pAdapter->wlan_suspend_comp_var,
                   msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
       if (0 >= ret)
       {
          hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on suspend failed %ld",
                 __func__, ret);
       }
       status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
       dev_put(pAdapter->dev);
       pAdapterNode = pNext;
   }

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

   return;
}

/**
 * @brief hdd_ReConfigSuspendDataClearedDuringRoaming() - Reconfigure the
 * suspend related data which was cleared during roaming in FWR.
 */
void hdd_ReConfigSuspendDataClearedDuringRoaming(hdd_context_t *pHddCtx)

{
    VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
    hdd_adapter_t *pAdapter;
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;

    ENTER();

    spin_lock(&pHddCtx->filter_lock);
    check_and_set_suspend_resume_mcbc_filter(pHddCtx);
    spin_unlock(&pHddCtx->filter_lock);

    hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
    if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Not able to set mcast/bcast filter "));

    vstatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
    //No need to configure GTK Offload from here because it might possible
    //cfg80211_set_rekey_data might not yet came, anyway GTK offload will
    //be handled as part of cfg80211_set_rekey_data processing.
    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vstatus )
    {
        pAdapter = pAdapterNode->pAdapter;
        if( pAdapter &&
        (( pAdapter->device_mode == WLAN_HDD_INFRA_STATION)  ||
          (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)))
        {
            if (pHddCtx->cfg_ini->fhostArpOffload)
            {
                //Configure ARPOFFLOAD
                vstatus = hdd_conf_arp_offload(pAdapter, TRUE);
                if (!VOS_IS_STATUS_SUCCESS(vstatus))
                {
                    hddLog(VOS_TRACE_LEVEL_INFO,
                        FL("Failed to disable ARPOffload Feature %d"), vstatus);
                }
            }
#ifdef WLAN_NS_OFFLOAD
            //Configure NSOFFLOAD
            if (pHddCtx->cfg_ini->fhostNSOffload)
            {
                hdd_conf_ns_offload(pAdapter, TRUE);
            }
#endif
#ifdef WLAN_FEATURE_PACKET_FILTERING
            /* During suspend, configure MC Addr list filter to the firmware
             * function takes care of checking necessary conditions before
             * configuring.
             */
            wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
#endif
        }
        vstatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }
    EXIT();
}

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->cfg_ini->enableModulatedDTIM)
           && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
   {
       pHddCtx->hdd_ignore_dtim_enabled = TRUE;
   }
   spin_lock(&pHddCtx->filter_lock);
   if ((newState == BMPS) &&  pHddCtx->hdd_wlan_suspended)
   {
      check_and_set_suspend_resume_mcbc_filter(pHddCtx);
      spin_unlock(&pHddCtx->filter_lock);
      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 confgured 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)
   {
      pmcRegisterDeviceStateUpdateInd(smeContext,
                                      hdd_PowerStateChangedCB, pHddCtx);
   }
}

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)
   {
      pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
   }
}

#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 successfull", __func__);
        }

    }
    else
    {
        if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
            (0 ==  memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
                     &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
            (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 dissable */
                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 dissable GTK offload, returned %d",
                            __func__, ret);
                    return;
                }
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        "%s: successfully dissabled GTK offload request to HAL",
                        __func__);
            }
        }
    }
    return;
}
#endif /*WLAN_FEATURE_GTK_OFFLOAD*/

void hdd_resume_wlan(void)
{
   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;
   tPmcState pmc_state;
   hdd_adapter_t *first_adapter = 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;
   }

   if (!pHddCtx->hdd_wlan_suspended)
   {
      hddLog(VOS_TRACE_LEVEL_INFO,
             "%s: Ignore resume wlan, Already resumed!", __func__);
      return;
   }

   pHddCtx->hdd_wlan_suspended = FALSE;
   hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);

   /* Get first valid adapter for disable/enable  bmps purpose */
   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
       first_adapter = pAdapterNode->pAdapter;
       if (first_adapter != NULL)
           break;
       status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
       pAdapterNode = pNext;
   }
   pmc_state = pmcGetPmcState(pHddCtx->hHal);
   if (BMPS == pmc_state && first_adapter)
   {
       /* put the device into full power */
       hddLog(VOS_TRACE_LEVEL_INFO,
             "%s: Disaling bmps during resume", __func__);
       wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_ACTIVE);
   }

   /*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) )
       {  // we skip this registration for modes other than STA, SAP and P2P client modes.
            status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
            pAdapterNode = pNext;
            continue;
       }


#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 == pmc_state)
         {
             pHddCtx->hdd_ignore_dtim_enabled = FALSE;
         }
      }

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

   if (BMPS == pmc_state && first_adapter)
   {
       /* put the device into full power */
       hddLog(VOS_TRACE_LEVEL_INFO,
             "%s: Enable bmps during resume", __func__);
      /* put the device back into BMPS */
      wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_AUTO);
   }

#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;
}


/*
 * Based on the ioctl command recieved by HDD, put WLAN driver
 * into the quiet mode. This is the same as the early suspend
 * notification that driver used to listen
 */
void hdd_set_wlan_suspend_mode(bool suspend)
{
    vos_ssr_protect(__func__);
    if (suspend)
        hdd_suspend_wlan();
    else
        hdd_resume_wlan();
    vos_ssr_unprotect(__func__);
}

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__);

#ifdef WCN_PRONTO
    if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
        wcnss_pronto_log_debug_regs();
#endif

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

#ifdef FEATURE_WLAN_DIAG_SUPPORT
/**
 * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state
 *
 * This Function send send ssr shutdown state 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

/**
 * hdd_send_hang_reason() - Send hang reason to the userspace
 *
 * Return: None
 */
static void hdd_send_hang_reason(hdd_context_t *hdd_ctx)
{
	unsigned int reason = 0;

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

	vos_get_recovery_reason(&reason);
	vos_reset_recovery_reason();
	wlan_hdd_send_hang_reason_event(hdd_ctx, reason);
}

/* 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 re-init never happens, then do SSR1 */
   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;
   }

   vos_set_snoc_high_freq_voting(false);
   //Stop the traffic monitor timer
   if ((pHddCtx->cfg_ini->dynSplitscan)&& (VOS_TIMER_STATE_RUNNING ==
                        vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
   {
        vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
   }
   vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
   vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
   vos_flush_work(&pHddCtx->sap_start_work);
   hdd_reset_all_adapters(pHddCtx);

   /* set default value of Tcp delack and stop timer */
   hdd_set_default_stop_delack_timer(pHddCtx);

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

   /* DeRegister with platform driver as client for Suspend/Resume */
   vosStatus = hddDeregisterPmOps(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
   }

   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;
   }
   if(TRUE == pHddCtx->isTxThreadSuspended){
      complete(&vosSchedContext->ResumeTxEvent);
      pHddCtx->isTxThreadSuspended= FALSE;
   }
   if(TRUE == pHddCtx->isRxThreadSuspended){
      complete(&vosSchedContext->ResumeRxEvent);
      pHddCtx->isRxThreadSuspended= FALSE;
   }
   /* 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);
   vosSchedContext->McThread = NULL;

   /* Wait for TX to exit */
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
   set_bit(TX_SHUTDOWN_EVENT, &vosSchedContext->txEventFlag);
   set_bit(TX_POST_EVENT, &vosSchedContext->txEventFlag);
   wake_up_interruptible(&vosSchedContext->txWaitQueue);
   wait_for_completion(&vosSchedContext->TxShutdown);
   vosSchedContext->TxThread = NULL;

   /* Wait for RX to exit */
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
   set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->rxEventFlag);
   set_bit(RX_POST_EVENT, &vosSchedContext->rxEventFlag);
   wake_up_interruptible(&vosSchedContext->rxWaitQueue);
   wait_for_completion(&vosSchedContext->RxShutdown);
   vosSchedContext->RxThread = NULL;

#ifdef WLAN_BTAMP_FEATURE
   vosStatus = WLANBAP_Stop(pVosContext);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Failed to stop BAP",__func__);
   }
#endif //WLAN_BTAMP_FEATURE
   vosStatus = vos_wda_shutdown(pVosContext);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Failed to stop wda %d", __func__, vosStatus);
       VOS_ASSERT(0);
   }

   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 and MC thread */
   vos_sched_flush_mc_mqs(vosSchedContext);
   vos_sched_flush_tx_mqs(vosSchedContext);
   vos_sched_flush_rx_mqs(vosSchedContext);
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
   wlan_logging_flush_pkt_queue();
   /*Free fw dump mem in case of SSR/Shutdown */
   wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
   wlan_free_fwr_mem_dump_buffer();
#endif

   /* Deinit all the TX 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__);
   }
   hdd_wlan_ssr_shutdown_event();
   hdd_send_hang_reason(pHddCtx);
   hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
                                   ,__func__);
   return VOS_STATUS_SUCCESS;
}

int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter)
{
    hdd_config_t *config;
    int status = VOS_STATUS_SUCCESS;
    hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

    config = hdd_ctx->cfg_ini;
    if (NULL == config) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  ("cfg_ini is NULL!!"));
        return -EINVAL;
    }
#ifdef DHCP_SERVER_OFFLOAD
    /* set dhcp server offload */
    if (config->enable_dhcp_srv_offload &&
        sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
        vos_event_reset(&adapter->dhcp_status.vos_event);
        status = wlan_hdd_set_dhcp_server_offload(adapter, true);
        if (!VOS_IS_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      ("HDD DHCP Server Offload Failed!!"));
            return -EINVAL;
        }
        status = vos_wait_single_event(&adapter->dhcp_status.vos_event, 2000);
        if (!VOS_IS_STATUS_SUCCESS(status) ||
            adapter->dhcp_status.dhcp_offload_status)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
                     adapter->dhcp_status.dhcp_offload_status);
            return -EINVAL;
        }
#ifdef MDNS_OFFLOAD
        if (config->enable_mdns_offload) {
            vos_event_reset(&adapter->mdns_status.vos_event);
            status = wlan_hdd_set_mdns_offload(adapter);
            if (VOS_IS_STATUS_SUCCESS(status))
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          ("HDD MDNS Server Offload Failed!!"));
                return -EINVAL;
            }
            status = vos_wait_single_event(&adapter->
                                           mdns_status.vos_event, 2000);
            if (!VOS_IS_STATUS_SUCCESS(status) ||
                adapter->mdns_status.mdns_enable_status ||
                adapter->mdns_status.mdns_fqdn_status ||
                adapter->mdns_status.mdns_resp_status)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
                          adapter->mdns_status.mdns_enable_status,
                          adapter->mdns_status.mdns_fqdn_status,
                          adapter->mdns_status.mdns_resp_status);
                return -EINVAL;
            }
        }
#endif /* MDNS_OFFLOAD */
    } else {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  ("DHCP Disabled ini %d, FW %d"),
                  config->enable_dhcp_srv_offload,
                  sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
    }
#endif /* DHCP_SERVER_OFFLOAD */
    return status;
}

/**
 * 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;
	hdd_hostapd_state_t *hostapd_state;

	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)) {
				hostapd_state =
					WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
				hddLog(VOS_TRACE_LEVEL_INFO, FL("Restart prev SAP session"));
				wlan_hdd_start_sap(adapter);
				if (!VOS_IS_STATUS_SUCCESS(
					hdd_dhcp_mdns_offload(adapter))) {
					vos_event_reset(
						&hostapd_state->vosEvent);
					hddLog(VOS_TRACE_LEVEL_ERROR,
						FL("DHCP/MDNS offload Failed!!"));
					if (VOS_STATUS_SUCCESS ==
					    WLANSAP_StopBss(
					      hdd_ctx->pvosContext)) {
						status = vos_wait_single_event(
							&hostapd_state->vosEvent
								, 10000);
						if (!VOS_IS_STATUS_SUCCESS(
								status)) {
							hddLog(LOGE, FL("SAP Stop Failed"));
							return;
						}
					}
				}
			}
		}
		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 state
*
* This Function send send ssr reinit state 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 inline 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)
{
   VOS_STATUS       vosStatus;
   v_CONTEXT_t      pVosContext = NULL;
   hdd_context_t    *pHddCtx = NULL;
   eHalStatus       halStatus;
#ifdef HAVE_WCNSS_CAL_DOWNLOAD
   int              max_retries = 0;
#endif
#ifdef HAVE_CBC_DONE
   int              max_cbc_retries = 0;
#endif
#ifdef WLAN_BTAMP_FEATURE
   hdd_config_t     *pConfig = NULL;
   WLANBAP_ConfigType btAmpConfig;
#endif

   struct device *dev = NULL;
   hdd_ssr_timer_del();
   hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);

#ifdef HAVE_WCNSS_CAL_DOWNLOAD
   /* wait until WCNSS driver downloads NV */
   while (!wcnss_device_ready() && 10 >= ++max_retries) {
       msleep(1000);
   }
   if (max_retries >= 10) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
      goto err_re_init;
   }
#endif

#ifdef HAVE_CBC_DONE
   while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
       msleep(1000);
   }
   if (max_cbc_retries >= 20) {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
   }
#endif

   vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);

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

   dev = wcnss_wlan_get_device();
   if (NULL == dev)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
      goto err_re_init;
   }

   /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
   vosStatus = vos_open(&pVosContext, dev);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__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_vosclose;
   }

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

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

   /* 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__);
      if (isSsrPanicOnFailure())
          VOS_BUG(0);
      goto err_vosclose;
   }

   /* Exchange capability info between Host and FW and also get versioning info from FW */
   hdd_exchange_version_and_caps(pHddCtx);

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

#ifdef CONFIG_ENABLE_LINUX_REG
   vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
             __func__);
      goto err_vosstop;
   }
#endif

#ifdef WLAN_BTAMP_FEATURE
   vosStatus = WLANBAP_Open(pVosContext);
   if(!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: Failed to open BAP",__func__);
      goto err_vosstop;
   }
   vosStatus = BSL_Init(pVosContext);
   if(!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: Failed to Init BSL",__func__);
     goto err_bap_close;
   }
   vosStatus = WLANBAP_Start(pVosContext);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Failed to start TL",__func__);
       goto err_bap_close;
   }
   pConfig = pHddCtx->cfg_ini;
   btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
   vosStatus = WLANBAP_SetConfig(&btAmpConfig);
#endif //WLAN_BTAMP_FEATURE

    /* Restart all adapters */
   hdd_start_all_adapters(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);
   wlan_hdd_tdls_init(pHddCtx);
   /* Register with platform driver as client for Suspend/Resume */
   vosStatus = hddRegisterPmOps(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
      goto err_bap_stop;
   }

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
   if (pHddCtx->cfg_ini->wlanLoggingEnable &&
               (pHddCtx->cfg_ini->enableFWLogging ||
                pHddCtx->cfg_ini->enableMgmtLogging ||
                pHddCtx->cfg_ini->enableContFWLogging))
   {
       hdd_init_frame_logging(pHddCtx);
   }
#endif

   /* 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;
   }
   sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
   vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);

   sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame);

#ifdef WLAN_FEATURE_EXTSCAN
    sme_EXTScanRegisterCallback(pHddCtx->hHal,
            wlan_hdd_cfg80211_extscan_callback,
                           pHddCtx);
#endif /* WLAN_FEATURE_EXTSCAN */

#ifdef FEATURE_OEM_DATA_SUPPORT
    sme_OemDataRegisterCallback(pHddCtx->hHal,
             wlan_hdd_cfg80211_oemdata_callback,
                          pHddCtx);
#endif /* FEATURE_OEM_DATA_SUPPORT */

   goto success;

err_unregister_pmops:
   hddDeregisterPmOps(pHddCtx);

err_bap_stop:
#ifdef CONFIG_HAS_EARLYSUSPEND
   hdd_unregister_mcast_bcast_filter(pHddCtx);
#endif
   hdd_close_all_adapters(pHddCtx);
#ifdef WLAN_BTAMP_FEATURE
   WLANBAP_Stop(pVosContext);
#endif

#ifdef WLAN_BTAMP_FEATURE
err_bap_close:
   WLANBAP_Close(pVosContext);
#endif

err_vosstop:
   vos_stop(pVosContext);

err_vosclose:
   if(!isSsrPanicOnFailure())
   {
       /* If we hit this, it means wlan driver is in bad state and needs
       * driver unload and load.
       */
       vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
       return VOS_STATUS_E_FAILURE;
   }

   vos_close(pVosContext);
   vos_sched_close(pVosContext);
   if (pHddCtx)
   {
       /* Unregister the Net Device Notifier */
       unregister_netdevice_notifier(&hdd_netdev_notifier);
       /* Clean up HDD Nlink Service */
       send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
#ifdef WLAN_KD_READY_NOTIFIER
       nl_srv_exit(pHddCtx->ptt_pid);
#else
       nl_srv_exit();
#endif /* WLAN_KD_READY_NOTIFIER */
       /* Free up dynamically allocated members inside HDD Adapter */
       kfree(pHddCtx->cfg_ini);
       pHddCtx->cfg_ini= NULL;

       wiphy_unregister(pHddCtx->wiphy);
       hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
       wiphy_free(pHddCtx->wiphy);
   }
   vos_preClose(&pVosContext);

#ifdef MEMORY_DEBUG
   vos_mem_exit();
#endif

err_re_init:
   /* Allow the phone to go to sleep */
   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
   vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
   VOS_BUG(0);
   return -EPERM;

success:
   hdd_wlan_ssr_reinit_event();
   /* Trigger replay of BTC events */
   send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);

   if (pHddCtx->cfg_ini->sap_internal_restart)
       hdd_ssr_restart_sap(pHddCtx);

   return VOS_STATUS_SUCCESS;
}
