📄 rtl81x9.c
字号:
pDrvCtrl->txBlocked = FALSE;
if(pDrvCtrl->unit == 0)
{
rtlNetTaskSemId0 = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
/*启动数据接收任务*/
(void)taskSpawn("tRtlRxTask0",45,0,4000,(FUNCPTR)rtlRecvTask0,pDrvCtrl,0,0,0,0,0,0,0,0,0);
}
else if(pDrvCtrl->unit == 1)
{
rtlNetTaskSemId1 = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
/*启动数据接收任务*/
(void)taskSpawn("tRtlRxTask1",45,0,4000,(FUNCPTR)rtlRecvTask1,pDrvCtrl,0,0,0,0,0,0,0,0,0);
}
SYS_INT_CONNECT (pDrvCtrl, rtl81x9Int, (int)pDrvCtrl, &result);
if (result == ERROR)
{
return ERROR;
}
SYS_INT_ENABLE (pDrvCtrl);
/* Init the RX buffer pointer register. */
rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0);
/*DRV_LOG (DRV_DEBUG_ALL, "rxbuffer start- %x: \n",(ULONG) pDrvCtrl->ptrRxBufSpace , 2, 3, 4, 5, 6);*/
/* Enable Tx and RX */
rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RX_ENB + RTL_CMD_TX_ENB, RTL_WIN_0);
/*
* Set the initial TX and RX configuration.
* Set the buffer size and set the wrap register
*/
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_CONFIG, RTL_TXCFG_CONFIG, RTL_WIN_0);
/* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-TXCFG - %x: \n",RTL_TXCFG_CONFIG , 2, 3, 4, 5, 6);*/
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, RTL_RXCFG_CONFIG, RTL_WIN_0);
rxcfg = rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_RX_CONFIG, RTL_WIN_0);
/* Set the Early Threshold bits depending on flags read */ /*vicadd*/
/* from initialisation string */
rxcfg |= ((pDrvCtrl->flags >> 16) << 24);
/* Set the individual bit to receive frames for this host only. */
rxcfg |= RTL_RXCG_APM;
/* If we want promiscuous mode, set the allframes bit. */
if (pDrvCtrl->ib->rtlIBMode == 0x8000)
{
rxcfg |= RTL_RXCG_AAP;
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, rxcfg, RTL_WIN_0);
}
else
{
rxcfg &= ~RTL_RXCG_AAP;
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, rxcfg, RTL_WIN_0);
}
/*
* Set capture broadcast bit to capture broadcast frames.
*/
rxcfg |= RTL_RXCG_AB;
/* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-RCR - %x: \n", rxcfg, 2, 3, 4, 5, 6);*/
pDrvCtrl-> reg_rcr =rxcfg;/* save it */
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, rxcfg, RTL_WIN_0);
/* We now need to update the Multicast Registers */
/* These values need to be finalised and written */
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_MAR0, 0xffff, RTL_WIN_0);
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_MAR0 + 4, 0xffff, RTL_WIN_0);
/* Enable Controller Interrupts */
/*vicadd*/
if(pDrvCtrl->flags & RTL_FLG_POLLING)
{
rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0, NONE);
}
else
{
rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);
}
/* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-IMR - %x: \n",RTL_VALID_INTERRUPTS , 2, 3, 4, 5, 6);*/
/* Start RX/TX process. */
rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_MISSED, 0, RTL_WIN_0);
/* Enable Tx and RX */
rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RX_ENB + RTL_CMD_TX_ENB, RTL_WIN_0);
/*
if(pDrvCtrl->unit == 0)
{
(void)taskSpawn("tRtlTxClearTask0",40,0,4000,(FUNCPTR)rtl8139IntTimer,pDrvCtrl,0,0,0,0,0,0,0,0,0);
}
else
{
(void)taskSpawn("tRtlTxClearTask1",40,0,4000,(FUNCPTR)rtl8139IntTimer,pDrvCtrl,0,0,0,0,0,0,0,0,0);
}*/
return (OK);
}
/*******************************************************************************
*
* rtl81x9Int - handle controller interrupt
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*
* RETURNS: N/A.
*/
LOCAL void rtl81x9Int
(
RTL81X9END_DEVICE *pDrvCtrl
)
{
u_short stat;
int rxcfg;
/* Disable controller interrupts. */
rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);
for (;;)
{
/* Read the interrupt status register */
stat = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);
DRV_LOG (DRV_DEBUG_INT, "ISR %x ", stat,0,0,0,0,0);
/* clear interrupts, */
if (stat)
rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_STATUS, stat, NONE);
/* Check if a valid Interrupt has been set */
if ((stat & RTL_VALID_INTERRUPTS) == 0)
break;
if (stat & RTL_IPT_PCI_ERR)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_PCI_ERR - Reset and Re initialise\n", 0,0,0,0,0,0);
rtl81x9Reset (pDrvCtrl);
rtl81x9Restart (pDrvCtrl);
}
if (stat & RTL_IPT_PCS_TIMEOUT)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_PCS_TIMEOUT\n", 0, 0, 0, 0, 0, 0);
}
if (stat & RTL_IPT_CABLE_LEN_CHG)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_CABLE_LEN_CHG\n", 0, 0, 0, 0, 0, 0);
}
if (stat & RTL_IPT_RX_FIFO_OVER)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_RX_FIFO_OVER\n", 0, 0, 0, 0, 0, 0);
}
if (stat & RTL_IPT_RX_UNDERUN)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_RX_UNDERUN\n", 0, 0, 0, 0, 0, 0);
/*vicadd*/ rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_STATUS, RTL_IPT_RX_OK|RTL_IPT_RX_OVERFLOW|RTL_IPT_RX_FIFO_OVER, NONE);
rxcfg=rtl81x9CsrReadLong (pDrvCtrl, RTL_REGS_RX_CONFIG, RTL_WIN_0);
DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-RCR - %x: \n", rxcfg, 2, 3, 4, 5, 6);
}
if (stat & RTL_IPT_RX_OVERFLOW)
{
DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_RX_OVERFLOW\n", 0, 0, 0, 0, 0, 0);
}
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_RX, "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);
/*释放信号量,开始接收数据*/
/*semGive(rtlNetTaskSemId);*/
}
/* Check for transmit Interrupt */
if (stat & RTL_IPT_TX_OK)
{
DRV_LOG (DRV_DEBUG_TX, "RTL_IPT_TX_OK\n", 0, 0, 0, 0, 0, 0);
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);
DRV_LOG (DRV_DEBUG_RX, "RTL_IPT_RX_OK\n", 0, 0, 0, 0, 0, 0);*/
if(pDrvCtrl->unit == 0)
{
/*释放信号量,开始接收数据*/
semGive(rtlNetTaskSemId0);
}
else if(pDrvCtrl->unit == 1)
{
/*释放信号量,开始接收数据*/
semGive(rtlNetTaskSemId1);
}
}
}
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;
int n=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;
DRV_LOG (DRV_DEBUG_RX, "rxData->ptrRxBufSpace=%x, cur_rx = %x\n", pDrvCtrl->ptrRxBufSpace, cur_rx, 3, 4, 5, 6);
DRV_LOG (DRV_DEBUG_RX, "rxData->rxStatusFlags=%x \n", PCI_WORD_SWAP(rxData->rxStatusFlags), 2, 3, 4, 5, 6);
DRV_LOG (DRV_DEBUG_RX, "rxData->rxPktLen=%x \n", PCI_WORD_SWAP(rxData->rxPktLen), 2, 3, 4, 5, 6);
DRV_LOG (DRV_DEBUG_RX, "rxData->pktData 0=%d, 1 =%d\n", rxData->pktData[0], rxData->pktData[1], 3, 4, 5, 6);
if ((PCI_WORD_SWAP(rxData->rxPktLen) >> 16) == RTL_RX_UNFINISHED)
{
DRV_LOG (DRV_DEBUG_RX, "RxHandError 0fff0: ", 1, 2, 3, 4, 5, 6);
break;
}
if (!(PCI_WORD_SWAP(rxData->rxStatusFlags) & RTL_RX_STATUS_OK))
{
if (PCI_WORD_SWAP(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 = PCI_WORD_SWAP(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -