Davicom公司DM9000A和DM9010 ISA NIC 以太网驱动分析
ist *mcptr = dev->mc_list;
int mc_cnt = dev->mc_count;
u32 hash_val;
u16 i, oft, hash_table[4];
DMFE_DBUG(0, dm9000_hash_table(), 0);
/* Set Node address */
for (i = 0, oft = 0x10; i 6; i++, oft++)
iow(db, oft, dev->dev_addr[i]);
/* Clear Hash Table */
for (i = 0; i 4; i++)
hash_table[i] = 0x0;
/* broadcast address */
hash_table[3] = 0x8000;
/* the multicast address in Hash Table : 64 bits */
for (i = 0; i mc_cnt; i++, mcptr = mcptr->next) {
hash_val = cal_CRC((char *)mcptr->dmi_addr, 6, 0) 0x3f;
hash_table[hash_val / 16] |= (u16) 1 (hash_val % 16);
}
/* Write the hash table to MAC MD table */
for (i = 0, oft = 0x16; i 4; i++) {
iow(db, oft++, hash_table[i] 0xff);
iow(db, oft++, (hash_table[i] >> 8) 0xff);
}
}
/*
Calculate the CRC valude of the Rx packet
flag = 1 : return the reverse CRC (for the received packet CRC)
0 : return the normal CRC (for Hash Table index)
*/
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
{
u32 crc = ether_crc_le(Len, Data);
if (flag)
return ~crc;
return crc;
}
/*
Read a byte from I/O port
*/
static u8 ior(board_info_t *db, int reg)
{
outb(reg, db->io_addr);
return inb(db->io_data);
}
/*
Write a byte to I/O port
*/
static void iow(board_info_t *db, int reg, u8 value)
{
outb(reg, db->io_addr);
outb(value, db->io_data);
}
/*
Read a word from phyxcer
*/
static u16 phy_read(board_info_t *db, int reg)
{
/* Fill the phyxcer register into REG_0C */
iow(db, DM9KS_EPAR, DM9KS_PHY | reg);
iow(db, DM9KS_EPCR, 0xc); /* Issue phyxcer read command */
udelay(100); /* Wait read complete */
iow(db, DM9KS_EPCR, 0x0); /* Clear phyxcer read command */
/* The read data keeps on REG_0D REG_0E */
return ( ior(db, DM9KS_EPDRH) 8 ) | ior(db, DM9KS_EPDRL);
}
/*
Write a word to phyxcer
*/
static void phy_write(board_info_t *db, int reg, u16 value)
{
/* Fill the phyxcer register into REG_0C */
iow(db, DM9KS_EPAR, DM9KS_PHY | reg);
/* Fill the written data into REG_0D REG_0E */
iow(db, DM9KS_EPDRL, (value 0xff));
iow(db, DM9KS_EPDRH, ( (value >> 8) 0xff));
iow(db, DM9KS_EPCR, 0xa); /* Issue phyxcer write command */
udelay(500); /* Wait write complete */
iow(db, DM9KS_EPCR, 0x0); /* Clear phyxcer write command */
}
#ifdef MODULE
MODULE_LICENSE(GPL);
MODULE_DESCRIPTION(Davicom DM9000A/DM9010 ISA/uP Fast Ethernet Driver);
MODULE_PARM(mode, i);
MODULE_PARM(irq, i);
MODULE_PARM(iobase, i);
MODULE_PARM_DESC(mode,Media Speed, 0:10MHD, 1:10MFD, 4:100MHD, 5:100MFD);
MODULE_PARM_DESC(irq,EtherLink IRQ number);
MODULE_PARM_DESC(iobase, EtherLink I/O base address);
/* Description:
when user used insmod to add module, system invoked init_module()
to initilize and register.
*/
int init_module(void)
{
switch(mode) {
case DM9KS_10MHD:
case DM9KS_100MHD:
case DM9KS_10MFD:
case DM9KS_100MFD:
media_mode = mode;
break;
default:
media_mode = DM9KS_AUTO;
}
dmfe_dev = dmfe_probe1();
if(IS_ERR(dmfe_dev))
return PTR_ERR(dmfe_dev);
return 0;
}
/* Description:
when user used rmmod to delete module, system invoked clean_module()
to un-register DEVICE.
*/
void cleanup_module(void)
{
struct net_device *dev = dmfe_dev;
DMFE_DBUG(0, clean_module(), 0);
unregister_netdev(dmfe_dev);
release_region(dev->base_addr, 2);
#if LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)
kfree(dev);
#else
free_netdev(dev);
#endif
DMFE_DBUG(0, clean_module() exit, 0);
}
#endif
以太网 驱动 分析 NIC ISA 公司 DM9000A DM9010 Davicom 相关文章:
- 基于S3C44B0X+μcLinux的嵌入式以太网设计(07-08)
- TM1300 DSP系统以太网接口的设计(03-07)
- 工业级特性在嵌入式处理中至关重要(05-08)
- 基于VxWorks的双端口网卡智能双冗余驱动(07-01)
- 基于μC/OS-II和TCP/IP协议的多串口服务器(08-23)
- 基于DSP/FPGA的以太网控制器的运动控制器设计(02-06)