免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
21 [报告]
发表于 2009-04-06 22:49 |只看该作者
独孤求真,是独孤九剑的什么什么关系?

论坛徽章:
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
22 [报告]
发表于 2009-04-07 09:44 |只看该作者
原帖由 dreamice 于 2009-4-6 22:49 发表
独孤求真,是独孤九剑的什么什么关系?


姓氏一样

论坛徽章:
0
23 [报告]
发表于 2009-04-07 16:31 |只看该作者
楼主的签名相当之震撼~~~

论坛徽章:
13
CU大牛徽章
日期:2013-04-17 11:20:3615-16赛季CBA联赛之吉林
日期:2017-05-25 16:45:4715-16赛季CBA联赛之福建
日期:2017-03-13 11:33:442017金鸡报晓
日期:2017-02-08 10:39:422017金鸡报晓
日期:2017-01-10 15:13:29IT运维版块每日发帖之星
日期:2016-03-15 06:20:01IT运维版块每日发帖之星
日期:2015-10-02 06:20:00CU十二周年纪念徽章
日期:2013-10-24 15:41:34CU大牛徽章
日期:2013-09-18 15:15:45CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-04-17 11:46:39CU大牛徽章
日期:2013-04-17 11:46:28
24 [报告]
发表于 2009-04-08 11:53 |只看该作者
其他都好,就是错别字太多啦。

论坛徽章:
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
25 [报告]
发表于 2009-04-13 19:48 |只看该作者
RTL8139的网卡芯片用的是什么型号,网上就找到了RTL8139C(L)的datasheet

[ 本帖最后由 Godbach 于 2009-4-13 19:57 编辑 ]

论坛徽章:
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
26 [报告]
发表于 2009-04-13 22:47 |只看该作者
网上搜索rtl8139C的datasheet,http://www.alldatasheet.com/view.jsp?Searchword=RTL8139C,有两个PDF文档,一个是RTL8100B,一个是RTL8139C。这两个可能是一个是一个是01年底,一个是02年初。

而RTL8100B中PID初始化为0x8139,而RTL8139C中初始化为0x8129。我本机读取的config中PID为0x8139. 看来应该参考第一个文档。

论坛徽章:
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
27 [报告]
发表于 2009-04-14 18:42 |只看该作者
网卡驱动中通常要读取设备的相关信息,由于网卡是标准的PCI设备,其前64bytes格式是固定的。配置信息也就是从前64bytes的空间去读取。
譬如,8139too.c中要读取网卡的Rev_ID,可以通过如下方式:
        pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
其中 PCI_REVISION_ID即Rev_ID在配置空间中的偏移。
跟踪了一下这个函数的执行,调用的宏为:
#define PCI_OP_READ(size,type,len) \
int pci_bus_read_config_##size \
        (struct pci_bus *bus, unsigned int devfn, int pos, type *value)        \
{                                                                        \
        int res;                                                        \
        unsigned long flags;                                                \
        u32 data = 0;                                                        \
        if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;        \
        spin_lock_irqsave(&pci_lock, flags);                                \
        res = bus->ops->read(bus, devfn, pos, len, &data);                \
        *value = (type)data;                                                \
        spin_unlock_irqrestore(&pci_lock, flags);                        \
        return res;                                                        \
}

其中size替换为byte即可。

这里可以看出,真正配置信息是从这行代码中读取的:
        res = bus->ops->read(bus, devfn, pos, len, &data);                \


bus是struct pci_bus类型的。各位有谁知道ops成员什么时候被赋值的。里面应该定义的是配置空间的读写函数。

论坛徽章:
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
28 [报告]
发表于 2009-04-14 21:07 |只看该作者
在arch/i386/pci/direct.c中定义了访问PCI配置空间的方法,这个直接对端口进行读写,应该是比较低层的实现
  1. /*
  2. * direct.c - Low-level direct PCI config space access
  3. */

  4. #include <linux/pci.h>
  5. #include <linux/init.h>
  6. #include <linux/dmi.h>
  7. #include "pci.h"

  8. /*
  9. * Functions for accessing PCI configuration space with type 1 accesses
  10. */

  11. #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
  12.         (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))

  13. int pci_conf1_read(unsigned int seg, unsigned int bus,
  14.                           unsigned int devfn, int reg, int len, u32 *value)
  15. {
  16.         unsigned long flags;

  17.         if ((bus > 255) || (devfn > 255) || (reg > 255)) {
  18.                 *value = -1;
  19.                 return -EINVAL;
  20.         }

  21.         spin_lock_irqsave(&pci_config_lock, flags);

  22.         outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);

  23.         switch (len) {
  24.         case 1:
  25.                 *value = inb(0xCFC + (reg & 3));
  26.                 break;
  27.         case 2:
  28.                 *value = inw(0xCFC + (reg & 2));
  29.                 break;
  30.         case 4:
  31.                 *value = inl(0xCFC);
  32.                 break;
  33.         }

  34.         spin_unlock_irqrestore(&pci_config_lock, flags);

  35.         return 0;
  36. }

  37. int pci_conf1_write(unsigned int seg, unsigned int bus,
  38.                            unsigned int devfn, int reg, int len, u32 value)
  39. {
  40.         unsigned long flags;

  41.         if ((bus > 255) || (devfn > 255) || (reg > 255))
  42.                 return -EINVAL;

  43.         spin_lock_irqsave(&pci_config_lock, flags);

  44.         outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);

  45.         switch (len) {
  46.         case 1:
  47.                 outb((u8)value, 0xCFC + (reg & 3));
  48.                 break;
  49.         case 2:
  50.                 outw((u16)value, 0xCFC + (reg & 2));
  51.                 break;
  52.         case 4:
  53.                 outl((u32)value, 0xCFC);
  54.                 break;
  55.         }

  56.         spin_unlock_irqrestore(&pci_config_lock, flags);

  57.         return 0;
  58. }

  59. #undef PCI_CONF1_ADDRESS

  60. struct pci_raw_ops pci_direct_conf1 = {
  61.         .read =                pci_conf1_read,
  62.         .write =        pci_conf1_write,
  63. };


  64. /*
  65. * Functions for accessing PCI configuration space with type 2 accesses
  66. */

  67. #define PCI_CONF2_ADDRESS(dev, reg)        (u16)(0xC000 | (dev << 8) | reg)

  68. static int pci_conf2_read(unsigned int seg, unsigned int bus,
  69.                           unsigned int devfn, int reg, int len, u32 *value)
  70. {
  71.         unsigned long flags;
  72.         int dev, fn;

  73.         if ((bus > 255) || (devfn > 255) || (reg > 255)) {
  74.                 *value = -1;
  75.                 return -EINVAL;
  76.         }

  77.         dev = PCI_SLOT(devfn);
  78.         fn = PCI_FUNC(devfn);

  79.         if (dev & 0x10)
  80.                 return PCIBIOS_DEVICE_NOT_FOUND;

  81.         spin_lock_irqsave(&pci_config_lock, flags);

  82.         outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  83.         outb((u8)bus, 0xCFA);

  84.         switch (len) {
  85.         case 1:
  86.                 *value = inb(PCI_CONF2_ADDRESS(dev, reg));
  87.                 break;
  88.         case 2:
  89.                 *value = inw(PCI_CONF2_ADDRESS(dev, reg));
  90.                 break;
  91.         case 4:
  92.                 *value = inl(PCI_CONF2_ADDRESS(dev, reg));
  93.                 break;
  94.         }

  95.         outb(0, 0xCF8);

  96.         spin_unlock_irqrestore(&pci_config_lock, flags);

  97.         return 0;
  98. }

  99. static int pci_conf2_write(unsigned int seg, unsigned int bus,
  100.                            unsigned int devfn, int reg, int len, u32 value)
  101. {
  102.         unsigned long flags;
  103.         int dev, fn;

  104.         if ((bus > 255) || (devfn > 255) || (reg > 255))
  105.                 return -EINVAL;

  106.         dev = PCI_SLOT(devfn);
  107.         fn = PCI_FUNC(devfn);

  108.         if (dev & 0x10)
  109.                 return PCIBIOS_DEVICE_NOT_FOUND;

  110.         spin_lock_irqsave(&pci_config_lock, flags);

  111.         outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  112.         outb((u8)bus, 0xCFA);

  113.         switch (len) {
  114.         case 1:
  115.                 outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
  116.                 break;
  117.         case 2:
  118.                 outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
  119.                 break;
  120.         case 4:
  121.                 outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
  122.                 break;
  123.         }

  124.         outb(0, 0xCF8);   

  125.         spin_unlock_irqrestore(&pci_config_lock, flags);

  126.         return 0;
  127. }

  128. #undef PCI_CONF2_ADDRESS

  129. static struct pci_raw_ops pci_direct_conf2 = {
  130.         .read =                pci_conf2_read,
  131.         .write =        pci_conf2_write,
  132. };
复制代码

论坛徽章:
0
29 [报告]
发表于 2009-04-15 11:22 |只看该作者
好东西啊,下来学习学习!!

论坛徽章:
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
30 [报告]
发表于 2009-04-15 16:13 |只看该作者
读了一下本机RTL8139网卡的配置信息:
[root@localhost 0000:00:0e.0]# od -x config
0000000 10ec 8139 0107 0290 0010 0200 4000 0000
0000020 c801 0000 b800 bfff 0000 0000 0000 0000
0000040 0000 0000 0000 0000 0000 0000 10ec 8139
0000060 0000 0000 0050 0000 0000 0000 010a 4020
0000100 0000 0000 0000 0000 0000 0000 0000 0000
0000120 0001 f7c2 0000 0000 0000 0000 0000 0000
0000140 0000 0000 0000 0000 0000 0000 0000 0000
*
0000400

不知道最前面的值代表什么,如果是字节书的话,MS也不连续啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP