?? s3c2510eth.c
字號:
{
#ifdef DEBUG_TRACE
printf(" S3C2510_ETH_TBD_MNOCARR\n");
#endif /* DEBUG_TRACE */
/* Up-date statistics. */
pDrvCtrl->mTxNocarr++;
}
if (pTbd->status & S3C2510_ETH_TBD_MDEFERERR)
{
#ifdef DEBUG_TRACE
printf(" S3C2510_ETH_TBD_MDEFERERR\n");
#endif /* DEBUG_TRACE */
/* Up-date statistics. */
pDrvCtrl->mTxDeferErr++;
}
if (pTbd->status & S3C2510_ETH_TBD_MUNDERFLOW)
{
#ifdef DEBUG_TRACE
printf(" S3C2510_ETH_TBD_MUNDERFLOW\n");
#endif /* DEBUG_TRACE */
/* Up-date statistics. */
pDrvCtrl->mTxUnderflow++;
}
if (pTbd->status & S3C2510_ETH_TBD_MEXCOLL)
{
#ifdef DEBUG_TRACE
printf(" S3C2510_ETH_TBD_MEXCOLL\n");
#endif /* DEBUG_TRACE */
/* Up-date statistics. */
pDrvCtrl->mTxExColl++;
}
return ERROR;
}
if (pTbd->status & S3C2510_ETH_TBD_MCOMP) /* MAC Tx Completed */
{
if (pTbd->status & S3C2510_ETH_TBD_MDEFER) /* MAC Tx Deferred Output */
{
#ifdef DEBUG_TRACE
printf(" S3C2510_ETH_TBD_MDEFER\n");
#endif /* DEBUG_TRACE */
/* Up-date statistics. */
pDrvCtrl->mTxDefer++;
}
if (pTbd->status & S3C2510_ETH_TBD_MCOLL) /* MAC Tx Collision is Occured */
{
#ifdef DEBUG_TRACE
printf(" S3C2510_ETH_TBD_MCOLL\n");
#endif /* DEBUG_TRACE */
/* Up-date statistics. */
pDrvCtrl->mTxColl++;
}
#ifdef DEBUG_TRACE
printf("pTbd(0x%08X), pBuf(0x%08X), status(0x%04X), length(%u)\n", (UINT32)pTbd, pTbd->pBuf, pTbd->status, pTbd->length);
#endif /* DEBUG_TRACE */
return OK;
}
printf("s3c2510Eth%d Error: Unknown TBD(0x%08X) status(0x%04X)\n", pDrvCtrl->unit, (UINT32)pTbd, pTbd->status);
return ERROR;
}
/*******************************************************************************
*
* s3c2510EthSend - send packet in interrupt mode
*
* RETURNS: OK, or END_ERR_BLOCK.
*/
STATUS s3c2510EthSend(
ETH_DRV_CTRL *pDrvCtrl, /* pointer to driver structure */
M_BLK_ID pMblk /* pointer to the mBlk/cluster pair */
)
{
int unit = pDrvCtrl->unit;
ULONG length;
PETHTBD pTbd;
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d Send, 0x%08X\n", unit, (UINT32)pMblk->mBlkHdr.mData);
#endif /* DEBUG_TRACE */
if (pDrvCtrl->bTxBlocked)
{
/* Retry later. */
return END_ERR_BLOCK;
}
if (pDrvCtrl->bPolling)
{
return ERROR;
}
length = pMblk->mBlkPktHdr.len;
/* Check frame length. */
if ((length <= SIZE_ETH_HDR) || (length > SIZE_ETH_MFLR))
{
printf("s3c2510Eth%d Error: Invalid Tx length, %u\n", unit, (UINT)length);
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifOutErrors++;
return ERROR;
}
/* Get the current free TBD. */
pTbd = s3c2510EthTbdGet(pDrvCtrl);
if (pTbd == NULL)
{
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d Error: Failed to allocate TBD\n", unit);
#endif /* DEBUG_TRACE */
/* Tx is busy. */
pDrvCtrl->bTxBlocked = TRUE;
/* Retry later. */
return END_ERR_BLOCK;
}
if ((pMblk->mBlkHdr.mData >= (char *)SYS_MEM_TOP) && (pMblk->mBlkHdr.mNext == NULL))
{
char *pBuf = pMblk->pClBlk->clNode.pClBuf;
length = pMblk->mBlkPktHdr.len;
/* Swap buffer. */
pMblk->pClBlk->clNode.pClBuf = (char *)(pTbd->pBuf - (SIZE_ETH_FB_HDR - 4));
pTbd->pBuf = (UINT32)(pBuf + (SIZE_ETH_FB_HDR - 4));
pMblk->mBlkHdr.mData = (char *)(pTbd->pBuf + SIZE_ETH_WA);
}
else
{
/* Copy data. */
length = netMblkToBufCopy(pMblk, (char *)(pTbd->pBuf + SIZE_ETH_WA), NULL);
}
#if 0
s3c2510DesRun(
(UCHAR *)(pTbd->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
s3c2510DesRun(
(UCHAR *)(pTbd->pBuf + SIZE_ETH_WA + SIZE_ETH_HDR),
(UCHAR *)(pTbd->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 *)(pTbd->pBuf + SIZE_ETH_WA + SIZE_ETH_HDR),
(UCHAR *)(pTbd->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
/* Free the Mblk. */
netMblkClChainFree(pMblk);
#ifdef DEBUG_TRACE
s3c2510EthHexDump((UCHAR *)(pTbd->pBuf + SIZE_ETH_WA), length);
#endif /* DEBUG_TRACE */
/* Start transmit. */
s3c2510EthTbdStart(pDrvCtrl, pTbd, length);
return OK;
}
/*******************************************************************************
*
* s3c2510EthPollReceive - receive packet in polled mode
*
* RETURNS: OK, or EAGAIN.
*/
STATUS s3c2510EthPollReceive(
ETH_DRV_CTRL *pDrvCtrl, /* pointer to driver structure */
M_BLK_ID pMblk /* pointer to the mBlk/cluster pair */
)
{
PETHRBD pRbd;
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d PollReceive\n", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
/* Get the first available RBD. */
pRbd = s3c2510EthRbdGet(pDrvCtrl);
/* If no RBD is available, retry it later. */
if (pRbd == NULL)
{
return EAGAIN;
}
do
{
ULONG length = s3c2510EthRbdCheck(pDrvCtrl, pRbd);
if (length == 0)
{
break;
}
/* If buffer is not large enough, we do not copy the received buffer. */
if ((ULONG)pMblk->mBlkHdr.mLen < length)
{
printf("s3c2510Eth%d Error: Too small Rx mBlk, %d\n", pDrvCtrl->unit, pMblk->mBlkHdr.mLen);
break;
}
#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;
}
/* Set up the mBlk properly. */
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkHdr.mLen = length;
pMblk->mBlkPktHdr.len = length;
/* Copy data. */
bcopy((char *)(pRbd->pBuf + SIZE_ETH_WA), (char *)pMblk->mBlkHdr.mData, length);
/* Free the used RBD. */
s3c2510EthRbdFree(pDrvCtrl, pRbd);
return OK;
} while (FALSE);
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifInErrors++;
/* Free the used RBD. */
s3c2510EthRbdFree(pDrvCtrl, pRbd);
return EAGAIN;
}
/*******************************************************************************
*
* s3c2510EthPollSend - send packet in polled mode
*
* RETURNS: OK, or EAGAIN.
*/
STATUS s3c2510EthPollSend(
ETH_DRV_CTRL *pDrvCtrl, /* pointer to driver structure */
M_BLK_ID pMblk /* pointer to the mBlk/cluster pair */
)
{
int unit = pDrvCtrl->unit;
ULONG length;
PETHTBD pTbd;
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d PollSend, 0x%08X\n", unit, (UINT32)pMblk->mBlkHdr.mData);
#endif /* DEBUG_TRACE */
length = pMblk->mBlkPktHdr.len;
/* Check frame length. */
if ((length <= SIZE_ETH_HDR) || (length > SIZE_ETH_MFLR))
{
printf("s3c2510Eth%d Error: Invalid Tx length, %u\n", unit, (UINT)length);
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifOutErrors++;
return ERROR;
}
/* Get the current free TBD. */
pTbd = s3c2510EthTbdGet(pDrvCtrl);
if (pTbd == NULL)
{
#ifdef DEBUG_TRACE
printf("s3c2510Eth%d Error: Failed to allocate TBD\n", unit);
#endif /* DEBUG_TRACE */
/* Retry later. */
return EAGAIN;
}
do
{
/* Copy data but do not free the Mblk. */
length = (ULONG)netMblkToBufCopy(pMblk, (char *)(pTbd->pBuf + SIZE_ETH_WA), NULL);
#ifdef DEBUG_TRACE
s3c2510EthHexDump((UCHAR *)(pTbd->pBuf + SIZE_ETH_WA), length);
#endif /* DEBUG_TRACE */
/* Start transmit. */
s3c2510EthTbdStart(pDrvCtrl, pTbd, length);
/* Check if completed. */
if (s3c2510EthTbdCheck(pDrvCtrl, pTbd) == OK)
{
/* 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;
}
/* Free the used TBD. */
s3c2510EthTbdFree(pDrvCtrl, pTbd);
return OK;
}
} while (FALSE);
/* Up-date statistics. */
pDrvCtrl->MIB2TBL.ifOutErrors++;
/* Free the used TBD. */
s3c2510EthTbdFree(pDrvCtrl, pTbd);
return EAGAIN;
}
/*******************************************************************************
*
* s3c2510EthIntRx - Rx interrupt service routine
*
* RETURNS : N/A
*/
void s3c2510EthIntRx(
ETH_DRV_CTRL *pDrvCtrl /* pointer to driver structure */
)
{
int unit = pDrvCtrl->unit;
UINT32 status;
/* Read and clear interrupt status. */
status = *S3C2510_BMRXSTAT(unit);
*S3C2510_BMRXSTAT(unit) |= status; /* jwchoi */
if (status & S3C2510_BMRXSTAT_BDONE) /* BDMA Rx Done */
{
if ((!pDrvCtrl->bPolling) && (!pDrvCtrl->bRxHandler))
{
pDrvCtrl->bRxHandler = TRUE;
netJobAdd((FUNCPTR)s3c2510EthRxHandler, (int)pDrvCtrl, 0, 0, 0, 0);
}
}
if (status & S3C2510_BMRXSTAT_BNO) /* BDMA Rx Not Owner */
{
/* Up-date statistics. */
pDrvCtrl->bmRxStatBno++;
if (!pDrvCtrl->bPolling)
{
pDrvCtrl->bRxHandler = TRUE;
netJobAdd((FUNCPTR)s3c2510EthRxHandler, (int)pDrvCtrl, 0, 0, 0, 0);
}
}
if (status & S3C2510_BMRXSTAT_BFULL) /* BDMA Rx Buffer Overflow */
{
/* Up-date statistics. */
pDrvCtrl->bmRxStatBfull++;
}
}
/*******************************************************************************
*
* s3c2510EthIntTx - Tx interrupt service routine
*
* RETURNS : N/A
*/
void s3c2510EthIntTx(
ETH_DRV_CTRL *pDrvCtrl /* pointer to driver structure */
)
{
int unit = pDrvCtrl->unit;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -