ethtool 在 Linux 中的实现框架和应用

王 俊元 和 商 小乐2013 年 5 月 06 日发布Linux 网卡驱动程序对 ethtool 的支持和实现从典型的以太网控制器说起网卡工作在 OSI 网络体系的最后两层,物理层和数据链路层,物理层定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口。物理层的芯片称之为 PHY。数据链路层则提供寻址机构、数据帧的构建、数据差错检查、传送控制、向网络层提供标准的数据接口等功能。以太网卡中数据链路层的芯片称之为 MAC 控制器。很多网卡的这两个部分是做到一起的。他们之间的关系是 PCI 总线接 MAC 总线,MAC 接 PHY,PHY 接网线(当然也不是直接接上的,还有一个变压装置)。一般地,一个典型的以太网控制器的基本结构如图 1 所示:图 1. 一个典型的符合 IEEE802.3 标准的的以太网控制器结构图

数据链路层 MAC 是 Media Access Control 的缩写,即媒体访问控制子层协议。该协议位于 OSI 七层协议中数据链路层的下半部分,主要负责控制与连接物理层的物理介质。在发送数据的时候,MAC 协议可以事先判断是否可以发送数据,如果可以发送将给数据加上一些控制信息,最终将数据以及控制信息以规定的格式发送到物理层;在接收数据的时候,MAC 协议首先判断输入的信息并是否发生传输错误,如果没有错误,则去掉控制信息发送至 LLC 层。以太网 MAC 由 IEEE-802.3 以太网标准定义。物理层 PHY 是物理接口收发器,它实现物理层。包括 MII/GMII(介质独立接口)子层、PCS(物理编码子层)、PMA(物理介质附加)子层、 PMD(物理介质相关)子层、MDI 子层。MII 即媒体独立接口 , “媒体独立”表明在不对 MAC 硬件重新设计或替换的情况下,任何类型的 PHY 设备都可以正常工作。包括分别用于发送器和接收器的两条独立信道。每条信道都有自己的数据、时钟和控制信号。MII 数据接口总共需要 16 个信号,包括 TX_ER,TXD<3:0>,TX_EN,TX_CLK,COL,RXD<3:0>,RX_EX,RX_CLK,CRS,RX_DV 等。RMII (Reduced Media Independant Interface ) 是简化的 MII 接口 ,在数据的收发上它比 MII 接口少了一倍的信号线,所以它一般要求是 50 兆的总线时钟 。RMII 一般用在多端口的交换机,它不是每个端口安排收、发两个时钟,而是所有的数据端口公用一个时钟用于所有端口的收发 ,这里就节省了不少的端口数目。RMII 的一个端口要求 7 个数据线 ,比 MII 少了一倍,所以交换机能够接入多一倍数据的端口。和 MII 一样,RMII 支持 10 兆和 100 兆的总线接口速度 。GMII(Gigabit MII) 是千兆网的 MII 接口,这个也有相应的 RGMII 接口,表示简化了的 GMII 接口。GMII 采用 8 位接口数据,工作时钟 125MHz,因此传输速率可达 1000Mbps 。同时兼容 MII 所规定的 10/100 Mbps 工作方式。MII 管理接口是个双信号接口,一个是时钟信号 MDC,另一个是数据信号 MDIO。通过管理接口,上层能监视和控制 PHY 的寄存器。PHY 里面的部分寄存器是 IEEE 定义的,这样 PHY 把自己的目前的状态反映到寄存器里面,MAC 通过管理接口不断的读取 PHY 的状态寄存器以得知目前 PHY 的状态,例如连接速度,双工的能力等。当然也可以通过管理接口设置 PHY 的寄存器达到控制的目的,例如流控的打开关闭,自协商模式还是强制模式等,这也是 ethtool 的工作原理。MDIO/MDC,即 PHY 管理接口串行通信总线,该总线由 IEEE 通过以太网标准 IEEE 802.3 的若干条款加以定义。MDIO 是一种简单的双线串行接口,将管理器件 ( 如 MAC 控制器、微处理器 ) 与具备管理功能的收发器 ( 如多端口吉比特以太网收发器或 10GbE XAUI 收发器 ) 相连接,从而控制收发器并从收发器收集状态信息。可收集的信息包括链接状态、传输速度与选择、断电、低功率休眠状态、TX/RX 模式选择、自动协商控制、环回模式控制等。除了拥有 IEEE 要求的功能之外,收发器厂商还可添加更多的信息收集功能。MDC 则是管理数据的时钟输入,最高速率可达 8.3MHz。MDIO 是管理数据的输入输出双向接口,数据是与 MDC 时钟同步的。MDIO 的工作流程为:MDIO 接口在没有传输数据的空闲状态(IDLE)数据线 MDIO 处于高阻态。MDIO 出现一个 2bit 的开始标识码 (01) 一个读 / 写操作开始。MDIO 出现一个 2bit 数据来标识是读操作 (10) 还是写操作 (01)。MDIO 出现一个 5bit 数据标识 PHY 的地址。MDIO 出现一个 5bitPHY 寄存器地址。MDIO 需要 2 个时钟的访问时间。MDIO 串行读出 / 写入 16bit 的寄存器数据。MDIO 恢复成 IDLE 状态,同时 MDIO 进入高阻状态。注:以上内容部分摘选自互联网。Linux 设备驱动程序中对 ethtool 的支持目前几乎所有的网卡驱动程序都有对 ethtool 的支持,其框架如图 2 所示,ethtool 框架包含内核空间和用户空间两部分:用户空间的部分负责将 ethtool 命令发送到内核,并接收命令的执行结果;内核空间的部分根据相应的命令字,通过 MDIO/MDC 读写 MII 寄存器,实现对网卡的管理,并把执行结果传回用户空间。由于 Linux 网络驱动程序是一个复杂而庞大的体系,这里只介绍驱动程序中对 MII 寄存器的定义,对 MDIO/MDC 的支持以及驱动程序中实现如何实现 ethtool 功能部分。图 2.ethtool 在 Linux 中的实现框架

IEEE 802.3 规定的 MII 寄存器关于 MII/GMII 接口 PHY 寄存器的定义在 802.3 的 22.2.4 Management functions. 章节中,如该章节中的 Table 22 – 6 和 Table 22 – 7(即本文的图 3 和图 4,均出自 http://standards.ieee.org/getieee802/download/802.3-2008_section2.pdf)所示,图 3. IEEE802.3 定义的 MII 管理寄存器集

可以看到寄存器分为基本集和扩展集,基本集的定义因 GMII 和 MII 而不同,对于 MII, 基本集包括寄存器 0 控制寄存器和 1 状态寄存器,而对于 GMII;基本集包括寄存器 0、1 和 15。控制寄存器 0 和状态寄存器 1 的定义如图 3 所示:图 4. IEEE802.3 定义的寄存器 0 控制寄存器和 1 状态寄存器

图 4. IEEE802.3 定义的寄存器 0 控制寄存器和 1 状态寄存器

对寄存器 0 和寄存器 1 的读写可以实现对网卡的管理,清单 1 列出了部分 PHY 管理寄存器以及控制寄存器和状态寄存器的各个 bit 的定义。清单 1,/kernel/drivers/net/Mii.h, 定义 PHY 管理寄存器123456789101112131415161718192021222324252627282930313233343536373839#define MII_BMCR            0x00        /* Basic mode control register */#define MII_BMSR            0x01        /* Basic mode status register  */#define MII_PHYSID1         0x02        /* PHYS ID 1                   */#define MII_PHYSID2         0x03        /* PHYS ID 2                   */#define MII_ADVERTISE       0x04        /* Advertisement control reg   */#define MII_LPA             0x05        /* Link partner ability reg    */#define MII_EXPANSION       0x06        /* Expansion register          */#define MII_CTRL1000        0x09        /* 1000BASE-T control          */.../* Basic mode control register. */#define BMCR_RESV               0x003f  /* Unused...                   */#define BMCR_SPEED1000          0x0040  /* MSB of Speed (1000)         */#define BMCR_CTST               0x0080  /* Collision test              */#define BMCR_FULLDPLX           0x0100  /* Full duplex                 */#define BMCR_ANRESTART          0x0200  /* Auto negotiation restart    */#define BMCR_ISOLATE            0x0400  /* Disconnect DP83840 from MII */#define BMCR_PDOWN              0x0800  /* Powerdown the DP83840       */#define BMCR_ANENABLE           0x1000  /* Enable auto negotiation     */#define BMCR_SPEED100           0x2000  /* Select 100Mbps              */#define BMCR_LOOPBACK           0x4000  /* TXD loopback bits           */#define BMCR_RESET              0x8000  /* Reset the DP83840           *//* Basic mode status register. */#define BMSR_ERCAP              0x0001  /* Ext-reg capability          */#define BMSR_JCD                0x0002  /* Jabber detected             */#define BMSR_LSTATUS            0x0004  /* Link status                 */#define BMSR_ANEGCAPABLE        0x0008  /* Able to do auto-negotiation */#define BMSR_RFAULT             0x0010  /* Remote fault detected       */#define BMSR_ANEGCOMPLETE       0x0020  /* Auto-negotiation complete   */#define BMSR_RESV               0x00c0  /* Unused...                   */#define BMSR_ESTATEN        0x0100      /* Extended Status in R15 */#define BMSR_100FULL2       0x0200      /* Can do 100BASE-T2 HDX */#define BMSR_100HALF2       0x0400      /* Can do 100BASE-T2 FDX */#define BMSR_10HALF             0x0800  /* Can do 10mbps, half-duplex  */#define BMSR_10FULL             0x1000  /* Can do 10mbps, full-duplex  */#define BMSR_100HALF            0x2000  /* Can do 100mbps, half-duplex */#define BMSR_100FULL            0x4000  /* Can do 100mbps, full-duplex */#define BMSR_100BASE4           0x8000  /* Can do 100mbps, 4k packets  */通过 MDC/MDIO 读写 MII 寄存器的具体实现在本文的前面部分介绍过 MDC/MDIO 的工作流程,网卡驱动程序中的 MDIO 读写函数 mdio_read 和 mdio_write,也就是清单 3 中的函数指针的具体实现是在各个网卡的驱动程序文件中完成的,都遵从 IEEE802.3 MDIO 的帧格式。典型的帧格式是第 22 条款中定义的格式:图 5.IEEE802.3 条款 22 定义的 MDIO 帧格式

域长度(bit)说明ST 2bits 01bOP 2bits 操作码,写为 01b,读为 10bPHYADR 5bits PHY IDREGADR 5bits 寄存器地址TA 2 bits 状态转换域,读操作为 X0b, 写操作为 10bDATA 16 bits 数据在驱动程序中实现 ethtool 功能在 kernel/include/linux/ethtool.h 定义了结构体 ethtool_ops,这个结构体的所有成员都是函数指针类型,定义了 ethtool 可以实现的功能,该结构体成员变量较多,在这里就不列出代码清单;同时,在结构体 net_device 中也有成员变量 ethtool_ops 如清单 2 所示,清单 2,kernel/include/linux/NetDevice.h, net_device 中成员变量 ethtool_ops123456struct net_device{...const struct ethtool_ops *ethtool_ops;...}网卡驱动程序需要初始化 ethtool_ops 并且实现其定义的函数功能,从而实现对 ethtool 的支持,以 Dm9000.c 为例。清单 3,kernel/drivers/net/Dm9000.c,DM9000 驱动程序对 ethtool 的支持12345678910111213141516171819static const struct ethtool_ops dm9000_ethtool_ops = {.get_drvinfo        = dm9000_get_drvinfo,.get_settings= dm9000_get_settings,.set_settings       = dm9000_set_settings,.get_msglevel       = dm9000_get_msglevel,.set_msglevel       = dm9000_set_msglevel,.nway_reset= dm9000_nway_reset,.get_link       = dm9000_get_link,.get_eeprom_len         = dm9000_get_eeprom_len,.get_eeprom         = dm9000_get_eeprom,.set_eeprom= dm9000_set_eeprom,.get_rx_csum= dm9000_get_rx_csum,.set_rx_csum= dm9000_set_rx_csum,.get_tx_csum= ethtool_op_get_tx_csum,.set_tx_csum= dm9000_set_tx_csum,};...ndev->ethtool_ops    = &dm9000_ethtool_ops;...清单 3 中的各个函数在 DM9000 的驱动程序中均有实现,比如如果需要查看当前网络的连接情况,可以通过 dm9000_get_link 获得,函数的具体实现如清单 4:清单 4,dm9000_get_link123456789101112131415161718192021static u32 dm9000_get_link(struct net_device *dev){board_info_t *dm = to_dm9000_board(dev);u32 ret;if (dm->flags & DM9000_PLATF_EXT_PHY)ret = mii_link_ok(&dm->mii);elseret = dm9000_read_locked(dm, DM9000_NSR) & NSR_LINKST ? 1 : 0;return ret;}kernel/drivers/net/Mii.cint mii_link_ok (struct mii_if_info *mii){/* first, a dummy read, needed to latch some MII phys */mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS)return 1;return 0;}可以看到最终的实现还是通过 MDIO/MDC 读取 PHY 寄存器得到。除了管理网卡的命令,ethtool 还有还有其它扩展的功能,ethtool 的框架十分有利于新功能的扩展,开发人员可以在这个框架里加入自己想要的功能来实现对除了网卡管理的其它功能,事实上,现在的 ethtool 已经提供了一些其它的功能,比如用来实现网卡 Firmware 的刷写和更新,对网络驱动程序日志的控制等,这些新功能对于调试程序,修正错误是十分有利的。清单 5, 部分 ethtool 的扩展功能:firmware 更新和修改日志级别12ethtool -f|--flash DEVNAME   FILENAMEethtool -s|--change DEVNAME  msglvl %d使用 ethtool 配置和管理网卡上一节主要介绍了 ethtool 实现的基础和方法,本节将主要介绍 ethtool 的一些用法,主要集中在 ethtool 在配置和管理网卡方面的用法。了解 ethtool 用法最好的方法是查看 ethtool 的帮助信息“ethtool -h” 或者 “man ethtool”,由于帮助信息很多,这里就不一一列出了,将会举例一些实际的应用例子代替。实例 1,利用 ethtool 来查看网卡接口 eth4 的信息清单 6,查看网卡的接口信息1234567891011121314151617181920root@IMMV2-DEV4:~# ethtool eth4Settings for eth4:Supported ports: [ TP ]Supported link modes:   10baseT/Half 10baseT/Full100baseT/Half 100baseT/Full1000baseT/FullSupports auto-negotiation: YesAdvertised link modes:  10baseT/Half 10baseT/Full100baseT/Half 100baseT/Full1000baseT/FullAdvertised auto-negotiation: YesSpeed: 100Mb/sDuplex: FullPort: Twisted PairPHYAD: 1Transceiver: internalAuto-negotiation: onSupports Wake-on: gWake-on: gLink detected: yes实例 2,关闭网卡的自动协商并且查看修改结果。清单 7,关闭网卡的自动协商并且查看修改结果12345678910111213141516171819root@IMMV2-DEV4:~# ethtool -s eth4 autoneg offroot@IMMV2-DEV4:~# ethtool eth4Settings for eth4:Supported ports: [ TP ]Supported link modes:   10baseT/Half 10baseT/Full100baseT/Half 100baseT/Full1000baseT/FullSupports auto-negotiation: YesAdvertised link modes:  Not reportedAdvertised auto-negotiation: NoSpeed: 100Mb/sDuplex: FullPort: Twisted PairPHYAD: 1Transceiver: internalAuto-negotiation: offSupports Wake-on: gWake-on: gLink detected: yes实例 3,关闭网卡的自动协商并且修改网卡的速率为 10Mb/s清单 8,关闭网卡的自动协商并修改网卡速率为 10Mb/s12345678910111213141516171819root@IMMV2-DEV4:~# ethtool -s eth4 autoneg off speed 10root@IMMV2-DEV4:~# ethtool eth4Settings for eth4:Supported ports: [ TP ]Supported link modes:   10baseT/Half 10baseT/Full100baseT/Half 100baseT/Full1000baseT/FullSupports auto-negotiation: YesAdvertised link modes:  Not reportedAdvertised auto-negotiation: NoSpeed: 10Mb/sDuplex: FullPort: Twisted PairPHYAD: 1Transceiver: internalAuto-negotiation: offSupports Wake-on: gWake-on: gLink detected: yesethtool 的其它功能可以根据其帮助信息规定的语法来实现,这里就不一一列举。扩展 ethtool根据 NIC 的一些特性,可以扩展 ethtool 来完成对网卡特殊功能的支持,一个典型的扩展应用就是增加 ethtool 对 SideBand 的支持功能,有关 SideBand 的介绍可以参考 IBM developerWorks 《浅谈 NCSI 及其在 Linux 上的实现》。图 6 是一个通过添加自定义的 cmd 和对应的实现函数来完成 SideBand 的 select_channel,enable_channel 及 disable_channel 等功能的框图。以 select_channel 为例,可以通过如下的步骤来实现。图 6, 扩展 ethtool 的 sideband 管理功能

ethtool 的在用户空间和内核空间同时添加命令字 ETHTOOL_SELCHANNEL;在 ethtool.ops 中添加与 ETHTOOL_SELCHANNEL 相对应的执行函数 ethtool_select_channel;在 dev_ethtool 函数中实现 ethtool_select_channel() 功能,这个函数的功能是利用协议栈的包发送接口向 NIC 的 mac 层发送包装后的 NCSI 命令协议包,并且接受相应的回应 , 类似的对于 ethtool_enable_channel(),ethtool_disable_channel 都可以按照相同的方法来扩展,可以看出 ethtool 框架的扩展性是很好的,有利于开发人员根据实际需要来量身定制。总结ethtool 是一个 Linux 下功能强大的网络管理工具,本文首先介绍了这个工具的实现原理和方法,重点介绍了 IEEE802.3.22 中的 MII 管理寄存器和 MDIO/MDC 标准以及 Linux 网络驱动程序中对 ethtool 的支持,然后实例说明了利用这个工具管理网卡的方法,最后介绍了在 ethtool 框架上扩展 SideBand 管理的实例,可以作为广大开发人员的一个参考。相关主题IEEE Standard 802.3: CSMA/CD Access Method and Physical Layer Specifications, Section Two,Chapter 22.2(retrieved on 15-10-2010),定义了 MII/GMII,MDC/MDIO 管理标准。ethtool 工具源码下载地址,Linux 用户空间的应用程序,可以查看 ethtool 的实现框架和提供的功能。Linux 2.6 内核代码下载地址:,可以查看 Linux 内核中对 ethtool 的支持。浅谈 NCSI 及其在 Linux 上的实现:这篇文章详细介绍了 SideBand 的协议栈和实现,可以做为扩展 ethtool 功能的参考。在developerWorks Linux 专区寻找为 Linux 开发人员(包括Linux 新手入门)准备的更多参考资料。

(0)

相关推荐

  • 【博文精选】以太网扫盲——SMI(MDC/MDIO)介绍

    SMI:串行管理接口(Serial Management Interface),通常直接被称为MDIO接口(Management Data Input/Output Interface).MDIO最早 ...

  • 谢爱磊|学术论文中的理论框架是什么,它从哪里来?

    作 者|谢爱磊 理论是什么?  一 理性是现代社会日常行动的重要特征,我们早已习惯了对日常生活中的事件和现象加以合理"解释".一般来说,这些解释可以是特殊的,也可以是一般的.特殊类 ...

  • 在Linux中安装ElasticSearch&Kibana&ik分词器

    概述: ElasticSearch是一个基于Lucene的搜索服务器 是一个分布式.高扩展.高实时的搜索与数据分析引擎 基于RESTful web接口 Elasticsearch是用Java语言开发的 ...

  • RocketMQ在Linux中安装启动

    RocketMQ: RocketMQ是阿里开源的一款非常优秀中间件产品,脱胎于阿里的另一款队列技术MetaQ,后捐赠给Apache基金会作为一款孵化技术,仅仅经历了一年多的时间就成为Apache基金会 ...

  • linux中执行cd之后直接ls列出所有文件

    以下command在cshell中生效 在.cshrc中加入下面的语句: alias cd 'cd \!* ; ll' 注意*后面的空格,以及ll之前的空格 进一步,可以同时打印出cd之后的path ...

  • 【地理干货】最全高中地理知识结构框架图,点击收藏!

    地理课是青少年学生认识地理环境.了解祖国最基础的课程,是与我们的生活最为贴近的学科之一,它的内容包罗万象,大至宇宙空间,小至一草一木,是青少年了解世界最直接的学科.对于高考生来说,地理更是一项难题,它 ...

  • Linux中的split命令,文件切割

    Linux中的文件,特别是日志文件,特别大了不好打开,可以用split命令来切割成小文件 split命令有两种方式: 1,指定行数来切割 split -l 300 log.txt newfile 每个 ...

  • LINUX中如何查看某个端口是否被占用

    之前查询端口是否被占用一直搞不明白,问了好多人,终于搞懂了,现在总结下: 1.netstat  -anp  |grep   端口号 如下,我以3306为例,netstat  -anp  |grep   ...

  • linux中find命令高级用法

    https://www.cnblogs.com/bianchengzhuji/p/10133821.html 在<Linux中的文件查找技巧>一文中,我们已经知道了文件查找的基本方法,今天 ...

  • 亲密关系中,建立框架的重要性

    首先,在挽回当中我们要树立属于自己的一个框架,很多人觉得啊,既然到了分手这一步,那么我去道歉,我去挽留,我去低位析求,对方可能会心软. 其实对方确实可能会心软,但是心软并不代表他愿意和你复合,所以说没 ...