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

#include "sme_api.h"
#include "sms_debug.h"
#include "csr_inside_api.h"
#include "sme_inside.h"
#include "p2p_api.h"
#include "lim_api.h"
#include "cfg_api.h"
#include "wma.h"

/*------------------------------------------------------------------
 *
 * handle SME remain on channel request.
 *
 *------------------------------------------------------------------*/

CDF_STATUS p2p_process_remain_on_channel_cmd(tpAniSirGlobal pMac,
					     tSmeCmd *p2pRemainonChn)
{
	CDF_STATUS status = CDF_STATUS_E_FAILURE;
	tSirRemainOnChnReq *pMsg;
	uint32_t len;
	tCsrRoamSession *pSession =
		CSR_GET_SESSION(pMac, p2pRemainonChn->sessionId);

	if (!pSession) {
		sms_log(pMac, LOGE, FL("  session %d not found "),
			p2pRemainonChn->sessionId);
		goto error;
	}

	if (!pSession->sessionActive) {
		sms_log(pMac, LOGE,
			FL("  session %d is invalid or listen is disabled "),
			p2pRemainonChn->sessionId);
		goto error;
	}
	len = sizeof(tSirRemainOnChnReq) + pMac->p2pContext.probeRspIeLength;

	if (len > 0xFFFF) {
		/*In coming len for Msg is more then 16bit value */
		sms_log(pMac, LOGE, FL("  Message length is very large, %d"),
			len);
		goto error;
	}

	pMsg = cdf_mem_malloc(len);
	if (NULL == pMsg)
		goto error;
	else {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "%s call",
			  __func__);
		cdf_mem_set(pMsg, sizeof(tSirRemainOnChnReq), 0);
		pMsg->messageType = eWNI_SME_REMAIN_ON_CHANNEL_REQ;
		pMsg->length = (uint16_t) len;
		cdf_mem_copy(pMsg->selfMacAddr, pSession->selfMacAddr.bytes,
			     sizeof(tSirMacAddr));
		pMsg->chnNum = p2pRemainonChn->u.remainChlCmd.chn;
		pMsg->phyMode = p2pRemainonChn->u.remainChlCmd.phyMode;
		pMsg->duration = p2pRemainonChn->u.remainChlCmd.duration;
		pMsg->sessionId = p2pRemainonChn->sessionId;
		pMsg->isProbeRequestAllowed =
			p2pRemainonChn->u.remainChlCmd.isP2PProbeReqAllowed;
		pMsg->scan_id = p2pRemainonChn->u.remainChlCmd.scan_id;
		if (pMac->p2pContext.probeRspIeLength)
			cdf_mem_copy((void *)pMsg->probeRspIe,
				     (void *)pMac->p2pContext.probeRspIe,
				     pMac->p2pContext.probeRspIeLength);
		status = cds_send_mb_message_to_mac(pMsg);
	}
error:
	if (CDF_STATUS_E_FAILURE == status)
		csr_release_roc_req_cmd(pMac);
	return status;
}

/*------------------------------------------------------------------
 *
 * handle LIM remain on channel rsp: Success/failure.
 *
 *------------------------------------------------------------------*/

CDF_STATUS sme_remain_on_chn_rsp(tpAniSirGlobal pMac, uint8_t *pMsg)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tListElem *pEntry = NULL;
	tSmeCmd *pCommand = NULL;
	bool fFound;
	remainOnChanCallback callback = NULL;
	struct sir_roc_rsp *rsp = (struct sir_roc_rsp *)pMsg;

	csr_get_active_scan_entry(pMac, rsp->scan_id, &pEntry);
	if (!pEntry) {
		sms_log(pMac, LOGE, FL("No cmd found in active list."));
		return status;
	}

	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
	if (eSmeCommandRemainOnChannel != pCommand->command)
		return status;

	callback = pCommand->u.remainChlCmd.callback;
	if (callback)
		callback(pMac, pCommand->u.remainChlCmd.callbackCtx,
			rsp->status, rsp->scan_id);

	fFound = csr_ll_remove_entry(&pMac->sme.smeScanCmdActiveList, pEntry,
				     LL_ACCESS_LOCK);
	if (fFound) {
		/* Now put this command back on the avilable command list */
		sme_release_command(pMac, pCommand);
	}
	sme_process_pending_queue(pMac);
	return status;
}

/*------------------------------------------------------------------
 *
 * Handle the Mgmt frm ind from LIM and forward to HDD.
 *
 *------------------------------------------------------------------*/

CDF_STATUS sme_mgmt_frm_ind(tHalHandle hHal, tpSirSmeMgmtFrameInd pSmeMgmtFrm)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tCsrRoamInfo pRoamInfo = { 0 };
	uint8_t i = 0;
	uint32_t SessionId = pSmeMgmtFrm->sessionId;

	pRoamInfo.nFrameLength =
		pSmeMgmtFrm->mesgLen - sizeof(tSirSmeMgmtFrameInd);
	pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
	pRoamInfo.frameType = pSmeMgmtFrm->frameType;
	pRoamInfo.rxChan = pSmeMgmtFrm->rxChan;
	pRoamInfo.rxRssi = pSmeMgmtFrm->rxRssi;
	if (CSR_IS_SESSION_ANY(SessionId)) {
		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
			if (CSR_IS_SESSION_VALID(pMac, i)) {
				SessionId = i;
				break;
			}
		}
	}

	if (i == CSR_ROAM_SESSION_MAX) {
		sms_log(pMac, LOGE, FL("No valid sessions found."));
		return CDF_STATUS_E_FAILURE;
	}
	/* forward the mgmt frame to HDD */
	csr_roam_call_callback(pMac, SessionId, &pRoamInfo, 0,
			       eCSR_ROAM_INDICATE_MGMT_FRAME, 0);

	return status;
}

/*------------------------------------------------------------------
 *
 * Handle the remain on channel ready indication from PE
 *
 *------------------------------------------------------------------*/

CDF_STATUS sme_remain_on_chn_ready(tHalHandle hHal, uint8_t *pMsg)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tListElem *pEntry = NULL;
	tSmeCmd *pCommand = NULL;
	tCsrRoamInfo RoamInfo;
	struct sir_roc_rsp *rsp =  (struct sir_roc_rsp *)pMsg;

	csr_get_active_scan_entry(pMac, rsp->scan_id, &pEntry);
	if (!pEntry) {
		sms_log(pMac, LOGE, FL("No cmd found in active list."));
		return status;
	}
	sms_log(pMac, LOG1,
		FL("Ready Ind %d %d"), rsp->session_id, rsp->scan_id);
	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
	if (eSmeCommandRemainOnChannel == pCommand->command) {
		RoamInfo.roc_scan_id = rsp->scan_id;
		/* forward the indication to HDD */
		RoamInfo.pRemainCtx = pCommand->u.remainChlCmd.callbackCtx;
		csr_roam_call_callback(pMac, rsp->session_id,
				       &RoamInfo, 0,
				       eCSR_ROAM_REMAIN_CHAN_READY, 0);
	}

	return status;
}

CDF_STATUS sme_send_action_cnf(tHalHandle hHal, uint8_t *pMsg)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tCsrRoamInfo RoamInfo;
	tSirSmeRsp *pSmeRsp = (tSirSmeRsp *) pMsg;

	/* forward the indication to HDD */
	/* RoamInfo can be passed as NULL....todo */
	csr_roam_call_callback(pMac, pSmeRsp->sessionId, &RoamInfo, 0,
			       eCSR_ROAM_SEND_ACTION_CNF,
			       (pSmeRsp->statusCode == eSIR_SME_SUCCESS) ? 0 :
			       eCSR_ROAM_RESULT_SEND_ACTION_FAIL);
	return status;
}

CDF_STATUS sme_p2p_open(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	CDF_STATUS status = CDF_STATUS_SUCCESS;

	/* If static structure is too big, Need to change this function to allocate memory dynamically */
	cdf_mem_zero(&pMac->p2pContext, sizeof(tp2pContext));

	if (!CDF_IS_STATUS_SUCCESS(status)) {
		sme_p2p_close(hHal);
	}

	return status;
}

CDF_STATUS p2p_stop(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (pMac->p2pContext.probeRspIe) {
		cdf_mem_free(pMac->p2pContext.probeRspIe);
		pMac->p2pContext.probeRspIe = NULL;
	}

	pMac->p2pContext.probeRspIeLength = 0;

	return CDF_STATUS_SUCCESS;
}

CDF_STATUS sme_p2p_close(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (pMac->p2pContext.probeRspIe) {
		cdf_mem_free(pMac->p2pContext.probeRspIe);
		pMac->p2pContext.probeRspIe = NULL;
	}

	pMac->p2pContext.probeRspIeLength = 0;

	return CDF_STATUS_SUCCESS;
}

tSirRFBand get_rf_band(uint8_t channel)
{
	if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
	    (channel <= SIR_11A_CHANNEL_END))
		return SIR_BAND_5_GHZ;

	if ((channel >= SIR_11B_CHANNEL_BEGIN) &&
	    (channel <= SIR_11B_CHANNEL_END))
		return SIR_BAND_2_4_GHZ;

	return SIR_BAND_UNKNOWN;
}

/* ---------------------------------------------------------------------------

    \fn p2p_remain_on_channel
    \brief  API to post the remain on channel command.
    \param  hHal - The handle returned by mac_open.
    \param  sessinId - HDD session ID.
    \param  channel - Channel to remain on channel.
    \param  duration - Duration for which we should remain on channel
    \param  callback - callback function.
    \param  pContext - argument to the callback function
    \return CDF_STATUS

   -------------------------------------------------------------------------------*/
CDF_STATUS p2p_remain_on_channel(tHalHandle hHal, uint8_t sessionId,
				 uint8_t channel, uint32_t duration,
				 remainOnChanCallback callback,
				 void *pContext, uint8_t isP2PProbeReqAllowed,
				 uint32_t scan_id)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tSmeCmd *pRemainChlCmd = NULL;
	uint32_t phyMode;

	pRemainChlCmd = sme_get_command_buffer(pMac);
	if (pRemainChlCmd == NULL)
		return CDF_STATUS_E_FAILURE;

	if (SIR_BAND_5_GHZ == get_rf_band(channel)) {
		phyMode = WNI_CFG_PHY_MODE_11A;
	} else {
		phyMode = WNI_CFG_PHY_MODE_11G;
	}

	cfg_set_int(pMac, WNI_CFG_PHY_MODE, phyMode);

	do {
		/* call set in context */
		pRemainChlCmd->command = eSmeCommandRemainOnChannel;
		pRemainChlCmd->sessionId = sessionId;
		pRemainChlCmd->u.remainChlCmd.chn = channel;
		pRemainChlCmd->u.remainChlCmd.duration = duration;
		pRemainChlCmd->u.remainChlCmd.isP2PProbeReqAllowed =
			isP2PProbeReqAllowed;
		pRemainChlCmd->u.remainChlCmd.callback = callback;
		pRemainChlCmd->u.remainChlCmd.callbackCtx = pContext;
		pRemainChlCmd->u.remainChlCmd.scan_id = scan_id;

		/* Put it at the head of the Q if we just finish finding the peer and ready to send a frame */
		status = csr_queue_sme_command(pMac, pRemainChlCmd, false);
	} while (0);

	sms_log(pMac, LOGW, "exiting function %s", __func__);

	return (status);
}

CDF_STATUS p2p_send_action(tHalHandle hHal, uint8_t sessionId,
			   const uint8_t *pBuf, uint32_t len, uint16_t wait,
			   bool noack, uint16_t channel_freq)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tSirMbMsgP2p *pMsg;
	uint16_t msgLen;

	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_MED,
		  " %s sends action frame", __func__);
	msgLen = (uint16_t) ((sizeof(tSirMbMsgP2p)) + len);
	pMsg = cdf_mem_malloc(msgLen);
	if (NULL == pMsg)
		status = CDF_STATUS_E_NOMEM;
	else {
		cdf_mem_set((void *)pMsg, msgLen, 0);
		pMsg->type = eWNI_SME_SEND_ACTION_FRAME_IND;
		pMsg->msgLen = msgLen;
		pMsg->sessionId = sessionId;
		pMsg->noack = noack;
		pMsg->channel_freq = channel_freq;
		pMsg->wait = (uint16_t) wait;
		cdf_mem_copy(pMsg->data, pBuf, len);
		status = cds_send_mb_message_to_mac(pMsg);
	}
	return (status);
}

CDF_STATUS p2p_cancel_remain_on_channel(tHalHandle hHal,
	uint8_t sessionId, uint32_t scan_id)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tSirMbMsgP2p *pMsg;
	uint16_t msgLen;

	/* Need to check session ID to support concurrency */

	msgLen = (uint16_t) (sizeof(tSirMbMsgP2p));
	pMsg = cdf_mem_malloc(msgLen);
	if (NULL == pMsg)
		status = CDF_STATUS_E_NOMEM;
	else {
		cdf_mem_set((void *)pMsg, msgLen, 0);
		pMsg->type = eWNI_SME_ABORT_REMAIN_ON_CHAN_IND;
		pMsg->msgLen = msgLen;
		pMsg->sessionId = sessionId;
		pMsg->scan_id = scan_id;
		status = cds_send_mb_message_to_mac(pMsg);
	}

	return (status);
}

CDF_STATUS p2p_set_ps(tHalHandle hHal, tP2pPsConfig *pNoA)
{
	tpP2pPsConfig pNoAParam;
	tSirMsgQ msg;
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pNoAParam = cdf_mem_malloc(sizeof(tP2pPsConfig));
	if (NULL == pNoAParam)
		status = CDF_STATUS_E_NOMEM;
	else {
		cdf_mem_set(pNoAParam, sizeof(tP2pPsConfig), 0);
		cdf_mem_copy(pNoAParam, pNoA, sizeof(tP2pPsConfig));
		msg.type = eWNI_SME_UPDATE_NOA;
		msg.bodyval = 0;
		msg.bodyptr = pNoAParam;
		lim_post_msg_api(pMac, &msg);
	}
	return status;
}
