?? gei82543rcvsnd.c
字號:
#include "gei82543Lib.h"
LOCAL void gei82543RxDesUpdate (END_DEVICE *);
extern void * sysVirtToPhys(void *virtAddr);
#define GEI_CAPACITY_LIMIT 5
/*************************************************************************
*
* gei82543RxDesUpdate - clean up the receive descriptor
*
* This routine cleans up receive descriptors, reusing the current cluster.
* Then it updates the tail pointer to make it available to the
* hardware.
*
* RETURNS: N/A
*/
LOCAL void gei82543RxDesUpdate
(
END_DEVICE * pDrvCtrl /* device to update */
)
{
int tempTail; /* temporary tail index */
char * pRxDesc; /* RX descriptor */
int tail;
DRV_LOG (DRV_DEBUG_RX, "gei82543RxDesUpdate...\n", 1, 2, 3, 4, 5, 6);
/* get the RX tail descriptor */
tempTail = pDrvCtrl->rxDescTail;
pRxDesc = GEI_GET_RX_DESC_ADDR(tempTail);
/* clean up status field */
GEI_WRITE_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET, 0);
/* update the tail pointer */
tail = tempTail + 1;
if (tail == pDrvCtrl->rxDescNum)
{
tail = 0;
}
pDrvCtrl->rxDescTail = tail;
/* kick this descriptor for receiving packet */
GEI_WRITE_REG(INTEL_82543GC_RDT, (UINT32)tempTail);
CACHE_PIPE_FLUSH();/*lint !e522*/
DRV_LOG (DRV_DEBUG_RX, "gei82543RxDesUpdate...Done\n",
1, 2, 3, 4, 5, 6);
return;
}
STATUS gei82543Recv
(
END_DEVICE * pDrvCtrl, /* device structure */
char * pRxDesc, /* pointer to RX descriptor */
UINT8 rxdStat /* RX descriptor status */
)
{
UINT16 len; /* len of packet received */
UINT8 rxdErr; /* RX descriptor Error field */
UINT8 csumErr; /* RX descriptor Error field */
int tempTail;
UINT32 tmpAddr;
UINT32 globalPort=0;
char * pBuf;
char * pNewData ;
void * pkt;
int tail;
DRV_LOG (DRV_DEBUG_RX, "gei82543Recv start...\n", 1, 2, 3, 4, 5, 6);
/* check packet status */
if (!(rxdStat & RXD_STAT_EOP))
{
DRV_CHG_CNT(pDrvCtrl->noPacketEOP,1);
DRV_LOG (DRV_DEBUG_RX, "Packet EOP not set\n", 1, 2, 3, 4, 5, 6);
LOGMSG("Packet EOP not set \n",1,2,3,4,5,6);
goto receiveError;
}
csumErr = GEI_READ_DESC_BYTE(pRxDesc, RXDESC_ERROR_OFFSET);
rxdErr = csumErr & ~(RXD_ERROR_IPE | RXD_ERROR_TCPE | RXD_ERROR_RSV);
if (rxdErr != 0)
{
DRV_CHG_CNT(pDrvCtrl->errPacketNum,1);
DRV_LOG (DRV_DEBUG_RX, "Packet Error 0x%x\n", rxdErr, 2, 3, 4, 5, 6);
LOGMSG("Packet error 0x%x \n",rxdErr, 2, 3, 4, 5, 6);
goto receiveError;
}
/* get packet length */
GEI_READ_DESC_WORD(pRxDesc, RXDESC_LENGTH_OFFSET, len);
if(len < MIN_ETHER_PACKET_SIZE)
{
DRV_LOG (DRV_DEBUG_RX, ("invalid packet length=0x%x!\n"), len,
0, 0, 0, 0, 0);
goto receiveError;
}
DRV_CHG_CNT(pDrvCtrl->rxPacketNum,1);
pNewData = (char *)endPktAlloc();
if ((char*)NULL == pNewData)
{
DRV_LOG (DRV_DEBUG_RX, ("Cannot malloc EndBuf for RX!\n"), 0,
0, 0, 0, 0, 0);
DRV_CHG_CNT(pDrvCtrl->noEndBuf,1);
goto receiveError;
}
else
{
DRV_CHG_CNT(pDrvCtrl->rxPktAlloc1Num,1);
}
if ( NULL== pDrvCtrl->drvObj.net)
{
globalPort = Ros_GlobalPort(pDrvCtrl->drvObj.slot, 1, 0);
if(NULL==(pDrvCtrl->drvObj.net = (void *)if_search(globalPort)))
{
DRV_CHG_CNT(pDrvCtrl->searchNetErr,1);
endPktFree(pNewData);
return ERROR;
}
}
/*get the end buffer address from pEndBufForRx[],not from the
GEI_READ_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET, rxBufAddr);
the rxBufAddr may be wrong after several shut/no shut operations
GEI_READ_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET, rxBufAddr);
pBufAddr = (char *)rxBufAddr;*/
pBuf = pDrvCtrl->pEndBufForRx[pDrvCtrl->rxDescTail];
/*view the content of the packets*/
drv_DebugRcvSndPkt(globalPort, (char *)pBuf, len, RX_DIRECTION);
END_BUF_GET_PKT(pBuf,pkt);/*lint !e63*/
etherPktProcess(pkt, pBuf, pDrvCtrl->drvObj.net, len);
/*
* Pre-invalidate new cluster before handing to hardware to avoid
* later cache-line write-back of dirty lines, which could overwrite
* received data. [This is especially important when using RX checksum
* offload.] Unfortunately, this requires that we invalidate
* the whole cluster rather than just the received portion.
*/
tmpAddr= (UINT32)sysVirtToPhys(pNewData);
GEI_WRITE_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET,tmpAddr);
/*put the new buffer address in pEndBufForRx[]*/
pDrvCtrl->pEndBufForRx[pDrvCtrl->rxDescTail] = (char *)tmpAddr;
tempTail = pDrvCtrl->rxDescTail;
tail = tempTail + 1;
if (tail == pDrvCtrl->rxDescNum)
{
tail = 0;
}
pDrvCtrl->rxDescTail = tail;
/* kick this descriptor for receiving packet */
GEI_WRITE_REG(INTEL_82543GC_RDT, (UINT32)tempTail);
CACHE_PIPE_FLUSH (); /*lint !e522*/
/* clean up status field */
GEI_WRITE_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET, 0);
DRV_LOG (DRV_DEBUG_RX, "Receive done!\n", 1, 2, 3, 4, 5, 6);
return OK;
receiveError:
gei82543RxDesUpdate (pDrvCtrl); /*lint !e961*/
if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)
{
pDrvCtrl->rxPacketDrvErr++;
}
DRV_LOG (DRV_DEBUG_RX, "Receive ERROR!\n", 1, 2, 3, 4, 5, 6);
return ERROR;
}
/*************************************************************************
*
* gei82543EndSend - driver send routine
*
* RETURNS: OK or ERROR.*/
STATUS drv_gei82543EndSend(UINT32 gPort, char *pBuf, int pktSize,char *pData)
{
int slotNum;
STATUS rc = OK;
UINT32 tmpAddr;
INTEL82543_TX_DES * pDesc = (INTEL82543_TX_DES *)NULL;
END_DEVICE *pDrvCtrl = (END_DEVICE *)NULL;
int tmpTail;
DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...\n", 1, 2, 3, 4, 5, 6);
slotNum = Ros_LocalPanel(gPort);
pDrvCtrl = geiEndDevice[slotNum];
if ((slotNum < 1) || (slotNum > MAX_IF_CARD_NUM) ||
((char *)NULL == pBuf) || ((char *)NULL == pData) ||
((END_DEVICE *)NULL == pDrvCtrl))
{
return ERROR;
}
IF_DRV_TX_SEM_TAKE (&pDrvCtrl->drvObj, WAIT_FOREVER);
/* check device start flag */
if (pDrvCtrl->devStartFlag != TRUE)
{
DRV_LOG (DRV_DEBUG_TX,
"drv_gei82543EndSend:Driver has not been started!\n",
1, 2,3, 4, 5, 6);
IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
return ERROR;
}
DRV_CHG_CNT(pDrvCtrl->txIntCount,1);
/*get the current transmit descriptor*/
pDesc = (INTEL82543_TX_DES *)GEI_GET_TX_DESC_ADDR(pDrvCtrl->txDescTail);
if (TXD_STAT_DD == (pDesc->TxStatus & TXD_STAT_DD))
{
/*empty current DESC which packet have been sent out by MAC controller.*/
if ((char *)NULL != pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail])
{
DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...Free TxBD!\n", 1, 2, 3, 4, 5, 6);
/*must free pData*/
endPktFree(pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail]);
pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail]=NULL;
}
/*view the content of the packets*/
drv_DebugRcvSndPkt(gPort, (char *)pBuf, pktSize, TX_DIRECTION);
pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail] = pData;
/*set the properity of the sending buffer*/
pDesc->TxpktLen = Drv_Swap16((UINT16)pktSize);
tmpAddr =(UINT32)sysVirtToPhys((void*)pBuf);
pDesc->pTxBufferLow = (char*)Drv_Swap32(tmpAddr);
pDesc->TxCmd = TXD_CMD_RS | TXD_CMD_EOP | TXD_CMD_IFCS |TXD_CMD_IDE;
pDesc->TxStatus = 0;
GEI_GET_TX_DESC_TAIL_UPDATE(tmpTail, 1);
pDrvCtrl->txDescFreeNum --;
if(0==pDrvCtrl->txDescFreeNum)
{
pDrvCtrl->txDescFreeNum=GEI_DEFAULT_TXDES_NUM-1;
}
CACHE_PIPE_FLUSH(); /*lint !e522*/
GEI_WRITE_REG(INTEL_82543GC_TDT, (UINT32)tmpTail);
pDrvCtrl->txDescTail = tmpTail;
DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...done\n",
1, 2, 3, 4, 5, 6);
}
else
{
DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...No TxBD OK!\n", 1, 2, 3, 4, 5, 6);
DRV_CHG_CNT(pDrvCtrl->txBDNotOK,1);
rc = ERROR;
}
DRV_CHG_CNT(pDrvCtrl->txPacketNum,1);
IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
return (rc);
}
int drv_MgeoCapacity(UINT32 gPort)
{
signed int distance;
int tmpTail;
INTEL82543_TX_DES * pDesc; /* pointer to descriptor */
END_DEVICE *pDrvCtrl;
int slotNum;
slotNum = Ros_LocalPanel(gPort);
pDrvCtrl = geiEndDevice[slotNum];
if ((slotNum < 1) || (slotNum > MAX_IF_CARD_NUM) ||
((END_DEVICE *)NULL == pDrvCtrl))
{
return ERROR;
}
DRV_LOG (DRV_DEBUG_TX, ("drv_MgeoCapacity...\n"), 1, 2, 3, 4, 5, 6);
IF_DRV_TX_SEM_TAKE (&pDrvCtrl->drvObj, WAIT_FOREVER);
/*make sure the driver is running*/
if (pDrvCtrl->devStartFlag == FALSE)
{
DRV_LOG (DRV_DEBUG_TX, ("MGEO driver is not running...\n"), 1, 2, 3, 4, 5, 6);
IF_DRV_TX_SEM_GIVE(&(pDrvCtrl->drvObj));
return (0);
}
distance = 0;
tmpTail = pDrvCtrl->txDescTail + 1;
while(distance < GEI_CAPACITY_LIMIT + 1)/*just find 5 available txbds*/
{
if (tmpTail >= pDrvCtrl->txDescNum)
{
tmpTail = 0;
}
/*get the descriptor to be checked*/
pDesc = (INTEL82543_TX_DES *) GEI_GET_TX_DESC_ADDR(tmpTail);
/*check the bd's DD bit to detemine the txbd whether it is available*/
if (TXD_STAT_DD !=(pDesc->TxStatus & TXD_STAT_DD))
{
DRV_LOG (DRV_DEBUG_TX, ("TXBD is not OK...\n"), 1, 2, 3, 4, 5, 6);
IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
return distance - 1;
}
distance++;
tmpTail++;
}
DRV_LOG (DRV_DEBUG_TX, "drv_MgeoCapacity...done\n",1, 2, 3, 4, 5, 6);
IF_DRV_TX_SEM_GIVE(&(pDrvCtrl->drvObj));
return distance - 1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -