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

在本文的前面部分介绍过 MDC/MDIO 的工作流程,网卡驱动程序中的 MDIO 读写函数 mdio_read 和 mdio_write���也就是清单 3 中的函数指针的具体实现是在各个网卡的驱动程序文件中完成的,都遵从 IEEE802.3 MDIO 的帧格式。典型的帧格式是第 22 条款中定义的格式:

图 5.IEEE802.3 条款 22 定义的 MDIO 帧格式

域长度(bit)说明
ST   2bits   01b  
OP   2bits   操作码,写为 01b,读为 10b  
PHYADR   5bits   PHY ID  
REGADR   5bits   寄存器地址  
TA   2 bits   状态转换域,读操作为 X0b, 写操作为 10b  
DATA   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_ops

struct net_device { ... const struct ethtool_ops *ethtool_ops; ... }

网卡驱动程序需要初始化 ethtool_ops 并且实现其定义的函数功能,从而实现对 ethtool 的支持,以 Dm9000.c 为例。

清单 3,kernel/drivers/net/Dm9000.c,DM9000 驱动程序对 ethtool 的支持

static 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_link

static 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); else ret = dm9000_read_locked(dm, DM9000_NSR) & NSR_LINKST ? 1 : 0; return ret; } kernel/drivers/net/Mii.c int 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 更新和修改日志级别

ethtool -f|--flash DEVNAME FILENAME ethtool -s|--change DEVNAME msglvl %d

使用 ethtool 配置和管理网卡

上一节主要介绍了 ethtool 实现的基础和方法,本节将主要介绍 ethtool 的一些用法,主要集中在 ethtool 在配置和管理网卡方面的用法。

了解 ethtool 用法最好的方法是查看 ethtool 的帮助信息“ethtool -h” 或者 “man ethtool”,由于帮助信息很多,这里就不一一列出了,将会举例一些实际的应用例子代替。

实例 1,利用 ethtool 来查看网卡接口 eth4 的信息

清单 6,查看网卡的接口信息

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/15830.html