微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Davicom公司DM9000A和DM9010 ISA NIC 以太网驱动分析

Davicom公司DM9000A和DM9010 ISA NIC 以太网驱动分析

时间:11-02 来源:互联网 点击:

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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top