📄 mplintr.c
字号:
//******************************************************************************
//
// MPLINTR.C
//
// Copyright (c) 2004 National Semiconductor Corporation.
// All Rights Reserved
//
// MPL Interrupt Processing.
//
// This file contains the API implementations for
// o MPL interrupt configuration
// o Enabling and Disabling interrupts
// o Processing interrupts
//
//******************************************************************************
#include <mplinternal.h>
//*****************************************************************************
// MplInterruptCfg
// Configure the interrupt hold-off delay (for interrupt coalescing).
//
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize
// delayMSec
// Interrupt hold off delay in microseconds
// transmitHold
// Interrupts hold off based on number of Tx pkts sent
// receiveHold
// Interrupts hold off based on number of Rx pkts sent
//
// Return Value
// NS_STATUS_SUCCESS
// Interrupts were successfully configured
//
//*****************************************************************************
MPL_STATUS
MplInterruptCfg (
IN NS_VOID *pMplHandle,
IN NS_UINT delayMSec,
IN NS_UINT transmitHold,
IN NS_UINT receiveHold
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
NS_UINT32 ihrVal = 0x0;
MPL_CENTER(DZONE_MPL_INTR, MplInterruptCfg);
// Force values to max supported
if (delayMSec > pMplCtx->caps.intrCaps.maxTimerHold)
{
delayMSec = pMplCtx->caps.intrCaps.maxTimerHold;
}
if (transmitHold > pMplCtx->caps.intrCaps.maxTransmitHold)
{
transmitHold = pMplCtx->caps.intrCaps.maxTransmitHold;
}
if (receiveHold > pMplCtx->caps.intrCaps.maxReceiveHold)
{
receiveHold = pMplCtx->caps.intrCaps.maxReceiveHold;
}
// Decide if we need to use the lower resolution clock
if (delayMSec >= 100)
{
// Compute clocks
delayMSec = delayMSec / 100;
}
else
{
ihrVal |= INTHLDTMR_4US;
// Compute clocks
delayMSec = delayMSec / 4;
}
// Write on the device
MPL_WRITE32(pMplCtx, IHR, ihrVal | delayMSec |
(transmitHold << INTHLDCNCL_TXPKTS_SHIFT) |
(receiveHold << INTHLDCNCL_RXPKTS_SHIFT));
MPL_CEXIT(DZONE_MPL_INTR, MplInterruptCfg);
return NS_STATUS_SUCCESS;
}
//*****************************************************************************
// MplInterruptEnable
// Enable the interrupt line on the network device.
//
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize
//
// Return Value
// NS_STATUS_SUCCESS
// Interrupts were successfully enabled
//
//*****************************************************************************
MPL_STATUS
MplInterruptEnable (
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// Enable Interrupts
MPL_WRITE32(pMplCtx, IER, INT_EN);
return NS_STATUS_SUCCESS;
}
//*****************************************************************************
// MplInterruptDisable
// Disable the interrupt line on the network device.
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize
// Return Value
// NS_STATUS_SUCCESS
// Interrupts were successfully disabled
//
//*****************************************************************************
MPL_STATUS
MplInterruptDisable (
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// Disable Interrupts
MPL_WRITE32(pMplCtx, IER, 0x0);
return NS_STATUS_SUCCESS;
}
//*****************************************************************************
// MplInterruptCheck
// Checks for and clears pending interrupt conditions on the device.
//
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize.
// pIrqsPresent
// A caller supplied variable in which the current interrupting
// conditions are noted.
//
// Return Value
// NS_STATUS_SUCCESS
// The current interrupting conditions were successfully read from the
// device and pending events do exist.
// NS_STATUS_FAILURE
// Interrupts are currently disabled, so no interrupt conditions exist.
// or the mask bits and status bits don't match
//
//*****************************************************************************
MPL_STATUS
MplInterruptCheck (
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// Make sure interrupts are currently enabled i.e. this is not a
// spurious interrupt
if (MPL_READ32(pMplCtx, IER) & INT_EN)
{
//Disable Interrupts FM: Make this version specific
MPL_WRITE32(pMplCtx, IER, 0x0);
// Read ISR
pMplCtx->isrReg = MPL_READ32(pMplCtx, ISR);
// Rev A3 (AspenPhy) don't seem to clear int on mere read of ISR
MPL_READ32(pMplCtx, MISR);
// Make sure this interrupt reason is not masked
if (pMplCtx->isrReg & pMplCtx->imrReg)
{
return NS_STATUS_SUCCESS;
}
else
{
// Interrupts will be disabled after reading the ISR
// so reenable it
MPL_WRITE32(pMplCtx, IER, INT_EN);
}
}
return NS_STATUS_FAILURE;
}
//*****************************************************************************
// MplInterruptCheckTransmit
// Checks for the presence of transmit engine related interrupt events.
//
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize.
//
// Return Value
// NS_STATUS_SUCCESS
// Pending transmit related events exist on the device
// NS_STATUS_FAILURE
// No transmit related events detected.
//
//*****************************************************************************
MPL_STATUS
MplInterruptCheckTransmit (
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// Check if any Tx events are triggered
if (pMplCtx->isrReg & (TXOK | TXDESC | TXERR | TXIDLE | TXUNDERRUN))
{
return NS_STATUS_SUCCESS;
}
else
{
return NS_STATUS_FAILURE;
}
}
//*****************************************************************************
// MplInterruptCheckReceive
// Checks for the presence of receive engine related interrupt events.
//
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize.
//
// Return Value
// NS_STATUS_SUCCESS
// Pending receive related events exist on the device
// NS_STATUS_FAILURE
// No receive related events detected.
//
//*****************************************************************************
MPL_STATUS
MplInterruptCheckReceive (
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// Check if any Rx events are triggered
if (pMplCtx->isrReg & (RXOK | RXDESC | RXERR | RXEARLY | RXOVERUN))
{
return NS_STATUS_SUCCESS;
}
else
{
return NS_STATUS_FAILURE;
}
}
//*****************************************************************************
// MplInterruptCheckInternal
// Checks for the presence of MAC/PHY internal (non data transfer related)
// interrupt events.
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize.
// Return Value
// NS_STATUS_SUCCESS
// Pending internal events exist on the device
// NS_STATUS_FAILURE
// No internal events detected.
//
//*****************************************************************************
MPL_STATUS
MplInterruptCheckInternal (
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// Check if any Tx events are triggered
if (pMplCtx->isrReg & (MIBSTATS | SW_INT | WOL_EVENT | PHYSTSCHANGE | RXIDLE|
RXSTSFIFO_OVRN | RXRST_COMPLETE | TXRST_COMPLETE))
{
return NS_STATUS_SUCCESS;
}
else
{
return NS_STATUS_FAILURE;
}
}
//*****************************************************************************
// MplInterruptDoneInternal
// Processes device’s internal (non data-type) interrupts.
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize
// maxEvents
// The maximum internal events (e.g. link change) that MPL should
// process before returning back to the caller.
// Return Value
// NS_STATUS_SUCCESS
// The internal event was successfully handled.
// NS_STATUS_ABORTED
// The processing was aborted since the maximum event count specified
// was met.
//
//*****************************************************************************
MPL_STATUS
MplInterruptDoneInternal (
IN NS_VOID *pMplHandle,
IN NS_UINT maxEvents
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
if (pMplCtx->isrReg & RXIDLE)
{
// Rx-Idle - For Perf tuning purposes
}
if (pMplCtx->isrReg & MIBSTATS)
{
// Go read MIB statistics
}
if (pMplCtx->isrReg & WOL_EVENT)
{
// Power Management Event, i.e. Wake-On-LAN
}
if (pMplCtx->isrReg & PHYSTSCHANGE)
{
// PHY status change: link is up or down
MplLinkInterrupt(pMplCtx);
}
if (pMplCtx->isrReg & SW_INT)
{
// Software Interrupt, set when SWI bit is set in CR
}
if (pMplCtx->isrReg & HIORDER_INT)
{
if (pMplCtx->isrReg & RXSTSFIFO_OVRN)
{
// Rx FIFO overrun (RXOVR)
}
}
if (pMplCtx->isrReg & RXRST_COMPLETE)
{
// recv reset complete
}
if (pMplCtx->isrReg & TXRST_COMPLETE)
{
// xmit reset complete
}
return NS_STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -