/*
 * Copyright (c) 2012-2014, 2016 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;
        }

        //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)
{

    //First take this command out of the active list
    if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, &pOemDataCmd->Link, LL_ACCESS_LOCK))
    {
        if (pOemDataCmd->u.oemDataCmd.oemDataReq.data) {
            vos_mem_free(pOemDataCmd->u.oemDataCmd.oemDataReq.data);
            pOemDataCmd->u.oemDataCmd.oemDataReq.data = NULL;
        }
        vos_mem_zero(&(pOemDataCmd->u.oemDataCmd), sizeof(tOemDataCmd));
        /* Now put this command back on the available 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
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus oemData_OemDataReq(tHalHandle hHal,
                                tANI_U8 sessionId,
                                tOemDataReqConfig *oemDataReqConfig,
                                tANI_U32 *pOemDataReqID)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tSmeCmd *pOemDataCmd = NULL;
    tOemDataReq *cmd_req;

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

        pMac->oemData.oemDataReqID = *(pOemDataReqID);

        pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;

        pOemDataCmd = smeGetCommandBuffer(pMac);

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

            cmd_req = &(pOemDataCmd->u.oemDataCmd.oemDataReq);
            /* set the oem data request */
            cmd_req->sessionId = sessionId;
            cmd_req->data_len =  oemDataReqConfig->data_len;
            cmd_req->data = vos_mem_malloc(cmd_req->data_len);

            if (!cmd_req->data) {
                smsLog(pMac, LOGE, FL("memory alloc failed"));
                status = eHAL_STATUS_FAILED_ALLOC;
                break;
            }

            vos_mem_copy(cmd_req->data, oemDataReqConfig->data,
                         cmd_req->data_len);
        }
        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;

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

    if (!pOemDataReq) {
        smsLog(pMac, LOGE, FL("oem data req is NULL"));
        return eHAL_STATUS_INVALID_PARAMETER;
    }

    pSession = CSR_GET_SESSION(pMac, pOemDataReq->sessionId);
    pMsg = vos_mem_malloc(sizeof(*pMsg));
    if (NULL == pMsg) {
        smsLog(pMac, LOGE, "Memory Allocation failed. %s", __func__);
        return eHAL_STATUS_FAILURE;
    }

    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) );
    pMsg->data_len = pOemDataReq->data_len;
    /* Incoming buffer ptr saved, set to null to avoid free by caller */
    pMsg->data = pOemDataReq->data;
    pOemDataReq->data = NULL;
    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, FL("OEM_DATA Failure, Release command"));
        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;
    tOemDataReq *req;

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

        /* In this case, there can be multiple OEM Data Responses for one
         * OEM Data request, SME does not peek into data response so SME
         * can not know which response is the last one. So SME clears active
         * request command on receiving first response and thereafter SME
         * passes each subsequent response to upper user layer.
         */
        pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
        if (pEntry)
        {
            pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
            if (eSmeCommandOemDataReq == pCommand->command)
            {
                if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
                                     &pCommand->Link, LL_ACCESS_LOCK))
                {
                    req = &(pCommand->u.oemDataCmd.oemDataReq);
                    vos_mem_free(req->data);
                    vos_mem_set(&(pCommand->u.oemDataCmd),
                                sizeof(tOemDataCmd), 0);
                    smeReleaseCommand(pMac, pCommand);
                }
            }
        }

        pOemDataRsp = (tSirOemDataRsp *)pMsg;

        /* Send to upper layer only if rsp is from target */
        if (pOemDataRsp->target_rsp) {
            smsLog(pMac, LOG1, FL("received target oem data resp"));
            send_oem_data_rsp_msg(pOemDataRsp->rsp_len,
                                  pOemDataRsp->oem_data_rsp);
            /* free this memory only if rsp is from target */
            vos_mem_free(pOemDataRsp->oem_data_rsp);
            pOemDataRsp->oem_data_rsp = NULL;
        } else {
            smsLog(pMac, LOG1, FL("received internal oem data resp"));
        }
    } 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*/
