微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM-Linux驱动--DM9000网卡驱动分析(三)

ARM-Linux驱动--DM9000网卡驱动分析(三)

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

iow(db, DM9000_GPR, 0x01);

iow(db, DM9000_IMR, IMR_PAR);

iow(db, DM9000_RCR, 0x00);

}

3、接下来了解一下数据的发送函数dm9000_start_xmit

上图可以看出DM9000的SRAM中地址0x0000到0x0BFF是TXBuffer,从0x0C00到0x3FFF是RXBuffer,包的有效数据必须提前放到TXBuffer缓冲区,使用端口命令来选择MWCMD寄存器。最后设置TXCR寄存器的bit[0]TXREQ来自动发送包。

发送包的步骤如下:

(1)检查存储器宽度,通过读取ISR的bit[7:6]来确定位数

(2)写数据到TXSRAM

(3)写传输长度到TXPLL和TXPLH寄存器

(4)设置TXCR的bit[0]TXREQ来发送包

view plainprint?

static int

dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)

{

unsigned long flags;

board_info_t *db = netdev_priv(dev);

dm9000_dbg(db, 3, "%s:\n", __func__);

if (db->tx_pkt_cnt > 1)

return NETDEV_TX_BUSY;

spin_lock_irqsave(&db->lock, flags);

writeb(DM9000_MWCMD, db->io_addr);

(db->outblk)(db->io_data, skb->data, skb->len);

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

db->tx_pkt_cnt++;

if (db->tx_pkt_cnt == 1) {

dm9000_send_packet(dev, skb->ip_summed, skb->len);

} else {

db->queue_pkt_len = skb->len;

db->queue_ip_summed = skb->ip_summed;

netif_stop_queue(dev);

}

spin_unlock_irqrestore(&db->lock, flags);

dev_kfree_skb(skb);

return NETDEV_TX_OK;

}

上面函数调用下面的函数 dm9000_send_packet来发送数据

view plainprint?

static void dm9000_send_packet(struct net_device *dev,

int ip_summed,

u16 pkt_len)

{

board_info_t *dm = to_dm9000_board(dev);

if (dm->ip_summed != ip_summed) {

if (ip_summed == CHECKSUM_NONE)

iow(dm, DM9000_TCCR, 0);

else

iow(dm, DM9000_TCCR, TCCR_IP | TCCR_UDP | TCCR_TCP);

dm->ip_summed = ip_summed;

}

iow(dm, DM9000_TXPLL, pkt_len);

iow(dm, DM9000_TXPLH, pkt_len >> 8);

iow(dm, DM9000_TCR, TCR_TXREQ);

}

5、下面看一下当一个数据包发送完成后的中断处理函数dm9000_tx_done

view plainprint?

static void dm9000_tx_done(struct net_device *dev, board_info_t *db)

{

int tx_status = ior(db, DM9000_NSR);

if (tx_status & (NSR_TX2END | NSR_TX1END)) {

db->tx_pkt_cnt--;

dev->stats.tx_packets++;

if (netif_msg_tx_done(db))

dev_dbg(db->dev, "tx done, NSR x\n", tx_status);

if (db->tx_pkt_cnt > 0)

dm9000_send_packet(dev, db->queue_ip_summed,

db->queue_pkt_len);

netif_wake_queue(dev);

}

}

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

网站地图

Top