📄 lan91c111end.c
字号:
Adapter->LinkChange = MEDIA_DISCONNECT;
DRV_LOG (DRV_DEBUG_INT, "\nMD Int : Link Detect : MEDIA_DISCONNECT \n",
1, 2, 3, 4, 5, 6);
}
}
else
{
if(Adapter->LinkChange == MEDIA_DISCONNECT)
Adapter->LinkChange = MEDIA_DISCONNECT;
else
Adapter->LinkChange = MEDIA_CONNECT;
}
Adapter->LinkStatusChange = Adapter->EphStatus & TFS_LINKERROR;
} /* done : MDINT */
else if(IntrSts & INT_RX_OVRN) /* start : RX_OVRINT */
{
/*Overflow sets receive abort. Clear it now.*/
/*sysOutByte(Adapter->IOBase + BANK2_INT_STS, INT_RX_OVRN);*/
SYS_IN_SHORT(Adapter->IOBase + BANK2_INT_STS,&tempb);
tempb &= 0xff00;
tempb |= INT_RX_OVRN;
SYS_OUT_SHORT(Adapter->IOBase + BANK2_INT_STS,tempb);
DRV_LOG (DRV_DEBUG_INT, " Rx_OverRun ",1, 2, 3, 4, 5, 6);
} /* done : RX_OVRINT */
}
netJobAdd ((FUNCPTR)lan91c111Send,(int)pDrvCtrl,0,0,0,0); /* kumar */
lan91c111IntExit:
SYS_OUT_SHORT(IOBase + BANK2_PTR, SavedPtr); /* restore pointer reg. */
SYS_OUT_SHORT(IOBase + BANK2_PNR, SavedPnr); /* restore packet number reg. */
SYS_OUT_SHORT(IOBase + BANK_SELECT, SavedBank);/* restore Bank select reg. */
CACHE_PIPE_FLUSH ();
DRV_LOG(DRV_DEBUG_INT,"-----------DONE INT--------------------\n",1,2,3,4,5,6);
return ;
}
/*******************************************************************************
* lan91c111Recv - process the next incoming packet
*
* Handle one incoming packet. The packet is checked for errors.
*
* RETURNS: N/A.
*/
STATUS lan91c111Recv
(
LAN91C111END_DEVICE *pDrvCtrl/*,
char *pData,
UINT len*/
)
{
M_BLK_ID pMblk;
CL_BLK_ID pClBlk;
int len;
/* Grab a cluster block to marry to the cluster we received. */
if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)
{
netClFree (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pRxReadIndex->pData);
DRV_LOG (DRV_DEBUG_ERR, "lan91c111Recv: Out of Cluster Blocks!\n",
1, 2, 3, 4, 5, 6);
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
/*
* OK, let's get an M_BLK_ID and marry it to the
* one in the ring.
*/
if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
{
netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);
netClFree (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pRxReadIndex->pData);
DRV_LOG (DRV_DEBUG_ERR, "lan91c111Recv: Out of M Blocks!\n",
1, 2, 3, 4, 5, 6);
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
/* Join the cluster to the MBlock */
netClBlkJoin (pClBlk,(char*) pDrvCtrl->pRxReadIndex->pData, lan91c111ClDescTbl[0].clSize, NULL, 0, 0, 0);
netMblkClJoin (pMblk, pClBlk);
len = pDrvCtrl->pRxReadIndex->len;
pMblk->mBlkHdr.mData = (char *)(pDrvCtrl->pRxReadIndex->pData + pDrvCtrl->offset);
pMblk->mBlkHdr.mLen = len ;
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkPktHdr.len = len;
#if PING_DEBUG
if(len > 70 && len <= 100)
memcpy((void *)RxBuff, (void *)pMblk->mBlkHdr.mData, len);
#endif
DRV_LOG (DRV_DEBUG_RX, "RX : Pkt : Len %d\n",
len, 2, 3, 4, 5, 6);
pDrvCtrl->pRxReadIndex->pData = NULL; /* free the slot */
if(pDrvCtrl->pRxReadIndex < pDrvCtrl->pRxBase + RX_PACKETS - 1)
pDrvCtrl->pRxReadIndex++;
else
pDrvCtrl->pRxReadIndex = pDrvCtrl->pRxBase;
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);
cleanRXD:
return (OK);
}
/*******************************************************************************
* lan91c111HandleRcvInt - task level interrupt service for input packets
*
* This routine is called at task level indirectly by the interrupt
* service routine to do any message received processing.
*
* The double loop is to protect against a race condition where the interrupt
* code see rxHandling as TRUE, but it is then turned off by task code.
* This race is not fatal, but does cause occassional delays until a second
* packet is received and then triggers the netTask to call this routine again.
*
* RETURNS: N/A.
*/
void lan91c111HandleRcvInt
(
LAN91C111END_DEVICE *pDrvCtrl /* interrupting device */
)
{
UINT receiveReady;
int loopCount=0;
pDrvCtrl->rxHandling = TRUE;
do {
lan91c111Recv (pDrvCtrl);
receiveReady = pDrvCtrl->pRxReadIndex->pData ? 1 : 0;
loopCount++;
} while ((receiveReady != 0) && (loopCount <= 30));
pDrvCtrl->rxHandling = FALSE;
return;
}
#define CLCHAIN_DBG 1
#if CLCHAIN_DBG
M_BLK_ID myMblk;
#endif
/******************************************************************************
* lan91c111Send - end send routine
*
* This routine will be called by the network stack whenever the upper layer want
* to send the datagram. It takes a pointer to mbuf. It extacts the data from the
* mbuf and writes in chip.
*
* RETURNS: status of the write operation
*/
STATUS lan91c111Send(END_OBJ *pEnd,M_BLK_ID pMblk)
{
LAN91C111END_DEVICE *pDrvCtrl = (LAN91C111END_DEVICE *)pEnd;
BOOLEAN status;
M_BLK_ID curMblk;
int currentKey;
DRV_LOG (DRV_DEBUG_TX, "lan91c111Send: called \n",1, 2, 3, 4, 5, 6);
/* This Block is to put the packet sent by the upper layers in a ring Buffer.Here
we are using ReadIndex and WriteIndex instead of allocpending and writepending Queues*/
/* He is not checking for null since he is sending null in the TX Int case...
I think we have to check for null ..ask kumar about this.. */
if(pMblk ==(M_BLK_ID) 1)
{
currentKey = intLock();
pDrvCtrl->AllocPending =FALSE;
curMblk = pDrvCtrl->pTxReadIndex->pMblk;
END_TX_SEM_TAKE (&pDrvCtrl->endObj,WAIT_FOREVER);
pDrvCtrl->sendDatalen = netMblkToBufCopy(curMblk,pDrvCtrl->sendBuf,NULL);
pDrvCtrl->sendDatalen = (ETHER_ZLEN < pDrvCtrl->sendDatalen) ? pDrvCtrl->sendDatalen : ETHER_ZLEN;
pDrvCtrl->pTxReadIndex->pMblk = NULL;
netMblkClChainFree(curMblk);
if ( pDrvCtrl->pTxReadIndex < pDrvCtrl->pTxBase + TX_PACKETS - 2)
pDrvCtrl->pTxReadIndex++;
else
pDrvCtrl->pTxReadIndex = pDrvCtrl->pTxBase;
lan91c111WriteToChip(pDrvCtrl);
intUnlock(currentKey);
END_TX_SEM_GIVE (&pDrvCtrl->endObj);
return OK;
}
else if(pMblk) /* put in ring buffer */
{
if(pDrvCtrl->pTxWriteIndex->pMblk)
{
/* TX fifo full, drop packet */
netMblkClChainFree(pMblk);
}
else
{
/* TX fifo not full, queue packet */
pDrvCtrl->pTxWriteIndex->pMblk = pMblk;
/*
DRV_LOG(DRV_DEBUG_TX,"TxWriteIndex : %d\n",pDrvCtrl->pTxWriteIndex,2,3,4,5,6);
*/
if(pDrvCtrl->pTxWriteIndex < (pDrvCtrl->pTxBase + TX_PACKETS - 2))
pDrvCtrl->pTxWriteIndex++;
else
pDrvCtrl->pTxWriteIndex = pDrvCtrl->pTxBase;
}
}
/* This Block calls two Functions one allocates the memory
from the MMU and other copies the stuff from clusters to the chip*/
curMblk = pDrvCtrl->pTxReadIndex->pMblk;
if(!curMblk)
{
DRV_LOG (DRV_DEBUG_ERR, "lan91c111Send: Current MBlk is NULL \n",1, 2, 3, 4, 5, 6);
return OK;
}
status = DoAllocate(pDrvCtrl);
if(status)
{
DRV_LOG(DRV_DEBUG_TX, "lan91c111Send : Got Access to MMU\n",1,2,3,4,5,6);
END_TX_SEM_TAKE (&pDrvCtrl->endObj,WAIT_FOREVER);
currentKey = intLock();
pDrvCtrl->sendDatalen = netMblkToBufCopy(curMblk,pDrvCtrl->sendBuf,NULL);
pDrvCtrl->sendDatalen = (ETHER_ZLEN < pDrvCtrl->sendDatalen) ? pDrvCtrl->sendDatalen : ETHER_ZLEN;
pDrvCtrl->pTxReadIndex->pMblk = NULL;
netMblkClChainFree(curMblk);
if ( pDrvCtrl->pTxReadIndex < pDrvCtrl->pTxBase + TX_PACKETS - 2)
pDrvCtrl->pTxReadIndex++;
else
pDrvCtrl->pTxReadIndex = pDrvCtrl->pTxBase;
lan91c111WriteToChip(pDrvCtrl);
intUnlock(currentKey);
}
else
{
USHORT OldMask;
int key;
key = intLock();
pDrvCtrl->AllocPending = TRUE;
SYS_IN_SHORT(pDrvCtrl->IOBase + BANK2_INT_STS, (PUSHORT)&OldMask);
SYS_OUT_SHORT(pDrvCtrl->IOBase + BANK2_INT_STS, 0);
OldMask |= ( INT_ALLOC << 8 );
OldMask &= 0xFF00; /* Do not ACK interrupts */
SYS_OUT_SHORT(pDrvCtrl->IOBase + BANK2_INT_STS, OldMask);
intUnlock(key);
DRV_LOG(DRV_DEBUG_TX, "lan91c111Send : Set Alloc Int bit\n",1,2,3,4,5,6);
}
END_TX_SEM_GIVE (&pDrvCtrl->endObj);
return OK;
}
/*****************************************************************************
* DoAllocate - allocates the memory for write operation
*
* This routine makes a request MMU for 2k bytes of memory for packet
* transmition.
*
* RETIRNS: status of the request
*/
BOOLEAN DoAllocate(LAN91C111END_DEVICE *pDrvCtrl)
{
UINT AllocateOk; /* Delay loop control */
UINT IOBase;
USHORT AllocSts;
IOBase = pDrvCtrl->IOBase;
SYS_OUT_SHORT(IOBase + BANK_SELECT, 2);
SYS_OUT_SHORT(IOBase + BANK2_MMU_CMD,(USHORT)((((pDrvCtrl->sendDatalen + FRAME_OVERHEAD) & 0xfffe) >> 8)|CMD_ALLOC));
AllocateOk = MMU_WAIT;
while(AllocateOk)
{
SYS_IN_SHORT(IOBase + BANK2_INT_STS,(PUSHORT) &AllocSts);
if(AllocSts & INT_ALLOC)
break;
AllocateOk--;
}
/* Check whether the allocation result is a pass or fail */
return((BOOLEAN) (AllocSts & INT_ALLOC));
}
/***********************************************************************
* writeToChip - write data to the chip
*
* This routine will writes the data to the chip and the transmission for
* transmition.
*
* RETURNS: N/A
*/
void lan91c111WriteToChip(LAN91C111END_DEVICE *pDrvCtrl)
{
UINT IOBase;
UINT DataPort;
USHORT TempWord;
BYTE TempByte;
USHORT length = pDrvCtrl->sendDatalen ;
char *p = pDrvCtrl->sendBuf ;
int key;
short tempb;
#if PING_DEBUG
if(length <= 100)
memcpy((void *)TxBuff, (void *)p, length);
#endif
/*-----------------3/13/01 2:38PM-------------------
* For faster data access
* --------------------------------------------------*/
if(pDrvCtrl->EarlyTransmit == TRUE)
{
EarlyTransmit(pDrvCtrl);
}
else
{
IOBase = pDrvCtrl->IOBase;
DataPort = IOBase + BANK2_DATA1;
key = intLock();
SYS_OUT_SHORT(IOBase + BANK_SELECT, 2);
/*-----------------3/13/01 2:35PM-------------------
* The next 3 lines of code reads the Alloc Result register
* and writes into the packet Number Register
* --------------------------------------------------*/
SYS_IN_SHORT( IOBase + BANK2_PNR,(PUSHORT) &TempWord );
TempByte = HIBYTE(TempWord);
SYS_OUT_SHORT(IOBase + BANK2_PNR,TempByte);
/*-----------------3/13/01 2:38PM-------------------
* From here we are writing the packet into the Chip
* --------------------------------------------------*/
SYS_OUT_SHORT(IOBase + BANK2_PTR,(USHORT) PTR_AUTO);
SYS_OUT_SHORT(DataPort,(USHORT) 0);
/* force byte count even 3/25/96 NW */
SYS_OUT_SHORT((DataPort), (USHORT) (0xfffe & (length + FRAME_OVERHEAD )) );
while(length > 3)
{
SYS_OUT_LONG((DataPort),(*((PULONG) p)));
length -= sizeof(ULONG);
p += sizeof(ULONG);
}
if(length > 1)
{
SYS_OUT_SHORT((DataPort),(*((PUSHORT) p)));
length -= sizeof(USHORT);
p += sizeof(USHORT);
}
if(length)
{
/*sysOutByte((DataPort),(*p));*/
SYS_IN_SHORT(DataPort,&tempb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -