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

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

  \file  vos_mq.c

  \brief virtual Operating System Services (vOSS) message queue APIs

   Message Queue Definitions and API

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

/* $Header$ */

/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/
#include <vos_mq.h>
#include "vos_sched.h"
#include <vos_api.h>

/*--------------------------------------------------------------------------
  Preprocessor definitions and constants
  ------------------------------------------------------------------------*/

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

/*-------------------------------------------------------------------------
  Function declarations and documenation
  ------------------------------------------------------------------------*/

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

  \brief vos_mq_init() - Initialize the vOSS Scheduler

  The \a vos_mq_init() function initializes the Message queue.

  \param  pMq - pointer to the message queue

  \return VOS_STATUS_SUCCESS - Message queue was successfully initialized and
          is ready to be used.

          VOS_STATUS_E_RESOURCES - Invalid parameter passed to the message
          queue initialize function.

  \sa vos_mq_init()

---------------------------------------------------------------------------*/
__inline VOS_STATUS vos_mq_init(pVosMqType pMq)
{

  /* Some quick sanity check*/
  if (pMq == NULL) {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: NULL pointer passed",__func__);
     return VOS_STATUS_E_FAILURE;
  }

  /*
  ** Now initialize the lock
  */
  spin_lock_init(&pMq->mqLock);

  /*
  ** Now initialize the List data structure
  */
  INIT_LIST_HEAD(&pMq->mqList);

  return VOS_STATUS_SUCCESS;

} /* vos_mq_init()*/

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

  \brief vos_mq_deinit() - DeInitialize the vOSS Scheduler

  The \a vos_mq_init() function de-initializes the Message queue.

  \param  pMq - pointer to the message queue

  \return None

  \sa vos_mq_deinit()

---------------------------------------------------------------------------*/
__inline void vos_mq_deinit(pVosMqType pMq)
{
  /*
  ** Some quick sanity check
  */
  if (pMq == NULL) {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: NULL pointer passed",__func__);
     return ;
  }

  /* we don't have to do anything with the embedded list or spinlock */

}/* vos_mq_deinit() */


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

  \brief vos_mq_put() - Add a message to the message queue

  The \a vos_mq_put() function add a message to the Message queue.

  \param  pMq - pointer to the message queue

  \param  pMsgWrapper - Msg Wrapper containing the message

  \return None

  \sa vos_mq_put()

---------------------------------------------------------------------------*/
__inline void vos_mq_put(pVosMqType pMq, pVosMsgWrapper pMsgWrapper)
{
  unsigned long flags;

  /*
  ** Some quick sanity check
  */
  if ((pMq == NULL) || (pMsgWrapper == NULL)) {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: NULL pointer passed",__func__);
     return ;
  }

  spin_lock_irqsave(&pMq->mqLock, flags);

  list_add_tail(&pMsgWrapper->msgNode, &pMq->mqList);

  spin_unlock_irqrestore(&pMq->mqLock, flags);

} /* vos_mq_put() */

/**
 * vos_mq_put_front() - adds a message to the head of message queue
 * @mq: message queue
 * @msg_wrapper: message wrapper
 *
 * This function is used to add a message to the head of message queue
 *
 * Return: None
 */
void vos_mq_put_front(pVosMqType mq, pVosMsgWrapper msg_wrapper)
{
	unsigned long flags;

	if ((mq == NULL) || (msg_wrapper == NULL)) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"%s: NULL pointer passed", __func__);
		return;
	}

	spin_lock_irqsave(&mq->mqLock, flags);
	list_add(&msg_wrapper->msgNode, &mq->mqList);
	spin_unlock_irqrestore(&mq->mqLock, flags);
}

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

  \brief vos_mq_get() - Get a message with its wrapper from a message queue

  The \a vos_mq_get() function retrieve a message with its wrapper from
      the Message queue.

  \param  pMq - pointer to the message queue

  \return pointer to the Message Wrapper

  \sa vos_mq_get()

---------------------------------------------------------------------------*/
__inline pVosMsgWrapper vos_mq_get(pVosMqType pMq)
{
  pVosMsgWrapper pMsgWrapper = NULL;

  /*
  ** Some quick sanity check
  */
  struct list_head * listptr;
  unsigned long flags;

  if (pMq == NULL) {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: NULL pointer passed",__func__);
     return NULL;
  }

  spin_lock_irqsave(&pMq->mqLock, flags);

  if( list_empty(&pMq->mqList) )
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
             "%s: VOS Message Queue is empty",__func__);
  }
  else
  {
    listptr = pMq->mqList.next;
    pMsgWrapper = (pVosMsgWrapper)list_entry(listptr, VosMsgWrapper, msgNode);
    list_del(pMq->mqList.next);
  }

  spin_unlock_irqrestore(&pMq->mqLock, flags);

  return pMsgWrapper;

} /* vos_mq_get() */


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

  \brief vos_is_mq_empty() - Return if the MQ is empty

  The \a vos_is_mq_empty() returns true if the queue is empty

  \param  pMq - pointer to the message queue

  \return pointer to the Message Wrapper

  \sa vos_mq_get()

---------------------------------------------------------------------------*/
__inline v_BOOL_t vos_is_mq_empty(pVosMqType pMq)
{
  v_BOOL_t  state = VOS_FALSE;
  unsigned long flags;

  /*
  ** Some quick sanity check
  */
  if (pMq == NULL)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: NULL pointer passed",__func__);
     return VOS_STATUS_E_FAILURE;
  }

  spin_lock_irqsave(&pMq->mqLock, flags);
  state = list_empty(&pMq->mqList)?VOS_TRUE:VOS_FALSE;
  spin_unlock_irqrestore(&pMq->mqLock, flags);

  return state;

} /* vos_mq_get() */
