新闻中心

EEPW首页>嵌入式系统>设计应用> Davicom公司DM9000A和DM9010 ISA NIC 以太网驱动分析

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

作者: 时间:2012-11-02 来源:网络 收藏

/* Request IO from system */

if(!request_region(iobase, 2, dev->name))

return -ENODEV;

printk( I/O: %x, VID: %x n,iobase, id_val);

dm9000_found = TRUE;

/* Allocated board information structure */

memset(dev->priv, 0, sizeof(struct board_info));

db = (board_info_t *)dev->priv;

dmfe_dev = dev;

db->io_addr = iobase;

db->io_data = iobase + 4;

/* driver system function */

dev->base_addr = iobase;

dev->irq = irq;

dev->open = dmfe_open;

dev->hard_start_xmit = dmfe_start_xmit;

dev->watchdog_timeo = HZ;

dev->tx_timeout = dmfe_timeout;

dev->stop = dmfe_stop;

dev->get_stats = dmfe_get_stats;

dev->set_multicast_list = dm9000_hash_table;

dev->do_ioctl = dmfe_do_ioctl;

#if defined(CHECKSUM)

dev->features = dev->features | NETIF_F_NO_CSUM;

#endif

/* Read SROM content */

for (i=0; i64; i++)

((u16 *)db->srom)[i] = read_srom_word(db, i);

/* Set Node Address */

for (i=0; i6; i++)

dev->dev_addr[i] = db->srom[i];

}//end of if()

iobase += 0x10;

}while(!dm9000_found iobase = DM9KS_MAX_IO);

return dm9000_found ? 0:-ENODEV;

}

/*

Open the interface.

The interface is opened whenever ifconfig actives it.

*/

static int dmfe_open(struct net_device *dev)

{

board_info_t *db = (board_info_t *)dev->priv;

u8 reg_nsr;

int i;

DMFE_DBUG(0, dmfe_open, 0);

if (request_irq(dev->irq,dmfe_interrupt,SA_SHIRQ,dev->name,dev))

return -EAGAIN;

/* Initilize DM910X board */

dmfe_init_dm9000(dev);

/* Init driver variable */

db->reset_counter = 0;

db->reset_tx_timeout = 0;

db->cont_rx_pkt_cnt = 0;

/* check link state and media speed */

db->Speed =10;

i=0;

do {

reg_nsr = ior(db,0x1);

if(reg_nsr 0x40) /* link OK!! */

{

/* wait for detected Speed */

mdelay(200);

reg_nsr = ior(db,0x1);

if(reg_nsr 0x80)

db->Speed =10;

else

db->Speed =100;

break;

}

i++;

mdelay(1);

}while(i3000); /* wait 3 second */

//printk(i=%d Speed=%dn,i,db->Speed);

/* set and active a timer process */

init_timer(db->timer);

db->timer.expires = DMFE_TIMER_WUT * 2;

db->timer.data = (unsigned long)dev;

db->timer.function = dmfe_timer;

add_timer(db->timer); //Move to DM9000 initiallization was finished.

netif_start_queue(dev);

return 0;

}

/* Set PHY operationg mode

*/

static void set_PHY_mode(board_info_t *db)

{

u16 phy_reg0 = 0x1200; /* Auto-negotiation Restart Auto-negotiation */

u16 phy_reg4 = 0x01e1; /* Default flow control disable*/

if ( !(db->op_mode DM9KS_AUTO) ) // op_mode didn't auto sense */

{

switch(db->op_mode) {

case DM9KS_10MHD: phy_reg4 = 0x21;

phy_reg0 = 0x1000;

break;

case DM9KS_10MFD: phy_reg4 = 0x41;

phy_reg0 = 0x1100;

break;

case DM9KS_100MHD: phy_reg4 = 0x81;

phy_reg0 = 0x3000;

break;

case DM9KS_100MFD: phy_reg4 = 0x101;

phy_reg0 = 0x3100;

break;

default:

break;

} // end of switch

} // end of if

phy_write(db, 0, phy_reg0);

phy_write(db, 4, phy_reg4);

}

/*

Initilize dm9000 board

*/

static void dmfe_init_dm9000(struct net_device *dev)

{

board_info_t *db = (board_info_t *)dev->priv;

DMFE_DBUG(0, dmfe_init_dm9000(), 0);

/* set the internal PHY power-on, GPIOs normal, and wait 2ms */

iow(db, DM9KS_GPR, 1); /* Power-Down PHY */

udelay(500);

iow(db, DM9KS_GPR, 0); /* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */

udelay(20); /* wait 2ms for PHY power-on ready */

/* do a software reset and wait 20us */

iow(db, DM9KS_NCR, 3);

udelay(20); /* wait 20us at least for software reset ok */

iow(db, DM9KS_NCR, 3); /* NCR (reg_00h) bit[0] RST=1 Loopback=1, reset on */

udelay(20); /* wait 20us at least for software reset ok */

/* I/O mode */

db->io_mode = ior(db, DM9KS_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */

/* Set PHY */

db->op_mode = media_mode;

set_PHY_mode(db);

/* Program operating register */

iow(db, DM9KS_NCR, 0);

iow(db, DM9KS_TCR, 0); /* TX Polling clear */

pid控制相关文章:pid控制原理




评论


相关推荐

技术专区

关闭