📄 ethernet.c
字号:
*(UINT32 *)SNDS_BDMASTAT = RxGood ;
*/
do
{
/*
* Check if Null list interrupt has occurred. If yes, reset
* and restart the Ethernet MAC (as given in Samsung sample code.
*/
if (bdmaStat.stat_reg.bdmaRxNullList)
{
sndsEndStop(pDrvCtrl); /* Stop RX and TX */
sndsEndReset(pDrvCtrl); /* reset the chip */
sndsEndFdFree(pDrvCtrl); /* Free the FDs */
sndsEndFdInitialize(pDrvCtrl); /* Reinitialize FDs */
sndsEndMacInitialize(pDrvCtrl); /* Initialize MAC */
sndsEndStart(pDrvCtrl); /* Start RX and TX */
break;
}
/*
* Received a good frame
*/
frameLength = gpReceiveFrameDescStart->rxStatusLength.frameLength;
/*Update error statistics counters */
/*
if(
(gpReceiveFrameDescStart->rxStatusLength.ovMax)|
(gpReceiveFrameDescStart->rxStatusLength.ctlRcv)|
(gpReceiveFrameDescStart->rxStatusLength.rx10Stat)|
(gpReceiveFrameDescStart->rxStatusLength.alignErr)|
(gpReceiveFrameDescStart->rxStatusLength.crcErr)|
(gpReceiveFrameDescStart->rxStatusLength.overFlow)|
(gpReceiveFrameDescStart->rxStatusLength.longErr)|
(gpReceiveFrameDescStart->rxStatusLength.rxPar)|
(gpReceiveFrameDescStart->rxStatusLength.rxHalted))
{
*/
if ((*(UINT32 *) (&gpReceiveFrameDescStart->rxStatusLength)) & 0xbfff0000 )
{
pDrvCtrl->statistics.rxBad++;
*(UINT32 *)SNDS_IOPDATA = 0xf3 ;
if (gpReceiveFrameDescStart->rxStatusLength.ovMax)
pDrvCtrl->statistics.rxOvMaxSize++;
if (gpReceiveFrameDescStart->rxStatusLength.ctlRcv)
pDrvCtrl->statistics.rxCtlRecd++;
if (gpReceiveFrameDescStart->rxStatusLength.rx10Stat)
pDrvCtrl->statistics.rx10Stat++;
if (gpReceiveFrameDescStart->rxStatusLength.alignErr)
pDrvCtrl->statistics.rxAlignErr++;
if (gpReceiveFrameDescStart->rxStatusLength.crcErr)
pDrvCtrl->statistics.rxCRCErr++;
if (gpReceiveFrameDescStart->rxStatusLength.overFlow)
pDrvCtrl->statistics.rxOverflowErr++;
if (gpReceiveFrameDescStart->rxStatusLength.longErr)
pDrvCtrl->statistics.rxLongErr++;
if (gpReceiveFrameDescStart->rxStatusLength.rxPar)
pDrvCtrl->statistics.rxParErr++;
if (gpReceiveFrameDescStart->rxStatusLength.rxHalted)
pDrvCtrl->statistics.rxHalted++;
}
else if((gpReceiveFrameDescStart->rxStatusLength.good))
{
pDrvCtrl->statistics.rxGood++;
pFrameData = (UINT16 *)(gpReceiveFrameDescStart->rxFrameData.frameDataPtr);
sndsEndBugFix (pFrameData);
sndsEndRecv (pDrvCtrl, (char *)pFrameData, frameLength);
GoodCnt++ ;
*(UINT32 *)SNDS_IOPDATA = 0x3f ;
/*printf("\n GoodCount %d, RxStatus %x \n", GoodCnt, *(UINT32 *)(&gpReceiveFrameDescStart->rxStatusLength) );*/
/*printf("G");*/
}
else ;
gpReceiveFrameDescStart->rxFrameData.o_bit = 1; /* Ownership back to BDMA */
gStatusLengthPrevious = *(UINT32 *)(&gpReceiveFrameDescStart->rxStatusLength); /* For MAC bug fix */
*(UINT32 *)(&gpReceiveFrameDescStart->rxStatusLength) = 0; /* Rx status length field */
gpReceiveFrameDescStart = gpReceiveFrameDescStart->nextRxFrameDesc;
} while (gpReceiveFrameDescStart != pReceiveFrameDesc);
#if 0
/* cjw */
if(!((*(UINT32 *)SNDS_BDMARXCON) & BRxEn)){
*(UINT32 *)SNDS_IOPDATA = 0xf0 ;
printf("\n\n\n\n BDMA Rx Stopped !!!!!! %x @@@@@@@@@@@@@@@\n\n\n\n\n", *(UINT32 *)SNDS_BDMARXCON);
}
if(!((*(UINT32 *)SNDS_BDMASTAT) & BRxNO)) {
*(UINT32 *)SNDS_IOPDATA = 0x00 ;
*(UINT32 *)SNDS_BDMASTAT = BRxNO;
}
*(UINT32 *)SNDS_IOPDATA = 0x0f ;
#endif
}
/*******************************************************************************
*
* sndsEndRecv - process the next incoming packet
*
* Handle one incoming packet. The packet is checked for errors.
*
* RETURNS: N/A.
*/
LOCAL STATUS sndsEndRecv
(
END_DEVICE *pDrvCtrl, /* device structure */
char* pData, /* packet to process */
UINT32 len
)
{
M_BLK_ID pMblk;
char* pNewCluster;
CL_BLK_ID pClBlk;
/* Add one to our unicast data. */
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
/*
* We implicitly are loaning here, if copying is necessary this
* step may be skipped, but the data must be copied before being
* passed up to the protocols.
*/
pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->end.pNetPool->clTbl[0]);
if (pNewCluster == NULL)
{
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
/* Grab a cluster block to marry to the cluster we received. */
if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
{
netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
/*
* OK we've got a spare, let's get an M_BLK_ID and marry it to the
* one in the ring.
*/
if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
{
netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
(UINT32)pData &= ~NON_CACHE_REGION;
/* Join the cluster to the MBlock */
netClBlkJoin (pClBlk, pData, SNDS_CL_SIZE, NULL, 0, 0, 0);
netMblkClJoin (pMblk, pClBlk);
pMblk->mBlkHdr.mData += SNDS_DATA_OFFSET;
if (gBugFixDone == TRUE)
pMblk->mBlkHdr.mData += 4;
pMblk->mBlkHdr.mLen = len;
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkPktHdr.len = len;
/* Call the upper layer's receive routine. */
END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);
/* gpReceiveFrameDescStart->rxFrameData.frameDataPtr = (UINT32) pNewCluster; Mistral Solution re-add */
gpReceiveFrameDescStart->rxFrameData.frameDataPtr = (UINT32) pNewCluster;
cleanRXD: /* old line 1 */
/* gpReceiveFrameDescStart->rxFrameData.frameDataPtr = (UINT32) pNewCluster; */
/* Mistral Solution re-add */
gpReceiveFrameDescStart->rxFrameData.frameDataPtr |= NON_CACHE_REGION;
return (OK);
}
/*******************************************************************************
*
* sndsEndSend - the driver send routine
*
* This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.
* The buffer must already have the addressing information properly installed
* in it. This is done by a higher layer. The last arguments are a free
* routine to be called when the device is done with the buffer and a pointer
* to the argument to pass to the free routine.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS sndsEndSend
(
END_DEVICE *pDrvCtrl, /* device ptr */
M_BLK_ID pNBuff /* data to send */
)
{
int len;
int oldLevel;
BOOL freeNow = TRUE;
TRANSMIT_FRAME_DESC *pTxFd;
BDMATXCON bdmaTxCon;
MACTXCON macTxCon;
*(UINT32 *)(&bdmaTxCon) = 0;
*(UINT32 *)(&macTxCon) = 0;
if (gpTransmitFrameDescStart->txFrameData.o_bit) /* Ownership with BDMA? */
return ERROR;
pTxFd = gpTransmitFrameDescStart;
len = pNBuff->mBlkPktHdr.len;
/*
* Obtain exclusive access to transmitter. This is necessary because
* we might have more than one stack transmitting at once.
*/
END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);
/* Set pointers in local structures to point to data. */
netMblkToBufCopy(pNBuff, (void *)pTxFd->txFrameData.frameDataPtr, NULL) ;
*(UINT32 *)(&pTxFd->txControl) = 0; /* Reset control word */
pTxFd->txControl.t_bit = 1;
pTxFd->txControl.a_bit = 1;
pTxFd->txControl.l_bit = 1;
pTxFd->txStatusLength.frameLength = len;
pTxFd->txFrameData.o_bit = 1;
/* place a transmit request */
oldLevel = intLock (); /* now sndsEndInt won't get confused */
/* initiate device transmit */
bdmaTxCon.txCon_resetval = *(UINT32 *)SNDS_BDMATXCON;
bdmaTxCon.txCon_reg.enable = 1;
*(UINT32 *)SNDS_BDMATXCON = bdmaTxCon.txCon_resetval;
macTxCon.macTxCon_resetval = *(UINT32 *)SNDS_MACTXCON;
macTxCon.macTxCon_reg.transmitEnable = 1;
*(UINT32 *)SNDS_MACTXCON = macTxCon.macTxCon_resetval;
intUnlock (oldLevel); /* now sndsEndInt won't get confused */
/* Advance our management index */
gpTransmitFrameDescStart = gpTransmitFrameDescStart->nextTxFrameDesc;
END_TX_SEM_GIVE (&pDrvCtrl->end);
/* Bump the statistic counter. */
END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);
/*
* Cleanup. The driver must either free the packet now or
* set up a structure so it can be freed later after a transmit
* interrupt occurs.
*/
if (freeNow)
netMblkClChainFree (pNBuff);
return (OK);
}
/*******************************************************************************
*
* sndsEndIoctl - the driver I/O control routine
*
* Process an ioctl request.
*
* RETURNS: A command specific response, usually OK or ERROR.
*/
LOCAL int sndsEndIoctl
(
END_DEVICE *pDrvCtrl, /* device receiving command */
int cmd, /* ioctl command code */
caddr_t data /* command argument */
)
{
int error = 0;
long value;
switch (cmd)
{
case EIOCSADDR:
if (data == NULL)
return (EINVAL);
bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),
END_HADDR_LEN(&pDrvCtrl->end));
break;
case EIOCGADDR:
if (data == NULL)
return (EINVAL);
bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,
END_HADDR_LEN(&pDrvCtrl->end));
break;
case EIOCSFLAGS:
value = (long)data;
if (value < 0)
{
value = ~value;
END_FLAGS_CLR (&pDrvCtrl->end, value);
}
else
{
END_FLAGS_SET (&pDrvCtrl->end, value);
}
sndsEndConfig (pDrvCtrl);
break;
case EIOCGFLAGS:
*(int *)data = END_FLAGS_GET(&pDrvCtrl->end);
break;
case EIOCPOLLSTART:
sndsEndPollStart (pDrvCtrl);
break;
case EIOCPOLLSTOP:
sndsEndPollStop (pDrvCtrl);
break;
case EIOCGMIB2:
if (data == NULL)
return (EINVAL);
bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data,
sizeof(pDrvCtrl->end.mib2Tbl));
break;
case EIOCGFBUF:
if (data == NULL)
return (EINVAL);
*(int *)data = 0; /**END_MIN_FBUF;**/
break;
default:
error = EINVAL;
}
return (error);
}
/******************************************************************************
*
* sndsEndConfig - reconfigure the interface under us.
*
* Reconfigure the interface setting promiscuous mode
*
* RETURNS: N/A.
*/
LOCAL void sndsEndConfig
(
END_DEVICE *pDrvCtrl /* device to be re-configured */
)
{
sndsEndReset(pDrvCtrl); /* reset the chip */
/* Set up address filter for multicasting. */
if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0)
sndsEndAddrFilterSet (pDrvCtrl);
if (pDrvCtrl->fdInitialized == TRUE)
sndsEndFdFree(pDrvCtrl); /* Free the FDs */
sndsEndFdInitialize(pDrvCtrl); /* Reinitialize FDs */
sndsEndMacInitialize(pDrvCtrl); /* Initialize MAC */
/* Was started before in interrupt mode? */
if ((END_FLAGS_GET(&pDrvCtrl->end) & IFF_RUNNING) && \
((pDrvCtrl->flags & LS_POLLING) == 0))
sndsEndStart(pDrvCtrl); /* Start again */
return;
}
/*******************************************************************************
*
* sndsEndPollStart - start polled mode operations
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS sndsEndPollStart
(
END_DEVICE* pDrvCtrl /* device to be polled */
)
{
int oldLevel;
BDMARXCON bdmaRxCon;
MACRXCON macRxCon;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -