新闻中心

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

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

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

#define check_rx_ready(a) ((a) == 0x01)

#else

inline u8 check_rx_ready(u8 rxbyte)

{

if (!(rxbyte 0x01))

return 0;

return ((rxbyte >> 4) | 0x01);

}

#endif

/*

Received a packet and pass to upper layer

*/

static void dmfe_packet_receive(struct net_device *dev)

{

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

struct sk_buff *skb;

u8 rxbyte, val;

u16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;

u32 tmpdata;

rx_t rx;

u16 * ptr = (u16*)rx;

u8* rdptr;

DMFE_DBUG(0, dmfe_packet_receive(), 0);

do {

/*store the value of Memory Data Read address register*/

MDRAH=ior(db, DM9KS_MDRAH);

MDRAL=ior(db, DM9KS_MDRAL);

ior(db, DM9KS_MRCMDX); /* Dummy read */

rxbyte = inb(db->io_data); /* Got most updated data */

/* packet ready to receive check */

if(!(val = check_rx_ready(rxbyte))) break;

/* A packet ready now Get status/length */

GoodPacket = TRUE;

outb(DM9KS_MRCMD, db->io_addr);

/* Read packet status length */

switch (db->io_mode)

{

case DM9KS_BYTE_MODE:

*ptr = inb(db->io_data) +

(inb(db->io_data) 8);

*(ptr+1) = inb(db->io_data) +

(inb(db->io_data) 8);

break;

case DM9KS_WORD_MODE:

*ptr = inw(db->io_data);

*(ptr+1) = inw(db->io_data);

break;

case DM9KS_DWORD_MODE:

tmpdata = inl(db->io_data);

*ptr = tmpdata;

*(ptr+1) = tmpdata >> 16;

break;

default:

break;

}

/* Packet status check */

if (rx.desc.status 0xbf)

{

GoodPacket = FALSE;

if (rx.desc.status 0x01)

{

db->stats.rx_fifo_errors++;

printk(n);

}

if (rx.desc.status 0x02)

{

db->stats.rx_crc_errors++;

printk(n);

}

if (rx.desc.status 0x80)

{

db->stats.rx_length_errors++;

printk(n);

}

if (rx.desc.status 0x08)

printk(n);

}

if (!GoodPacket)

{

// drop this packet!!!

switch (db->io_mode)

{

case DM9KS_BYTE_MODE:

for (i=0; i

inb(db->io_data);

break;

case DM9KS_WORD_MODE:

tmplen = (rx.desc.length + 1) / 2;

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

inw(db->io_data);

break;

case DM9KS_DWORD_MODE:

tmplen = (rx.desc.length + 3) / 4;

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

inl(db->io_data);

break;

}

continue;/*next the packet*/

}

skb = dev_alloc_skb(rx.desc.length+4);

if (skb == NULL )

{

printk(KERN_INFO %s: Memory squeeze.n, dev->name);

/*re-load the value into Memory data read address register*/

iow(db,DM9KS_MDRAH,MDRAH);

iow(db,DM9KS_MDRAL,MDRAL);

return;

}

else

{

/* Move data from DM9000 */

skb->dev = dev;

skb_reserve(skb, 2);

rdptr = (u8*)skb_put(skb, rx.desc.length - 4);

/* Read received packet from RX SARM */

switch (db->io_mode)

{

case DM9KS_BYTE_MODE:

for (i=0; i

rdptr[i]=inb(db->io_data);

break;

case DM9KS_WORD_MODE:

tmplen = (rx.desc.length + 1) / 2;

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

((u16 *)rdptr)[i] = inw(db->io_data);

break;

case DM9KS_DWORD_MODE:

tmplen = (rx.desc.length + 3) / 4;

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

((u32 *)rdptr)[i] = inl(db->io_data);

break;

}

/* Pass to upper layer */

skb->protocol = eth_type_trans(skb,dev);

#if defined(CHECKSUM)

if (val == 0x01)

skb->ip_summed = CHECKSUM_UNNECESSARY;

#endif

netif_rx(skb);

dev->last_rx=jiffies;

db->stats.rx_packets++;

db->stats.rx_bytes += rx.desc.length;

db->cont_rx_pkt_cnt++;

if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)

{

dmfe_tx_done(0);

break;

}

}

}while((rxbyte 0x01) == DM9KS_PKT_RDY);

DMFE_DBUG(0, [END]dmfe_packet_receive(), 0);

}

/*

Read a word data from SROM

*/

static u16 read_srom_word(board_info_t *db, int offset)

{

iow(db, DM9KS_EPAR, offset);

iow(db, DM9KS_EPCR, 0x4);

udelay(200);

iow(db, DM9KS_EPCR, 0x0);

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




评论


相关推荐

技术专区

关闭