📄 rtl81x9.c
字号:
if (stat & RTL_IPT_TX_ERR)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_TX_ERR\n", 0, 0, 0, 0, 0, 0);
rtl81x9HandleTxInt (pDrvCtrl);
}
if (stat & RTL_IPT_RX_ERR)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_RX_ERR\n", 0, 0, 0, 0, 0, 0);
if (netJobAdd ((FUNCPTR)rtl81x9HandleRecvInt, (int) pDrvCtrl,
0, 0, 0, 0) != OK)
DRV_LOG (DRV_DEBUG_INT, "xl: netJobAdd (rtl81x9HandleRecvInt) failed\n", 0, 0, 0, 0, 0, 0);
}
/* Check for transmit Interrupt */
if (stat & RTL_IPT_TX_OK)
{
rtl81x9HandleTxInt (pDrvCtrl);
}
if (stat & RTL_IPT_RX_OK)
{
if (netJobAdd ((FUNCPTR)rtl81x9HandleRecvInt, (int) pDrvCtrl,
0, 0, 0, 0) != OK)
DRV_LOG (DRV_DEBUG_INT, "xl: netJobAdd (rtl81x9HandleRecvInt) failed\n", 0, 0, 0, 0, 0, 0);
}
}
rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);
}
/*******************************************************************************
*
* rtl81x9HandleTxInt - task level interrupt service for tx packets
*
* This routine is called by the interrupt service routine to do any
* message transmission processing.
*
* RETURNS: N/A.
*/
LOCAL void rtl81x9HandleTxInt
(
RTL81X9END_DEVICE *pDrvCtrl
)
{
int txDesc;
for (txDesc=0; txDesc < RTL_NUM_TX_DESC; txDesc++)
{
u_long txstatus;
txstatus = rtl81x9CsrReadLong (pDrvCtrl,
RTL_REGS_TX_STATUS0 + (txDesc*4), NONE);
if (txstatus & RTL_TX_STATUS_OK)
{
/* Has the packet been sent previously */
if ((txstatus & RTL_TX_HOST_OWNS) && (pDrvCtrl->pDescMem[txDesc] != NULL))
{
/* Clear the buffer that was registered to the Descriptor */
/*vicadd netClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[txDesc]);*/
pDrvCtrl->pDescMem[txDesc] = NULL;
pDrvCtrl->freeDesc++;
if (pDrvCtrl->freeDesc > RTL_NUM_TX_DESC)
pDrvCtrl->freeDesc = RTL_NUM_TX_DESC;
}
}
else if (txstatus & (RTL_TX_UNDERRUN |
RTL_TX_OUT_OF_WINDOW |
RTL_TX_ABORTED ))
{
/* Clear the buffer that was registered to the Descriptor */
/*vicaddnetClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[txDesc]);*/
pDrvCtrl->pDescMem[txDesc] = NULL;
rtl81x9CsrWriteLong (pDrvCtrl,
RTL_REGS_TX_STATUS0 + (txDesc*4), RTL_TX_HOST_OWNS, NONE);
}
}
}
/*******************************************************************************
*
* rtl81x9HandleRecvInt - task level interrupt service for input packets
*
* This routine is called by the interrupt service routine to do any
* message received processing.
*
* RETURNS: N/A.
*/
LOCAL void rtl81x9HandleRecvInt
(
RTL81X9END_DEVICE *pDrvCtrl
)
{
int len, wrapSize;
M_BLK_ID pMblk;
char* pNewCluster;
CL_BLK_ID pClBlk;
RTL_RX_DATA *rxData;
USHORT cur_rx;
/*USHORT limit,max_bytes = 0;*/
USHORT rx_bytes = 0;
char *readPtr;
/* Disable interrupts by clearing the interrupt mask. */
cur_rx = ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, NONE)
+ 16) % RTL_RXBUFLEN);
/* limit = (rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_ADDR, NONE) % RTL_RXBUFLEN);
if (limit < cur_rx)
max_bytes = (RTL_RXBUFLEN - cur_rx) + limit;
else
max_bytes = limit - cur_rx;
*/
while ((rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_CHIP_CMD, NONE) &
RTL_CMD_RX_BUF_EMPTY) == 0)
{
/*rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE) ;*//*test*/
readPtr = (pDrvCtrl->ptrRxBufSpace + cur_rx);
rxData = (RTL_RX_DATA *) readPtr;
if ((rxData->rxPktLen >> 16) == RTL_RX_UNFINISHED)
{
DRV_LOG (DRV_DEBUG_ALL, "RxHandError 0fff0: ", 1, 2, 3, 4, 5, 6);
break;
}
if (!(rxData->rxStatusFlags & RTL_RX_STATUS_OK))
{
if (rxData->rxStatusFlags & (RTL_RX_BAD_SYMBOL|
RTL_RX_RUNT|
RTL_RX_TOO_LONG|
RTL_RX_CRC_ERROR|
RTL_RX_BAD_ALIGN))
{
/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
RTL_CMD_RX_ENB, RTL_WIN_0);*/
rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
RTL_CMD_RX_ENB, RTL_WIN_0);
rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0);
/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_RX_BUF_PTR, cur_rx - 16, RTL_WIN_0);*/
cur_rx = 0;
/*DRV_LOG (DRV_DEBUG_ALL, "RxHandError:rxData->rxStatusFlags=%x ", rxData->rxStatusFlags, 2, 3, 4, 5, 6);
i = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);
DRV_LOG (DRV_DEBUG_INT, "ISR %x ", i,0,0,0,0,0);*/
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, pDrvCtrl->reg_rcr, RTL_WIN_0);
}
break;
}
/* No errors; receive the packet. */
len = rxData->rxPktLen; /* get packet length */
/*DRV_LOG (DRV_DEBUG_RX, "Rmask %x", rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_INTR_MASK, NONE), 0, 0, 0, 0, 0); *//*test*/
rx_bytes += len + 4;
len -= RTL_CRC_SIZE;
/*
* Avoid trying to read more bytes than we know
* the chip has prepared for us.
*/
/*if (rx_bytes > max_bytes)
{
DRV_LOG (DRV_DEBUG_ALL, "MAX bytes error rx_bytes=%x max_bytes=%x\n", rx_bytes, max_bytes, 0, 0, 0, 0);
break; unknow what do
}*/
if(len>1518) {
/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
RTL_CMD_RX_ENB, RTL_WIN_0);*/
rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
RTL_CMD_RX_ENB, RTL_WIN_0);
rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0);
/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_RX_BUF_PTR, cur_rx - 16, RTL_WIN_0);*/
cur_rx = 0;
DRV_LOG (DRV_DEBUG_ALL, "RxHandError:rxData->rxStatusFlags=%x ", rxData->rxStatusFlags, 2, 3, 4, 5, 6);
/*i = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);*/
/*DRV_LOG (DRV_DEBUG_INT, "ISR %x ", i,0,0,0,0,0);*/
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, pDrvCtrl->reg_rcr, RTL_WIN_0);
DRV_LOG (DRV_DEBUG_ALL, "MAX bytes error rx_bytes>1518=%x \n", len, 0, 0, 0, 0, 0);
break;
}
/* DRV_LOG (DRV_DEBUG_LOAD, "Rx_Bytes=%x len=%x max_byte=%x\n", rx_bytes, len, max_bytes, 4, 5, 6);*/
/* If we cannot get a buffer to loan then bail out. */
pNewCluster = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);
/*DRV_LOG (DRV_DEBUG_RX, "Cannot loan cluster!\n", 0, 0, 0, 0, 0, 0);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);*/
if (pNewCluster == NULL)
{
DRV_LOG (DRV_DEBUG_RX, "Cannot loan cluster!\n", 0, 0, 0, 0, 0, 0);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
{
netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 0, 0, 0, 0, 0, 0);
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);
DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 0, 0, 0, 0, 0, 0);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
/* Copy the data found into the new cluster, we have (+4) to get us past the */
/* data that the rtl chip places at the start of the message and we remove */
/* the CRC from the end of the message */
if ((readPtr + len) >= (pDrvCtrl->ptrRxBufSpace + RTL_RXBUFLEN))
{
wrapSize = (int) ((readPtr + len) - (pDrvCtrl->ptrRxBufSpace + RTL_RXBUFLEN));
/* Copy in first section of message as stored */
/* at the end of the ring buffer */
memcpy (pNewCluster, readPtr + 4, len - wrapSize);
/* Copy in end of message as stored */
/* at the start of the ring buffer */
/*vicadd*/
#ifdef CPU_PENTIUM
memcpy (pNewCluster +len - wrapSize -4, pDrvCtrl->ptrRxBufSpace, wrapSize+0x04);
/* there have some error compiler's bug in this line*/
/* If I just copy the correct bytes the last two bytes will*/
/* have some trouble, so I copy extra bytes to fix the CPU or*/
/* OS's bug vic */
#else
memcpy (pNewCluster /*+len - wrapSize -4*/, pDrvCtrl->ptrRxBufSpace, wrapSize/*+0x04*/);
#endif
cur_rx = (wrapSize + RTL_CRC_SIZE + 4 + 3) & ~3;
/*DRV_LOG (DRV_DEBUG_ALL, "wrapsize=%x readptr=%x len=%x pNew=%x newwrapsize %x\n",wrapSize,readPtr,len,pNewCluster,pNewCluster-wrapSize ,6);
DRV_LOG (DRV_DEBUG_ALL, "header=%02x %02x %02x %02x %02x %02x \n",readPtr[4],readPtr[5],readPtr[6],readPtr[7],readPtr[8],readPtr[9]);
DRV_LOG (DRV_DEBUG_ALL, "newheader=%02x %02x %02x %02x %02x %02x \n",pNewCluster[0],pNewCluster[1],pNewCluster[2],pNewCluster[3],pNewCluster[4],pNewCluster[5]);*/
/*DRV_LOG (DRV_DEBUG_ALL, "len=%02x \n",len,2, 3, 4, 5, 6);*/
}
else
{
memcpy (pNewCluster, readPtr + 4, len);
cur_rx = (cur_rx + len + RTL_CRC_SIZE + 4 + 3) & ~3;
}
/* Disable interrupts by clearing the interrupt mask. */
/*vicadd rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);*/
/* We then write the CAPR as the next ptr we will read minus 0x10 which */
/* give us a little leeway to ensure that there is no overflow */
rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, (cur_rx - 16), RTL_WIN_0);
/*DRV_LOG (DRV_DEBUG_ALL, "CAPR=%x len=%d\n",(cur_rx - 16), len, 0, 0, 0, 0);*/
/* Enable interrupts by setting the interrupt mask. */
/*vicadd rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);*/
/* Join the cluster to the MBlock */
netClBlkJoin (pClBlk, pNewCluster, len, NULL, 0, 0, 0);
netMblkClJoin (pMblk, pClBlk);
/* make the packet data coherent */
RTL_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, len);
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);
}
cleanRXD:
}
/*******************************************************************************
*
* rtl81x9Ioctl - interface ioctl procedure
*
* Process an interface ioctl request.
*
* This routine implements the network interface control functions.
* It handles EIOCSADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS, EIOCMULTIADD,
* EIOCMULTIDRTL, EIOCMULTIGET, EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 commands.
*
* RETURNS: OK if successful, otherwise EINVAL.
*/
LOCAL int rtl81x9Ioctl
(
RTL81X9END_DEVICE * pDrvCtrl,
int cmd,
caddr_t data
)
{
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;
value--; /* HRTLP: WHY ??? */
END_FLAGS_CLR (&pDrvCtrl->end, value);
}
else
{
END_FLAGS_SET (&pDrvCtrl->end, value);
}
rtl81x9Config (pDrvCtrl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -