/**
 * @file IxNpeMhSend.c
 *
 * @author Intel Corporation
 * @date 18 Jan 2002
 *
 * @brief This file contains the implementation of the private API for the
 * Send module.
 *
 *
 * @par
 * IXP400 SW Release version 2.0
 *
 * -- Copyright Notice --
 *
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 *
 * @par
 * SPDX-License-Identifier:	BSD-3-Clause
 * @par
 * -- End of Copyright Notice --
*/

/*
 * Put the system defined include files required.
 */


/*
 * Put the user defined include files required.
 */

#include "IxNpeMhMacros_p.h"

#include "IxNpeMhConfig_p.h"
#include "IxNpeMhSend_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"

/*
 * #defines and macros used in this file.
 */

/**
 * @def IX_NPEMH_INFIFO_RETRY_DELAY_US
 *
 * @brief Amount of time (uSecs) to delay between retries
 * while inFIFO is Full when attempting to send a message
 */
#define IX_NPEMH_INFIFO_RETRY_DELAY_US (1)


/*
 * Typedefs whose scope is limited to this file.
 */

/**
 * @struct IxNpeMhSendStats
 *
 * @brief This structure is used to maintain statistics for the Send
 * module.
 */

typedef struct
{
    UINT32 sends;             /**< send invocations */
    UINT32 sendWithResponses; /**< send with response invocations */
    UINT32 queueFulls;        /**< fifo queue full occurrences */
    UINT32 queueFullRetries;  /**< fifo queue full retry occurrences */
    UINT32 maxQueueFullRetries; /**< max fifo queue full retries */
    UINT32 callbackFulls;     /**< callback list full occurrences */
} IxNpeMhSendStats;

/*
 * Variable declarations global to this file only.  Externs are followed by
 * static variables.
 */

PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES];

/*
 * Extern function prototypes.
 */

/*
 * Static function prototypes.
 */
PRIVATE
BOOL ixNpeMhSendInFifoIsFull(
    IxNpeMhNpeId npeId,
    UINT32 maxSendRetries);

/*
 * Function definition: ixNpeMhSendInFifoIsFull
 */

PRIVATE
BOOL ixNpeMhSendInFifoIsFull(
    IxNpeMhNpeId npeId,
    UINT32 maxSendRetries)
{
    BOOL isFull = false;
    UINT32 numRetries = 0;

    /* check the NPE's inFIFO */
    isFull = ixNpeMhConfigInFifoIsFull (npeId);

    /* we retry a few times, just to give the NPE a chance to read from */
    /* the FIFO if the FIFO is currently full */
    while (isFull && (numRetries++ < maxSendRetries))
    {
	if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT)
	{
	    /* Delay here for as short a time as possible (1 us). */
	    /* Adding a delay here should ensure we are not hogging */
	    /* the AHB bus while we are retrying                    */
	    ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
	}

        /* re-check the NPE's inFIFO */
        isFull = ixNpeMhConfigInFifoIsFull (npeId);

        /* update statistical info */
        ixNpeMhSendStats[npeId].queueFullRetries++;
    }

    /* record the highest number of retries that occurred */
    if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries)
    {
	ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries;
    }

    if (isFull)
    {
        /* update statistical info */
        ixNpeMhSendStats[npeId].queueFulls++;
    }

    return isFull;
}

/*
 * Function definition: ixNpeMhSendMessageSend
 */

IX_STATUS ixNpeMhSendMessageSend (
    IxNpeMhNpeId npeId,
    IxNpeMhMessage message,
    UINT32 maxSendRetries)
{
    IX_STATUS status;

    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
                     "ixNpeMhSendMessageSend\n");

    /* update statistical info */
    ixNpeMhSendStats[npeId].sends++;

    /* check if the NPE's inFIFO is full - if so return an error */
    if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
    {
        IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
        return IX_FAIL;
    }

    /* write the message to the NPE's inFIFO */
    status = ixNpeMhConfigInFifoWrite (npeId, message);

    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
                     "ixNpeMhSendMessageSend\n");

    return status;
}

/*
 * Function definition: ixNpeMhSendMessageWithResponseSend
 */

IX_STATUS ixNpeMhSendMessageWithResponseSend (
    IxNpeMhNpeId npeId,
    IxNpeMhMessage message,
    IxNpeMhMessageId solicitedMessageId,
    IxNpeMhCallback solicitedCallback,
    UINT32 maxSendRetries)
{
    IX_STATUS status = IX_SUCCESS;

    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
                     "ixNpeMhSendMessageWithResponseSend\n");

    /* update statistical info */
    ixNpeMhSendStats[npeId].sendWithResponses++;

    /* sr: this sleep will call the receive routine (no interrupts used!!!) */
    ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);

    /* check if the NPE's inFIFO is full - if so return an error */
    if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
    {
        IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
        return IX_FAIL;
    }

    /* save the solicited callback */
    status = ixNpeMhSolicitedCbMgrCallbackSave (
        npeId, solicitedMessageId, solicitedCallback);
    if (status != IX_SUCCESS)
    {
        IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n");

        /* update statistical info */
        ixNpeMhSendStats[npeId].callbackFulls++;

        return status;
    }

    /* write the message to the NPE's inFIFO */
    status = ixNpeMhConfigInFifoWrite (npeId, message);

    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
                     "ixNpeMhSendMessageWithResponseSend\n");

    return status;
}

/*
 * Function definition: ixNpeMhSendShow
 */

void ixNpeMhSendShow (
    IxNpeMhNpeId npeId)
{
    /* show the message send invocation counter */
    IX_NPEMH_SHOW ("Send invocations",
                   ixNpeMhSendStats[npeId].sends);

    /* show the message send with response invocation counter */
    IX_NPEMH_SHOW ("Send with response invocations",
                   ixNpeMhSendStats[npeId].sendWithResponses);

    /* show the fifo queue full occurrence counter */
    IX_NPEMH_SHOW ("Fifo queue full occurrences",
                   ixNpeMhSendStats[npeId].queueFulls);

    /* show the fifo queue full retry occurrence counter */
    IX_NPEMH_SHOW ("Fifo queue full retry occurrences",
                   ixNpeMhSendStats[npeId].queueFullRetries);

    /* show the fifo queue full maximum retries counter */
    IX_NPEMH_SHOW ("Maximum fifo queue full retries",
                   ixNpeMhSendStats[npeId].maxQueueFullRetries);

    /* show the callback list full occurrence counter */
    IX_NPEMH_SHOW ("Solicited callback list full occurrences",
                   ixNpeMhSendStats[npeId].callbackFulls);
}

/*
 * Function definition: ixNpeMhSendShowReset
 */

void ixNpeMhSendShowReset (
    IxNpeMhNpeId npeId)
{
    /* reset the message send invocation counter */
    ixNpeMhSendStats[npeId].sends = 0;

    /* reset the message send with response invocation counter */
    ixNpeMhSendStats[npeId].sendWithResponses = 0;

    /* reset the fifo queue full occurrence counter */
    ixNpeMhSendStats[npeId].queueFulls = 0;

    /* reset the fifo queue full retry occurrence counter */
    ixNpeMhSendStats[npeId].queueFullRetries = 0;

    /* reset the max fifo queue full retries counter */
    ixNpeMhSendStats[npeId].maxQueueFullRetries = 0;

    /* reset the callback list full occurrence counter */
    ixNpeMhSendStats[npeId].callbackFulls = 0;
}
