u-boot/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c

321 lines
9.4 KiB
C
Raw Normal View History

/**
* @file IxNpeMhReceive.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Receive module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* @par
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhConfig_p.h"
#include "IxNpeMhReceive_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
#include "IxNpeMhUnsolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhReceiveStats
*
* @brief This structure is used to maintain statistics for the Receive
* module.
*/
typedef struct
{
UINT32 isrs; /**< receive ISR invocations */
UINT32 receives; /**< receive messages invocations */
UINT32 messages; /**< messages received */
UINT32 solicited; /**< solicited messages received */
UINT32 unsolicited; /**< unsolicited messages received */
UINT32 callbacks; /**< callbacks invoked */
} IxNpeMhReceiveStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
PRIVATE
void ixNpeMhReceiveIsr (int npeId);
PRIVATE
void ixNpeMhReceiveIsr (int npeId)
{
int lockKey;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveIsr\n");
lockKey = ixOsalIrqLock ();
/* invoke the message receive routine to get messages from the NPE */
ixNpeMhReceiveMessagesReceive (npeId);
/* update statistical info */
ixNpeMhReceiveStats[npeId].isrs++;
ixOsalIrqUnlock (lockKey);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveIsr\n");
}
/*
* Function definition: ixNpeMhReceiveInitialize
*/
void ixNpeMhReceiveInitialize (void)
{
IxNpeMhNpeId npeId = 0;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveInitialize\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* register our internal ISR for the NPE to handle "outFIFO not */
/* empty" interrupts */
ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr);
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveInitialize\n");
}
/*
* Function definition: ixNpeMhReceiveMessagesReceive
*/
IX_STATUS ixNpeMhReceiveMessagesReceive (
IxNpeMhNpeId npeId)
{
IxNpeMhMessage message = { { 0, 0 } };
IxNpeMhMessageId messageId = 0;
IxNpeMhCallback callback = NULL;
IX_STATUS status;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveMessagesReceive\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].receives++;
/* while the NPE has messages in its outFIFO */
while (!ixNpeMhConfigOutFifoIsEmpty (npeId))
{
/* read a message from the NPE's outFIFO */
status = ixNpeMhConfigOutFifoRead (npeId, &message);
if (IX_SUCCESS != status)
{
return status;
}
/* get the ID of the message */
messageId = ixNpeMhConfigMessageIdGet (message);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG,
"Received message from NPE %d with ID 0x%02X\n",
npeId, messageId);
/* update statistical info */
ixNpeMhReceiveStats[npeId].messages++;
/* try to find a matching unsolicited callback for this message. */
/* we assume the message is unsolicited. only if there is no */
/* unsolicited callback for this message type do we assume the */
/* message is solicited. it is much faster to check for an */
/* unsolicited callback, so doing this check first should result */
/* in better performance. */
ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
npeId, messageId, &callback);
if (callback != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
"Found matching unsolicited callback\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].unsolicited++;
}
/* if no unsolicited callback was found try to find a matching */
/* solicited callback for this message */
if (callback == NULL)
{
ixNpeMhSolicitedCbMgrCallbackRetrieve (
npeId, messageId, &callback);
if (callback != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
"Found matching solicited callback\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].solicited++;
}
}
/* if a callback (either unsolicited or solicited) was found */
if (callback != NULL)
{
/* invoke the callback to pass the message back to the client */
callback (npeId, message);
/* update statistical info */
ixNpeMhReceiveStats[npeId].callbacks++;
}
else /* no callback (neither unsolicited nor solicited) was found */
{
IX_NPEMH_TRACE2 (IX_NPEMH_WARNING,
"No matching callback for NPE %d"
" and ID 0x%02X, discarding message\n",
npeId, messageId);
/* the message will be discarded. this is normal behaviour */
/* if the client passes a NULL solicited callback when */
/* sending a message. this indicates that the client is not */
/* interested in receiving the response. alternatively a */
/* NULL callback here may signify an unsolicited message */
/* with no appropriate registered callback. */
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveMessagesReceive\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhReceiveShow
*/
void ixNpeMhReceiveShow (
IxNpeMhNpeId npeId)
{
/* show the ISR invocation counter */
IX_NPEMH_SHOW ("Receive ISR invocations",
ixNpeMhReceiveStats[npeId].isrs);
/* show the receive message invocation counter */
IX_NPEMH_SHOW ("Receive messages invocations",
ixNpeMhReceiveStats[npeId].receives);
/* show the message received counter */
IX_NPEMH_SHOW ("Messages received",
ixNpeMhReceiveStats[npeId].messages);
/* show the solicited message counter */
IX_NPEMH_SHOW ("Solicited messages received",
ixNpeMhReceiveStats[npeId].solicited);
/* show the unsolicited message counter */
IX_NPEMH_SHOW ("Unsolicited messages received",
ixNpeMhReceiveStats[npeId].unsolicited);
/* show the callback invoked counter */
IX_NPEMH_SHOW ("Callbacks invoked",
ixNpeMhReceiveStats[npeId].callbacks);
/* show the message discarded counter */
IX_NPEMH_SHOW ("Received messages discarded",
(ixNpeMhReceiveStats[npeId].messages -
ixNpeMhReceiveStats[npeId].callbacks));
}
/*
* Function definition: ixNpeMhReceiveShowReset
*/
void ixNpeMhReceiveShowReset (
IxNpeMhNpeId npeId)
{
/* reset the ISR invocation counter */
ixNpeMhReceiveStats[npeId].isrs = 0;
/* reset the receive message invocation counter */
ixNpeMhReceiveStats[npeId].receives = 0;
/* reset the message received counter */
ixNpeMhReceiveStats[npeId].messages = 0;
/* reset the solicited message counter */
ixNpeMhReceiveStats[npeId].solicited = 0;
/* reset the unsolicited message counter */
ixNpeMhReceiveStats[npeId].unsolicited = 0;
/* reset the callback invoked counter */
ixNpeMhReceiveStats[npeId].callbacks = 0;
}