目录
介绍
ethtool是Linux里查询或配置网络驱动和设备的重要工具。
使用概要:
ethtool ethx //查询ethx网口基本设置,其中 x 是对应网卡的编号,如eth0、eth1等等
ethtool –h //显示ethtool的命令帮助(help)
ethtool –i ethX //查询ethX网口的相关信息
ethtool –d ethX //查询ethX网口注册性信息
ethtool –r ethX //重置ethX网口到自适应模式
ethtool –S ethX //查询ethX网口收发包统计
ethtool –s ethX [speed 10|100|1000] [duplex half|full] [autoneg on|off] //设置网口速率10/100/1000M、设置网口半/全双工、设置网口是否自协商ethtool -E eth0 magic 0x10798086 offset 0x10 value 0x1A //修改网卡EEPROM内容(0x1079 网卡device id , 0x8086网卡verdor id )
ethtool -e eth0 //dump网卡EEPROM内容
ethtool在Linux里的帮助信息如下:
$ ethtool -h
ethtool version 5.10
Usage:
ethtool [ FLAGS ] DEVNAME Display standard information about device
ethtool [ FLAGS ] -s|--change DEVNAME Change generic options
[ speed %d ]
[ duplex half|full ]
[ port tp|aui|bnc|mii|fibre|da ]
[ mdix auto|on|off ]
[ autoneg on|off ]
[ advertise %x[/%x] | mode on|off ... [--] ]
[ phyad %d ]
[ xcvr internal|external ]
[ wol %d[/%d] | p|u|m|b|a|g|s|f|d... ]
[ sopass %x:%x:%x:%x:%x:%x ]
[ msglvl %d[/%d] | type on|off ... [--] ]
[ master-slave master-preferred|slave-preferred|master-force|slave-force ]
ethtool [ FLAGS ] -a|--show-pause DEVNAME Show pause options
ethtool [ FLAGS ] -A|--pause DEVNAME Set pause options
[ autoneg on|off ]
[ rx on|off ]
[ tx on|off ]
ethtool [ FLAGS ] -c|--show-coalesce DEVNAME Show coalesce options
ethtool [ FLAGS ] -C|--coalesce DEVNAME Set coalesce options
[adaptive-rx on|off]
[adaptive-tx on|off]
[rx-usecs N]
[rx-frames N]
[rx-usecs-irq N]
[rx-frames-irq N]
[tx-usecs N]
[tx-frames N]
[tx-usecs-irq N]
[tx-frames-irq N]
[stats-block-usecs N]
[pkt-rate-low N]
[rx-usecs-low N]
[rx-frames-low N]
[tx-usecs-low N]
[tx-frames-low N]
[pkt-rate-high N]
[rx-usecs-high N]
[rx-frames-high N]
[tx-usecs-high N]
[tx-frames-high N]
[sample-interval N]
ethtool [ FLAGS ] -g|--show-ring DEVNAME Query RX/TX ring parameters
ethtool [ FLAGS ] -G|--set-ring DEVNAME Set RX/TX ring parameters
[ rx N ]
[ rx-mini N ]
[ rx-jumbo N ]
[ tx N ]
ethtool [ FLAGS ] -k|--show-features|--show-offload DEVNAME Get state of protocol offload and other features
ethtool [ FLAGS ] -K|--features|--offload DEVNAME Set protocol offload and other features
FEATURE on|off ...
ethtool [ FLAGS ] -i|--driver DEVNAME Show driver information
ethtool [ FLAGS ] -d|--register-dump DEVNAME Do a register dump
[ raw on|off ]
[ file FILENAME ]
ethtool [ FLAGS ] -e|--eeprom-dump DEVNAME Do a EEPROM dump
[ raw on|off ]
[ offset N ]
[ length N ]
ethtool [ FLAGS ] -E|--change-eeprom DEVNAME Change bytes in device EEPROM
[ magic N ]
[ offset N ]
[ length N ]
[ value N ]
ethtool [ FLAGS ] -r|--negotiate DEVNAME Restart N-WAY negotiation
ethtool [ FLAGS ] -p|--identify DEVNAME Show visible port identification (e.g. blinking)
[ TIME-IN-SECONDS ]
ethtool [ FLAGS ] -t|--test DEVNAME Execute adapter self test
[ online | offline | external_lb ]
ethtool [ FLAGS ] -S|--statistics DEVNAME Show adapter statistics
ethtool [ FLAGS ] --phy-statistics DEVNAME Show phy statistics
ethtool [ FLAGS ] -n|-u|--show-nfc|--show-ntuple DEVNAME Show Rx network flow classification options or rules
[ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 [context %d] |
rule %d ]
ethtool [ FLAGS ] -N|-U|--config-nfc|--config-ntuple DEVNAME Configure Rx network flow classification options or rules
rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... [context %d] |
flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4|ip6|tcp6|udp6|ah6|esp6|sctp6
[ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]
[ dst %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]
[ proto %d [m %x] ]
[ src-ip IP-ADDRESS [m IP-ADDRESS] ]
[ dst-ip IP-ADDRESS [m IP-ADDRESS] ]
[ tos %d [m %x] ]
[ tclass %d [m %x] ]
[ l4proto %d [m %x] ]
[ src-port %d [m %x] ]
[ dst-port %d [m %x] ]
[ spi %d [m %x] ]
[ vlan-etype %x [m %x] ]
[ vlan %x [m %x] ]
[ user-def %x [m %x] ]
[ dst-mac %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]
[ action %d ] | [ vf %d queue %d ]
[ context %d ]
[ loc %d]] |
delete %d
ethtool [ FLAGS ] -T|--show-time-stamping DEVNAME Show time stamping capabilities
ethtool [ FLAGS ] -x|--show-rxfh-indir|--show-rxfh DEVNAME Show Rx flow hash indirection table and/or RSS hash key
[ context %d ]
ethtool [ FLAGS ] -X|--set-rxfh-indir|--rxfh DEVNAME Set Rx flow hash indirection table and/or RSS hash key
[ context %d|new ]
[ equal N | weight W0 W1 ... | default ]
[ hkey %x:%x:%x:%x:%x:.... ]
[ hfunc FUNC ]
[ delete ]
ethtool [ FLAGS ] -f|--flash DEVNAME Flash firmware image from the specified file to a region on the device
FILENAME [ REGION-NUMBER-TO-FLASH ]
ethtool [ FLAGS ] -P|--show-permaddr DEVNAME Show permanent hardware address
ethtool [ FLAGS ] -w|--get-dump DEVNAME Get dump flag, data
[ data FILENAME ]
ethtool [ FLAGS ] -W|--set-dump DEVNAME Set dump flag of the device
N
ethtool [ FLAGS ] -l|--show-channels DEVNAME Query Channels
ethtool [ FLAGS ] -L|--set-channels DEVNAME Set Channels
[ rx N ]
[ tx N ]
[ other N ]
[ combined N ]
ethtool [ FLAGS ] --show-priv-flags DEVNAME Query private flags
ethtool [ FLAGS ] --set-priv-flags DEVNAME Set private flags
FLAG on|off ...
ethtool [ FLAGS ] -m|--dump-module-eeprom|--module-info DEVNAME Query/Decode Module EEPROM information and optical diagnostics if available
[ raw on|off ]
[ hex on|off ]
[ offset N ]
[ length N ]
ethtool [ FLAGS ] --show-eee DEVNAME Show EEE settings
ethtool [ FLAGS ] --set-eee DEVNAME Set EEE settings
[ eee on|off ]
[ advertise %x ]
[ tx-lpi on|off ]
[ tx-timer %d ]
ethtool [ FLAGS ] --set-phy-tunable DEVNAME Set PHY tunable
[ downshift on|off [count N] ]
[ fast-link-down on|off [msecs N] ]
[ energy-detect-power-down on|off [msecs N] ]
ethtool [ FLAGS ] --get-phy-tunable DEVNAME Get PHY tunable
[ downshift ]
[ fast-link-down ]
[ energy-detect-power-down ]
ethtool [ FLAGS ] --get-tunable DEVNAME Get tunable
[ rx-copybreak ]
[ tx-copybreak ]
[ pfc-precention-tout ]
ethtool [ FLAGS ] --set-tunable DEVNAME Set tunable
[ rx-copybreak N]
[ tx-copybreak N]
[ pfc-precention-tout N]
ethtool [ FLAGS ] --reset DEVNAME Reset components
[ flags %x ]
[ mgmt ]
[ mgmt-shared ]
[ irq ]
[ irq-shared ]
[ dma ]
[ dma-shared ]
[ filter ]
[ filter-shared ]
[ offload ]
[ offload-shared ]
[ mac ]
[ mac-shared ]
[ phy ]
[ phy-shared ]
[ ram ]
[ ram-shared ]
[ ap ]
[ ap-shared ]
[ dedicated ]
[ all ]
ethtool [ FLAGS ] --show-fec DEVNAME Show FEC settings
ethtool [ FLAGS ] --set-fec DEVNAME Set FEC settings
[ encoding auto|off|rs|baser|llrs [...]]
ethtool [ FLAGS ] -Q|--per-queue DEVNAME Apply per-queue command.
The supported sub commands include --show-coalesce, --coalesce [queue_mask %x] SUB_COMMAND
ethtool [ FLAGS ] --cable-test DEVNAME Perform a cable test
ethtool [ FLAGS ] --cable-test-tdr DEVNAME Print cable test time domain reflectrometery data
[ first N ]
[ last N ]
[ step N ]
[ pair N ]
ethtool [ FLAGS ] --show-tunnels DEVNAME Show NIC tunnel offload information
ethtool [ FLAGS ] -h|--help Show this help
ethtool [ FLAGS ] --version Show version number
ethtool --monitor Show kernel notifications
( [ --all ]
| -s | --change
| -s | --change
| -s | --change
| -s | --change
| -k | --show-features | --show-offload | -K | --features | --offload
| --show-priv-flags | --set-priv-flags
| -g | --show-ring | -G | --set-ring
| -l | --show-channels | -L | --set-channels
| -c | --show-coalesce | -C | --coalesce
| -a | --show-pause | -A | --pause
| --show-eee | --set-eee
| --cable-test
| --cable-test-tdr )
[ DEVNAME | * ]
FLAGS:
--debug MASK turn on debugging messages
--json enable JSON output format (not supported by all commands)
-I|--include-statistics request device statistics related to the command (not supported by all commands)
ethtool在Linux的框架
用户空间和内核空间上下交互的流程如下:
Linux内核部分
Linux内核里struct net_device结构体成员ethtool_ops结构体如下:
struct ethtool_ops {
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
/* 通常使用 %get_link_ksettings/%set_link_ksettings API。获取多项设备设置,比如以太网Link设置。*/
int (*set_settings)(struct net_device *, struct ethtool_cmd *);
/* 通常使用 %get_link_ksettings/%set_link_ksettings API。设置多项设备设置,包括以太网Link设置。*/
void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
/* 报告驱动/设备信息。只能设置@driver, @version, @fw_version and @bus_info这些域。如果没有实现,@driver 和 @bus_info 域会根据netdev的父设备填充。 */
int (*get_regs_len)(struct net_device *);
/* 获取get_regs需要的字符串长度。 */
void (*get_regs)(struct net_device *, struct ethtool_regs *, void *);
/* 获取设备寄存器 */
void (*get_wol)(struct net_device *, struct ethtool_wolinfo *);
/* 报告是否Wake-on-Lan启用 */
int (*set_wol)(struct net_device *, struct ethtool_wolinfo *);
/* 关闭或开启Wake-on-Lan功能 */
u32 (*get_msglevel)(struct net_device *);
/* 报告驱动消息等级 */
void (*set_msglevel)(struct net_device *, u32);
/* 设置驱动消息等级 */
int (*nway_reset)(struct net_device *);
/* 重协商 */
u32 (*get_link)(struct net_device *);
/* 报告是否物理Link状态是UP的。*/
int (*get_eeprom_len)(struct net_device *);
/* 读取EEPROM有效地址范围 */
int (*get_eeprom)(struct net_device *,
struct ethtool_eeprom *, u8 *);
/* 从EEPROM设备中读取数据 */
int (*set_eeprom)(struct net_device *,
struct ethtool_eeprom *, u8 *);
/* 向EEPROM设备中写入数据 */
int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *);
/* 获取中断聚合参数 */
int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *);
/* 设置中断聚合参数 */
void (*get_ringparam)(struct net_device *,
struct ethtool_ringparam *);
/* 报告ring大小 */
int (*set_ringparam)(struct net_device *,
struct ethtool_ringparam *);
/* 设置ring大小 */
void (*get_pauseparam)(struct net_device *,
struct ethtool_pauseparam*);
/* 报告暂停参数 */
int (*set_pauseparam)(struct net_device *,
struct ethtool_pauseparam*);
/* 设置暂停参数 */
void (*self_test)(struct net_device *, struct ethtool_test *, u64 *);
/* 运行指定的自测试 */
void (*get_strings)(struct net_device *, u32 stringset, u8 *);
/* 返回字符串集合来描述请求的目标 */
int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state);
/* 标识物理设备 */
void (*get_ethtool_stats)(struct net_device *,
struct ethtool_stats *, u64 *);
/* 返回有关设备的扩展统计信息 */
int (*begin)(struct net_device *);
/* 所有其他操作之前被调用的函数 */
void (*complete)(struct net_device *);
/* 所有其他操作之后被调用的函数,除了begin */
u32 (*get_priv_flags)(struct net_device *);
/* 报告驱动特有的特性标记 */
int (*set_priv_flags)(struct net_device *, u32);
/* 设置驱动特有的特性标记 */
int (*get_sset_count)(struct net_device *, int);
/* 获取@get_strings会写入的字符串个数 */
int (*get_rxnfc)(struct net_device *,
struct ethtool_rxnfc *, u32 *rule_locs);
/* 获取RX流分类规则 */
int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
/* 设置RX流分类规则 */
int (*flash_device)(struct net_device *, struct ethtool_flash *);
/* 将固件镜像写入flash存储空间 */
int (*reset)(struct net_device *, u32 *);
/* 重置设备 */
u32 (*get_rxfh_indir_size)(struct net_device *);
/* 获取RX流摘要key的大小 */
int (*get_rxfh_indir)(struct net_device *, u32 *);
/**/
int (*set_rxfh_indir)(struct net_device *, const u32 *);
/**/
void (*get_channels)(struct net_device *, struct ethtool_channels *);
/**/
int (*set_channels)(struct net_device *, struct ethtool_channels *);
/**/
int (*get_dump_flag)(struct net_device *, struct ethtool_dump *);
/**/
int (*get_dump_data)(struct net_device *,
struct ethtool_dump *, void *);
/**/
int (*set_dump)(struct net_device *, struct ethtool_dump *);
/**/
int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
/**/
int (*get_module_info)(struct net_device *,
struct ethtool_modinfo *);
/* 获取可插拔模块内eeprom包含的大小和类型 */
int (*get_module_eeprom)(struct net_device *,
struct ethtool_eeprom *, u8 *);
/* 从可插拔模块内获取eeprom信息 */
int (*get_eee)(struct net_device *, struct ethtool_eee *);
/**/
int (*set_eee)(struct net_device *, struct ethtool_eee *);
/**/
/* RHEL SPECIFIC
*
* The following padding has been inserted before ABI freeze to
* allow extending the structure while preserve ABI. Feel free
* to replace reserved slots with required structure field
* additions of your backport.
*/
RH_KABI_USE_P(1, u32 (*get_rxfh_key_size)(struct net_device *))
RH_KABI_USE_P(2, int (*get_rxfh)(struct net_device *, u32 *indir,
u8 *key, u8 *hfunc))
RH_KABI_USE_P(3, int (*set_rxfh)(struct net_device *,
const u32 *indir, const u8 *key,
const u8 hfunc))
RH_KABI_USE_P(4, int (*get_tunable)(struct net_device *,
const struct ethtool_tunable *,
void *))
RH_KABI_USE_P(5, int (*set_tunable)(struct net_device *,
const struct ethtool_tunable *,
const void *))
RH_KABI_USE_P(6, int (*get_per_queue_coalesce)(struct net_device *,
u32,
struct ethtool_coalesce *))
RH_KABI_USE_P(7, int (*set_per_queue_coalesce)(struct net_device *,
u32,
struct ethtool_coalesce *))
RH_KABI_USE_P(8, int (*get_link_ksettings)(struct net_device *,
struct ethtool_link_ksettings *))
RH_KABI_USE_P(9, int (*set_link_ksettings)(struct net_device *,
const struct ethtool_link_ksettings *))
RH_KABI_USE_P(10,int (*get_fecparam)(struct net_device *,
struct ethtool_fecparam *))
RH_KABI_USE_P(11,int (*set_fecparam)(struct net_device *,
struct ethtool_fecparam *))
RH_KABI_USE_P(12,int (*get_rxfh_context)(struct net_device *, u32 *indir, u8 *key,
u8 *hfunc, u32 rss_context))
RH_KABI_USE_P(13,int (*set_rxfh_context)(struct net_device *, const u32 *indir,
const u8 *key, const u8 hfunc,
u32 *rss_context, bool delete))
RH_KABI_RESERVE_P(14)
RH_KABI_RESERVE_P(15)
RH_KABI_RESERVE_P(16)
};
/* include/linux/ethtool.h */
以Intel网卡驱动igb举例,在pci probe函数里调用igb_set_ethtool_ops(netdev),给ethtool_ops结构体里的成员函数赋值。
1. module_init(igb_init_module);
2. ret = pci_register_driver(&igb_driver);
3. static int igb_probe(struct pci_dev *, const struct pci_device_id *)
{
......
igb_set_ethtool_ops(netdev);
......
}
/* linux-3.10.0-957.el7/drivers/net/ethernet/intel/igb/igb_main.c */
static int igb_get_module_eeprom(struct net_device *netdev,
struct ethtool_eeprom *ee, u8 *data)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
u32 status = 0;
u16 *dataword;
u16 first_word, last_word;
int i = 0;
if (ee->len == 0)
return -EINVAL;
first_word = ee->offset >> 1;
last_word = (ee->offset + ee->len - 1) >> 1;
dataword = kmalloc(sizeof(u16) * (last_word - first_word + 1),
GFP_KERNEL);
if (!dataword)
return -ENOMEM;
/* Read EEPROM block, SFF-8079/SFF-8472, word at a time */
for (i = 0; i < last_word - first_word + 1; i++) {
status = igb_read_phy_reg_i2c(hw, (first_word + i) * 2,
&dataword[i]);
if (status) {
/* Error occurred while reading module */
kfree(dataword);
return -EIO;
}
be16_to_cpus(&dataword[i]);
}
memcpy(data, (u8 *)dataword + (ee->offset & 1), ee->len);
kfree(dataword);
return 0;
}
static const struct ethtool_ops igb_ethtool_ops = {
.get_drvinfo = igb_get_drvinfo,
.get_regs_len = igb_get_regs_len,
.get_regs = igb_get_regs,
.get_wol = igb_get_wol,
.set_wol = igb_set_wol,
.get_msglevel = igb_get_msglevel,
.set_msglevel = igb_set_msglevel,
.nway_reset = igb_nway_reset,
.get_link = igb_get_link,
.get_eeprom_len = igb_get_eeprom_len,
.get_eeprom = igb_get_eeprom,
.set_eeprom = igb_set_eeprom,
.get_ringparam = igb_get_ringparam,
.set_ringparam = igb_set_ringparam,
.get_pauseparam = igb_get_pauseparam,
.set_pauseparam = igb_set_pauseparam,
.self_test = igb_diag_test,
.get_strings = igb_get_strings,
.set_phys_id = igb_set_phys_id,
.get_sset_count = igb_get_sset_count,
.get_ethtool_stats = igb_get_ethtool_stats,
.get_coalesce = igb_get_coalesce,
.set_coalesce = igb_set_coalesce,
.get_ts_info = igb_get_ts_info,
.get_rxnfc = igb_get_rxnfc,
.set_rxnfc = igb_set_rxnfc,
.get_eee = igb_get_eee,
.set_eee = igb_set_eee,
.get_module_info = igb_get_module_info,
.get_module_eeprom = igb_get_module_eeprom,
.get_rxfh_indir_size = igb_get_rxfh_indir_size,
.get_rxfh = igb_get_rxfh,
.set_rxfh = igb_set_rxfh,
.get_channels = igb_get_channels,
.set_channels = igb_set_channels,
.get_priv_flags = igb_get_priv_flags,
.set_priv_flags = igb_set_priv_flags,
.begin = igb_ethtool_begin,
.complete = igb_ethtool_complete,
.get_link_ksettings = igb_get_link_ksettings,
.set_link_ksettings = igb_set_link_ksettings,
};
void igb_set_ethtool_ops(struct net_device *netdev)
{
netdev->ethtool_ops = &igb_ethtool_ops;
}
/* linux-3.10.0-957.el7/drivers/net/ethernet/intel/igb/igb_ethtool.c */
ethtool应用程序
#ifndef TEST_ETHTOOL
int send_ioctl(struct cmd_context *ctx, void *cmd)
{
ctx->ifr.ifr_data = cmd;
return ioctl(ctx->fd, SIOCETHTOOL, &ctx->ifr);
}
#endif
static int do_getmodule(struct cmd_context *ctx)
{
struct ethtool_modinfo modinfo;
struct ethtool_eeprom *eeprom;
u32 geeprom_offset = 0;
u32 geeprom_length = -1;
int geeprom_changed = 0;
int geeprom_dump_raw = 0;
int geeprom_dump_hex = 0;
int err;
struct cmdline_info cmdline_geeprom[] = {
{ "offset", CMDL_U32, &geeprom_offset, NULL },
{ "length", CMDL_U32, &geeprom_length, NULL },
{ "raw", CMDL_BOOL, &geeprom_dump_raw, NULL },
{ "hex", CMDL_BOOL, &geeprom_dump_hex, NULL },
};
parse_generic_cmdline(ctx, &geeprom_changed,
cmdline_geeprom, ARRAY_SIZE(cmdline_geeprom));
if (geeprom_dump_raw && geeprom_dump_hex) {
printf("Hex and raw dump cannot be specified together\n");
return 1;
}
modinfo.cmd = ETHTOOL_GMODULEINFO;
err = send_ioctl(ctx, &modinfo);
if (err < 0) {
perror("Cannot get module EEPROM information");
return 1;
}
if (geeprom_length == -1)
geeprom_length = modinfo.eeprom_len;
if (modinfo.eeprom_len < geeprom_offset + geeprom_length)
geeprom_length = modinfo.eeprom_len - geeprom_offset;
eeprom = calloc(1, sizeof(*eeprom)+geeprom_length);
if (!eeprom) {
perror("Cannot allocate memory for Module EEPROM data");
return 1;
}
eeprom->cmd = ETHTOOL_GMODULEEEPROM;
eeprom->len = geeprom_length;
eeprom->offset = geeprom_offset;
err = send_ioctl(ctx, eeprom);
if (err < 0) {
perror("Cannot get Module EEPROM data");
free(eeprom);
return 1;
}
/*
* SFF-8079 EEPROM layout contains the memory available at A0 address on
* the PHY EEPROM.
* SFF-8472 defines a virtual extension of the EEPROM, where the
* microcontroller on the SFP/SFP+ generates a page at the A2 address,
* which contains data relative to optical diagnostics.
* The current kernel implementation returns a blob, which contains:
* - ETH_MODULE_SFF_8079 => The A0 page only.
* - ETH_MODULE_SFF_8472 => The A0 and A2 page concatenated.
*/
if (geeprom_dump_raw) {
fwrite(eeprom->data, 1, eeprom->len, stdout);
} else {
if (eeprom->offset != 0 ||
(eeprom->len != modinfo.eeprom_len)) {
geeprom_dump_hex = 1;
} else if (!geeprom_dump_hex) {
switch (modinfo.type) {
#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
case ETH_MODULE_SFF_8079:
sff8079_show_all(eeprom->data);
break;
case ETH_MODULE_SFF_8472:
sff8079_show_all(eeprom->data);
sff8472_show_all(eeprom->data);
break;
#endif
default:
geeprom_dump_hex = 1;
break;
}
}
if (geeprom_dump_hex)
dump_hex(stdout, eeprom->data,
eeprom->len, eeprom->offset);
}
free(eeprom);
return 0;
}
static const struct option {
const char *opts;
int want_device;
int (*func)(struct cmd_context *);
char *help;
char *opthelp;
} args[] = {
{ "-i|--driver", 1, do_gdrv, "Show driver information" },
{ "-m|--dump-module-eeprom|--module-info", 1, do_getmodule,
"Query/Decode Module EEPROM information and optical diagnostics if available",
" [ raw on|off ]\n"
" [ hex on|off ]\n"
" [ offset N ]\n"
" [ length N ]\n" },
{}
};
/* ethtool.c */
ethtool应用程序在获取可插拔模块eeprom信息的时候,根据命令行-m参数,调用do_getmodule函数,在具体代码实现过程描述为,通过ioclt socket套接字下发获取命令,得到eeprom->data后通过sff8079_show_all(eeprom->data);和sff8472_show_all(eeprom->data);把EEPROM信息打印出来。