📄 halrtl8139.c
字号:
BSP_OutLong( pEtherDevDataTable->IoBaseAddr + R8139_IDR0, *(unsigned long *)(macAddr + 0));
BSP_OutLong( pEtherDevDataTable->IoBaseAddr + R8139_IDR0+4, *(unsigned long *)(macAddr + 4));
BSP_OutByte( pEtherDevDataTable->IoBaseAddr + R8139_9346CR, 0x00);
for (i = 0; i < 6; i++)
{
pEtherDevDataTable->macaddr[i] = macAddr[i];
}
return TRUE;
}
/**
* @brief
* 获取该网络设备的网络连接情况。
*
* @param[in] pEtherDevData 设备数据块指针,该结构的类型由HAL定义。
* @param[out] lineStatus 连接状态
DNET_IFOPERSTATUS_UP 或者 DNET_IFOPERSTATUS_DOWN。
*
* @return 成功返回TRUE;否则,返回FALSE。
*/
T_BOOL rtl8139_LineCheck( T_VOID *pEtherDevData, T_WORD *lineStatus)
{
//T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
// 该接口8139不支持,直接返回就绪状态
*lineStatus = DNET_IFOPERSTATUS_UP;
return TRUE;
}
/**
* @brief
* 侦察RTL8139。
*
* @param[in] pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
* @param[in] index:该设备在系统中相同设备的索引。
*
* @return 成功返回TRUE;否则,返回FALSE。
*/
T_MODULE T_BOOL rtl8139_Probe( T_HAL_RTL8139_DEV_DATA * pEtherDevDataTable, T_WORD index )
{
T_BSP_DEV_PUB_DATA *devPubInfo = &(pEtherDevDataTable->pub);
T_UBYTE bus;
T_UBYTE device_fn;
struct pci_dev *pPciDevRtl8139;
T_UWORD type;
T_UWORD ioBase;
if( pci_find_device( devPubInfo->vendorId, devPubInfo->deviceId, index, &bus, &device_fn ) != 0 )
{
return FALSE;
}
if( pci_get_dev( bus, device_fn, &pPciDevRtl8139 ) != 0 )
{
return FALSE;
}
pci_get_baseaddr( pPciDevRtl8139, PCI_BASE_ADDRESS_0, &type, &ioBase );
if( type != PCI_RES_IO )
{
return FALSE;
}
if( pPciDevRtl8139->irq == 0xff )
{
devPubInfo->vectorNum = 0;
}
else
{
devPubInfo->vectorNum = 1;
devPubInfo->vector0[0] = pPciDevRtl8139->irq + 0x20;
}
pEtherDevDataTable->IoBaseAddr = ioBase;
return TRUE;
}
/**
* @brief
* 处理发送中断。
*
* @param[in] pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
*
* @return 成功返回TRUE;否则,返回FALSE。
*/
T_MODULE int Rtl8139_Tx( T_HAL_RTL8139_DEV_DATA * pEtherDevDataTable )
{
unsigned int dirty_tx = 0;
int entry = 0;
int txstatus ;
unsigned char txbusy = 0;
for (;entry< NUM_TX_DESC;entry++)
{
BSP_InLong(pEtherDevDataTable->IoBaseAddr+R8139_TSD0 + entry*4, txstatus);
if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted )))
continue;
if (txstatus&TxAborted)
{
BSP_OutLong(pEtherDevDataTable->IoBaseAddr+R8139_TCR,(TX_DMA_BURST<<8)|0x00000001);
continue;
}
if (txstatus & TxUnderrun)
{
if (pEtherDevDataTable->tx_flag < 0x00300000)
pEtherDevDataTable->tx_flag += 0x00020000;
}
txbusy |= (1<<entry);
}
pEtherDevDataTable->txbusy &= (~txbusy & 0x0f);
if ( (pEtherDevDataTable->tx_full) && (txbusy & (1<<pEtherDevDataTable->txentry) ) )
{
fnDM_SemaphoreRelease(pEtherDevDataTable->outbufmutex);
pEtherDevDataTable->tx_full = 0;
}
return TRUE;
}
/**
* @brief
* 发送数据包。
*
* @param[in] pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
*
* @return 成功返回TRUE;否则,返回FALSE。
*/
T_MODULE void Rtl8139_TxTmo( T_HAL_RTL8139_DEV_DATA * pEtherDevDataTable )
{
int i;
T_BYTE ioByte;
// disable interrupts by clearing the interrupt mask.
BSP_OutHWord(pEtherDevDataTable->IoBaseAddr+R8139_IMR,0x0000);
// Soft reset the chip.
BSP_OutByte(pEtherDevDataTable->IoBaseAddr+R8139_CR,0x10);
for (i = 0; i < 6; i++)
BSP_OutByte(pEtherDevDataTable->IoBaseAddr+R8139_IDR0+i,pEtherDevDataTable->macaddr[i]);
pEtherDevDataTable->dirty_tx = pEtherDevDataTable->cur_tx = 0;
pEtherDevDataTable->tx_full = 0;
pEtherDevDataTable->txbusy = 0;
pEtherDevDataTable->txentry = 0;
pEtherDevDataTable->tx_flag = (TX_FIFO_THRESH<<11);
for (i = 5000; i > 0; i--)
{
BSP_InByte(pEtherDevDataTable->IoBaseAddr+R8139_CR, ioByte );
if ((ioByte & 0x10) == 0)
break;
}
if(i<=0)
return;
// Must enable Tx/Rx before setting transfer thresholds!
BSP_OutByte(pEtherDevDataTable->IoBaseAddr+R8139_CR,0x0c);/*enable tx and rx bit*/
BSP_OutLong(pEtherDevDataTable->IoBaseAddr+R8139_RCR,
(RX_FIFO_THRESH << 13)|(pEtherDevDataTable->rxBufSize<< 11)|(RX_DMA_BURST<<8)|RX_OPTION);
BSP_OutLong(pEtherDevDataTable->IoBaseAddr+R8139_TCR,(TX_DMA_BURST<<8));
// Enable all known interrupts by setting the interrupt mask.
BSP_OutHWord(pEtherDevDataTable->IoBaseAddr+R8139_IMR,
PCIErr|PCSTimeout|RxUnderrun|RxOverflow|RxFIFOOver|TxErr|TxOK|RxErr|RxOK);
return;
}
/**
* @brief
* 初始化RTL8139 HAL参数。
*
* @param[in] pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
*
* @return 成功返回TRUE;否则,返回FALSE。
*/
T_MODULE void Rtl8139_InitRing( T_HAL_RTL8139_DEV_DATA * pEtherDevDataTable )
{
int i = 0;
pEtherDevDataTable->tx_full = 0;
pEtherDevDataTable->cur_rx = 0;
pEtherDevDataTable->cur_tx = 0;
pEtherDevDataTable->dirty_rx = 0;
pEtherDevDataTable->dirty_tx = 0;
pEtherDevDataTable->txentry = 0;
pEtherDevDataTable->tx_flag = (TX_FIFO_THRESH<<11);
for (i = 0; i < NUM_TX_DESC; i++)
{
pEtherDevDataTable->txbusy = 0;
pEtherDevDataTable->tx_buf[i] = &pEtherDevDataTable->tx_bufs[i*pEtherDevDataTable->txBufSize];
}
return ;
}
/***************************************************************************
Routine Description:
Runs the AUTODIN II CRC algorithm on buffer Buffer of length Length.
Arguments:
Buffer - the input buffer
Length - the length of Buffer
Return Value:
The 32-bit CRC value.
Note:
This is adapted from the comments in the assembly language
version in _GENREQ.ASM of the DWB NE1000/2000 driver.
***************************************************************************/
T_MODULE unsigned long ComputeCrc( unsigned char * Buffer, unsigned short Length )
{
unsigned long Crc, Carry;
unsigned short i, j;
unsigned char CurByte;
Crc = 0xffffffff;
for (i = 0; i < Length; i++)
{
CurByte = Buffer[i];
for (j = 0; j < 8; j++)
{
Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
Crc <<= 1;
CurByte >>= 1;
if (Carry)
Crc = (Crc ^ 0x04c11db6) | Carry;
}
}
return Crc;
}
/***************************************************************************
Routine Description:
For a given multicast address, returns the byte and bit in
the card multicast registers that it hashes to. Calls
ComputeCrc() to determine the CRC value.
Arguments:
Address - the address
Byte - the byte that it hashes to
Value - will have a 1 in the relevant bit
Return Value:
None.
***************************************************************************/
T_MODULE void GetMultiBit( unsigned char Address[6], unsigned char * Byte, unsigned char * Value )
{
unsigned long Crc;
unsigned short BitNumber;
Crc = ComputeCrc(Address, 6);
BitNumber = ( unsigned short )((Crc >> 26) & 0x3f);
* Byte = ( unsigned char )(BitNumber / 8);
* Value = ( unsigned char )((unsigned char)1 << (BitNumber % 8));
}
/***********************************************************
* MODULE: rtl8139_mCastAddrAdd
*
* PURPOSE:
* Fill card multicast registers.
*
* PARAMETERS
* Input:
* Output:
* Return value: OK
*
***********************************************************/
T_MODULE void Rtl8139_mCastAddrAdd(T_HAL_RTL8139_DEV_DATA * pEtherDevDataTable, char *buf)
{
unsigned char Byte, Bit;
unsigned char MultiByte = 0 ;
unsigned char mcast[8];
GetMultiBit(buf, &Byte, &Bit);
MultiByte = Bit;
BSP_InLong(pEtherDevDataTable->IoBaseAddr + R8139_MAR0, *(unsigned long *)(&mcast[0]));
BSP_InLong(pEtherDevDataTable->IoBaseAddr + R8139_MAR0+4, *(unsigned long *)(&mcast[4]));
mcast[Byte] |= MultiByte;
BSP_OutLong(pEtherDevDataTable->IoBaseAddr + R8139_MAR0, *(unsigned long *)(&mcast[0]));
BSP_OutLong(pEtherDevDataTable->IoBaseAddr + R8139_MAR0+4,*(unsigned long *)(&mcast[4]));
return;
}
/***********************************************************
* MODULE: rtl8139_mCastAddrDel
*
* PURPOSE:
* Erases and refills the card multicast registers.
* Used when an address has been deleted and all bits must be recomputed.
*
* PARAMETERS
* Input:
* Output:
* Return value: OK
*
***********************************************************/
T_MODULE void Rtl8139_mCastAddrDel(T_HAL_RTL8139_DEV_DATA * pEtherDevDataTable, void *buf)
{
unsigned char Byte, Bit;
unsigned char MultiByte = 0 ;
unsigned char tmp_addr[6];
ETHER_MULTI * pcurr;
unsigned char mcast[8] = {0,0,0,0,0,0,0,0};
for(pcurr = ((struct macforhash *)buf)->chainpointer; pcurr; pcurr = pcurr->next)
{
memcpy(tmp_addr, pcurr->haddr, 6);
GetMultiBit(tmp_addr, &Byte, &Bit);
MultiByte = Bit;
mcast[Byte] |= MultiByte;
}
BSP_OutLong(pEtherDevDataTable->IoBaseAddr + R8139_MAR0, *(unsigned long *)(&mcast[0]));
BSP_OutLong(pEtherDevDataTable->IoBaseAddr + R8139_MAR0+4, *(unsigned long *)(&mcast[4]));
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -