新闻中心

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

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

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

iow(db, DM9KS_BPTR, 0x3f); /* Less 3kb, 600us */

iow(db, DM9KS_SMCR, 0); /* Special Mode */

iow(db, DM9KS_NSR, 0x2c); /* clear TX status */

iow(db, DM9KS_ISR, 0x0f); /* Clear interrupt status */

/* Added by jackal at 03/29/2004 */

#if defined(CHECKSUM)

iow(db, DM9KS_TCCR, 0x07); /* TX UDP/TCP/IP checksum enable */

iow(db, DM9KS_RCSR, 0x02); /*Receive checksum enable */

#endif

#if defined(ETRANS)

iow(db, DM9KS_ETXCSR, 0x83);

#endif

/* Set address filter table */

dm9000_hash_table(dev);

/* Activate / */

iow(db, DM9KS_RXCR, DM9KS_REG05 | 1); /* RX enable */

iow(db, DM9KS_IMR, DM9KS_REGFF); // Enable TX/RX interrupt mask

/* Init Driver variable */

db->tx_pkt_cnt = 0;

netif_carrier_on(dev);

spin_lock_init(db->lock);

}

/*

Hardware start transmission.

Send a packet to media from the upper layer.

*/

static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)

{

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

char * data_ptr;

int i, tmplen;

if(db->Speed == 10)

{if (db->tx_pkt_cnt >= 1) return 1;}

else

{if (db->tx_pkt_cnt >= 2) return 1;}

/* packet counting */

db->tx_pkt_cnt++;

db->stats.tx_packets++;

db->stats.tx_bytes+=skb->len;

if (db->Speed == 10)

{if (db->tx_pkt_cnt >= 1) netif_stop_queue(dev);}

else

{if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);}

/* Disable all interrupt */

iow(db, DM9KS_IMR, DM9KS_DISINTR);

/* Set TX length to reg. 0xfc 0xfd */

iow(db, DM9KS_TXPLL, (skb->len 0xff));

iow(db, DM9KS_TXPLH, (skb->len >> 8) 0xff);

/* Move data to TX SRAM */

data_ptr = (char *)skb->data;

outb(DM9KS_MWCMD, db->io_addr); // Write data into SRAM trigger

switch(db->io_mode)

{

case DM9KS_BYTE_MODE:

for (i = 0; i skb->len; i++)

outb((data_ptr[i] 0xff), db->io_data);

break;

case DM9KS_WORD_MODE:

tmplen = (skb->len + 1) / 2;

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

outw(((u16 *)data_ptr)[i], db->io_data);

break;

case DM9KS_DWORD_MODE:

tmplen = (skb->len + 3) / 4;

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

outl(((u32 *)data_ptr)[i], db->io_data);

break;

}

#if !defined(ETRANS)

/* Issue TX polling command */

iow(db, DM9KS_TCR, 0x1); /* Cleared after TX complete*/

#endif

/* Saved the time stamp */

dev->trans_start = jiffies;

db->cont_rx_pkt_cnt =0;

/* Free this SKB */

dev_kfree_skb(skb);

/* Re-enable interrupt */

iow(db, DM9KS_IMR, DM9KS_REGFF);

return 0;

}

/*

Stop the interface.

The interface is stopped when it is brought.

*/

static int dmfe_stop(struct net_device *dev)

{

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

DMFE_DBUG(0, dmfe_stop, 0);

/* deleted timer */

del_timer(db->timer);

netif_stop_queue(dev);

/* free interrupt */

free_irq(dev->irq, dev);

/* RESET devie */

phy_write(db, 0x00, 0x8000); /* PHY RESET */

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

iow(db, DM9KS_IMR, DM9KS_DISINTR); /* Disable all interrupt */

iow(db, DM9KS_RXCR, 0x00); /* Disable RX */

/* Dump Statistic counter */

#if FALSE

printk(nRX FIFO OVERFLOW %lxn, db->stats.rx_fifo_errors);

printk(RX CRC %lxn, db->stats.rx_crc_errors);

printk(RX LEN Err %lxn, db->stats.rx_length_errors);

printk(RESET %xn, db->reset_counter);

printk(RESET: TX Timeout %xn, db->reset_tx_timeout);

printk(g_TX_nsr %xn, g_TX_nsr);

#endif

return 0;

}

static void dmfe_tx_done(unsigned long unused)

{

struct net_device *dev = dmfe_dev;

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

int nsr;

DMFE_DBUG(0, dmfe_tx_done(), 0);

nsr = ior(db, DM9KS_NSR);

if(nsr 0x04) db->tx_pkt_cnt--;

if(nsr 0x08) db->tx_pkt_cnt--;

if (db->tx_pkt_cnt 0)

{

printk([dmfe_tx_done] tx_pkt_cnt ERROR!!n);

db->tx_pkt_cnt =0;

}

if (db->Speed == 10)

{if(db->tx_pkt_cnt 1 ) netif_wake_queue(dev);}

else

{if(db->tx_pkt_cnt 2 ) netif_wake_queue(dev);}

return;

}

/*

DM9000 insterrupt handler

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




评论


相关推荐

技术专区

关闭