免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Godbach
打印 上一主题 下一主题

RTL8139网卡驱动程序分析[转] [复制链接]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
41 [报告]
发表于 2009-04-23 09:43 |只看该作者
原帖由 accessory 于 2009-4-22 23:23 发表


是的。不过没必要每次用到MAC地址时都去读硬件,那样效率太低。所以一般是读一次,保存在内存里。


但是还是同样的问题啊,为什么已经可以从IO读取MAC了,还要在从eeprom中读取。直接将IO地址中保存的MAC地址copy给内存不就可以了吗?

论坛徽章:
0
42 [报告]
发表于 2009-04-24 00:26 |只看该作者
不好意思,一开始没看清楚你的问题。
RTL8139上的MAC地址保存在2个地方。一个在EEPROM里面,这个是默认的,不能改的。另外一个地方在IOADDR的前6个字节。这个地方是可以写的,临时的。
这样设计的用途是为了让驱动程序更改MAC地址。如果驱动不改MAC的话,那么就用从EEPROM里面读出来的。

不知道解释清楚了没?

PS:个人理解,仅供参考

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
43 [报告]
发表于 2009-04-24 10:15 |只看该作者
原帖由 accessory 于 2009-4-24 00:26 发表
不好意思,一开始没看清楚你的问题。
RTL8139上的MAC地址保存在2个地方。一个在EEPROM里面,这个是默认的,不能改的。另外一个地方在IOADDR的前6个字节。这个地方是可以写的,临时的。
这样设计的用途是为了让 ...


多谢accessory兄讲解。应该明白了。EEPROM中的信息主要用在驱动初始化的时候读取一下固化好的MAC地址。然后IOADDR在初始的时候应该保存的也是同样的MAC地址。但是IOADDR中的MAC是允许用户在对网卡的操作中修改MAC地址的,这个可以修改的MAC地址是保存在IOADDR的。
是不是随后网卡正常运行使用的时候,基本上不需要再从EEPROM中读取MAC地址了?

论坛徽章:
0
44 [报告]
发表于 2009-04-24 23:00 |只看该作者
是的.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
45 [报告]
发表于 2009-04-24 23:44 |只看该作者
原帖由 accessory 于 2009-4-24 23:00 发表
是的.


多谢啊。

论坛徽章:
0
46 [报告]
发表于 2009-04-25 00:09 |只看该作者
不客气 :wink:

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
47 [报告]
发表于 2009-04-26 00:54 |只看该作者

回复 #31 Godbach 的帖子

看了一下接口技术中介绍PCI部分,这个地方应该是PCI规范的东西。

论坛徽章:
0
48 [报告]
发表于 2009-04-27 09:05 |只看该作者
研究一下,谢谢分离。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
49 [报告]
发表于 2009-04-27 09:54 |只看该作者
讨论一下read_eeprom这个函数阿。
程序在 rtl8139_init_one函数中调用该函数:
  1. addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
  2.         for (i = 0; i < 3; i++)
  3.                 ((u16 *) (dev->dev_addr))[i] =
  4.                     le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
复制代码

应该是先读取eerpom的前16bits,如果其值为0x8129则addr_len=8,否则为6。

这个地方有些不太理解是为什么?看一下read_eeprom函数的前半部分:
  1. static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_len)
  2. {
  3.         int i;
  4.         unsigned retval = 0;
  5.         int read_cmd = location | (EE_READ_CMD << addr_len);

  6.         RTL_W8 (Cfg9346, EE_ENB & ~EE_CS);
  7.         RTL_W8 (Cfg9346, EE_ENB);
  8.         eeprom_delay ();

  9.         /* Shift the read command bits out. */
  10.         for (i = 4 + addr_len; i >= 0; i--) {
  11.                 int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
  12.                 RTL_W8 (Cfg9346, EE_ENB | dataval);
  13.                 eeprom_delay ();
  14.                 RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK);
  15.                 eeprom_delay ();
  16.         }
  17.         RTL_W8 (Cfg9346, EE_ENB);
  18.         eeprom_delay ();
复制代码

以上代码首先是要组成eerpom的读命令。然后通过写寄存器cfg9346来选中eerpom。并将读命令一个一个bit的写到eerpom中。但是不太理解的是,为什么read_cmd = location | (EE_READ_CMD << addr_len)。
EE_READ_CMD为什么要左移的位数和 addr_len有关,这个参数的作用是什么?

论坛徽章:
0
50 [报告]
发表于 2009-04-27 11:23 |只看该作者
嗯,参考下,感谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP