/*
 * Copyright (c) 2012-2019 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.
 */

/**========================================================================

  \file  wlan_hdd_p2p.c

  \brief WLAN Host Device Driver implementation for P2P commands interface


  ========================================================================*/

#include <wlan_hdd_includes.h>
#include <wlan_hdd_hostapd.h>
#include <net/cfg80211.h>
#include "sme_Api.h"
#include "sme_QosApi.h"
#include "wlan_hdd_p2p.h"
#include "sapApi.h"
#include "wlan_hdd_main.h"
#include "vos_trace.h"
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <net/ieee80211_radiotap.h>
#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif
#include "wlan_hdd_trace.h"
#include "vos_types.h"
#include "vos_trace.h"
#include "vos_sched.h"

//Ms to Micro Sec
#define MS_TO_MUS(x)   ((x)*1000);
tANI_U8* hdd_getActionString( tANI_U16 MsgType )
{
    switch (MsgType)
    {
       CASE_RETURN_STRING(SIR_MAC_ACTION_SPECTRUM_MGMT);
       CASE_RETURN_STRING(SIR_MAC_ACTION_QOS_MGMT);
       CASE_RETURN_STRING(SIR_MAC_ACTION_DLP);
       CASE_RETURN_STRING(SIR_MAC_ACTION_BLKACK);
       CASE_RETURN_STRING(SIR_MAC_ACTION_PUBLIC_USAGE);
       CASE_RETURN_STRING(SIR_MAC_ACTION_RRM);
       CASE_RETURN_STRING(SIR_MAC_ACTION_FAST_BSS_TRNST);
       CASE_RETURN_STRING(SIR_MAC_ACTION_HT);
       CASE_RETURN_STRING(SIR_MAC_ACTION_SA_QUERY);
       CASE_RETURN_STRING(SIR_MAC_ACTION_PROT_DUAL_PUB);
       CASE_RETURN_STRING(SIR_MAC_ACTION_WNM);
       CASE_RETURN_STRING(SIR_MAC_ACTION_UNPROT_WNM);
       CASE_RETURN_STRING(SIR_MAC_ACTION_TDLS);
       CASE_RETURN_STRING(SIR_MAC_ACITON_MESH);
       CASE_RETURN_STRING(SIR_MAC_ACTION_MHF);
       CASE_RETURN_STRING(SIR_MAC_SELF_PROTECTED);
       CASE_RETURN_STRING(SIR_MAC_ACTION_WME);
       CASE_RETURN_STRING(SIR_MAC_ACTION_VHT);
       default:
           return ("UNKNOWN");
    }
}


#ifdef WLAN_FEATURE_P2P_DEBUG
#define MAX_P2P_ACTION_FRAME_TYPE 9
const char *p2p_action_frame_type[]={"GO Negotiation Request",
                                     "GO Negotiation Response",
                                     "GO Negotiation Confirmation",
                                     "P2P Invitation Request",
                                     "P2P Invitation Response",
                                     "Device Discoverability Request",
                                     "Device Discoverability Response",
                                     "Provision Discovery Request",
                                     "Provision Discovery Response"};

/* We no need to protect this variable since
 * there is no chance of race to condition
 * and also not make any complicating the code
 * just for debugging log
 */
tP2PConnectionStatus globalP2PConnectionStatus = P2P_NOT_ACTIVE;

#endif
#define MAX_TDLS_ACTION_FRAME_TYPE 11
const char *tdls_action_frame_type[] = {"TDLS Setup Request",
                                        "TDLS Setup Response",
                                        "TDLS Setup Confirm",
                                        "TDLS Teardown",
                                        "TDLS Peer Traffic Indication",
                                        "TDLS Channel Switch Request",
                                        "TDLS Channel Switch Response",
                                        "TDLS Peer PSM Request",
                                        "TDLS Peer PSM Response",
                                        "TDLS Peer Traffic Response",
                                        "TDLS Discovery Request" };

extern struct net_device_ops net_ops_struct;

static int hdd_wlan_add_rx_radiotap_hdr( struct sk_buff *skb,
                                         int rtap_len, int flag );

static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
                                  hdd_cfg80211_state_t* cfgState,
                                  tANI_BOOLEAN actionSendSuccess );

static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
                                               tANI_U32 nFrameLength,
                                               tANI_U8* pbFrames,
                                               tANI_U8 frameType );

static v_BOOL_t wlan_hdd_is_type_p2p_action( const u8 *buf, uint32_t len )
{
    const u8 *ouiPtr;

    if (len < WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET + 1) {
        return VOS_FALSE;
    }

    if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] !=
               WLAN_HDD_PUBLIC_ACTION_FRAME ) {
        return VOS_FALSE;
    }

    if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET] !=
               WLAN_HDD_VENDOR_SPECIFIC_ACTION ) {
        return VOS_FALSE;
    }

    ouiPtr = &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET];

    if ( WPA_GET_BE24(ouiPtr) != WLAN_HDD_WFA_OUI ) {
        return VOS_FALSE;
    }

    if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET] !=
               WLAN_HDD_WFA_P2P_OUI_TYPE ) {
        return VOS_FALSE;
    }

    return VOS_TRUE;
}

static bool hdd_p2p_is_action_type_rsp( const u8 *buf, uint32_t len )
{
    tActionFrmType actionFrmType;

    if ( wlan_hdd_is_type_p2p_action(buf, len) )
    {
        actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET];
        if ( actionFrmType != WLAN_HDD_INVITATION_REQ &&
            actionFrmType != WLAN_HDD_GO_NEG_REQ &&
            actionFrmType != WLAN_HDD_DEV_DIS_REQ &&
            actionFrmType != WLAN_HDD_PROV_DIS_REQ )
            return VOS_TRUE;
    }
    return VOS_FALSE;
}

eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx,
                                                eHalStatus status )
{
    hdd_adapter_t *pAdapter = (hdd_adapter_t*) pCtx;
    hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    rem_on_channel_request_type_t req_type;

    if (pHddCtx == NULL)
    {
        hddLog(LOGE, "%s: Hdd Context is NULL", __func__);
        return eHAL_STATUS_FAILURE;
    }

    mutex_lock(&pHddCtx->roc_lock);

    pRemainChanCtx = cfgState->remain_on_chan_ctx;
    if (pRemainChanCtx == NULL)
    {
        hddLog( LOGW,
                "%s: No Rem on channel pending for which Rsp is received", __func__);
        mutex_unlock(&pHddCtx->roc_lock);
        return eHAL_STATUS_SUCCESS;
    }

    hddLog( VOS_TRACE_LEVEL_INFO,
            "Received ROC rsp (request type %d, channel %d, cookie %llu",
            pRemainChanCtx->rem_on_chan_request,
            pRemainChanCtx->chan.center_freq,
            pRemainChanCtx->cookie);
    if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop(
                    &pRemainChanCtx->hdd_remain_on_chan_timer)))
    {
        hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer"));
    }
    if(!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
                    &pRemainChanCtx->hdd_remain_on_chan_timer)))
    {
        hddLog( LOGE, FL("Failed to destroy hdd_remain_on_chan_timer"));
    }
    if ( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
    {
        if( cfgState->buf )
        {
           hddLog( LOG1,
                   "%s: We need to receive yet an ack from one of tx packet",
                   __func__);
        }
        cfg80211_remain_on_channel_expired(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                              pRemainChanCtx->dev->ieee80211_ptr,
#else
                              pRemainChanCtx->dev,
#endif
                              pRemainChanCtx->cookie,
                              &pRemainChanCtx->chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                              pRemainChanCtx->chan_type,
#endif
                              GFP_KERNEL);
        pAdapter->lastRocTs = vos_timer_get_system_time();
    }

    req_type = pRemainChanCtx->rem_on_chan_request;
    mutex_unlock(&pHddCtx->roc_lock);

    if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
         ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
         ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
       )
    {
        tANI_U8 sessionId = pAdapter->sessionId;
        if( REMAIN_ON_CHANNEL_REQUEST == req_type )
        {
            sme_DeregisterMgmtFrame(
                       hHal, sessionId,
                      (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
                       NULL, 0 );
        }
    }
    else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
    {
        WLANSAP_DeRegisterMgmtFrame(
                (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
                NULL, 0 );
    }
    mutex_lock(&pHddCtx->roc_lock);
    pRemainChanCtx = cfgState->remain_on_chan_ctx;
    if ( pRemainChanCtx )
    {
        /* Trigger kernel panic if ROC timer state is not set to unused state
         * before freeing the ROC ctx.
         */
         if (VOS_TIMER_STATE_UNUSED != vos_timer_getCurrentState(
                 &pRemainChanCtx->hdd_remain_on_chan_timer))
            VOS_BUG(0);

        if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL
                && pRemainChanCtx->action_pkt_buff.frame_length != 0)
        {
            vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
        }
        hddLog( LOG1, FL(
                    "Freeing ROC ctx cfgState->remain_on_chan_ctx=%pK"),
                cfgState->remain_on_chan_ctx);
        vos_mem_free( pRemainChanCtx );
        pRemainChanCtx = NULL;
        cfgState->remain_on_chan_ctx = NULL;
    }
    mutex_unlock(&pHddCtx->roc_lock);
    if (eHAL_STATUS_SUCCESS != status)
        complete(&pAdapter->rem_on_chan_ready_event);
    complete(&pAdapter->cancel_rem_on_chan_var);
    pAdapter->is_roc_inprogress = FALSE;
    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
    return eHAL_STATUS_SUCCESS;
}

VOS_STATUS wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter)
{
    hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    int status = 0;

    if (NULL == pHddCtx)
    {
        hddLog(LOGE, "%s: HddCtx is NULL", __func__);
        return VOS_STATUS_E_FAILURE;
    }

    mutex_lock(&pHddCtx->roc_lock);
    pRemainChanCtx = cfgState->remain_on_chan_ctx;
    if(pRemainChanCtx != NULL)
    {
        if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(
                    &pRemainChanCtx->hdd_remain_on_chan_timer))
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "Cancel Existing ROC (cookie=%llu)",
                    pRemainChanCtx->cookie);

            if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop(
                           &pRemainChanCtx->hdd_remain_on_chan_timer)))
            {
                hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer"));
            }
        }
        /* Wait till remain on channel ready indication before issuing cancel
         * remain on channel request, otherwise if remain on channel not
         * received and if the driver issues cancel remain on channel then lim
         * will be in unknown state.
         */
        if (pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress != TRUE)
        {
            mutex_unlock(&pHddCtx->roc_lock);
            status = wait_for_completion_interruptible_timeout(
                                        &pAdapter->rem_on_chan_ready_event,
                                        msecs_to_jiffies(WAIT_REM_CHAN_READY));
            if (0 >= status)
            {
                mutex_lock(&pHddCtx->roc_lock);
                pRemainChanCtx = cfgState->remain_on_chan_ctx;
                if (pRemainChanCtx)
                    pRemainChanCtx->is_pending_roc_cancelled = TRUE;
                mutex_unlock(&pHddCtx->roc_lock);
                hddLog( LOGE,
                        "%s: timeout waiting for remain on channel"
                        " ready indication %d",
                        __func__, status);
                vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
                      WLAN_LOG_INDICATOR_HOST_DRIVER,
                      WLAN_LOG_REASON_HDD_TIME_OUT,
                      FALSE, TRUE);
                return VOS_STATUS_E_FAILURE;
            }

            mutex_lock(&pHddCtx->roc_lock);
            pRemainChanCtx = cfgState->remain_on_chan_ctx;
            if (NULL == pRemainChanCtx)
            {
                mutex_unlock(&pHddCtx->roc_lock);
                hddLog( LOGE,
                        "%s-%d: pRemainChanCtx is NULL",
                        __func__, __LINE__);
                return VOS_STATUS_E_FAILURE;
            }
            /* Check again if cancel remain on channel is started.
             * If its started wait for its completiona and return.
             */
            if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress)
            {
                mutex_unlock(&pHddCtx->roc_lock);
                hddLog( LOG1,
                      "ROC timer cancellation in progress,"
                      " wait for completion");
                status = wait_for_completion_interruptible_timeout(
                                     &pAdapter->cancel_rem_on_chan_var,
                                     msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
                if (0 >= status)
                {
                    hddLog( LOGE,
                          "%s:wait on cancel_rem_on_chan_var failed %d",
                           __func__, status);
                    return VOS_STATUS_E_FAILURE;
                }
                return VOS_STATUS_SUCCESS;
            }
            else
                pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
            INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
            mutex_unlock(&pHddCtx->roc_lock);

            /* Issue abort remain on chan request to sme.
             * The remain on channel callback will make sure the remain_on_chan
             * expired event is sent.
             */
            if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
                   ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
                   ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ))
            {
                if (eHAL_STATUS_SUCCESS !=
                    sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
                                                     pAdapter->sessionId ))
                {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                            FL("Failed to Cancel Remain on Channel"));
                }
            }
            else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
            {
                 WLANSAP_CancelRemainOnChannel(
                         (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
            }

            status = wait_for_completion_interruptible_timeout(
                                    &pAdapter->cancel_rem_on_chan_var,
                                    msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
            if (0 >= status)
            {
                hddLog(LOGE,
                       FL("Timeout waiting for cancel remain on channel ready indication %d"),
                       status);
                return VOS_STATUS_E_FAILURE;
            }
         }
         else
         {
              hddLog( LOG1,
                      "ROC timer cancellation in progress,"
                      " wait for completion");
              mutex_unlock(&pHddCtx->roc_lock);
              status = wait_for_completion_interruptible_timeout(
                                     &pAdapter->cancel_rem_on_chan_var,
                                     msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
              if (0 >= status)
              {
                  hddLog( LOGE,
                          "%s:wait on cancel_rem_on_chan_var failed %d",
                           __func__, status);
                  return VOS_STATUS_E_FAILURE;
              }
              return VOS_STATUS_SUCCESS;
         }
    }
    else
    {
       hddLog(LOG1,
               "%s: remain_on_chan_ctx is NULL", __func__);
       mutex_unlock(&pHddCtx->roc_lock);
    }
    return VOS_STATUS_SUCCESS;
}

int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter)
{
   int status = 0;
   hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );

   if(WLAN_HDD_P2P_GO != pAdapter->device_mode)
   {
     //Cancel Existing Remain On Channel
     //If no action frame is pending
     if( cfgState->remain_on_chan_ctx != NULL)
     {
        //Check whether Action Frame is pending or not
        if( cfgState->buf == NULL)
        {
           wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
        }
        else
        {
           hddLog(VOS_TRACE_LEVEL_DEBUG,
                   "Cannot Cancel Existing Remain on Channel");
           status = -EBUSY;
        }
     }
   }
   return status;
}
void wlan_hdd_remain_on_chan_timeout(void *data)
{
    hdd_adapter_t *pAdapter = (hdd_adapter_t *)data;
    hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
    hdd_cfg80211_state_t *cfgState;
    hdd_context_t *pHddCtx;

    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        hddLog( LOGE, FL("pAdapter is invalid %pK !!!"), pAdapter);
        return;
    }
    pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
    cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    mutex_lock(&pHddCtx->roc_lock);
    pRemainChanCtx = cfgState->remain_on_chan_ctx;

    if (NULL == pRemainChanCtx)
    {
        hddLog( LOGE, FL("No Remain on channel is pending"));
        mutex_unlock(&pHddCtx->roc_lock);
        return;
    }

    if ( TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
    {
        mutex_unlock(&pHddCtx->roc_lock);
        hddLog( LOGE, FL("Cancellation already in progress"));
        return;
    }

    pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
    INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
    mutex_unlock(&pHddCtx->roc_lock);
    hddLog( LOG1,"%s: Cancel Remain on Channel on timeout", __func__);
    if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
          ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
           ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
       )
    {
        if (eHAL_STATUS_SUCCESS !=
                sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
                    pAdapter->sessionId ))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    FL("Failed to Cancel Remain on Channel"));
        }
    }
    else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
    {
        WLANSAP_CancelRemainOnChannel(
                (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
    }

    wlan_hdd_start_stop_tdls_source_timer(pHddCtx, eTDLS_SUPPORT_ENABLED);

    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
}

static int wlan_hdd_p2p_start_remain_on_channel(
        hdd_adapter_t *pAdapter)
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_adapter_t *pAdapter_temp;
    v_BOOL_t isGoPresent = VOS_FALSE;
    hdd_context_t *pHddCtx;
    hdd_cfg80211_state_t *cfgState;
    hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
    rem_on_channel_request_type_t request_type;
    unsigned int duration;
    v_U16_t hw_value;

    int ret = 0;

    ENTER();
    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Adapter is NULL",__func__);
        return -EINVAL;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }
    cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    if (NULL == cfgState)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: cfgState is not valid ",__func__);
        return -EINVAL;
    }
    mutex_lock(&pHddCtx->roc_lock);
    pRemainChanCtx = cfgState->remain_on_chan_ctx;
    if ( pRemainChanCtx  == NULL)
    {
        mutex_unlock(&pHddCtx->roc_lock);
        hddLog( LOGE,
                "%s-%d: pRemainChanCtx is NULL",
                __func__, __LINE__);
        return ret;
    }
    request_type = pRemainChanCtx->rem_on_chan_request;
    /* Initialize Remain on chan timer */
    status = vos_timer_init(&pRemainChanCtx->hdd_remain_on_chan_timer,
            VOS_TIMER_TYPE_SW,
            wlan_hdd_remain_on_chan_timeout,
            pAdapter);
    if (status != VOS_STATUS_SUCCESS)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("Not able to initalize remain_on_chan timer"));
        hddLog( LOG1, FL(
                    "Freeing ROC ctx cfgState->remain_on_chan_ctx=%pK"),
                cfgState->remain_on_chan_ctx);
        cfgState->remain_on_chan_ctx = NULL;
        vos_mem_free(pRemainChanCtx);
        mutex_unlock(&pHddCtx->roc_lock);
        return -EINVAL;
    }

    duration = pRemainChanCtx->duration;
    hw_value = pRemainChanCtx->chan.hw_value;
    mutex_unlock(&pHddCtx->roc_lock);

    status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
    {
        pAdapter_temp = pAdapterNode->pAdapter;
        if (WLAN_HDD_P2P_GO == pAdapter_temp->device_mode)
        {
            isGoPresent = VOS_TRUE;
        }
        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }
    hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
    //call sme API to start remain on channel.
    if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
            ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
            ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
       )
    {
        tANI_U8 sessionId = pAdapter->sessionId;
        //call sme API to start remain on channel.
        if (eHAL_STATUS_SUCCESS != sme_RemainOnChannel(
                WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId,
                hw_value, duration,
                wlan_hdd_remain_on_channel_callback, pAdapter,
                (tANI_U8)(request_type == REMAIN_ON_CHANNEL_REQUEST)? TRUE:FALSE))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    FL(" RemainOnChannel returned fail"));

            mutex_lock(&pHddCtx->roc_lock);
            pRemainChanCtx = cfgState->remain_on_chan_ctx;
            hddLog( LOG1, FL(
                        "Freeing ROC ctx cfgState->remain_on_chan_ctx=%pK"),
                         cfgState->remain_on_chan_ctx);
            if (pRemainChanCtx)
            {
                if(!VOS_IS_STATUS_SUCCESS(vos_timer_destroy
                            (&pRemainChanCtx->hdd_remain_on_chan_timer)))
                {
                    hddLog( LOGE, FL(
                        "Failed to destroy hdd_remain_on_chan_timer"));
                }
                vos_mem_free(pRemainChanCtx);
                cfgState->remain_on_chan_ctx = NULL;
            }
            mutex_unlock(&pHddCtx->roc_lock);
            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
            return -EINVAL;
        }

        if( REMAIN_ON_CHANNEL_REQUEST == request_type)
        {
            if( eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame(
                        WLAN_HDD_GET_HAL_CTX(pAdapter),
                        sessionId, (SIR_MAC_MGMT_FRAME << 2) |
                        (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0 ))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,    "sme_RegisterMgmtFrame returned fail");
            }
        }

    }
    else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
    {
        //call sme API to start remain on channel.
        if (VOS_STATUS_SUCCESS != WLANSAP_RemainOnChannel(
                    (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                    hw_value, duration,
                    wlan_hdd_remain_on_channel_callback, pAdapter ))

        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: WLANSAP_RemainOnChannel returned fail", __func__);
            mutex_lock(&pHddCtx->roc_lock);
            pRemainChanCtx = cfgState->remain_on_chan_ctx;
            hddLog( LOG1, FL(
                        "Freeing ROC ctx cfgState->remain_on_chan_ctx=%pK"),
                         cfgState->remain_on_chan_ctx);
            if (pRemainChanCtx)
            {
                if(!VOS_IS_STATUS_SUCCESS(vos_timer_destroy
                            (&pRemainChanCtx->hdd_remain_on_chan_timer)))
                {
                    hddLog( LOGE, FL(
                        "Failed to destroy hdd_remain_on_chan_timer"));
                }
                vos_mem_free (pRemainChanCtx);
                cfgState->remain_on_chan_ctx = NULL;
            }
            mutex_unlock(&pHddCtx->roc_lock);
            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
            return -EINVAL;
        }


        if (VOS_STATUS_SUCCESS != WLANSAP_RegisterMgmtFrame(
                    (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                    (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
                    NULL, 0 ))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__);
            WLANSAP_CancelRemainOnChannel(
                    (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
            return -EINVAL;
        }

    }

    wlan_hdd_start_stop_tdls_source_timer(pHddCtx, eTDLS_SUPPORT_DISABLED);

    pAdapter->is_roc_inprogress = TRUE;
    EXIT();
    return 0;
}


static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy,
                                   struct net_device *dev,
                                   struct ieee80211_channel *chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                                   enum nl80211_channel_type channel_type,
#endif
                                   unsigned int duration, u64 *cookie,
                                   rem_on_channel_request_type_t request_type )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_remain_on_chan_ctx_t *pRemainChanCtx;
    hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    hdd_context_t *pHddCtx = NULL;
    VOS_STATUS checkReadyInd;
    hdd_adapter_t *pStaAdapter;
    int status = 0;

    ENTER();
    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

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

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
                                 __func__,pAdapter->device_mode);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
    hddLog(VOS_TRACE_LEVEL_INFO,
           "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, dur %d,"
           " request type %d, cookie %llu",
           chan->hw_value, chan->center_freq, channel_type, duration,
           request_type, *cookie);
#else
     hddLog(VOS_TRACE_LEVEL_INFO,
            "chan(hw_val)0x%x chan(centerfreq) %d, duration %d"
            " reuest type %d, cookie %llu", chan->hw_value, chan->center_freq,
            duration, request_type, *cookie );
#endif
    //Cancel existing remain On Channel if any
    checkReadyInd = wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
    if (VOS_STATUS_SUCCESS != checkReadyInd)
    {
       hddLog( LOGE, FL("Cancel Roc in progress"));
       return -EBUSY;
    }

    if (TRUE == pHddCtx->btCoexModeSet)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
           FL("BTCoex Mode operation in progress"));
        return -EBUSY;
    }

    if(hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx, NULL,
                                   NULL))
    {
        hddLog( LOGE,
               "%s: Connection is in progress", __func__);
        return -EBUSY;
    }

    mutex_lock(&pHddCtx->roc_lock);

   if (cfgState->remain_on_chan_ctx)
       VOS_BUG(0);

    pRemainChanCtx = vos_mem_malloc( sizeof(hdd_remain_on_chan_ctx_t) );
    if( NULL == pRemainChanCtx )
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
             "%s: Not able to allocate memory for Channel context",
                                         __func__);
        mutex_unlock(&pHddCtx->roc_lock);
        return -ENOMEM;
    }

    vos_mem_zero(pRemainChanCtx, sizeof (hdd_remain_on_chan_ctx_t));
    vos_mem_copy( &pRemainChanCtx->chan, chan,
                   sizeof(struct ieee80211_channel) );

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
    pRemainChanCtx->chan_type = channel_type;
#endif
    pRemainChanCtx->duration = duration;
    pRemainChanCtx->dev = dev;
    *cookie = (uintptr_t) pRemainChanCtx;
    pRemainChanCtx->cookie = *cookie;
    pRemainChanCtx->rem_on_chan_request = request_type;
    cfgState->remain_on_chan_ctx = pRemainChanCtx;
    cfgState->current_freq = chan->center_freq;
    pRemainChanCtx->action_pkt_buff.freq = 0;
    pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
    pRemainChanCtx->action_pkt_buff.frame_length = 0;
    pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = FALSE;
    pRemainChanCtx->is_pending_roc_cancelled = FALSE;

    INIT_COMPLETION(pAdapter->rem_on_chan_ready_event);

    if (REMAIN_ON_CHANNEL_REQUEST == request_type)
    {
        pStaAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
        if((NULL != pStaAdapter)&&
                hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pStaAdapter)))
        {
            if (pAdapter->lastRocTs !=0 &&
                    ((vos_timer_get_system_time() - pAdapter->lastRocTs )
                     < pHddCtx->cfg_ini->gP2PListenDeferInterval))
            {
                if (pRemainChanCtx->duration > HDD_P2P_MAX_ROC_DURATION)
                    pRemainChanCtx->duration = HDD_P2P_MAX_ROC_DURATION;

                mutex_unlock(&pHddCtx->roc_lock);

                schedule_delayed_work(&pAdapter->roc_work,
                        msecs_to_jiffies(pHddCtx->cfg_ini->gP2PListenDeferInterval));
                hddLog(VOS_TRACE_LEVEL_INFO, "Defer interval is %hu, pAdapter %pK",
                        pHddCtx->cfg_ini->gP2PListenDeferInterval, pAdapter);
                return 0;
            }
        }
    }

    mutex_unlock(&pHddCtx->roc_lock);
    status = wlan_hdd_p2p_start_remain_on_channel(pAdapter);

    EXIT();
    return status;
}

int __wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                                struct wireless_dev *wdev,
#else
                                struct net_device *dev,
#endif
                                struct ieee80211_channel *chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                                enum nl80211_channel_type channel_type,
#endif
                                unsigned int duration, u64 *cookie )
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    struct net_device *dev = wdev->netdev;
#endif
    hdd_adapter_t *pAdapter;
    hdd_context_t *pHddCtx;
    int ret = 0;

    ENTER();
    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Adapter is NULL",__func__);
        return -EINVAL;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_REMAIN_ON_CHANNEL,
                     pAdapter->sessionId, REMAIN_ON_CHANNEL_REQUEST));
    ret = wlan_hdd_request_remain_on_channel(wiphy, dev,
                                        chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                                        channel_type,
#endif
                                        duration, cookie,
                                        REMAIN_ON_CHANNEL_REQUEST);
    EXIT();
    return ret;
}

int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                                struct wireless_dev *wdev,
#else
                                struct net_device *dev,
#endif
                                struct ieee80211_channel *chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                                enum nl80211_channel_type channel_type,
#endif
                                unsigned int duration, u64 *cookie )
{
   int ret;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                                               wdev,
#else
                                               dev,
#endif
                                               chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                                               channel_type,
#endif
                                               duration, cookie);
   vos_ssr_unprotect(__func__);

   return ret;
}


void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter )
{
    hdd_cfg80211_state_t *cfgState = NULL;
    hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;
    hdd_context_t *pHddCtx;
    VOS_STATUS status;
    if (NULL == pAdapter)
    {
       hddLog(LOGE, FL("pAdapter is NULL"));
       return;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (NULL == pHddCtx)
    {
        hddLog(LOGE, FL("pHddCtx is NULL"));
        return;
    }
    cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    pAdapter->startRocTs = vos_timer_get_system_time();
    mutex_lock(&pHddCtx->roc_lock);
    pRemainChanCtx = cfgState->remain_on_chan_ctx;
    if( pRemainChanCtx != NULL )
    {
        MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                         TRACE_CODE_HDD_REMAINCHANREADYHANDLER,
                         pAdapter->sessionId, pRemainChanCtx->duration));
        //start timer for actual duration
        status = vos_timer_start(&pRemainChanCtx->hdd_remain_on_chan_timer,
                                (pRemainChanCtx->duration));
        if (VOS_STATUS_SUCCESS!=status)
        {
            hddLog( LOGE, FL("Remain on Channel timer start failed"));
        }
        if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request)
        {
            cfg80211_ready_on_channel(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                               pAdapter->dev->ieee80211_ptr,
#else
                               pAdapter->dev,
#endif
                               (uintptr_t)pRemainChanCtx,
                               &pRemainChanCtx->chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                               pRemainChanCtx->chan_type,
#endif
                               pRemainChanCtx->duration, GFP_KERNEL );
        }
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
        else if( OFF_CHANNEL_ACTION_TX == pRemainChanCtx->rem_on_chan_request)
        {
            complete(&pAdapter->offchannel_tx_event);
        }
#endif
        // Check for cached action frame
        if ( pRemainChanCtx->action_pkt_buff.frame_length != 0 )
        {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
            cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr,
                             pRemainChanCtx->action_pkt_buff.freq, 0,
                             pRemainChanCtx->action_pkt_buff.frame_ptr,
                             pRemainChanCtx->action_pkt_buff.frame_length,
                             NL80211_RXMGMT_FLAG_ANSWERED);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
            cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr,
                             pRemainChanCtx->action_pkt_buff.freq, 0,
                             pRemainChanCtx->action_pkt_buff.frame_ptr,
                             pRemainChanCtx->action_pkt_buff.frame_length,
                             NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
            cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr,
                              pRemainChanCtx->action_pkt_buff.freq, 0,
                              pRemainChanCtx->action_pkt_buff.frame_ptr,
                              pRemainChanCtx->action_pkt_buff.frame_length,
                              GFP_ATOMIC );
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
            cfg80211_rx_mgmt( pAdapter->dev,
                              pRemainChanCtx->action_pkt_buff.freq, 0,
                              pRemainChanCtx->action_pkt_buff.frame_ptr,
                              pRemainChanCtx->action_pkt_buff.frame_length,
                              GFP_ATOMIC );
#else
            cfg80211_rx_mgmt( pAdapter->dev,
                              pRemainChanCtx->action_pkt_buff.freq,
                              pRemainChanCtx->action_pkt_buff.frame_ptr,
                              pRemainChanCtx->action_pkt_buff.frame_length,
                              GFP_ATOMIC );
#endif //LINUX_VERSION_CODE
            hddLog( LOGE, "%s: Sent cached action frame to supplicant", __func__);
            vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
            pRemainChanCtx->action_pkt_buff.frame_length = 0;
            pRemainChanCtx->action_pkt_buff.freq = 0;
            pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
        }
        hddLog( VOS_TRACE_LEVEL_INFO, "Ready on chan ind (cookie=%llu)",
                pRemainChanCtx->cookie);
        complete(&pAdapter->rem_on_chan_ready_event);
        if (TRUE == pRemainChanCtx->is_pending_roc_cancelled)
        {
            mutex_unlock(&pHddCtx->roc_lock);
            /* since pRemainChanCtx->is_pending_roc_cancelled is
             * set, it means Cancel Reamain on channel command is
             * pending because remain on channel event was not
             * ready when cancel ROC  was issued.So issue
             * cancel ROC now.
             */
            wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
        }
        else
        {
            mutex_unlock(&pHddCtx->roc_lock);
        }
    }
    else
    {
        mutex_unlock(&pHddCtx->roc_lock);
        hddLog( LOGW, "%s: No Pending Remain on channel Request", __func__);
    }
    return;
}

int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                                                struct wireless_dev *wdev,
#else
                                                struct net_device *dev,
#endif
                                                u64 cookie )
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    struct net_device *dev = wdev->netdev;
#endif
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
    int status;
    u64 cookie_dummy;

    ENTER();
    cookie_dummy = cookie << 32;
    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL,
                     pAdapter->sessionId, cookie_dummy));
    hddLog( LOG1, "Cancel remain on channel req");

    status = wlan_hdd_validate_context(pHddCtx);

    if (0 != status)
    {
        return status;
    }
    hddLog( LOG1, "Cancel remain on channel req (cookie = %llu)", cookie);

    /* FIXME cancel currently running remain on chan.
     * Need to check cookie and cancel accordingly
     */
    mutex_lock(&pHddCtx->roc_lock);
    pRemainChanCtx = cfgState->remain_on_chan_ctx;
    if( (cfgState->remain_on_chan_ctx == NULL) ||
        (cfgState->remain_on_chan_ctx->cookie != cookie) )
    {
        mutex_unlock(&pHddCtx->roc_lock);
        hddLog( LOGE,
            "%s: No Remain on channel pending with specified cookie value",
             __func__);
        return -EINVAL;
    }
    if (TRUE != pRemainChanCtx->is_pending_roc_cancelled)
    {
       mutex_unlock(&pHddCtx->roc_lock);
       /* wait until remain on channel ready event received
        * for already issued remain on channel request */
       status = wait_for_completion_interruptible_timeout(&pAdapter->rem_on_chan_ready_event,
            msecs_to_jiffies(WAIT_REM_CHAN_READY));
       if (0 >= status)
       {
           hddLog( LOGE,
                   "%s: timeout waiting for remain on channel ready indication %d",
                   __func__, status);
           mutex_lock(&pHddCtx->roc_lock);
           if (cfgState->remain_on_chan_ctx)
               cfgState->remain_on_chan_ctx->is_pending_roc_cancelled = TRUE;
           mutex_unlock(&pHddCtx->roc_lock);
           vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
                 WLAN_LOG_INDICATOR_HOST_DRIVER,
                 WLAN_LOG_REASON_HDD_TIME_OUT,
                 FALSE, TRUE);
           return 0;

       }
        mutex_lock(&pHddCtx->roc_lock);
    }
    else
    {
        hddLog( LOG1, FL("Cancel ROC event is already pending, "
                         "waiting for ready on channel indication.") );
        mutex_unlock(&pHddCtx->roc_lock);
        return 0;
    }
    if (NULL != cfgState->remain_on_chan_ctx)
    {
        if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop(
                    &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer)))
        {
            hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer"));
        }
        if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress)
        {
            mutex_unlock(&pHddCtx->roc_lock);
            hddLog( LOG1,
                    FL("ROC timer cancellation in progress,"
                       " wait for completion"));
            status = wait_for_completion_interruptible_timeout(
                                             &pAdapter->cancel_rem_on_chan_var,
                                             msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
            if (0 >= status)
            {
                hddLog( LOGE,
                        "%s:wait on cancel_rem_on_chan_var failed %d",
                        __func__, status);
            }
            return 0;
        }
        else
            pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
    }
    INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
    mutex_unlock(&pHddCtx->roc_lock);
    /* Issue abort remain on chan request to sme.
     * The remain on channel callback will make sure the remain_on_chan
     * expired event is sent.
     */
    if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
         ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
         ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ))
    {
        tANI_U8 sessionId = pAdapter->sessionId;
        if (eHAL_STATUS_SUCCESS !=
                sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
                                           sessionId ))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    FL("Failed to Cancel Remain on Channel"));
        }
    }
    else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
    {
        WLANSAP_CancelRemainOnChannel(
                (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
    }
    else
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid device_mode = %d",
                            __func__, pAdapter->device_mode);
       return -EIO;
    }
    status = wait_for_completion_interruptible_timeout(&pAdapter->cancel_rem_on_chan_var,
            msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
    if (0 >= status)
    {
        hddLog( LOGE,
              "%s:wait on cancel_rem_on_chan_var failed %d", __func__, status);
    }
    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);

    EXIT();
    return 0;
}

int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                                                struct wireless_dev *wdev,
#else
                                                struct net_device *dev,
#endif
                                                u64 cookie )
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                                                    wdev,
#else
                                                    dev,
#endif
                                                    cookie);
    vos_ssr_unprotect(__func__);

    return ret;
}


#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
                     struct ieee80211_channel *chan, bool offchan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid,
#endif
                     unsigned int wait,
                     const u8 *buf, size_t len,  bool no_cck,
                     bool dont_wait_for_ack, u64 *cookie )
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
                     struct ieee80211_channel *chan, bool offchan,
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid, unsigned int wait,
                     const u8 *buf, size_t len,  bool no_cck,
                     bool dont_wait_for_ack, u64 *cookie )
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
                     struct ieee80211_channel *chan, bool offchan,
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid, unsigned int wait,
                     const u8 *buf, size_t len, u64 *cookie )
#else
int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
                     struct ieee80211_channel *chan,
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid,
                     const u8 *buf, size_t len, u64 *cookie )
#endif //LINUX_VERSION_CODE
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    struct net_device *dev = wdev->netdev;
#endif
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    hdd_adapter_t *pGoAdapter;
    hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
    hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
    tANI_U8 type;
    tANI_U8 subType;
    tActionFrmType actionFrmType = WLAN_HDD_ACTION_FRM_TYPE_MAX;
    bool noack = 0;
    int status;
    uint32_t mgmt_hdr_len = sizeof(struct ieee80211_hdr_3addr);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    uint8_t home_ch = 0;
#endif
    eHalStatus hal_status;

    ENTER();

    if (len < mgmt_hdr_len + 1) {
        hddLog(VOS_TRACE_LEVEL_ERROR,"Invalid Length");
        return -EINVAL;
    }

    type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
    subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                      TRACE_CODE_HDD_ACTION, pAdapter->sessionId,
                      pAdapter->device_mode ));
    status = wlan_hdd_validate_context(pHddCtx);

    if (0 != status)
    {
        return status;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d",
                            __func__, pAdapter->device_mode, type);

    /* When frame to be transmitted is auth mgmt, then trigger
     * sme_send_mgmt_tx to send auth frame.
     */
    if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
        (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_AUTH)) {
         hal_status = sme_send_mgmt_tx(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                       pAdapter->sessionId, buf, len);
         if (HAL_STATUS_SUCCESS(hal_status))
              return 0;
         else
              return -EINVAL;
    }

    if ((type == SIR_MAC_MGMT_FRAME) &&
            (subType == SIR_MAC_MGMT_ACTION) &&
            wlan_hdd_is_type_p2p_action(
            &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET], len - mgmt_hdr_len))
    {
        actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
#ifdef WLAN_FEATURE_P2P_DEBUG
        if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA",
                                   actionFrmType);
        }
        else
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA",
            p2p_action_frame_type[actionFrmType]);
            if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
                (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
            {
                 globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
                 hddLog(LOGE,"[P2P State]Inactive state to "
                            "GO negotiation progress state");
            }
            else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
                (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
            {
                 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
                 hddLog(LOGE,"[P2P State]GO nego progress to GO nego"
                             " completed state");
            }
        }
#endif
    }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
    noack = dont_wait_for_ack;
#endif


    //If the wait is coming as 0 with off channel set
    //then set the wait to 200 ms
    if (offchan && !wait)
    {
        wait = ACTION_FRAME_DEFAULT_WAIT;
        mutex_lock(&pHddCtx->roc_lock);
        pRemainChanCtx = cfgState->remain_on_chan_ctx;
        if (pRemainChanCtx)
        {
            tANI_U32 current_time = vos_timer_get_system_time();
            int remaining_roc_time = ((int) pRemainChanCtx->duration -
                    (current_time - pAdapter->startRocTs));
            if ( remaining_roc_time > ACTION_FRAME_DEFAULT_WAIT)
                wait = remaining_roc_time;
        }
        mutex_unlock(&pHddCtx->roc_lock);
    }

    //Call sme API to send out a action frame.
    // OR can we send it directly through data path??
    // After tx completion send tx status back.
    if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) ||
         ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
       )
    {
        if (type == SIR_MAC_MGMT_FRAME)
        {
            if (subType == SIR_MAC_MGMT_PROBE_RSP)
            {
                /* Drop Probe response recieved from supplicant, as for GO and
                   SAP PE itself sends probe response
                   */
                goto err_rem_channel;
            }
            else if ((subType == SIR_MAC_MGMT_DISASSOC) ||
                    (subType == SIR_MAC_MGMT_DEAUTH))
            {
                /* During EAP failure or P2P Group Remove supplicant
                 * is sending del_station command to driver. From
                 * del_station function, Driver will send deauth frame to
                 * p2p client. No need to send disassoc frame from here.
                 * so Drop the frame here and send tx indication back to
                 * supplicant.
                 */
                tANI_U8 dstMac[ETH_ALEN] = {0};
                memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN);
                hddLog(VOS_TRACE_LEVEL_INFO,
                        "%s: Deauth/Disassoc received for STA:"
                        MAC_ADDRESS_STR,
                        __func__,
                        MAC_ADDR_ARRAY(dstMac));
                goto err_rem_channel;
            }
        }
    }

    if( NULL != cfgState->buf )
    {
        if ( !noack )
        {
            hddLog( LOGE, "(%s):Previous P2P Action frame packet pending",
                          __func__);
            hdd_cleanup_actionframe(pAdapter->pHddCtx, pAdapter);
        }
        else
        {
            hddLog( LOGE, "(%s):Pending Action frame packet return EBUSY",
                          __func__);
            return -EBUSY;
        }
    }

    if( subType == SIR_MAC_MGMT_ACTION)
    {
        hddLog( LOG1, "Action frame tx request : %s",
            hdd_getActionString(buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET]));
    }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    if ( (( WLAN_HDD_SOFTAP == pAdapter->device_mode ) ||
          ( WLAN_HDD_P2P_GO == pAdapter->device_mode )) &&
          (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)))
    {
        home_ch = pAdapter->sessionCtx.ap.operatingChannel;
    }
    else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
            (pAdapter->sessionCtx.station.conn_info.connState ==
             eConnectionState_Associated))
    {
        home_ch = pAdapter->sessionCtx.station.conn_info.operationChannel;
    }
    else
    {
        pGoAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
        if (pGoAdapter && test_bit(SOFTAP_BSS_STARTED,
                                   &pGoAdapter->event_flags))
            home_ch = pGoAdapter->sessionCtx.ap.operatingChannel;
    }

    //If GO adapter exists and operating on same frequency
    //then we will not request remain on channel
    if (ieee80211_frequency_to_channel(chan->center_freq) == home_ch)
    {
        /*  if GO exist and is not off channel
         *  wait time should be zero.
         */
        wait = 0;
        goto send_frame;
    }
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    if( offchan && wait)
    {
        int status;
        rem_on_channel_request_type_t req_type = OFF_CHANNEL_ACTION_TX;
        // In case of P2P Client mode if we are already
        // on the same channel then send the frame directly
        mutex_lock(&pHddCtx->roc_lock);
        pRemainChanCtx = cfgState->remain_on_chan_ctx;
        if( (pRemainChanCtx != NULL) &&
            (cfgState->current_freq == chan->center_freq)
          )
        {
            if ( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(
                      &pRemainChanCtx->hdd_remain_on_chan_timer) )
            {
               /* Some times FW is taking almost 500 msec for
                * full 15 retries, which leads to ROC expiration
                * by the time peer gets response from other peer.
                * Therefore as part of temporary fix , in host
                * ROC time is extended. For frames where we are
                * expecting response from peer , its extended by
                * 500 msec to make ROC wait time as 1 sec and
                * in other cases its extended by 300 msec to make
                * total ROC wait as 500 msec.
                * TODO: FW needs to fix as why 15 retry is taking
                *       such long time.
                */
                if ( actionFrmType == WLAN_HDD_INVITATION_REQ ||
                     actionFrmType == WLAN_HDD_GO_NEG_REQ ||
                     actionFrmType == WLAN_HDD_GO_NEG_RESP )
                   wait = wait + ACTION_FRAME_RSP_WAIT;
                else if ( actionFrmType == WLAN_HDD_GO_NEG_CNF ||
                          actionFrmType == WLAN_HDD_INVITATION_RESP )
                   wait = wait + ACTION_FRAME_ACK_WAIT;

                if (!VOS_IS_STATUS_SUCCESS(vos_timer_stop(
                                &pRemainChanCtx->hdd_remain_on_chan_timer)))
                {
                    hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer"));
                }
                status = vos_timer_start(
                       &pRemainChanCtx->hdd_remain_on_chan_timer,
                       wait);

                mutex_unlock(&pHddCtx->roc_lock);

                hddLog(VOS_TRACE_LEVEL_INFO,
                   "action frame: extending the wait time %u",
                   wait);

                if ( status != VOS_STATUS_SUCCESS )
                {
                    hddLog( LOGE, "Remain on Channel timer start failed");
                }
                goto send_frame;
            }
            else
            {
                if ( TRUE ==
                     pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
                {
                    mutex_unlock(&pHddCtx->roc_lock);
                    hddLog(VOS_TRACE_LEVEL_INFO,
                           "action frame tx: waiting for completion of ROC ");

                    status = wait_for_completion_interruptible_timeout(
                                       &pAdapter->cancel_rem_on_chan_var,
                                       msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
                    if (0 >= status)
                    {
                        hddLog( LOGE,
                               "%s:wait on cancel_rem_on_chan_var failed %d",
                                __func__, status);
                    }
                    goto bypass_lock;
                }
            }
        }
        mutex_unlock(&pHddCtx->roc_lock);
bypass_lock:
        hddLog(VOS_TRACE_LEVEL_INFO,
               "action frame: Request ROC for wait time %u", wait);
        INIT_COMPLETION(pAdapter->offchannel_tx_event);
        status = wlan_hdd_request_remain_on_channel(wiphy, dev,
                                        chan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                                        channel_type,
#endif
                                        wait, cookie,
                                        req_type);

        if(0 != status)
        {
            if( (-EBUSY == status) &&
                (cfgState->current_freq == chan->center_freq) )
            {
                goto send_frame;
            }
            goto err_rem_channel;
        }
        /* Wait for driver to be ready on the requested channel */
        status = wait_for_completion_interruptible_timeout(
                     &pAdapter->offchannel_tx_event,
                     msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX));
        if(0 >= status)
        {
            hddLog( LOGE, "wait on offchannel_tx_event failed %d", status);
            goto err_rem_channel;
        }
    }
    else if ( offchan )
    {
        /* Check before sending action frame
           whether we already remain on channel */
        if(NULL == cfgState->remain_on_chan_ctx)
        {
            goto err_rem_channel;
        }
    }
    send_frame:
#endif

    if(!noack)
    {
        cfgState->buf = vos_mem_malloc( len ); //buf;
        if( cfgState->buf == NULL )
            return -ENOMEM;

        cfgState->len = len;

        vos_mem_copy( cfgState->buf, buf, len);

        mutex_lock(&pHddCtx->roc_lock);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
        if( cfgState->remain_on_chan_ctx )
        {
            cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie;
            *cookie = cfgState->action_cookie;
        }
        else
        {
#endif
            *cookie = (uintptr_t) cfgState->buf;
            cfgState->action_cookie = *cookie;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
        }
#endif
        mutex_unlock(&pHddCtx->roc_lock);
    }

    if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
         (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
         ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
       )
    {
        tANI_U8 sessionId = pAdapter->sessionId;

        if ((type == SIR_MAC_MGMT_FRAME) &&
                (subType == SIR_MAC_MGMT_ACTION) &&
            wlan_hdd_is_type_p2p_action(
             &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET],
             len - mgmt_hdr_len))
        {
            actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
            hddLog(LOG1, "Tx Action Frame %u.", actionFrmType);
            if (actionFrmType == WLAN_HDD_PROV_DIS_REQ)
            {
                cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING;
                hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING.", __func__);
            }
            else if (actionFrmType == WLAN_HDD_GO_NEG_REQ)
            {
                cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING;
                hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING.", __func__);
            }
        }

        if (eHAL_STATUS_SUCCESS !=
               sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter),
                               sessionId, buf, len, wait, noack))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "%s: sme_sendAction returned fail", __func__);
            goto err;
        }
    }
    else if( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
            ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
           )
     {
        if( VOS_STATUS_SUCCESS !=
             WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                  buf, len, 0 ) )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: WLANSAP_SendAction returned fail", __func__);
            goto err;
        }
    }

    return 0;
err:
    if(!noack)
    {
       hdd_sendActionCnf( pAdapter, FALSE );
    }
    return 0;
err_rem_channel:
    *cookie = (uintptr_t)cfgState;
    cfg80211_mgmt_tx_status(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                            pAdapter->dev->ieee80211_ptr,
#else
                            pAdapter->dev,
#endif
                            *cookie, buf, len, FALSE, GFP_KERNEL );
    EXIT();
    return 0;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                     struct cfg80211_mgmt_tx_params *params, u64 *cookie)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
                     struct ieee80211_channel *chan, bool offchan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid,
#endif
                     unsigned int wait,
                     const u8 *buf, size_t len,  bool no_cck,
                     bool dont_wait_for_ack, u64 *cookie )
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
                     struct ieee80211_channel *chan, bool offchan,
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid, unsigned int wait,
                     const u8 *buf, size_t len,  bool no_cck,
                     bool dont_wait_for_ack, u64 *cookie )
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
                     struct ieee80211_channel *chan, bool offchan,
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid, unsigned int wait,
                     const u8 *buf, size_t len, u64 *cookie )
#else
int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
                     struct ieee80211_channel *chan,
                     enum nl80211_channel_type channel_type,
                     bool channel_type_valid,
                     const u8 *buf, size_t len, u64 *cookie )
#endif //LINUX_VERSION_CODE
{
    int ret;

    vos_ssr_protect(__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    ret =  __wlan_hdd_mgmt_tx(wiphy, wdev, params->chan, params->offchan,
                              params->wait, params->buf, params->len,
                              params->no_cck, params->dont_wait_for_ack,
                              cookie);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    ret =  __wlan_hdd_mgmt_tx(wiphy, wdev,
                              chan, offchan,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                              channel_type,
                              channel_type_valid,
#endif
                              wait,
                              buf, len, no_cck,
                              dont_wait_for_ack, cookie);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
    ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
                             channel_type, channel_type_valid, wait,
                             buf, len,  no_cck,
                             dont_wait_for_ack, cookie);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
                     channel_type, channel_type_valid, wait,
                     buf, len, cookie);
#else
    ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, channel_type,
                             channel_type_valid, buf, len, cookie);
#endif //LINUX_VERSION_CODE
    vos_ssr_unprotect(__func__);

    return ret;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
                                          struct wireless_dev *wdev,
                                          u64 cookie)
{
    u64 cookie_dummy;
    cookie_dummy = cookie << 32;
    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, NO_SESSION, cookie_dummy));
    return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, wdev, cookie );
}
#else
int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
                                          struct net_device *dev,
                                          u64 cookie)
{
    u64 cookie_dummy;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    cookie_dummy = cookie << 32;
    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT,
                     pAdapter->sessionId, cookie_dummy));
    return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, dev, cookie );
}
#endif
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
                                          struct wireless_dev *wdev,
                                          u64 cookie)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie);
    vos_ssr_unprotect(__func__);

    return ret;
}
#else
int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
                                          struct net_device *dev,
                                          u64 cookie)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, dev, cookie);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif
#endif

void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess )
{
    hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );

    cfgState->actionFrmState = HDD_IDLE;

    if( NULL == cfgState->buf )
    {
        return;
    }
    if (cfgState->is_go_neg_ack_received)
    {
        cfgState->is_go_neg_ack_received = 0;
        /* Sometimes its possible that host may receive the ack for GO
         * negotiation req after sending go negotaition confirmation,
         * in such case drop the ack received for the go negotiation
         * request, so that supplicant waits for the confirmation ack
         * from firmware.
         */
        hddLog( LOG1, FL("Drop the pending ack received in cfgState->actionFrmState %d"),
                cfgState->actionFrmState);
        return;
    }

    hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess);

    /* If skb is NULL it means this packet was received on CFG80211 interface
     * else it was received on Monitor interface */
    if( cfgState->skb == NULL )
    {
        /*
         * buf is the same pointer it passed us to send. Since we are sending
         * it through control path, we use different buffers.
         * In case of mac80211, they just push it to the skb and pass the same
         * data while sending tx ack status.
         * */
         cfg80211_mgmt_tx_status(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                pAdapter->dev->ieee80211_ptr,
#else
                pAdapter->dev,
#endif
                cfgState->action_cookie,
                cfgState->buf, cfgState->len, actionSendSuccess, GFP_KERNEL );
         vos_mem_free( cfgState->buf );
         cfgState->buf = NULL;
    }
    else
    {
        hdd_adapter_t* pMonAdapter =
                    hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR );
        if( pMonAdapter == NULL )
        {
            hddLog( LOGE, "Not able to get Monitor Adapter");
            cfgState->skb = NULL;
            vos_mem_free( cfgState->buf );
            cfgState->buf = NULL;
            complete(&pAdapter->tx_action_cnf_event);
            return;
        }
        /* Send TX completion feedback over monitor interface. */
        hdd_wlan_tx_complete( pMonAdapter, cfgState, actionSendSuccess );
        cfgState->skb = NULL;
        vos_mem_free( cfgState->buf );
        cfgState->buf = NULL;
        /* Look for the next Mgmt packet to TX */
        hdd_mon_tx_mgmt_pkt(pAdapter);
    }
    complete(&pAdapter->tx_action_cnf_event);
}

/**
 * hdd_setP2pNoa
 *
 *FUNCTION:
 * This function is called from hdd_hostapd_ioctl function when Driver
 * get P2P_SET_NOA comand from wpa_supplicant using private ioctl
 *
 *LOGIC:
 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
 *
 *ASSUMPTIONS:
 *
 *
 *NOTE:
 *
 * @param  dev         Pointer to net device structure
 * @param  command     Pointer to command
 *
 * @return Status
 */

int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tP2pPsConfig NoA;
    int count, duration, start_time;
    char *param;
    tANI_U8 ret = 0;

    param = strnchr(command, strlen(command), ' ');
    if (param == NULL)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: strnchr failed to find delimeter",__func__);
          return -EINVAL;
    }
    param++;
    ret = sscanf(param, "%d %d %d", &count, &start_time, &duration);
    if (ret < 3)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: P2P_SET GO NoA: fail to read param "
               "count=%d duration=%d interval=%d ",
                __func__, count, start_time, duration);
        return -EINVAL;
    }
    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s: P2P_SET GO NoA: count=%d duration=%d interval=%d",
                __func__, count, start_time, duration);
    duration = MS_TO_MUS(duration);
    /* PS Selection
     * Periodic NoA (2)
     * Single NOA   (4)
     */
    NoA.opp_ps = 0;
    NoA.ctWindow = 0;
    if (count == 1)
    {
        NoA.duration = 0;
        NoA.single_noa_duration = duration;
        NoA.psSelection = P2P_POWER_SAVE_TYPE_SINGLE_NOA;
    }
    else
    {
        NoA.duration = duration;
        NoA.single_noa_duration = 0;
        NoA.psSelection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA;
    }
    NoA.interval = MS_TO_MUS(100);
    NoA.count = count;
    NoA.sessionid = pAdapter->sessionId;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
                "interval %d count %d single noa duration %d "
                "PsSelection %x", __func__, NoA.opp_ps,
                NoA.ctWindow, NoA.duration, NoA.interval, 
                NoA.count, NoA.single_noa_duration,
                NoA.psSelection);

    sme_p2pSetPs(hHal, &NoA);
    return status;
}

/**
 * hdd_setP2pOpps
 *
 *FUNCTION:
 * This function is called from hdd_hostapd_ioctl function when Driver
 * get P2P_SET_PS comand from wpa_supplicant using private ioctl
 *
 *LOGIC:
 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
 *
 *ASSUMPTIONS:
 *
 *
 *NOTE:
 *
 * @param  dev         Pointer to net device structure
 * @param  command     Pointer to command
 *
 * @return Status
 */

int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tP2pPsConfig NoA;
    char *param;
    int legacy_ps, opp_ps, ctwindow;
    tANI_U8 ret = 0;

    param = strnchr(command, strlen(command), ' ');
    if (param == NULL)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: strnchr failed to find delimeter",__func__);
        return -EINVAL;
    }
    param++;
    ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow);
    if (ret < 3)
    {
        VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: P2P_SET GO PS: fail to read param "
                 " legacy_ps=%d opp_ps=%d ctwindow=%d ",
                 __func__, legacy_ps, opp_ps, ctwindow);
        return -EINVAL;
    }
    VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d",
                 __func__, legacy_ps, opp_ps, ctwindow);

    /* PS Selection
     * Opportunistic Power Save (1)
     */

    /* From wpa_cli user need to use separate command to set ctWindow and Opps
     * When user want to set ctWindow during that time other parameters
     * values are coming from wpa_supplicant as -1.
     * Example : User want to set ctWindow with 30 then wpa_cli command :
     * P2P_SET ctwindow 30
     * Command Received at hdd_hostapd_ioctl is as below:
     * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30)
     */
    if (ctwindow != -1)
    {

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "Opportunistic Power Save is %s",
                    (TRUE == pAdapter->ops) ? "Enable" : "Disable" );

        if (ctwindow != pAdapter->ctw)
        {
            pAdapter->ctw = ctwindow;

            if(pAdapter->ops)
            {
                NoA.opp_ps = pAdapter->ops;
                NoA.ctWindow = pAdapter->ctw;
                NoA.duration = 0;
                NoA.single_noa_duration = 0;
                NoA.interval = 0;
                NoA.count = 0;
                NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
                NoA.sessionid = pAdapter->sessionId;

                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                            "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
                            "interval %d count %d single noa duration %d "
                            "PsSelection %x", __func__, NoA.opp_ps,
                            NoA.ctWindow, NoA.duration, NoA.interval, 
                            NoA.count, NoA.single_noa_duration,
                            NoA.psSelection);

               sme_p2pSetPs(hHal, &NoA);
           }
           return 0;
        }
    }

    if (opp_ps != -1)
    {
        pAdapter->ops = opp_ps;

        if ((opp_ps != -1) && (pAdapter->ctw))
        {
            NoA.opp_ps = opp_ps;
            NoA.ctWindow = pAdapter->ctw;
            NoA.duration = 0;
            NoA.single_noa_duration = 0;
            NoA.interval = 0;
            NoA.count = 0;
            NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
            NoA.sessionid = pAdapter->sessionId;

            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
                        "interval %d count %d single noa duration %d "
                        "PsSelection %x", __func__, NoA.opp_ps,
                        NoA.ctWindow, NoA.duration, NoA.interval, 
                        NoA.count, NoA.single_noa_duration,
                        NoA.psSelection);

           sme_p2pSetPs(hHal, &NoA);
        }
    }
    return status;
}

int hdd_setP2pPs( struct net_device *dev, void *msgData )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tP2pPsConfig NoA;
    p2p_app_setP2pPs_t *pappNoA = (p2p_app_setP2pPs_t *) msgData;

    NoA.opp_ps = pappNoA->opp_ps;
    NoA.ctWindow = pappNoA->ctWindow;
    NoA.duration = pappNoA->duration;
    NoA.interval = pappNoA->interval;
    NoA.count = pappNoA->count;
    NoA.single_noa_duration = pappNoA->single_noa_duration;
    NoA.psSelection = pappNoA->psSelection;
    NoA.sessionid = pAdapter->sessionId;

    sme_p2pSetPs(hHal, &NoA);
    return status;
}

static tANI_U8 wlan_hdd_get_session_type( enum nl80211_iftype type )
{
    tANI_U8 sessionType;

    switch( type )
    {
        case NL80211_IFTYPE_AP:
            sessionType = WLAN_HDD_SOFTAP;
            break;
        case NL80211_IFTYPE_P2P_GO:
            sessionType = WLAN_HDD_P2P_GO;
            break;
        case NL80211_IFTYPE_P2P_CLIENT:
            sessionType = WLAN_HDD_P2P_CLIENT;
            break;
        case NL80211_IFTYPE_STATION:
            sessionType = WLAN_HDD_INFRA_STATION;
            break;
        case NL80211_IFTYPE_MONITOR:
            sessionType = WLAN_HDD_MONITOR;
            break;
        default:
            sessionType = WLAN_HDD_INFRA_STATION;
            break;
    }

    return sessionType;
}

/**
 * hdd_close_all_adapters_per_mode() - close all adapters per mode
 * @hdd_ctx: pointer to hdd context
 * @mode: all adapters to be deleted in this mode
 *
 * Return: None
 */
static void
hdd_close_all_adapters_per_mode(hdd_context_t *hdd_ctx,
				uint32_t mode)
{
	hdd_adapter_t *adapter = hdd_get_adapter(hdd_ctx, mode);

	while (adapter) {
		hdd_stop_adapter(hdd_ctx, adapter, VOS_TRUE);
		hdd_deinit_adapter(hdd_ctx, adapter, TRUE);
		hdd_close_adapter(hdd_ctx, adapter, VOS_TRUE);

		adapter = hdd_get_adapter(hdd_ctx, mode);
	}
}

static void wlan_hdd_create_p2p_adapter(hdd_context_t *hdd_ctx,
					tANI_U8 rtnl_held)
{
	hdd_adapter_t *p2p_adapter;

	p2p_adapter = hdd_open_adapter(hdd_ctx, WLAN_HDD_P2P_DEVICE, "p2p%d",
				       &hdd_ctx->p2pDeviceAddress.bytes[0],
				       rtnl_held);
	if (!p2p_adapter)
		hddLog(LOGE,
		 FL("Failed to do hdd_open_adapter for P2P Device Interface"));
}

/**
 * wlan_hdd_add_monitor_check() - check for monitor intf and add if needed
 * @hdd_ctx: pointer to hdd context
 * @adapter: output pointer to hold created monitor adapter
 * @type: type of the interface
 * @name: name of the interface
 *
 * Return: 0 - on success
 *         1 - on failure
 */
static int
wlan_hdd_add_monitor_check(hdd_context_t *hdd_ctx, hdd_adapter_t **adapter,
			   enum nl80211_iftype type, const char *name)
{
	hdd_adapter_t *sta_adapter;
	hdd_adapter_t *mon_adapter;
	uint32_t i;

	*adapter = NULL;

	/*
	 * If add interface request is for monitor mode, then it can run in
	 * parallel with only one station interface.
	 * If there is no existing station interface return error
	 */
	if (type != NL80211_IFTYPE_MONITOR)
		return 0;

	if (!sme_IsFeatureSupportedByFW(STA_MONITOR_SCC)) {
		hddLog(LOGE, FL("No FW support for STA + MON SCC"));
		return -EINVAL;
	}

	if (hdd_ctx->no_of_open_sessions[VOS_MONITOR_MODE]) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: monitor mode already exists, only one is possible",
		       __func__);

		return -EBUSY;
	}

	/* Ensure there is only one station interface */
	if (hdd_ctx->no_of_open_sessions[VOS_STA_MODE] != 1) {
		hddLog(LOGE,
		 FL("cannot add monitor mode, due to %u sta interfaces"),
		 hdd_ctx->no_of_open_sessions[VOS_STA_MODE]);

		return -EINVAL;
	}

	sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
	if (!sta_adapter) {
		hddLog(LOGE, FL("No station adapter"));
		return -EINVAL;
	}

	/* delete all the other interfaces */
	for (i = VOS_STA_SAP_MODE; i <= VOS_P2P_DEVICE; i++) {
		if (i == VOS_FTM_MODE || i == VOS_MONITOR_MODE)
			continue;

		hdd_close_all_adapters_per_mode(hdd_ctx, i);
	}

	mon_adapter = hdd_open_adapter(hdd_ctx, WLAN_HDD_MONITOR, name,
				       wlan_hdd_get_intf_addr(hdd_ctx),
				       VOS_TRUE);
	if (!mon_adapter) {
		hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",
		       __func__);
		wlan_hdd_create_p2p_adapter(hdd_ctx, TRUE);
		return -EINVAL;
	}

	*adapter = mon_adapter;
	return 0;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
static struct wireless_dev *
__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
			    const char *name,
			    unsigned char name_assign_type,
			    enum nl80211_iftype type,
			    u32 *flags,
			    struct vif_params *params)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static struct net_device *
__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
			    const char *name,
			    unsigned char name_assign_type,
			    enum nl80211_iftype type,
			    u32 *flags,
			    struct vif_params *params)
#else
static int
__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
			    const char *name,
			    unsigned char name_assign_type,
			    enum nl80211_iftype type,
			    u32 *flags,
			    struct vif_params *params)
#endif
{
    hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
    hdd_adapter_t *pAdapter = NULL;
    hdd_scaninfo_t *pScanInfo = NULL;
    int ret = 0;

    ENTER();

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
       return ERR_PTR(-EINVAL);
#else
       return -EAGAIN;
#endif
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type));
    if (WLAN_HDD_P2P_CLIENT != wlan_hdd_get_session_type(type) &&
            WLAN_HDD_INFRA_STATION != wlan_hdd_get_session_type(type) &&
            hdd_get_adapter(pHddCtx, wlan_hdd_get_session_type(type)) != NULL)
    {
       hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Interface type %d already exists. Two"
                     "interfaces of same type are not supported currently.",__func__, type);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
       return ERR_PTR(-EINVAL);
#else
       return -EAGAIN;
#endif
    }

    if (pHddCtx->concurrency_mode == VOS_STA_MON) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: STA + MONITOR mode is in progress, cannot add new interface",
               __func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
       return ERR_PTR(-EINVAL);
#else
        return -EBUSY;
#endif
    }

    pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
    pScanInfo =  &pHddCtx->scan_info;
    if ((pScanInfo != NULL) && (pAdapter != NULL) &&
        (pHddCtx->scan_info.mScanPending))
    {
        hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
                           eCSR_SCAN_ABORT_DEFAULT);
        hddLog(VOS_TRACE_LEVEL_INFO,
               "%s: Abort Scan while adding virtual interface",__func__);
    }

    ret = wlan_hdd_add_monitor_check(pHddCtx, &pAdapter, type, name);
    if (ret) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
       return ERR_PTR(-EINVAL);
#else
       return ret;
#endif
    }

    if (pAdapter)
        goto return_adapter;

    pAdapter = NULL;
    if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated &&
        ((NL80211_IFTYPE_P2P_GO == type) ||
         (NL80211_IFTYPE_P2P_CLIENT == type)))
    {
            /* Generate the P2P Interface Address. this address must be
             * different from the P2P Device Address.
             */
            v_MACADDR_t p2pDeviceAddress = pHddCtx->p2pDeviceAddress;
            p2pDeviceAddress.bytes[4] ^= 0x80;
            pAdapter = hdd_open_adapter( pHddCtx,
                                         wlan_hdd_get_session_type(type),
                                         name, p2pDeviceAddress.bytes,
                                         VOS_TRUE );
    }
    else
    {
       pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type),
                          name, wlan_hdd_get_intf_addr(pHddCtx), VOS_TRUE );
    }

    if( NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
        return ERR_PTR(-EINVAL);
#else
        return -EINVAL;
#endif
    }

    if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO ||
        type == NL80211_IFTYPE_AP)
    {
        /* Below function Notifies Mode change and
         * If p2p session is detected then invokes functionality to
         * Teardown TDLS links and disable offchannel if any. Since
         * TDLS is not supported in case of concurrency.
         */
        hddLog(LOG1, FL("Interface type = %d"), type);
        hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
    }

return_adapter:

    EXIT();
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    return pAdapter->dev->ieee80211_ptr;
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    return pAdapter->dev;
#else
    return 0;
#endif
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
					       const char *name,
					       unsigned char name_assign_type,
					       enum nl80211_iftype type,
					       struct vif_params *params)
{
	struct wireless_dev *wdev;

	vos_ssr_protect(__func__);
	wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
					   type, &params->flags, params);
	vos_ssr_unprotect(__func__);

	return wdev;
}
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) || \
	defined(WITH_BACKPORTS)
/**
 * wlan_hdd_add_virtual_intf() - Add virtual interface wrapper
 * @wiphy: wiphy pointer
 * @name: User-visible name of the interface
 * @name_assign_type: the name of assign type of the netdev
 * @nl80211_iftype: (virtual) interface types
 * @flags: monitor mode configuration flags (not used)
 * @vif_params: virtual interface parameters (not used)
 *
 * Return: the pointer of wireless dev, otherwise ERR_PTR.
 */
struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
                                               const char *name,
                                               unsigned char name_assign_type,
                                               enum nl80211_iftype type,
                                               u32 *flags,
                                               struct vif_params *params)
{
        struct wireless_dev *wdev;

        vos_ssr_protect(__func__);
        wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
                                           type, flags, params);
        vos_ssr_unprotect(__func__);
        return wdev;

}
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
/**
 * wlan_hdd_add_virtual_intf() - Add virtual interface wrapper
 * @wiphy: wiphy pointer
 * @name: User-visible name of the interface
 * @nl80211_iftype: (virtual) interface types
 * @flags: monitor mode configuration flags (not used)
 * @vif_params: virtual interface parameters (not used)
 *
 * Return: the pointer of wireless dev, otherwise ERR_PTR.
 */
struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
                                               const char *name,
                                               enum nl80211_iftype type,
                                               u32 *flags,
                                               struct vif_params *params)
{
        struct wireless_dev *wdev;
        unsigned char name_assign_type = 0;

        vos_ssr_protect(__func__);
        wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
                                           type, flags, params);
        vos_ssr_unprotect(__func__);
        return wdev;

}

#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
struct wireless_dev* wlan_hdd_add_virtual_intf(
                  struct wiphy *wiphy, char *name, enum nl80211_iftype type,
                  u32 *flags, struct vif_params *params )
{
        struct wireless_dev *wdev;
        unsigned char name_assign_type = 0;

        vos_ssr_protect(__func__);
        wdev = __wlan_hdd_add_virtual_intf(wiphy, (const char *)name,
                                           name_assign_type,
                                           type, flags, params);
        vos_ssr_unprotect(__func__);
        return wdev;

}

#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
struct net_device* wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
					     char *name,
					     enum nl80211_iftype type,
					     u32 *flags,
					     struct vif_params *params)
{
	struct net_device *ndev;
	unsigned char name_assign_type = 0;

	vos_ssr_protect(__func__);
	ndev = __wlan_hdd_add_virtual_intf(wiphy, (const char *)name, name_assign_type,
                                           type, flags, params);
        vos_ssr_unprotect(__func__);
        return wdev;

}
#else
int wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
			      enum nl80211_iftype type,
			      u32 *flags, struct vif_params *params)
{
	int ret;
	unsigned char name_assign_type = 0;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_add_virtual_intf(wiphy, (const char *)name, name_assign_type,
                                           type, flags, params);
        vos_ssr_unprotect(__func__);

        return ret;
}
#endif

/**
 * hdd_delete_adapter() - stop and close adapter
 * @hdd_ctx: pointer to hdd context
 * @adapter: adapter to be deleted
 * @rtnl_held: rtnl lock held
 *
 * Rerurn: None
 */
static void
hdd_delete_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
		   tANI_U8 rtnl_held)
{
	wlan_hdd_release_intf_addr(hdd_ctx, adapter->macAddressCurrent.bytes);
	hdd_stop_adapter(hdd_ctx, adapter, VOS_TRUE);
	hdd_deinit_adapter(hdd_ctx, adapter, TRUE);
	hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
}

/**
 * wlan_hdd_del_monitor() - delete monitor interface
 * @hdd_ctx: pointer to hdd context
 * @adapter: adapter to be deleted
 * @rtnl_held: rtnl lock held
 *
 * This function is invoked to delete monitor interface and also
 * station interface if needed.
 *
 * Return: None
 */
static void
wlan_hdd_del_monitor(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
		     tANI_U8 rtnl_held)
{
	hdd_adapter_t *monitor_adapter;
	bool delete_station = false;

	monitor_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
	if (monitor_adapter != adapter)
		delete_station = true;

	/* delete the monitor adapter and re-create the p2p-dev adapter */
	hdd_delete_adapter(hdd_ctx, monitor_adapter, rtnl_held);

	wlan_hdd_create_p2p_adapter(hdd_ctx, rtnl_held);

	if (delete_station)
		hdd_delete_adapter(hdd_ctx, adapter, rtnl_held);
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
#else
int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
#endif
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    struct net_device *dev = wdev->netdev;
#endif
    hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    int status;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_DEL_VIRTUAL_INTF,
                     pAdapter->sessionId, pAdapter->device_mode));
    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
           __func__,pAdapter->device_mode);

    status = wlan_hdd_validate_context(pHddCtx);

    if (0 != status)
    {
        return status;
    }

    if (pHddCtx->concurrency_mode == VOS_STA_MON)
        wlan_hdd_del_monitor(pHddCtx, pAdapter, TRUE);
    else
        hdd_delete_adapter(pHddCtx, pAdapter, TRUE);

    EXIT();
    return 0;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
#else
int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
#endif
{
    int ret;

    vos_ssr_protect(__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    ret = __wlan_hdd_del_virtual_intf(wiphy, wdev);
#else
    ret = __wlan_hdd_del_virtual_intf(wiphy, dev);
#endif
    vos_ssr_unprotect(__func__);

    return ret;
}

void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
                                        tANI_U32 nFrameLength,
                                        tANI_U8* pbFrames,
                                        tANI_U8 frameType )
{
    //Indicate a Frame over Monitor Intf.
    int rxstat;
    struct sk_buff *skb = NULL;
    int needed_headroom = 0;
    int flag = HDD_RX_FLAG_IV_STRIPPED | HDD_RX_FLAG_DECRYPTED |
               HDD_RX_FLAG_MMIC_STRIPPED;
#ifdef WLAN_OPEN_SOURCE
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
    hdd_context_t* pHddCtx = (hdd_context_t*)(pMonAdapter->pHddCtx);
#endif
#endif
    hddLog( LOG1, FL("Indicate Frame over Monitor Intf"));

    if (NULL == pbFrames)
    {
        hddLog(LOGE, FL("NULL frame pointer"));
        return;
    }

    /* room for the radiotap header based on driver features
     * 1 Byte for RADIO TAP Flag, 1 Byte padding and 2 Byte for
     * RX flags.
     * */
     needed_headroom = sizeof(struct ieee80211_radiotap_header) + 4;

     //alloc skb  here
     skb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC);
     if (unlikely(NULL == skb))
     {
         hddLog( LOGW, FL("Unable to allocate skb"));
         return;
     }
     skb_reserve(skb, VPKT_SIZE_BUFFER);
     if (unlikely(skb_headroom(skb) < nFrameLength))
     {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "HDD [%d]: Insufficient headroom, "
                   "head[%pK], data[%pK], req[%d]",
                   __LINE__, skb->head, skb->data, nFrameLength);
         kfree_skb(skb);
         return ;
     }
     // actually push the data
     memcpy(skb_push(skb, nFrameLength), pbFrames, nFrameLength);
     /* prepend radiotap information */
     if( 0 != hdd_wlan_add_rx_radiotap_hdr( skb, needed_headroom, flag ) )
     {
         hddLog( LOGE, FL("Not Able Add Radio Tap"));
         //free skb
         kfree_skb(skb);
         return ;
     }

     skb_reset_mac_header( skb );
     skb->dev = pMonAdapter->dev;
     skb->protocol = eth_type_trans( skb, skb->dev );
     skb->ip_summed = CHECKSUM_NONE;
#ifdef WLAN_OPEN_SOURCE
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
     vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
                                   HDD_WAKE_LOCK_DURATION,
                                   WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
#endif
#endif
     rxstat = netif_rx_ni(skb);
     if( NET_RX_SUCCESS == rxstat )
     {
         hddLog( LOG1, FL("Success"));
     }
     else
         hddLog( LOGE, FL("Failed %d"), rxstat);

     return ;
}

void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
                            tANI_U32 nFrameLength,
                            tANI_U8* pbFrames,
                            tANI_U8 frameType,
                            tANI_U32 rxChan,
                            tANI_S8 rxRssi)
{
    tANI_U16 freq;
    tANI_U16 extend_time;
    tANI_U8 type = 0;
    tANI_U8 subType = 0;
    tActionFrmType actionFrmType;
    hdd_cfg80211_state_t *cfgState = NULL;
    hdd_scaninfo_t *pScanInfo = NULL;
    hdd_context_t *pHddCtx = NULL;
    VOS_STATUS status;
    hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;

    hddLog(VOS_TRACE_LEVEL_INFO, FL("Frame Type = %d Frame Length = %d"),
                     frameType, nFrameLength);

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

    if (0 == nFrameLength)
    {
        hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
        return;
    }

    if (NULL == pbFrames)
    {
        hddLog(LOGE, FL("pbFrames is NULL"));
        return;
    }

    type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
    subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);

    /* Get pAdapter from Destination mac address of the frame */
    if ((type == SIR_MAC_MGMT_FRAME) &&
        (subType != SIR_MAC_MGMT_PROBE_REQ) &&
        (nFrameLength > WLAN_HDD_80211_FRM_DA_OFFSET + VOS_MAC_ADDR_SIZE) &&
        !vos_is_macaddr_broadcast(
         (v_MACADDR_t *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]))
    {
         pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter),
                            &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]);
         if (NULL == pAdapter)
         {
             /* Under assumtion that we don't receive any action frame
              * with BCST as destination we dropping action frame
              */
             hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = "
                               MAC_ADDRESS_STR ,
                               MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]));
             hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d"
                              " subType = %d",__func__,frameType,nFrameLength,subType);
             return;
         }
    }


    if (NULL == pAdapter->dev)
    {
        hddLog( LOGE, FL("pAdapter->dev is NULL"));
        return;
    }

    if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
    {
        hddLog( LOGE, FL("pAdapter has invalid magic"));
        return;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (NULL == pHddCtx)
    {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
         return;
    }

    if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
        (WLAN_HDD_P2P_GO == pAdapter->device_mode ))
    {
        hdd_adapter_t *pMonAdapter =
            hdd_get_mon_adapter( WLAN_HDD_GET_CTX(pAdapter) );

        if (NULL != pMonAdapter)
        {
            hddLog( LOG1, FL("Indicate Frame over Monitor Interface"));
            hdd_sendMgmtFrameOverMonitorIface( pMonAdapter, nFrameLength,
                    pbFrames, frameType);
            return;
        }
    }

    //Channel indicated may be wrong. TODO
    //Indicate an action frame.
    if( rxChan <= MAX_NO_OF_2_4_CHANNELS )
    {
        freq = ieee80211_channel_to_frequency( rxChan,
                HDD_NL80211_BAND_2GHZ);
    }
    else
    {
        freq = ieee80211_channel_to_frequency( rxChan,
                HDD_NL80211_BAND_5GHZ);
    }

    cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );

    if ((type == SIR_MAC_MGMT_FRAME) &&
        (subType == SIR_MAC_MGMT_ACTION) &&
        (nFrameLength > WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1))
    {
        if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)
        {
            // public action frame
            if((WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + SIR_MAC_P2P_OUI_SIZE + 2 <
                nFrameLength) &&
               (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] ==
                SIR_MAC_ACTION_VENDOR_SPECIFIC) &&
                vos_mem_compare(&pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE))
            // P2P action frames
            {
                actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
                hddLog(LOG1, "Rx Action Frame %u", actionFrmType);
#ifdef WLAN_FEATURE_P2P_DEBUG
                if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] <--- OTA",
                                                                actionFrmType);
                }
                else
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s <--- OTA",
                    p2p_action_frame_type[actionFrmType]);
                    if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
                        (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
                    {
                         globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
                         hddLog(LOGE,"[P2P State]Inactive state to "
                           "GO negotiation progress state");
                    }
                    else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
                        (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
                    {
                         globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
                 hddLog(LOGE,"[P2P State]GO negotiation progress to "
                             "GO negotiation completed state");
                    }
                    else if( (actionFrmType == WLAN_HDD_INVITATION_REQ) &&
                        (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
                    {
                         globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
                         hddLog(LOGE,"[P2P State]Inactive state to GO negotiation"
                                     " completed state Autonomous GO formation");
                    }
                }
#endif
             mutex_lock(&pHddCtx->roc_lock);
             pRemainChanCtx = cfgState->remain_on_chan_ctx;

             if (pRemainChanCtx != NULL && VOS_TIMER_STATE_RUNNING
                                 == vos_timer_getCurrentState(&pRemainChanCtx->hdd_remain_on_chan_timer))
             {
                 if ( actionFrmType == WLAN_HDD_GO_NEG_REQ ||
                      actionFrmType == WLAN_HDD_GO_NEG_RESP ||
                      actionFrmType == WLAN_HDD_INVITATION_REQ ||
                      actionFrmType == WLAN_HDD_DEV_DIS_REQ ||
                      actionFrmType == WLAN_HDD_PROV_DIS_REQ )
                 {
                      hddLog( LOG1, "Extend RoC timer on reception of"
                              " Action Frame");
                      if ((actionFrmType == WLAN_HDD_GO_NEG_REQ)
                                  || (actionFrmType == WLAN_HDD_GO_NEG_RESP))
                              extend_time = 2 * ACTION_FRAME_DEFAULT_WAIT;
                      else
                              extend_time = ACTION_FRAME_DEFAULT_WAIT;
                      if (completion_done(&pAdapter->rem_on_chan_ready_event))
                      {
                          if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop(
                                   &pRemainChanCtx->hdd_remain_on_chan_timer)))
                          {
                              hddLog( LOGE, FL(
                                    "Failed to stop hdd_remain_on_chan_timer"));
                          }
                          status = vos_timer_start(
                                     &pRemainChanCtx->hdd_remain_on_chan_timer,
                                     extend_time);
                          if (status != VOS_STATUS_SUCCESS)
                          {
                              hddLog( LOGE, "ROC timer start failed");
                          }
                      }
                      else
                      {
                        // Buffer Packet
                          if (pRemainChanCtx->action_pkt_buff.frame_length == 0)
                          {
                              pRemainChanCtx->action_pkt_buff.frame_length =
                                                                  nFrameLength;
                              pRemainChanCtx->action_pkt_buff.freq = freq;
                              pRemainChanCtx->action_pkt_buff.frame_ptr
                                                = vos_mem_malloc(nFrameLength);
                              vos_mem_copy(
                                     pRemainChanCtx->action_pkt_buff.frame_ptr,
                                     pbFrames, nFrameLength);
                              hddLog( LOGE,"%s:"
                                "Action Pkt Cached successfully !!!", __func__);
                          }
                          else
                          {
                              hddLog( LOGE,"%s:"
                                      "Frames are pending. dropping frame !!!",
                                      __func__);
                          }
                          mutex_unlock(&pHddCtx->roc_lock);
                          return;
                      }
                 }
             }
             if (pRemainChanCtx != NULL &&
                  vos_timer_is_initialized(
                     &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer) &&
                  VOS_TIMER_STATE_RUNNING != vos_timer_getCurrentState(
                      &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer))
                 hddLog( LOG1, "%s:"
                         "Rcvd action frame after timer expired ", __func__);

             mutex_unlock(&pHddCtx->roc_lock);

             if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) &&
                   (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) ||
                  ((actionFrmType == WLAN_HDD_GO_NEG_RESP) &&
                   (cfgState->actionFrmState == HDD_GO_NEG_REQ_ACK_PENDING)))
             {
                 hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ",
                         __func__);
                 cfgState->is_go_neg_ack_received = 1;

                 hdd_sendActionCnf(pAdapter, TRUE);
             }
            }
#ifdef FEATURE_WLAN_TDLS
            else if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP)
            {
                u8 *mac = &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6];
                hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] TDLS Discovery Response," MAC_ADDRESS_STR " RSSI[%d] <--- OTA",
                 MAC_ADDR_ARRAY(mac),rxRssi);

                wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi);
                wlan_hdd_tdls_recv_discovery_resp(pAdapter, mac);
            }
#endif
        }

         pScanInfo =  &pHddCtx->scan_info;
         if ((pScanInfo != NULL) && (pHddCtx->scan_info.mScanPending))
         {
             hddLog(LOGE,"Action frame received when Scanning is in"
                          " progress. Abort Scan.");
             hdd_abort_mac_scan(pAdapter->pHddCtx,
                                pScanInfo->sessionId,
                                eCSR_SCAN_ABORT_DEFAULT);
         }

        if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_TDLS_ACTION_FRAME)
        {
            actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1];
            if(actionFrmType >= MAX_TDLS_ACTION_FRAME_TYPE)
            {
                hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] Action type[%d] <--- OTA",
                                                            actionFrmType);
            }
            else
            {
                hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] %s <--- OTA",
                    tdls_action_frame_type[actionFrmType]);
            }
            vos_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
              SIR_MAC_ACTION_RX, SIR_MAC_MGMT_ACTION,
              actionFrmType, &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6]);
        }

        if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_QOS_ACTION_FRAME)&&
             (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_QOS_MAP_CONFIGURE) )
        {
            sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
                pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
        }
    }

    //Indicate Frame Over Normal Interface
    hddLog( LOG1, FL("Indicate Frame over NL80211 Interface"));
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
    cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100, pbFrames,
                     nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
    cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100, pbFrames,
                     nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100,
                      pbFrames, nFrameLength,
                      GFP_ATOMIC );
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
    cfg80211_rx_mgmt( pAdapter->dev, freq, rxRssi * 100,
                      pbFrames, nFrameLength,
                      GFP_ATOMIC );
#else
    cfg80211_rx_mgmt( pAdapter->dev, freq,
                      pbFrames, nFrameLength,
                      GFP_ATOMIC );
#endif //LINUX_VERSION_CODE
}

/*
 * ieee80211_add_rx_radiotap_header - add radiotap header
 */
static int hdd_wlan_add_rx_radiotap_hdr (
             struct sk_buff *skb, int rtap_len, int flag )
{
    u8 rtap_temp[20] = {0};
    struct ieee80211_radiotap_header *rthdr;
    unsigned char *pos;
    u16 rx_flags = 0;

    rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]);

    /* radiotap header, set always present flags */
    rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS)   |
                                    (1 << IEEE80211_RADIOTAP_RX_FLAGS));
    rthdr->it_len = cpu_to_le16(rtap_len);

    pos = (unsigned char *) (rthdr + 1);

    /* the order of the following fields is important */

    /* IEEE80211_RADIOTAP_FLAGS */
    *pos = 0;
    pos++;

    /* IEEE80211_RADIOTAP_RX_FLAGS: Length 2 Bytes */
    /* ensure 2 byte alignment for the 2 byte field as required */
    if ((pos - (u8 *)rthdr) & 1)
        pos++;
    put_unaligned_le16(rx_flags, pos);
    pos += 2;

    // actually push the data
    memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len);

    return 0;
}

static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
                                  hdd_cfg80211_state_t* cfgState,
                                  tANI_BOOLEAN actionSendSuccess )
{
    struct ieee80211_radiotap_header *rthdr;
    unsigned char *pos;
    struct sk_buff *skb = cfgState->skb;
#ifdef WLAN_OPEN_SOURCE
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
    hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
#endif
#endif

    /* 2 Byte for TX flags and 1 Byte for Retry count */
    u32 rtHdrLen = sizeof(*rthdr) + 3;

    u8 *data;

    /* We have to return skb with Data starting with MAC header. We have
     * copied SKB data starting with MAC header to cfgState->buf. We will pull
     * entire skb->len from skb and then we will push cfgState->buf to skb
     * */
    if( NULL == skb_pull(skb, skb->len) )
    {
        hddLog( LOGE, FL("Not Able to Pull %d byte from skb"), skb->len);
        kfree_skb(cfgState->skb);
        return;
    }

    data = skb_push( skb, cfgState->len );

    if (data == NULL)
    {
        hddLog( LOGE, FL("Not Able to Push %zu byte to skb"), cfgState->len);
        kfree_skb( cfgState->skb );
        return;
    }

    memcpy( data, cfgState->buf, cfgState->len );

    /* send frame to monitor interfaces now */
    if( skb_headroom(skb) < rtHdrLen )
    {
        hddLog( LOGE, FL("No headroom for rtap header"));
        kfree_skb(cfgState->skb);
        return;
    }

    rthdr = (struct ieee80211_radiotap_header*) skb_push( skb, rtHdrLen );

    memset( rthdr, 0, rtHdrLen );
    rthdr->it_len = cpu_to_le16( rtHdrLen );
    rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
                                    (1 << IEEE80211_RADIOTAP_DATA_RETRIES)
                                   );

    pos = (unsigned char *)( rthdr+1 );

    // Fill TX flags
    *pos = actionSendSuccess;
    pos += 2;

    // Fill retry count
    *pos = 0;
    pos++;

    skb_set_mac_header( skb, 0 );
    skb->ip_summed = CHECKSUM_NONE;
    skb->pkt_type  = PACKET_OTHERHOST;
    skb->protocol  = htons(ETH_P_802_2);
    memset( skb->cb, 0, sizeof( skb->cb ) );
#ifdef WLAN_OPEN_SOURCE
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
    vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
                                  HDD_WAKE_LOCK_DURATION,
                                  WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
#endif
#endif
    if (in_interrupt())
        netif_rx( skb );
    else
        netif_rx_ni( skb );

    /* Enable Queues which we have disabled earlier */
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
    netif_tx_start_all_queues( pAdapter->dev );

}

void __hdd_p2p_roc_work_queue(struct work_struct *work)
{
    hdd_adapter_t *pAdapter = container_of(to_delayed_work(work), hdd_adapter_t, roc_work);
    hddLog( VOS_TRACE_LEVEL_INFO, FL("%s: "), __func__);
    wlan_hdd_p2p_start_remain_on_channel(pAdapter);
    return;
}

void hdd_p2p_roc_work_queue(struct work_struct *work)
{
    vos_ssr_protect(__func__);
    __hdd_p2p_roc_work_queue(work);
    vos_ssr_unprotect(__func__);
    return;
}
