📄 mpllink.c
字号:
// NS_STATUS_FAILURE
// The link state is not UP.
//
//*****************************************************************************
MPL_STATUS
MplLinkUpComplete (
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
NS_UINT32 txCfgVal, rxCfgVal;
ENTER(MplLinkUpComplete);
// Check if the link is really up
if (pMplCtx->linkStatus != MPL_LINK_STATUS_UP)
{
EXIT(MplLinkUpComplete);
return NS_STATUS_FAILURE;
}
// Finish PHY link setup
if (MplPhyLinkSetupComplete(pMplHandle) == NS_FALSE)
{
EXIT(MplLinkUpComplete);
return NS_STATUS_FAILURE;
}
// Setup MAC operations
txCfgVal = MPL_READ32(pMplCtx, TXCFG);
rxCfgVal = MPL_READ32(pMplCtx, RXCFG);
if (pMplCtx->linkCfg.duplex == MPL_LINK_DUPLEX_FULL)
{
// Set MAC to full duplex operation
// Tx Engine - Ignore : Carrier Sense and Heartbeat
MPL_WRITE32(pMplCtx, TXCFG, txCfgVal | CARRIER_IGNORE | SQE_IGNORE);
// Rx Engine - Enable : FD operation
MPL_WRITE32(pMplCtx, RXCFG, rxCfgVal | FULLDUPLEX_EN);
}
else
{
// Set MAC to half duplex operation
// Tx Engine - Enable : Carrier Sense and Heartbeat
MPL_WRITE32(pMplCtx, TXCFG, (txCfgVal & ~(CARRIER_IGNORE | SQE_IGNORE)));
// Rx Engine - Disable : FD operation
MPL_WRITE32(pMplCtx, RXCFG, (rxCfgVal & ~(FULLDUPLEX_EN)));
}
// Set Pause configuration on the MAC
setPause(pMplCtx);
EXIT(MplLinkUpComplete);
return NS_STATUS_SUCCESS;
}
//*****************************************************************************
// MplLinkInterrupt
// Processes an incoming link related interrupt
// At this time this is an MPL internal function (called from
// MplIntteruptDoneInternal)
//
// Parameters
// pMplHandle
// MPL device handle returned following a call to MplInitialize
//
// Return Value
// NS_STATUS_SUCCESS
// The interrupt was successfully fielded.
//
//*****************************************************************************
MPL_STATUS
MplLinkInterrupt(
IN NS_VOID *pMplHandle
)
{
MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle;
// Notify NSM, it will ensure further processing after
// taking care of synchronization issues
NsmLinkStatusChange(pMplCtx->pClientHandle);
return NS_STATUS_SUCCESS;
}
//*****************************************************************************
//
// linkCompare
// Check if the requested link configuration matches the one on the
// device
//
// Parameters
// pMplCtx
// Pointer to MPL Context
//
// Return Value
// NS_TRUE
// The requested link configuration matches the one on the device
// NS_FALSE
// The requested link configuration does NOT match the one on the device
//
//*****************************************************************************
static
NS_BOOLEAN
linkCompare(
IN MPL_CONTEXT *pMplCtx,
IN MPL_LINK_CFG *pLinkCfg
)
{
NS_BOOLEAN autoDone;
ENTER(linkCompare);
// FM: Check if this version of the PHY would need some patch work
// If so, then we need to reestablish link
if (MplPhyRequiresPatch(pMplCtx) == NS_TRUE)
{
EXIT(linkCompare);
return NS_FALSE;
}
// Check if link is up, if not no match
if (MplPhyGetLinkStatus(pMplCtx) != MPL_LINK_STATUS_UP)
{
EXIT(linkCompare);
return NS_FALSE;
}
// Check if speed matches
if (MplPhyGetLinkSpeed(pMplCtx) != pLinkCfg->speed)
{
EXIT(linkCompare);
return NS_FALSE;
}
// Check if duplex matches
if (MplPhyGetLinkDuplex(pMplCtx) != pLinkCfg->duplex)
{
EXIT(linkCompare);
return NS_FALSE;
}
// Check if current pause matches
if (pMplCtx->pauseType != pLinkCfg->pauseType)
{
EXIT(linkCompare);
return NS_FALSE;
}
// Check if Auto-Neg is requested, but prev setup was in forced mode
autoDone = MplPhyAutoNegDone(pMplCtx);
if ((pLinkCfg->mode == MPL_LINK_MODE_AUTO) && (autoDone == NS_FALSE))
{
EXIT(linkCompare);
return NS_FALSE;
}
// Check if forced mode is requested, but prev setup was in Auto-Neg mode
if ((pLinkCfg->mode == MPL_LINK_MODE_FORCED) && (autoDone == NS_TRUE))
{
EXIT(linkCompare);
return NS_FALSE;
}
// All OK, link cfg matches
return NS_TRUE;
}
//*****************************************************************************
//
// setPause
// Set the pause configurations on the MAC
//
// Parameters
// pMplCtx
// Pointer to MPL Context
//
// Return Value
// None
//
//*****************************************************************************
static
NS_VOID
setPause(
IN MPL_CONTEXT *pMplCtx
)
{
NS_UINT32 pcrVal = 0x0;
MPL_LINK_CFG *pLinkCfg = &pMplCtx->linkCfg;
ENTER(setPause);
// Check if pause frame reception is enabled
if (pMplCtx->pauseType & MPL_LINK_PAUSE_RECEIVE)
{
pcrVal |= RXPAUSE_EN | PS_MCAST | PS_DA;
}
// Check if pause frame transmission is enabled
if (pMplCtx->pauseType & MPL_LINK_PAUSE_TRANSMIT)
{
// Status FIFO - Lower Threshold
if (pLinkCfg->pauseRxSTLO == 0x0)
pcrVal |= PTHRESHLO_SFIFO_DIS;
else if (pLinkCfg->pauseRxSTLO < 2)
pcrVal |= PTHRESHLO_SFIFO2PKTS;
else if (pLinkCfg->pauseRxSTLO < 4)
pcrVal |= PTHRESHLO_SFIFO4PKTS;
else
pcrVal |= PTHRESHLO_SFIFO8PKTS;
// Status FIFO - Higher Threshold
if (pLinkCfg->pauseRxSTHI < pLinkCfg->pauseRxSTLO)
pLinkCfg->pauseRxSTHI = pLinkCfg->pauseRxSTLO;
if (pLinkCfg->pauseRxSTHI == 0x0)
pcrVal |= PTHRESHHI_SFIFO_DIS;
else if (pLinkCfg->pauseRxSTHI >= 4)
pcrVal |= PTHRESHHI_SFIFO8PKTS;
else if (pLinkCfg->pauseRxSTHI >= 2)
pcrVal |= PTHRESHHI_SFIFO4PKTS;
else
pcrVal |= PTHRESHHI_SFIFO2PKTS;
// Data FIFO - Lower Threshold
if (pLinkCfg->pauseRxDALO == 0x0)
pcrVal |= PTHRESHLO_DFIFO_DIS;
else if (pLinkCfg->pauseRxDALO < 512)
pcrVal |= PTHRESHLO_DFIFO512;
else if (pLinkCfg->pauseRxDALO < 1024)
pcrVal |= PTHRESHLO_DFIFO1024;
else
pcrVal |= PTHRESHLO_DFIFO1536;
// Data FIFO - Higher Threshold
if (pLinkCfg->pauseRxDAHI < pLinkCfg->pauseRxDALO)
pLinkCfg->pauseRxDAHI = pLinkCfg->pauseRxDALO;
if (pLinkCfg->pauseRxDAHI == 0x0)
pcrVal |= PTHRESHHI_DFIFO_DIS;
else if (pLinkCfg->pauseRxDAHI >= 1024)
pcrVal |= PTHRESHHI_DFIFO1536;
else if (pLinkCfg->pauseRxDAHI >= 512)
pcrVal |= PTHRESHHI_DFIFO1024;
else
pcrVal |= PTHRESHHI_DFIFO512;
// Set pause counter
pcrVal |= pLinkCfg->pauseCtr;
}
MPL_WRITE32(pMplCtx, PCR, pcrVal);
EXIT(setPause);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -