dm9k驱动的理解

DM9000A发送过程的理解
发送包函数:
1.	static int dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
2.	{
3.	board_info_t *db = (board_info_t *) dev->priv;
4.	
5.	PRINTK3("dm9000_start_xmit/n");
6.	
7.	if (db->tx_pkt_cnt > 1)
8.	   return 1;
9.	/*停止接收*/
10.	netif_stop_queue(dev);
11.	
12.	/* Disable all interrupts 
13.	关闭发送,接收中断*/
14.	iow(db, DM9000_IMR, IMR_PAR);
15.	
16.	/* Move data to DM9000 TX RAM */
17.	writeb(DM9000_MWCMD, db->io_addr);
18.	/*把skb的数据拷贝到DM9000的SRAM中*/
19.	(db->outblk)(db->io_data, skb->data, skb->len);
20.	/*统计值加上相应的长度*/
21.	db->stats.tx_bytes += skb->len;
22.	
23.	/* TX control: First packet immediately send, second packet queue */
24.	if (db->tx_pkt_cnt == 0) {
25.	
26.	   /* First Packet 
27.	   发送的包增加*/
28.	   db->tx_pkt_cnt++;
29.	
30.	   /* Set TX length to DM9000 
31.	   设定DM9000需要发送的包长度*/
32.	   iow(db, DM9000_TXPLL, skb->len & 0xff);
33.	   iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);
34.	
35.	   /* Issue TX polling command 
36.	   设定发送请求,即启动发送*/
37.	   iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
38.	   /*启动时间*/
39.	   dev->trans_start = jiffies; /* save the time stamp */
40.	
41.	} else {
42.	   /*第二个包发送,在tx_done中实现*/
43.	   /* Second packet */
44.	   db->tx_pkt_cnt++;
45.	   db->queue_pkt_len = skb->len;
46.	}
47.	
48.	/* free this SKB
49.	发送完毕释放skb */
50.	dev_kfree_skb(skb);
51.	
52.	/* Re-enable resource check 
53.	第一个包发送完毕,即内存拷贝完毕,不是实际总线上的
54.	可以启动第二包拷贝到SRAM*/
55.	if (db->tx_pkt_cnt == 1)
56.	   netif_wake_queue(dev);
57.	
58.	/* Re-enable interrupt 
59.	重新启用中断,这时DM9000若发送完成,会产生发送完毕中断*/
60.	iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
61.	
62.	return 0;
63.	}
数据方向:
CPU->dm9k
需要做的工作:
1.假设发的第一个包,Move data to DM9000 TX RAM,包数目增加1,写包长度,使能发送
2.假设发的第二个包,Move data to DM9000 TX RAM,包数目增加1
3.发的第三个包,直接返回
发送中断:
1.	static void
2.	dm9000_tx_done(struct net_device *dev, board_info_t * db)
3.	{
4.	int tx_status = ior(db, DM9000_NSR); /* Got TX status */
5.	
6.	/*一个包已经发送完毕*/
7.	if (tx_status & (NSR_TX2END | NSR_TX1END)) {
8.	   /* One packet sent complete */
9.	   db->tx_pkt_cnt--;
10.	   db->stats.tx_packets++;
11.	
12.	   /* Queue packet check & send 
13.	   当前还有一个包未发送,且在缓冲区中,是第二个包*/
14.	   if (db->tx_pkt_cnt > 0) {
15.	    /*设定DM9000发送包的长度*/
16.	    iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff);
17.	    iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff);
18.	    /*启动发送*/
19.	    iow(db, DM9000_TCR, TCR_TXREQ);
20.	    dev->trans_start = jiffies;
21.	   }
22.	   /*通知内核*/
23.	   netif_wake_queue(dev);
24.	}
25.	}
在发送中断里
如果第一个包,然后包数减1;
如果第二个包,重新设置第二个包的长度,使能发送


DM9000A PHY & EEPROM 读写操作
读:

1.       把PHY或EEPROM地址写入REG-0Ch  , phy reg-0ch bit6 置为1

2.       REG-0BH bit2 bit3 设置读命令

3.       监测REG-0BH bit0位读进度状态, 0表示读完

4.       清零读命令

5.       从REG0DH REG0EH寄存器读出值返回给CPU

写:

1.         把PHY或EEPROM地址写入REG-0Ch  , phy reg-0ch bit6 置为1

2.         CPU把设置的值写入REG0DH REG0EH

3.         REG-0BH bit1 bit3 设置写命令

4.         监测REG-0BH bit0位读进度状态, 0表示读完

5.         清零读命令

其它: REG0BH bit3:0 EEPROM bit3:1 PHY  bit1: Write bit2:Read , 读写数据宽度为16bit (word格式)





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值