ethtool 调用流程

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_NAMESIZE
    union
      {
    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;
  };


 

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐分享-程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值