新闻中心

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

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

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

receive the packet to upper layer, free the transmitted packet

*/

#if LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)

static void dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)

#else

static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)

#endif

{

struct net_device *dev = dev_id;

board_info_t *db;

int int_status,i;

u8 reg_save;

DMFE_DBUG(0, dmfe_interrupt(), 0);

/* A real interrupt coming */

db = (board_info_t *)dev->priv;

spin_lock(db->lock);

/* Save previous register address */

reg_save = inb(db->io_addr);

/* Disable all interrupt */

iow(db, DM9KS_IMR, DM9KS_DISINTR);

/* Got / interrupt status */

int_status = ior(db, DM9KS_ISR); /* Got ISR */

iow(db, DM9KS_ISR, int_status); /* Clear ISR status */

/* Link status change */

if (int_status DM9KS_LINK_INTR)

{

netif_stop_queue(dev);

for(i=0; i500; i++) /*wait link OK, waiting time =0.5s */

{

phy_read(db,0x1);

if(phy_read(db,0x1) 0x4) /*Link OK*/

{

/* wait for detected Speed */

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

udelay(1000);

/* set media speed */

if(phy_read(db,0)0x2000) db->Speed =100;

else db->Speed =10;

break;

}

udelay(1000);

}

netif_wake_queue(dev);

//printk([INTR]i=%d speed=%dn,i, (int)(db->Speed));

}

/* Received the coming packet */

if (int_status DM9KS_RX_INTR)

dmfe_packet_receive(dev);

/* Trnasmit Interrupt check */

if (int_status DM9KS_TX_INTR)

dmfe_tx_done(0);

if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)

{

iow(db, DM9KS_IMR, 0xa2);

}

else

{

/* Re-enable interrupt mask */

iow(db, DM9KS_IMR, DM9KS_REGFF);

}

/* Restore previous register address */

outb(reg_save, db->io_addr);

spin_unlock(db->lock);

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)

return IRQ_HANDLED;

#endif

}

/*

Get statistics from driver.

*/

static struct net_device_stats * dmfe_get_stats(struct net_device *dev)

{

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

DMFE_DBUG(0, dmfe_get_stats, 0);

return db->stats;

}

/*

Process the upper socket ioctl command

*/

static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)

{

DMFE_DBUG(0, dmfe_do_ioctl(), 0);

return 0;

}

/* Our watchdog timed out. Called by the networking layer */

static void

dmfe_timeout(struct net_device *dev)

{

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

DMFE_DBUG(0, dmfe_TX_timeout(), 0);

printk(TX time-out -- dmfe_timeout().n);

db->reset_tx_timeout++;

db->stats.tx_errors++;

#if FALSE

printk(TX packet count = %dn, db->tx_pkt_cnt);

printk(TX timeout = %dn, db->reset_tx_timeout);

printk(22H=0x%02x 23H=0x%02xn,ior(db,0x22),ior(db,0x23));

printk(faH=0x%02x fbH=0x%02xn,ior(db,0xfa),ior(db,0xfb));

#endif

dmfe_reset(dev);

}

static void dmfe_reset(struct net_device * dev)

{

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

u8 reg_save;

int i;

/* Save previous register address */

reg_save = inb(db->io_addr);

netif_stop_queue(dev);

db->reset_counter++;

dmfe_init_dm9000(dev);

db->Speed =10;

for(i=0; i1000; i++) /*wait link OK, waiting time=1 second */

{

if(phy_read(db,0x1) 0x4) /*Link OK*/

{

if(phy_read(db,0)0x2000) db->Speed =100;

else db->Speed =10;

break;

}

udelay(1000);

}

netif_wake_queue(dev);

/* Restore previous register address */

outb(reg_save, db->io_addr);

}

/*

A periodic timer routine

*/

static void dmfe_timer(unsigned long data)

{

struct net_device * dev = (struct net_device *)data;

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

DMFE_DBUG(0, dmfe_timer(), 0);

if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)

{

db->cont_rx_pkt_cnt=0;

iow(db, DM9KS_IMR, DM9KS_REGFF);

}

/* Set timer again */

db->timer.expires = DMFE_TIMER_WUT;

add_timer(db->timer);

return;

}

#if !defined(CHECKSUM)

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




评论


相关推荐

技术专区

关闭