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

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

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

et timer again */

db->timer.expires = DMFE_TIMER_WUT;

add_timer(db->timer);

return;

}

#if !defined(CHECKSUM)

#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);

return (ior(db, DM9KS_EPDRL) + (ior(db, DM9KS_EPDRH) 8) );

}

/*

Set DM9000A/DM9010 multicast address

*/

static void dm9000_hash_table(struct net_device *dev)

{

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

struct dev_mc_l

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

网站地图

Top