?? s3c2510eth.c
字號(hào):
UINT32 status;
/* Read and clear interrupt status. */
status = (UINT32)*S3C2510_BMTXSTAT(unit);
*S3C2510_BMTXSTAT(unit) |= status; /* jwchoi */
if (status & S3C2510_BMTXSTAT_MCOMP) /* MAC Tx Completion */
{
if ((!pDrvCtrl->bPolling) && (!pDrvCtrl->bTxHandler))
{
pDrvCtrl->bTxHandler = TRUE;
netJobAdd((FUNCPTR)s3c2510EthTxHandler, (int)pDrvCtrl, 0, 0, 0, 0);
}
}
if (status & S3C2510_BMTXSTAT_BNO) /* BDMA Tx Not Owner */
{
/* Up-date statistics. */
pDrvCtrl->bmTxStatBno++;
}
if (status & S3C2510_BMTXSTAT_BEMPTY) /* BDMA Tx Buffer Empty */
{
/* Up-date statistics. */
pDrvCtrl->bmTxStatBempty++;
}
}
/*******************************************************************************
*
* s3c2510EthRbdProcess - porcess a RBD
*
* RETURNS : N/A
*/
void s3c2510EthRbdProcess(
ETH_DRV_CTRL *pDrvCtrl, /* pointer to driver structure */
PETHRBD pRbd /* pointer to the RBD */
)
{
ULONG length;
length = s3c2510EthRbdCheck(pDrvCtrl, pRbd);
if (length == 0)
{
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifInErrors++;
}
else
{
#ifdef DEBUG_TRACE
s3c2510EthHexDump((UCHAR *)(pRbd->pBuf + SIZE_ETH_WA), length);
#endif /* DEBUG_TRACE */
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifInOctets += length;
if (((UINT8 *)(pRbd->pBuf + SIZE_ETH_WA))[0] & 0x01)
{
pDrvCtrl->MIB2TBL.ifInNUcastPkts += 1;
}
else
{
pDrvCtrl->MIB2TBL.ifInUcastPkts += 1;
}
if (pDrvCtrl->pClPool)
{
M_BLK_ID pMblk;
CL_BLK_ID pClBlk;
char *pBuf;
if (pDrvCtrl->pClPool->clNumFree > (NUM_TBD_ETH / 8))
{
pMblk = netMblkGet(pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA);
pClBlk = netClBlkGet(pDrvCtrl->endObj.pNetPool, M_DONTWAIT);
END_TX_SEM_TAKE(&pDrvCtrl->endObj, WAIT_FOREVER);
pBuf = netClusterGet(pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPool);
END_TX_SEM_GIVE(&pDrvCtrl->endObj);
}
else
{
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d Error: no cluster buffer for the Rx\n", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
pMblk = NULL;
pClBlk = NULL;
pBuf = NULL;
}
if ((!pMblk) || (!pClBlk) || (!pBuf))
{
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifInDiscards++;
if (pMblk)
{
netMblkFree(pDrvCtrl->endObj.pNetPool, pMblk);
}
#ifdef DEBUG_TRACE
else
{
printf("s3c2510Eth%d Error: failed to allocate M_BLK\n", pDrvCtrl->unit);
}
#endif /* DEBUG_TRACE */
if (pClBlk)
{
netClBlkFree(pDrvCtrl->endObj.pNetPool, pClBlk);
}
#ifdef DEBUG_TRACE
else
{
printf("s3c2510Eth%d Error: failed to allocate CL_BLK\n", pDrvCtrl->unit);
}
#endif /* DEBUG_TRACE */
if (pBuf)
{
netClFree(pDrvCtrl->endObj.pNetPool, pBuf);
}
#ifdef DEBUG_TRACE
else
{
printf("s3c2510Eth%d Error: failed to allocate cluster buffer\n", pDrvCtrl->unit);
}
#endif /* DEBUG_TRACE */
}
else
{
netClBlkJoin(pClBlk, (char *)(pRbd->pBuf - (SIZE_ETH_FB_HDR - 4)), SIZE_ETH_MDMA, NULL, 0, 0, 0);
netMblkClJoin(pMblk, pClBlk);
/* Set up the mBlk properly. */
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkHdr.mData = (char *)(pRbd->pBuf + SIZE_ETH_WA);
pMblk->mBlkHdr.mLen = length;
pMblk->mBlkPktHdr.len = length;
#if 0 /* One time 3DES Run */
s3c2510DesRun(
(UCHAR *)(pRbd->pBuf + SIZE_ETH_WA + SIZE_ETH_HDR),
(UCHAR *)(FB_END),
#ifdef DES_4WORD
((length - SIZE_ETH_HDR + 31) / 32) * 32,
#else /* DES_4WORD */
((length - SIZE_ETH_HDR + 7) / 8) * 8,
#endif /* DES_4WORD */
1, 1, 1, 1, 1, 1, 1, 1,
TRUE
);
#endif
#if 0 /* Two time 3DES Run */
s3c2510DesRun(
(UCHAR *)(pRbd->pBuf + SIZE_ETH_WA + SIZE_ETH_HDR),
(UCHAR *)(pRbd->pBuf + SIZE_ETH_WA + SIZE_ETH_HDR),
#ifdef DES_4WORD
((length - SIZE_ETH_HDR + 31) / 32) * 32,
#else /* DES_4WORD */
((length - SIZE_ETH_HDR + 7) / 8) * 8,
#endif /* DES_4WORD */
1, 1, 1, 1, 1, 1, 1, 1,
TRUE
);
s3c2510DesRun(
(UCHAR *)(pRbd->pBuf + SIZE_ETH_WA + SIZE_ETH_HDR),
(UCHAR *)(pRbd->pBuf + SIZE_ETH_WA + SIZE_ETH_HDR),
#ifdef DES_4WORD
((length - SIZE_ETH_HDR + 31) / 32) * 32,
#else /* DES_4WORD */
((length - SIZE_ETH_HDR + 7) / 8) * 8,
#endif /* DES_4WORD */
1, 1, 1, 1, 1, 1, 1, 1,
FALSE
);
#endif
/* Swap the buffer. */
pRbd->pBuf = (UINT32)(pBuf + (SIZE_ETH_FB_HDR - 4));
/* Call END receive routine. */
END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);
}
}
else if (pDrvCtrl->receiveRtn)
{
pDrvCtrl->receiveRtn(pDrvCtrl, (char *)(pRbd->pBuf + SIZE_ETH_WA), length);
}
}
/* Free the used RBD. */
s3c2510EthRbdFree(pDrvCtrl, pRbd);
}
/*******************************************************************************
*
* s3c2510EthTbdProcess - porcess a TBD
* RETURNS : N/A
*/
void s3c2510EthTbdProcess(
ETH_DRV_CTRL *pDrvCtrl, /* pointer to driver structure */
PETHTBD pTbd /* pointer to the TBD */
)
{
if (s3c2510EthTbdCheck(pDrvCtrl, pTbd) == ERROR)
{
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifOutErrors++;
}
else
{
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifOutOctets += (ULONG)pTbd->length;
if (((UINT8 *)(pTbd->pBuf + SIZE_ETH_WA))[0] & 0x01)
{
pDrvCtrl->MIB2TBL.ifOutNUcastPkts += 1;
}
else
{
pDrvCtrl->MIB2TBL.ifOutUcastPkts += 1;
}
}
END_TX_SEM_TAKE(&pDrvCtrl->endObj, WAIT_FOREVER);
/* Free the used TBD. */
s3c2510EthTbdFree(pDrvCtrl, pTbd);
END_TX_SEM_GIVE(&pDrvCtrl->endObj);
}
/*******************************************************************************
*
* s3c2510EthRxHandler - Rx interrupt handler
*
* RETURNS : N/A
*/
void s3c2510EthRxHandler(
ETH_DRV_CTRL *pDrvCtrl /* pointer to driver structure */
)
{
int unit = pDrvCtrl->unit;
UINT32 count;
PETHRBD pRbd;
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d RxHandler\n", unit);
#endif /* DEBUG_TRACE */
pDrvCtrl->bRxHandler = FALSE;
count = *S3C2510_BRXBDCNT(unit);
do
{
/* Get the first available RBD. */
pRbd = s3c2510EthRbdGet(pDrvCtrl);
if (pRbd == NULL)
{
break;
}
s3c2510EthRbdProcess(pDrvCtrl, pRbd);
} while (count != pDrvCtrl->rbdIndex);
/* Enable MAC Rx. */
*S3C2510_MRXCON(unit) |= S3C2510_MRXCON_EN; /* Receive Enable */
/* Enable BDMA Rx. */
*S3C2510_BRXCON(unit) |= S3C2510_BRXCON_EN; /* BDMA Rx Block Enable */
}
/*******************************************************************************
*
* s3c2510EthTxHandler - Tx interrupt handler
*
* RETURNS : N/A
*/
void s3c2510EthTxHandler(
ETH_DRV_CTRL *pDrvCtrl /* pointer to driver structure */
)
{
int unit = pDrvCtrl->unit;
UINT32 count;
PETHTBD pTbd;
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d TxHandler\n", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
pDrvCtrl->bTxHandler = FALSE;
count = *S3C2510_BTXBDCNT(unit);
do
{
/* Get the first completed TBD. */
pTbd = (PETHTBD)(pDrvCtrl->tbdBase + pDrvCtrl->tbdIndex * SIZE_BD);
if ((pTbd->status & S3C2510_ETH_TBD_O) || (pTbd->length == 0))
{
break;
}
END_TX_SEM_TAKE(&pDrvCtrl->endObj, WAIT_FOREVER);
s3c2510EthTbdProcess(pDrvCtrl, pTbd);
END_TX_SEM_GIVE(&pDrvCtrl->endObj);
} while (count != pDrvCtrl->tbdIndex);
/* Restart Tx if it was blocked. */
if (pDrvCtrl->bTxBlocked)
{
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d Restart Tx\n", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
muxTxRestart(&pDrvCtrl->endObj);
pDrvCtrl->bTxBlocked = FALSE;
}
}
/*******************************************************************************
*
* s3c2510EthShow - display driver statstics.
*
* RETURNS : N/A
*/
STATUS s3c2510EthShow(int unit)
{
ETH_DRV_CTRL *pDrvCtrl = (ETH_DRV_CTRL *)endFindByName(ETH_DEV_NAME, unit);
if (!pDrvCtrl)
{
return -1;
}
if (pDrvCtrl->endObj.pNetPool)
{
printf("pNetPool(0x%08X)\n", (UINT32)pDrvCtrl->endObj.pNetPool);
printf(" mBlkCnt: %d\n", pDrvCtrl->endObj.pNetPool->mBlkCnt);
printf(" mBlkFree: %d\n", pDrvCtrl->endObj.pNetPool->mBlkFree);
}
if (pDrvCtrl->pClPool)
{
printf("pClPool(0x%08X)\n", (UINT32)pDrvCtrl->pClPool);
printf(" clSize: %d\n", pDrvCtrl->pClPool->clSize);
printf(" clNum: %d\n", pDrvCtrl->pClPool->clNum);
printf(" clNumFree: %d\n", pDrvCtrl->pClPool->clNumFree);
}
printf("RBD(0x%08X)\n", pDrvCtrl->rbdBase);
printf(" rbdIndex: %d\n", pDrvCtrl->rbdIndex);
printf(" BRXBDCNT: %d\n", *S3C2510_BRXBDCNT(unit));
printf("TBD(0x%08X)\n", pDrvCtrl->tbdBase);
printf(" tbdIndex: %d\n", pDrvCtrl->tbdIndex);
printf(" tbdFree: %d\n", pDrvCtrl->tbdFree);
printf(" BTXBDCNT: %d\n", *S3C2510_BTXBDCNT(unit));
printf("Rx statistics%s\n", (!((*S3C2510_BRXCON(unit)) & S3C2510_BRXCON_EN)) ? ", stopped" : "");
printf(" bmRxStatBfull: %d\n", pDrvCtrl->bmRxStatBfull);
printf(" bmRxStatBno: %d\n", pDrvCtrl->bmRxStatBno);
printf(" bRxMso: %d\n", pDrvCtrl->bRxMso);
printf(" mRxHalted: %d\n", pDrvCtrl->mRxHalted);
printf(" mRxParErr: %d\n", pDrvCtrl->mRxParErr);
printf(" mRxLongErr: %d\n", pDrvCtrl->mRxLongErr);
printf(" mRxOverflow: %d\n", pDrvCtrl->mRxOverflow);
printf(" mRxCrcErr: %d\n", pDrvCtrl->mRxCrcErr);
printf(" mRxAlignErr: %d\n", pDrvCtrl->mRxAlignErr);
printf("Tx statistics%s\n", (!((*S3C2510_BTXCON(unit)) & S3C2510_BTXCON_EN)) ? ", stopped" : "");
printf(" bmTxStatBempty: %d\n", pDrvCtrl->bmTxStatBempty);
printf(" bmTxStatBno: %d\n", pDrvCtrl->bmTxStatBno);
printf(" mTxPaused: %d\n", pDrvCtrl->mTxPaused);
printf(" mTxHalted: %d\n", pDrvCtrl->mTxHalted);
printf(" mTxSqeErr: %d\n", pDrvCtrl->mTxSqeErr);
printf(" mTxParErr: %d\n", pDrvCtrl->mTxParErr);
printf(" mTxLateColl: %d\n", pDrvCtrl->mTxLateColl);
printf(" mTxNocarr: %d\n", pDrvCtrl->mTxNocarr);
printf(" mTxDeferErr: %d\n", pDrvCtrl->mTxDeferErr);
printf(" mTxUnderflow: %d\n", pDrvCtrl->mTxUnderflow);
printf(" mTxExColl: %d\n", pDrvCtrl->mTxExColl);
printf(" mTxDefer: %d\n", pDrvCtrl->mTxDefer);
printf(" mTxExColl: %d\n", pDrvCtrl->mTxExColl);
printf(" bTxBlocked: %d\n", pDrvCtrl->bTxBlocked);
return OK;
}
/*******************************************************************************
*
* s3c2510EthMiiShow - display MII registers.
*
* RETURNS : N/A
*/
STATUS s3c2510EthMiiShow(int unit)
{
ETH_DRV_CTRL *pDrvCtrl = (ETH_DRV_CTRL *)endFindByName(ETH_DEV_NAME, unit);
UINT8 phyAddr;
if (!pDrvCtrl)
{
return -1;
}
phyAddr = pDrvCtrl->phyInfo.phyAddr;
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_CTRL_REG, &pDrvCtrl->PHYREGS.phyCtrl);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_STAT_REG, &pDrvCtrl->PHYREGS.phyStatus);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_PHY_ID1_REG, &pDrvCtrl->PHYREGS.phyId1);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_PHY_ID2_REG, &pDrvCtrl->PHYREGS.phyId2);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_AN_ADS_REG, &pDrvCtrl->PHYREGS.phyAds);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_AN_PRTN_REG, &pDrvCtrl->PHYREGS.phyPrtn);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_AN_EXP_REG, &pDrvCtrl->PHYREGS.phyExp);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, MII_AN_NEXT_REG, &pDrvCtrl->PHYREGS.phyNext);
s3c2510EthMiiRead(pDrvCtrl, phyAddr, L80225_STAT_REG, &pDrvCtrl->l80225Status);
printf("Standard MII register\n");
printf(" MII_CTRL_REG: 0x%04X\n", pDrvCtrl->PHYREGS.phyCtrl);
prin
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -