📄 drv8139.c
字号:
ArpPacket[31] = LanIPaddr & 0xff;
for(i = 0; i < 6; i++)
ArpPacket[i+32] = Broadcast[i];
ArpPacket[38] = (DefGateWay >> 24) & 0xff;
ArpPacket[39] = (DefGateWay >> 16) & 0xff;
ArpPacket[40] = (DefGateWay >> 8) & 0xff;
ArpPacket[41] = DefGateWay & 0xff;
for(i = 42; i < 63; i++)
ArpPacket[i] = 0;
}
/****************************************************************************
* function name: SendArpPacket
* design date:2001-8-17,
* function description: send arp request packet to default gateway
* call: no
* called: NiLan, ni_poll
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
void SendArpPacket(unsigned long addr)
{
UInt32 status;
ArpPacket[38] = (addr >> 24) & 0xff;
ArpPacket[39] = (addr >> 16) & 0xff;
ArpPacket[40] = (addr >> 8) & 0xff;
ArpPacket[41] = addr & 0xff;
memcpy((void*)(TxDesc[CurDescId]), (void*)ArpPacket, 64);
_cache_copyback((void*)(int)(TxDesc[CurDescId]), TX_BUF_SIZE);
status &= 0xffffc000; //The driver must set OWN bit to 0 after set descriptor size
status |= 0x003f0000|64; //Set Descriptor Size, tx FIFO is 2k
IoWriteReg32(TSD0 + CurDescId * 4, status);
CurDescId++;
CurDescId = CurDescId % NUM_TX_DESC;
//_dp("send arp packet\n");
}
/****************************************************************************
* function name: map_mcast
* design date:2001-5-10,
* function description: map protocol multicast address to hardware multicast
* address
* call: no
* called: ni_ioctl
* input parameter: mmap = location of the mapping structure
* output parameter: no
* return value: 0 if hardware address has been filled in.
* EINVALID if not a known protocol.
* change record: no
*****************************************************************************/
//多播组地址到以太网地址的转换,这种地址分配将使以太网多播地址中的23bit与IP多播组号对应起来,
//通过将多播组号中的低位23bit映射到以太网地址中的低位23bit实现
//(注:每发一个多播包都会调用这个函数进行一次地址转换)
static ULONG map_mcast(struct ni_map_mcast *mmap)
{
register char *prtladdr, *hdwraddr;
//printf("[map_mcast]: enter map_mcast.\n") ;
if (mmap->type == 0x800)
{
prtladdr = mmap->prtladdr;
hdwraddr = mmap->hdwraddr;
hdwraddr[0] = 0x01;
hdwraddr[1] = 0x00;
hdwraddr[2] = 0x5E;
hdwraddr[3] = prtladdr[1] & 0x7F; //0111 1111 (7+8+8 = 23)
hdwraddr[4] = prtladdr[2]; // 8
hdwraddr[5] = prtladdr[3]; // 8
}
else
return(EINVALID);
return(0);
}
/****************************************************************************
* function name: lan_add_mcast
* design date:2001-5-10,
* function description: Add a multicast address to the table in sorted order
* call: no
* called: ni_ioctl
* input parameter: addr = pointer to the address to add
* output parameter: no
* return value: 0
* change record: no
*****************************************************************************/
static long lan_add_mcast(UCHAR *addr)
{
int i = 0 ;
int i_ret = 0 ;
/* unsigned char sz_text[64]= {0} ;
printf("[lan_add_mcast]: enter lan_add_mcast (0x)") ;
for (i = 0; i < 14; i ++)
{
printf("%.2x", addr[i]) ;
}
printf("\n") ;
*/
LAN_HWA * pDestHWA = (LAN_HWA *)addr ;
for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
{
if (1 == g_multi_addr[i].is_used &&
g_multi_addr[i].addr.byte[0] == addr[0] &&
g_multi_addr[i].addr.byte[1] == addr[1] &&
g_multi_addr[i].addr.byte[2] == addr[2] &&
g_multi_addr[i].addr.byte[3] == addr[3] &&
g_multi_addr[i].addr.byte[4] == addr[4] &&
g_multi_addr[i].addr.byte[5] == addr[5])
{
DP(("[lan_add_mcast]: the multiaddress[(0x)%.2x%.2x%.2x%.2x%.2x%.2x] had exist!\n",
addr[0],addr[1],addr[2],addr[3],addr[4],addr[5])) ;
return 0 ;
}
}
for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
{
if (0 == g_multi_addr[i].is_used)
{
g_multi_addr[i].addr.byte[0] = addr[0] ;
g_multi_addr[i].addr.byte[1] = addr[1] ;
g_multi_addr[i].addr.byte[2] = addr[2] ;
g_multi_addr[i].addr.byte[3] = addr[3] ;
g_multi_addr[i].addr.byte[4] = addr[4] ;
g_multi_addr[i].addr.byte[5] = addr[5] ;
g_multi_addr[i].is_used = 1 ;
DP(("[lan_add_mcast]: add new multiaddress[(0x)%.2x%.2x%.2x%.2x%.2x%.2x]\n",
addr[0],addr[1],addr[2],addr[3],addr[4],addr[5])) ;
return 0 ;
}
}
return -1 ;
}
/****************************************************************************
* function name: lan_del_mcast
* design date:2001-5-10,
* function description: Delete a mulicast address from the table
* call: no
* called: ni_ioctl
* input parameter: addr = pointer to the address to remove
* output parameter: no
* return value: 0
* change record: no
*****************************************************************************/
static long lan_del_mcast(UCHAR *addr)
{
int i = 0 ;
//-------------------------------------------------------------------------------
LAN_HWA * pDestHWA = (LAN_HWA *)addr ;
// printf("[lan_del_mcast]: enter lan_del_mcast.\n") ;
for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
{
if (1 == g_multi_addr[i].is_used &&
g_multi_addr[i].addr.byte[0] == addr[0] &&
g_multi_addr[i].addr.byte[1] == addr[1] &&
g_multi_addr[i].addr.byte[2] == addr[2] &&
g_multi_addr[i].addr.byte[3] == addr[3] &&
g_multi_addr[i].addr.byte[4] == addr[4] &&
g_multi_addr[i].addr.byte[5] == addr[5])
{
g_multi_addr[i].addr.word1 = 0xffff ;
g_multi_addr[i].addr.word2 = 0xffff ;
g_multi_addr[i].addr.word3 = 0xffff ;
g_multi_addr[i].is_used = 0 ;
DP(("[lan_del_mcast]: del multiaddress[(0x)%.2x%.2x%.2x%.2x%.2x%.2x]\n",
addr[0],addr[1],addr[2],addr[3],addr[4],addr[5])) ;
break ;
}
}
//-------------------------------------------------------------------------------
IoWriteReg32(MAR0, 0xffffffff);
IoWriteReg32(MAR4, 0xffffffff);
intRaise(V_LAN);
return 0;
}
/****************************************************************************
* function name: bzero
* design date:2001-5-8,
* function description: Zero memory at specified address
* call: no
* called: SetupLanParams, InitBuffers
* input parameter: ptr = pointer to the address to zero
* length = length of memory to be zeroed
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
static void bzero(UCHAR *ptr, int length)
{
while(length--)
*ptr++ = 0;
}
/****************************************************************************
* function name: LanPciInit
* design date:2001-5-8,
* function description: Initialize the LAN PCI Configuration Registers,
* All Multibyte registers follow little endian byte
* ordering.
* call: PciWrCfg8, PciWrCfg16, PciWrCfg32
* called: NiLan
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
static void LanPciInit(void) // LAN PCI Configuration Registers
{
PciWrCfg16(CF_CMD, 0);//PCI Command Register - clear
//PCI Status Register - clear
PciWrCfg16(CF_STATUS, LAN_DS_PER|LAN_DS_SERR|LAN_DS_MA|LAN_DS_RTA|LAN_DS_DPAR);
// PCI IO Map Base register - Set IO Space Base Address
PciWrCfg32(CBIO, LAN_PCI_IO_BASE);
//PCI Latency Timer Register - initialize
PciWrCfg8(CF_LATENCY, 0xff);
//PCI Command Register - Set //IO Space Enable,Bus Master Enable
PciWrCfg16(CF_CMD, 0x45);
}
/****************************************************************************
* function name: LanInit
* design date:2001-5-8,
* function description: Initialize 8139 Control and Status Registers
* call: LanChipReset,IoWriteReg8,IoWriteReg16,IoWriteReg32,IoReadReg8,
* IoReadReg16,IoReadReg32
* called: ni_init
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
void LanInit()
{
UCHAR i, value8;
USHORT value16;
ULONG value;
//DP8139("enter LanInit()\n");
value = IoReadReg32(IDR0);
//printf("1.mac long:0x%x\n",value);
//read Mac address
SelfAddr[0]=(unsigned char)value;
SelfAddr[1]=(unsigned char )(value>>8);
SelfAddr[2]=(unsigned char )(value>>16);
SelfAddr[3]=(unsigned char )(value>>24);
value = IoReadReg32(IDR4);
SelfAddr[4]=(unsigned char )value;
SelfAddr[5]=(unsigned char )(value>>8);
//printf("2.mac long:0x%x\n",value);
i = 0;
do
{
LanChipReset(); //Perform software reset of the chip
//-----------------------------------------------------------------------
// Config register write enable: Before writing to CONFIG0,
// 1, 3, 4 registers, and bit13, 12, 8 of BMCR(offset
// 62h-63h), the RTL8139D(L) must be placed in this mode.
// This will prevent RTL8139D(L)'s configurations from
// accidental change.
IoWriteReg8(CR9346, 0xc0); //enable config
//-----------------------------------------------------------------------
value = SelfAddr[0] | SelfAddr[1] << 8 | SelfAddr[2] << 16 | SelfAddr[3] << 24;
IoWriteReg32(IDR0, value);
value = SelfAddr[4] | SelfAddr[5] << 8;
IoWriteReg32(IDR4, value);
//-----------------------------------------------------------------------
// Multicast Register(Driver is responsible for initializing these registers.)
IoWriteReg32(MAR0, 0xffffffff);
IoWriteReg32(MAR4, 0xffffffff);
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// Basic Mode Control Register: 0x1000(0001 0000 0000 0000)
// This bit enables/disables the NWay auto-negotiation function.
// Set to 1 to enable auto-negotiation, bit13 will be ignored.
// Set to 0 disables auto-negotiation, bit13 and bit8 will determine the
// link speed and the data transfer mode, respectively.
// This bit‘s initial value comes from 93C46.
value16 = IoReadReg16(BMCR);
//printf("[LanInit]: read BMCR[0x%x]", value16) ;
value16 |= 0x1100; // 0001 0001 0000 0000 : duplex mode
//value16 |= 0x3100; // 0011 0001 0000 0000 : Spd_Set: 1 = 100Mbps; 0 = 10Mbps.
value16 &= 0xfeff; // 1111 1110 1111 1111 : normal operation
//printf(", write BMCR[0x%x].\n", value16) ;//0x1000
IoWriteReg16(BMCR, value16);
//-----------------------------------------------------------------------
// Media Status Register
value8 = IoReadReg8(MSR);
value8 |= 0xc0; // 1100 0000
IoWriteReg8(MSR, value8); // 0xdc(1101 1100)
//printf("[LanInit]: MSR[0x%x].\n", value8) ;
// Configuration Register 1
value8 = IoReadReg8(CONFIG1);
value8 &= 0x3f; // 0011 1111
value8 |= 0x40; // 0100 0000
IoWriteReg8(CONFIG1, value8); // 0x4d (0100 1101)
//printf("[LanInit]: CONFIG1[0x%x].\n", value8) ;
//-----------------------------------------------------------------------
// Configuration Register 4
// operator:| 0x80(1000 0000) means: RxFIFOAutoClr: Set to 1, the RTL8139D(L)
// will clear the Rx FIFO overflow automatically.
value8 = IoReadReg8(CONFIG4);
value8 |= 0x80; // 1000 0000
IoWriteReg8(CONFIG4, value8); // 0x88 (1000 1000)
//printf("[LanInit]: CONFIG4[0x%x].\n", value8) ;
//-----------------------------------------------------------------------
// This register contains the advertised abilities of this device as they
// will be transmitted to its link partner during Auto-negotiation.
value16 = IoReadReg16(ANAR);
value16 |= 0x5e1; //0000 0101 1110 0001
IoWriteReg16(ANAR, value16); // 0x5e1
//printf("[LanInit]: ANAR[0x%x].\n", value16) ;
IoWriteReg8(CR9346, 0x0); //disable config
value8 = IoReadReg8(MSR); // 0x1c (0001 1100)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -