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

#ifdef FEATURE_OEM_DATA_SUPPORT
/** ------------------------------------------------------------------------- *
    ------------------------------------------------------------------------- *


    \file oemDataApi.c

    Implementation for the OEM DATA REQ/RSP interfaces.
   ========================================================================== */
#include "aniGlobal.h"
#include "oemDataApi.h"
#include "palApi.h"
#include "smeInside.h"
#include "smsDebug.h"

#include "csrSupport.h"
#include "wlan_qct_tl.h"

#include "vos_diag_core_log.h"
#include "vos_diag_core_event.h"

/* ---------------------------------------------------------------------------
    \fn oemData_OemDataReqOpen
    \brief This function must be called before any API call to (OEM DATA REQ/RSP module)
    \return eHalStatus
  -------------------------------------------------------------------------------*/

eHalStatus oemData_OemDataReqOpen(tHalHandle hHal)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    do
    {
        //initialize all the variables to null
        vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
        if(!HAL_STATUS_SUCCESS(status))
        {
            smsLog(pMac, LOGE, "oemData_OemDataReqOpen: Cannot allocate memory for the timer function");
            break;
        }
    } while(0);

    return status;
}

/* ---------------------------------------------------------------------------
    \fn oemData_OemDataReqClose
    \brief This function must be called before closing the csr module
    \return eHalStatus
  -------------------------------------------------------------------------------*/

eHalStatus oemData_OemDataReqClose(tHalHandle hHal)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    do
    {
        if(!HAL_STATUS_SUCCESS(status))
        {
            smsLog(pMac, LOGE, "oemData_OemDataReqClose: Failed in oemData_OemDataReqClose at StopTimers");
            break;
        }

        if(pMac->oemData.pOemDataRsp != NULL)
        {
            vos_mem_free(pMac->oemData.pOemDataRsp);
        }

        //initialize all the variables to null
        vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
    } while(0);

    return eHAL_STATUS_SUCCESS;
}

/* ---------------------------------------------------------------------------
    \fn oemData_ReleaseOemDataReqCommand
    \brief This function removes the oemDataCommand from the active list and
           and frees up any memory occupied by this
    \return eHalStatus
  -------------------------------------------------------------------------------*/
void oemData_ReleaseOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataCmd, eOemDataReqStatus oemDataReqStatus)
{
    //Do the callback
    pOemDataCmd->u.oemDataCmd.callback(pMac, pOemDataCmd->u.oemDataCmd.pContext, pOemDataCmd->u.oemDataCmd.oemDataReqID, oemDataReqStatus);

    //First take this command out of the active list
    if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, &pOemDataCmd->Link, LL_ACCESS_LOCK))
    {
        vos_mem_set(&(pOemDataCmd->u.oemDataCmd), sizeof(tOemDataCmd), 0);

        //Now put this command back on the avilable command list
        smeReleaseCommand(pMac, pOemDataCmd);
    }
    else
    {
        smsLog(pMac, LOGE, "OEM_DATA: **************** oemData_ReleaseOemDataReqCommand cannot release the command");
    }
}

/* ---------------------------------------------------------------------------
    \fn oemData_OemDataReq
    \brief Request an OEM DATA RSP
    \param sessionId - Id of session to be used
    \param pOemDataReqID - pointer to an object to get back the request ID
    \param callback - a callback function that is called upon finish
    \param pContext - a pointer passed in for the callback
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus oemData_OemDataReq(tHalHandle hHal,
                                tANI_U8 sessionId,
                                tOemDataReqConfig *oemDataReqConfig,
                                tANI_U32 *pOemDataReqID,
                                oemData_OemDataReqCompleteCallback callback,
                                void *pContext)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tSmeCmd *pOemDataCmd = NULL;

    do
    {
        if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
           status = eHAL_STATUS_FAILURE;
           break;
        }

        pMac->oemData.oemDataReqConfig.sessionId = sessionId;
        pMac->oemData.callback = callback;
        pMac->oemData.pContext = pContext;
        pMac->oemData.oemDataReqID = *(pOemDataReqID);

        vos_mem_copy((v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq),
                     (v_VOID_t*)(oemDataReqConfig->oemDataReq),
                     OEM_DATA_REQ_SIZE);

        pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;

        pOemDataCmd = smeGetCommandBuffer(pMac);

        //fill up the command before posting it.
        if(pOemDataCmd)
        {
            pOemDataCmd->command = eSmeCommandOemDataReq;
            pOemDataCmd->u.oemDataCmd.callback = callback;
            pOemDataCmd->u.oemDataCmd.pContext = pContext;
            pOemDataCmd->u.oemDataCmd.oemDataReqID = pMac->oemData.oemDataReqID;

            //set the oem data request
            pOemDataCmd->u.oemDataCmd.oemDataReq.sessionId = pMac->oemData.oemDataReqConfig.sessionId;
            vos_mem_copy((v_VOID_t*)(pOemDataCmd->u.oemDataCmd.oemDataReq.oemDataReq),
                         (v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq),
                         OEM_DATA_REQ_SIZE);
        }
        else
        {
            status = eHAL_STATUS_FAILURE;
            break;
        }

        //now queue this command in the sme command queue
        //Here since this is not interacting with the csr just push the command
        //into the sme queue. Also push this command with the normal priority
        smePushCommand(pMac, pOemDataCmd, eANI_BOOLEAN_FALSE);

    } while(0);

    if(!HAL_STATUS_SUCCESS(status) && pOemDataCmd)
    {
        oemData_ReleaseOemDataReqCommand(pMac, pOemDataCmd, eOEM_DATA_REQ_FAILURE);
        pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
    }

    return status;
}

/* ---------------------------------------------------------------------------
    \fn oemData_SendMBOemDataReq
    \brief Request an OEM DATA REQ to be passed down to PE
    \param pMac:
    \param pOemDataReq: Pointer to the oem data request
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus oemData_SendMBOemDataReq(tpAniSirGlobal pMac, tOemDataReq *pOemDataReq)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSirOemDataReq* pMsg;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pOemDataReq->sessionId );

    smsLog(pMac, LOGW, "OEM_DATA: entering Function %s", __func__);

    pMsg = vos_mem_malloc(sizeof(*pMsg));
    if ( NULL == pMsg )
       status = eHAL_STATUS_FAILURE;
    else
       status = eHAL_STATUS_SUCCESS;
    if(HAL_STATUS_SUCCESS(status))
    {
	vos_mem_set(pMsg, sizeof(*pMsg), 0);
        pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_OEM_DATA_REQ);
	pMsg->messageLen = pal_cpu_to_be16((uint16_t) sizeof(*pMsg));
        vos_mem_copy(pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr) );
        vos_mem_copy(pMsg->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE);
        smsLog(pMac, LOGW, "OEM_DATA: sending message to pe%s", __func__);
        status = palSendMBMessage(pMac->hHdd, pMsg);
    }

    smsLog(pMac, LOGW, "OEM_DATA: exiting Function %s", __func__);

    return status;
}

/* ---------------------------------------------------------------------------
    \fn oemData_ProcessOemDataReqCommand
    \brief This function is called by the smeProcessCommand when the case hits
           eSmeCommandOemDataReq
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataReqCmd)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;

    //check if the system is in proper mode of operation for
    //oem data req/rsp to be functional. Currently, concurrency is not
    //supported and the driver must be operational only as
    //STA for oem data req/rsp to be functional. We return an invalid
    //mode flag if it is operational as any one of the following
    //in any of the active sessions
    //1. AP Mode
    //2. IBSS Mode
    //3. BTAMP Mode ...

    if(eHAL_STATUS_SUCCESS == oemData_IsOemDataReqAllowed(pMac))
    {
        smsLog(pMac, LOG1, "%s: OEM_DATA REQ allowed in the current mode", __func__);
        pMac->oemData.oemDataReqActive = eANI_BOOLEAN_TRUE;
        status = oemData_SendMBOemDataReq(pMac, &(pOemDataReqCmd->u.oemDataCmd.oemDataReq));
    }
    else
    {
        smsLog(pMac, LOG1, "%s: OEM_DATA REQ not allowed in the current mode", __func__);
        status = eHAL_STATUS_FAILURE;
    }

    if(!HAL_STATUS_SUCCESS(status))
    {
        smsLog(pMac, LOG1, "%s: OEM_DATA Failure, Release command", __func__);
        oemData_ReleaseOemDataReqCommand(pMac, pOemDataReqCmd, eOEM_DATA_REQ_INVALID_MODE);
        pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
    }

    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_HandleOemDataRsp
    \brief This function processes the oem data response obtained from the PE
    \param pMsg - Pointer to the pSirOemDataRsp
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg)
{
    eHalStatus                         status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal                     pMac;
    tListElem                          *pEntry = NULL;
    tSmeCmd                            *pCommand = NULL;
    tSirOemDataRsp*                    pOemDataRsp = NULL;
    pMac = PMAC_STRUCT(hHal);

    smsLog(pMac, LOG1, "%s: OEM_DATA Entering", __func__);

    do
    {
        if(pMsg == NULL)
        {
            smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
            status = eHAL_STATUS_FAILURE;
            break;
        }

        pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
        if(pEntry)
        {
            pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
            if(eSmeCommandOemDataReq == pCommand->command)
            {
                pOemDataRsp = (tSirOemDataRsp*)pMsg;

                //make sure to acquire the lock before modifying the data
                status = sme_AcquireGlobalLock(&pMac->sme);
                if(!HAL_STATUS_SUCCESS(status))
                {
                    break;
                }

                if(pMac->oemData.pOemDataRsp != NULL)
                {
                    vos_mem_free(pMac->oemData.pOemDataRsp);
                }
                pMac->oemData.pOemDataRsp = (tOemDataRsp*)vos_mem_malloc(sizeof(tOemDataRsp));

                if(pMac->oemData.pOemDataRsp == NULL)
                {
                    sme_ReleaseGlobalLock(&pMac->sme);
                    smsLog(pMac, LOGE, "in %s vos_mem_malloc failed for pMac->oemData.pOemDataRsp", __func__);
                    status = eHAL_STATUS_FAILURE;
                    break;
                }

                smsLog(pMac, LOGE, "Before memory copy");
                vos_mem_copy((v_VOID_t*)(pMac->oemData.pOemDataRsp),
                             (v_VOID_t*)(&pOemDataRsp->oemDataRsp),
                             sizeof(tOemDataRsp));
                smsLog(pMac, LOGE, "after memory copy");
                sme_ReleaseGlobalLock(&pMac->sme);
            }
            else
            {
                smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO REQs are ACTIVE ...",
                    __func__);
                status = eHAL_STATUS_FAILURE;
                break;
            }
        }
        else
        {
            smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO commands are ACTIVE ...", __func__);
            status = eHAL_STATUS_FAILURE;
            break;
        }

        oemData_ReleaseOemDataReqCommand(pMac, pCommand, eHAL_STATUS_SUCCESS);
        pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;

    } while(0);

    return status;
}

/* ---------------------------------------------------------------------------
    \fn oemData_IsOemDataReqAllowed
    \brief This function checks if OEM DATA REQs can be performed in the
           current driver state
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tANI_U32 sessionId;

    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
    {
        if(CSR_IS_SESSION_VALID(pMac, sessionId))
        {
            //co-exist with IBSS or BT-AMP mode is not supported
            if(csrIsConnStateIbss(pMac, sessionId) || csrIsBTAMP(pMac, sessionId) )
            {
                //co-exist with IBSS or BT-AMP mode is not supported
                smsLog(pMac, LOGW, "OEM DATA REQ is not allowed due to IBSS|BTAMP exist in session %d", sessionId);
                status = eHAL_STATUS_CSR_WRONG_STATE;
                break;
            }
        }
    }

    smsLog(pMac, LOG1, "Exiting oemData_IsOemDataReqAllowed with status %d", status);

    return (status);
}

#endif /*FEATURE_OEM_DATA_SUPPORT*/
