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格式)
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格式)