1. bcmgenet_ethtool_ops 分析
static const struct ethtool_ops bcmgenet_ethtool_ops = {.begin = bcmgenet_begin,.complete = bcmgenet_complete,.get_strings = bcmgenet_get_strings,.get_sset_count = bcmgenet_get_sset_count,.get_ethtool_stats = bcmgenet_get_ethtool_stats,.get_drvinfo = bcmgenet_get_drvinfo,.get_link = ethtool_op_get_link,.get_msglevel = bcmgenet_get_msglevel,.set_msglevel = bcmgenet_set_msglevel,.get_wol = bcmgenet_get_wol,.set_wol = bcmgenet_set_wol,.get_eee = bcmgenet_get_eee,.set_eee = bcmgenet_set_eee,.nway_reset = phy_ethtool_nway_reset,.get_coalesce = bcmgenet_get_coalesce,.set_coalesce = bcmgenet_set_coalesce,.get_link_ksettings = bcmgenet_get_link_ksettings,.set_link_ksettings = bcmgenet_set_link_ksettings,
};
2.核心转换层
net/core/ethtool.c
int dev_ethtool(struct net *net, struct ifreq *ifr)
int dev_ethtool(struct net *net, struct ifreq *ifr)
{struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);void __user *useraddr = ifr->ifr_data;u32 ethcmd, sub_cmd;switch (ethcmd) {.....case ETHTOOL_GEEE:rc = ethtool_get_eee(dev, useraddr);break;....}if (dev->ethtool_ops->complete)dev->ethtool_ops->complete(dev);if (old_features != dev->features)netdev_features_change(dev);return rc;
}
3. ethtool源码=>确定cmd
static int do_geee(struct cmd_context *ctx)
{struct ethtool_eee eeecmd;if (ctx->argc != 0)exit_bad_args();eeecmd.cmd = ETHTOOL_GEEE;if (send_ioctl(ctx, &eeecmd)) {perror("Cannot get EEE settings");return 1;}fprintf(stdout, "EEE Settings for %s:\n", ctx->devname);dump_eeecmd(&eeecmd);return 0;
}
static const struct option {const char *opts;int want_device;int (*func)(struct cmd_context *);char *help;char *opthelp;
} args[] = {...{ "--show-eee", 1, do_geee, "Show EEE settings"},}
4. ethtool调用分析实战
root@raspberrypi:/home/niyu# ethtool --show-eee eth0
EEE Settings for eth0:
EEE status: disabled
Tx LPI: disabled
Supported EEE link modes: 100baseT/Full
1000baseT/Full
Advertised EEE link modes: 100baseT/Full
1000baseT/Full
Link partner advertised EEE link modes: Not reported
root@raspberrypi:/home/niyu# dmesg
[ 2379.731178] bcmgenet fd580000.genet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
[ 2395.556547] CPU: 0 PID: 812 Comm: ethtool Not tainted 4.19.127-v8+ #38
[ 2395.556561] Hardware name: Raspberry Pi 4 Model B Rev 1.5 (DT)
[ 2395.556569] Call trace:
[ 2395.556590] dump_backtrace+0x0/0x178
[ 2395.556600] show_stack+0x28/0x34
[ 2395.556612] __dump_stack+0x20/0x28
[ 2395.556621] dump_stack+0x88/0xc4
[ 2395.556646] bcmgenet_get_eee+0x24/0x88 [genet] //结束
[ 2395.556657] ethtool_get_eee+0x5c/0xe8
[ 2395.556666] dev_ethtool+0x2a8/0x75c
[ 2395.556675] dev_ioctl+0xf8/0x288 //开始
[ 2395.556686] sock_do_ioctl+0xf8/0x284
[ 2395.556696] sock_ioctl+0x320/0x484
[ 2395.556708] vfs_ioctl+0x44/0x74
[ 2395.556717] do_vfs_ioctl+0x2d0/0x304
[ 2395.556726] ksys_ioctl+0x54/0x88
[ 2395.556735] __se_sys_ioctl+0x38/0x4c
[ 2395.556744] __arm64_sys_ioctl+0x2c/0x38
[ 2395.556753] __invoke_syscall+0x28/0x34
[ 2395.556761] invoke_syscall+0x58/0x7c
[ 2395.556769] el0_svc_common+0x74/0xec
[ 2395.556777] el0_svc_handler+0x70/0x94
[ 2395.556786] el0_svc+0x8/0xc
5 补充
struct cmd_context {const char *devname; /* net device name */int fd; /* socket suitable for ethtool ioctl */struct ifreq ifr; /* ifreq suitable for ethtool ioctl */int argc; /* number of arguments to the sub-command */char **argp; /* arguments to the sub-command */
};struct ifreq{
# define IFHWADDRLEN 6
# define IFNAMSIZ IF_NAMESIZEunion{char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */} ifr_ifrn;union{struct sockaddr ifru_addr;struct sockaddr ifru_dstaddr;struct sockaddr ifru_broadaddr;struct sockaddr ifru_netmask;struct sockaddr ifru_hwaddr;short int ifru_flags;int ifru_ivalue;int ifru_mtu;struct ifmap ifru_map;char ifru_slave[IFNAMSIZ]; char ifru_newname[IFNAMSIZ];__caddr_t ifru_data; //填充cmd} ifr_ifru;};