• 【无标题】ethtool程序,从用户态调用内核态调用分析


    1. 说明

    • 用户层ethtool使用的是: ethtool-6.5 为例,下载来自:
      https://mirrors.edge.kernel.org/pub/software/network/ethtool/

    • 内核层:在内核源码中,VSCode -->【ctrl+p】搜索文件:linux/ethtool.h及 core/ethtool.c,相关实现在这两个文件中。

    2. 应用层 ethtool-6.5

    • ethtool.c
      下面的 args 结构体展示了成员的选项(.opts)、执行函数(.func)、netlink执行函数(.nlfunc,暂时不必关心)、帮助(.xhelp)。
      通过他们,能看出ethtool命令行后面跟什么选项时,调用了什么函数!
    // 
    static const struct option args[] = {
    	{
    		/* "default" entry when no switch is used */
    		.opts	= "",
    		.func	= do_gset,
    		.nlfunc	= nl_gset,
    		.help	= "Display standard information about device",
    	},
    	{
    		.opts	= "-s|--change",
    		.func	= do_sset,
    		.nlfunc	= nl_sset,
    		.help	= "Change generic options",
    		.xhelp	= "		[ speed %d ]\n"
    			  "		[ lanes %d ]\n"
    			  "		[ duplex half|full ]\n"
    			  "		[ port tp|aui|bnc|mii|fibre|da ]\n"
    			  "		[ mdix auto|on|off ]\n"
    			  "		[ autoneg on|off ]\n"
    			  "		[ advertise %x[/%x] | mode on|off ... [--] ]\n"
    			  "		[ phyad %d ]\n"
    			  "		[ xcvr internal|external ]\n"
    			  "		[ wol %d[/%d] | p|u|m|b|a|g|s|f|d... ]\n"
    			  "		[ sopass %x:%x:%x:%x:%x:%x ]\n"
    			  "		[ msglvl %d[/%d] | type on|off ... [--] ]\n"
    			  "		[ master-slave preferred-master|preferred-slave|forced-master|forced-slave ]\n"
    	},
    	{
    		.opts	= "-a|--show-pause",
    		.json	= true,
    		.func	= do_gpause,
    		.nlfunc	= nl_gpause,
    		.help	= "Show pause options",
    		.xhelp	= "		[ --src aggregate | emac | pmac ]\n"
    	},
    	{
    		.opts	= "-A|--pause",
    		.func	= do_spause,
    		.nlfunc	= nl_spause,
    		.help	= "Set pause options",
    		.xhelp	= "		[ autoneg on|off ]\n"
    			  "		[ rx on|off ]\n"
    			  "		[ tx on|off ]\n"
    	},
    	{
    		.opts	= "-c|--show-coalesce",
    		.json	= true,
    		.func	= do_gcoalesce,
    		.nlfunc	= nl_gcoalesce,
    		.help	= "Show coalesce options"
    	},
    	{
    		.opts	= "-C|--coalesce",
    		.func	= do_scoalesce,
    		.nlfunc	= nl_scoalesce,
    		.help	= "Set coalesce options",
    		.xhelp	= "		[adaptive-rx on|off]\n"
    			  "		[adaptive-tx on|off]\n"
    			  "		[rx-usecs N]\n"
    			  "		[rx-frames N]\n"
    			  "		[rx-usecs-irq N]\n"
    			  "		[rx-frames-irq N]\n"
    			  "		[tx-usecs N]\n"
    			  "		[tx-frames N]\n"
    			  "		[tx-usecs-irq N]\n"
    			  "		[tx-frames-irq N]\n"
    			  "		[stats-block-usecs N]\n"
    			  "		[pkt-rate-low N]\n"
    			  "		[rx-usecs-low N]\n"
    			  "		[rx-frames-low N]\n"
    			  "		[tx-usecs-low N]\n"
    			  "		[tx-frames-low N]\n"
    			  "		[pkt-rate-high N]\n"
    			  "		[rx-usecs-high N]\n"
    			  "		[rx-frames-high N]\n"
    			  "		[tx-usecs-high N]\n"
    			  "		[tx-frames-high N]\n"
    			  "		[sample-interval N]\n"
    			  "		[cqe-mode-rx on|off]\n"
    			  "		[cqe-mode-tx on|off]\n"
    			  "		[tx-aggr-max-bytes N]\n"
    			  "		[tx-aggr-max-frames N]\n"
    			  "		[tx-aggr-time-usecs N]\n"
    	},
    	{
    		.opts	= "-g|--show-ring",
    		.json	= true,
    		.func	= do_gring,
    		.nlfunc	= nl_gring,
    		.help	= "Query RX/TX ring parameters"
    	},
    	{
    		.opts	= "-G|--set-ring",
    		.func	= do_sring,
    		.nlfunc	= nl_sring,
    		.help	= "Set RX/TX ring parameters",
    		.xhelp	= "		[ rx N ]\n"
    			  "		[ rx-mini N ]\n"
    			  "		[ rx-jumbo N ]\n"
    			  "		[ tx N ]\n"
    			  "		[ rx-buf-len N ]\n"
    			  "		[ cqe-size N ]\n"
    			  "		[ tx-push on|off ]\n"
    			  "		[ rx-push on|off ]\n"
    			  "		[ tx-push-buf-len N]\n"
    	},
    	{
    		.opts	= "-k|--show-features|--show-offload",
    		.json	= true,
    		.func	= do_gfeatures,
    		.nlfunc	= nl_gfeatures,
    		.help	= "Get state of protocol offload and other features"
    	},
    	{
    		.opts	= "-K|--features|--offload",
    		.func	= do_sfeatures,
    		.nlfunc	= nl_sfeatures,
    		.help	= "Set protocol offload and other features",
    		.xhelp	= "		FEATURE on|off ...\n"
    	},
    	{
    		.opts	= "-i|--driver",
    		.func	= do_gdrv,
    		.help	= "Show driver information"
    	},
    	{
    		.opts	= "-d|--register-dump",
    		.func	= do_gregs,
    		.help	= "Do a register dump",
    		.xhelp	= "		[ raw on|off ]\n"
    			  "		[ file FILENAME ]\n"
    	},
    	{
    		.opts	= "-e|--eeprom-dump",
    		.func	= do_geeprom,
    		.help	= "Do a EEPROM dump",
    		.xhelp	= "		[ raw on|off ]\n"
    			  "		[ offset N ]\n"
    			  "		[ length N ]\n"
    	},
    	{
    		.opts	= "-E|--change-eeprom",
    		.func	= do_seeprom,
    		.help	= "Change bytes in device EEPROM",
    		.xhelp	= "		[ magic N ]\n"
    			  "		[ offset N ]\n"
    			  "		[ length N ]\n"
    			  "		[ value N ]\n"
    	},
    	{
    		.opts	= "-r|--negotiate",
    		.func	= do_nway_rst,
    		.help	= "Restart N-WAY negotiation"
    	},
    	{
    		.opts	= "-p|--identify",
    		.func	= do_phys_id,
    		.help	= "Show visible port identification (e.g. blinking)",
    		.xhelp	= "		[ TIME-IN-SECONDS ]\n"
    	},
    	{
    		.opts	= "-t|--test",
    		.func	= do_test,
    		.help	= "Execute adapter self test",
    		.xhelp	= "		[ online | offline | external_lb ]\n"
    	},
    	{
    		.opts	= "-S|--statistics",
    		.json	= true,
    		.func	= do_gnicstats,
    		.nlchk	= nl_gstats_chk,
    		.nlfunc	= nl_gstats,
    		.help	= "Show adapter statistics",
    		.xhelp	= "		[ --all-groups | --groups [eth-phy] [eth-mac] [eth-ctrl] [rmon] ]\n"
    			  "		[ --src aggregate | emac | pmac ]\n"
    	},
    	{
    		.opts	= "--phy-statistics",
    		.func	= do_gphystats,
    		.help	= "Show phy statistics"
    	},
    	{
    		.opts	= "-n|-u|--show-nfc|--show-ntuple",
    		.func	= do_grxclass,
    		.help	= "Show Rx network flow classification options or rules",
    		.xhelp	= "		[ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
    			  "tcp6|udp6|ah6|esp6|sctp6 [context %d] |\n"
    			  "		  rule %d ]\n"
    	},
    	{
    		.opts	= "-N|-U|--config-nfc|--config-ntuple",
    		.func	= do_srxclass,
    		.help	= "Configure Rx network flow classification options or rules",
    		.xhelp	= "		rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
    			  "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... [context %d] |\n"
    			  "		flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4|"
    			  "ip6|tcp6|udp6|ah6|esp6|sctp6\n"
    			  "			[ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
    			  "			[ dst %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
    			  "			[ proto %d [m %x] ]\n"
    			  "			[ src-ip IP-ADDRESS [m IP-ADDRESS] ]\n"
    			  "			[ dst-ip IP-ADDRESS [m IP-ADDRESS] ]\n"
    			  "			[ tos %d [m %x] ]\n"
    			  "			[ tclass %d [m %x] ]\n"
    			  "			[ l4proto %d [m %x] ]\n"
    			  "			[ src-port %d [m %x] ]\n"
    			  "			[ dst-port %d [m %x] ]\n"
    			  "			[ spi %d [m %x] ]\n"
    			  "			[ vlan-etype %x [m %x] ]\n"
    			  "			[ vlan %x [m %x] ]\n"
    			  "			[ user-def %x [m %x] ]\n"
    			  "			[ dst-mac %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
    			  "			[ action %d ] | [ vf %d queue %d ]\n"
    			  "			[ context %d ]\n"
    			  "			[ loc %d ] |\n"
    			  "		delete %d\n"
    	},
    	{
    		.opts	= "-T|--show-time-stamping",
    		.func	= do_tsinfo,
    		.nlfunc	= nl_tsinfo,
    		.help	= "Show time stamping capabilities"
    	},
    	{
    		.opts	= "-x|--show-rxfh-indir|--show-rxfh",
    		.json	= true,
    		.func	= do_grxfh,
    		.nlfunc	= nl_grss,
    		.help	= "Show Rx flow hash indirection table and/or RSS hash key",
    		.xhelp	= "		[ context %d ]\n"
    	},
    	{
    		.opts	= "-X|--set-rxfh-indir|--rxfh",
    		.func	= do_srxfh,
    		.help	= "Set Rx flow hash indirection table and/or RSS hash key",
    		.xhelp	= "		[ context %d|new ]\n"
    			  "		[ equal N | weight W0 W1 ... | default ]\n"
    			  "		[ hkey %x:%x:%x:%x:%x:.... ]\n"
    			  "		[ hfunc FUNC ]\n"
    			  "		[ delete ]\n"
    	},
    	{
    		.opts	= "-f|--flash",
    		.func	= do_flash,
    		.help	= "Flash firmware image from the specified file to a region on the device",
    		.xhelp	= "		FILENAME [ REGION-NUMBER-TO-FLASH ]\n"
    	},
    	{
    		.opts	= "-P|--show-permaddr",
    		.func	= do_permaddr,
    		.nlfunc	= nl_permaddr,
    		.help	= "Show permanent hardware address"
    	},
    	{
    		.opts	= "-w|--get-dump",
    		.func	= do_getfwdump,
    		.help	= "Get dump flag, data",
    		.xhelp	= "		[ data FILENAME ]\n"
    	},
    	{
    		.opts	= "-W|--set-dump",
    		.func	= do_setfwdump,
    		.help	= "Set dump flag of the device",
    		.xhelp	= "		N\n"
    	},
    	{
    		.opts	= "-l|--show-channels",
    		.func	= do_gchannels,
    		.nlfunc	= nl_gchannels,
    		.help	= "Query Channels"
    	},
    	{
    		.opts	= "-L|--set-channels",
    		.func	= do_schannels,
    		.nlfunc	= nl_schannels,
    		.help	= "Set Channels",
    		.xhelp	= "		[ rx N ]\n"
    			  "		[ tx N ]\n"
    			  "		[ other N ]\n"
    			  "		[ combined N ]\n"
    	},
    	{
    		.opts	= "--show-priv-flags",
    		.func	= do_gprivflags,
    		.nlfunc	= nl_gprivflags,
    		.help	= "Query private flags"
    	},
    	{
    		.opts	= "--set-priv-flags",
    		.func	= do_sprivflags,
    		.nlfunc	= nl_sprivflags,
    		.help	= "Set private flags",
    		.xhelp	= "		FLAG on|off ...\n"
    	},
    	{
    		.opts	= "-m|--dump-module-eeprom|--module-info",
    		.func	= do_getmodule,
    		.nlfunc = nl_getmodule,
    		.help	= "Query/Decode Module EEPROM information and optical diagnostics if available",
    		.xhelp	= "		[ raw on|off ]\n"
    			  "		[ hex on|off ]\n"
    			  "		[ offset N ]\n"
    			  "		[ length N ]\n"
    			  "		[ page N ]\n"
    			  "		[ bank N ]\n"
    			  "		[ i2c N ]\n"
    	},
    	{
    		.opts	= "--show-eee",
    		.func	= do_geee,
    		.nlfunc	= nl_geee,
    		.help	= "Show EEE settings",
    	},
    	{
    		.opts	= "--set-eee",
    		.func	= do_seee,
    		.nlfunc	= nl_seee,
    		.help	= "Set EEE settings",
    		.xhelp	= "		[ eee on|off ]\n"
    			  "		[ advertise %x ]\n"
    			  "		[ tx-lpi on|off ]\n"
    			  "		[ tx-timer %d ]\n"
    	},
    	{
    		.opts	= "--set-phy-tunable",
    		.func	= do_set_phy_tunable,
    		.help	= "Set PHY tunable",
    		.xhelp	= "		[ downshift on|off [count N] ]\n"
    			  "		[ fast-link-down on|off [msecs N] ]\n"
    			  "		[ energy-detect-power-down on|off [msecs N] ]\n"
    	},
    	{
    		.opts	= "--get-phy-tunable",
    		.func	= do_get_phy_tunable,
    		.help	= "Get PHY tunable",
    		.xhelp	= "		[ downshift ]\n"
    			  "		[ fast-link-down ]\n"
    			  "		[ energy-detect-power-down ]\n"
    	},
    	{
    		.opts	= "--get-tunable",
    		.func	= do_gtunable,
    		.help	= "Get tunable",
    		.xhelp	= "		[ rx-copybreak ]\n"
    			  "		[ tx-copybreak ]\n"
    			  "		[ tx-buf-size ]\n"
    			  "		[ pfc-prevention-tout ]\n"
    	},
    	{
    		.opts	= "--set-tunable",
    		.func	= do_stunable,
    		.help	= "Set tunable",
    		.xhelp	= "		[ rx-copybreak N ]\n"
    			  "		[ tx-copybreak N ]\n"
    			  "		[ tx-buf-size N ]\n"
    			  "		[ pfc-prevention-tout N ]\n"
    	},
    	{
    		.opts	= "--reset",
    		.func	= do_reset,
    		.help	= "Reset components",
    		.xhelp	= "		[ flags %x ]\n"
    			  "		[ mgmt ]\n"
    			  "		[ mgmt-shared ]\n"
    			  "		[ irq ]\n"
    			  "		[ irq-shared ]\n"
    			  "		[ dma ]\n"
    			  "		[ dma-shared ]\n"
    			  "		[ filter ]\n"
    			  "		[ filter-shared ]\n"
    			  "		[ offload ]\n"
    			  "		[ offload-shared ]\n"
    			  "		[ mac ]\n"
    			  "		[ mac-shared ]\n"
    			  "		[ phy ]\n"
    			  "		[ phy-shared ]\n"
    			  "		[ ram ]\n"
    			  "		[ ram-shared ]\n"
    			  "		[ ap ]\n"
    			  "		[ ap-shared ]\n"
    			  "		[ dedicated ]\n"
    			  "		[ all ]\n"
    	},
    	{
    		.opts	= "--show-fec",
    		.json	= true,
    		.func	= do_gfec,
    		.nlfunc	= nl_gfec,
    		.help	= "Show FEC settings",
    	},
    	{
    		.opts	= "--set-fec",
    		.func	= do_sfec,
    		.nlfunc	= nl_sfec,
    		.help	= "Set FEC settings",
    		.xhelp	= "		[ encoding auto|off|rs|baser|llrs [...] ]\n"
    	},
    	{
    		.opts	= "-Q|--per-queue",
    		.func	= do_perqueue,
    		.help	= "Apply per-queue command. ",
    		.xhelp	= "The supported sub commands include --show-coalesce, --coalesce"
    			  "		[queue_mask %x] SUB_COMMAND\n",
    	},
    	{
    		.opts	= "--cable-test",
    		.json	= true,
    		.nlfunc	= nl_cable_test,
    		.help	= "Perform a cable test",
    	},
    	{
    		.opts	= "--cable-test-tdr",
    		.json	= true,
    		.nlfunc	= nl_cable_test_tdr,
    		.help	= "Print cable test time domain reflectrometery data",
    		.xhelp	= "		[ first N ]\n"
    			  "		[ last N ]\n"
    			  "		[ step N ]\n"
    			  "		[ pair N ]\n"
    	},
    	{
    		.opts	= "--show-tunnels",
    		.nlfunc	= nl_gtunnels,
    		.help	= "Show NIC tunnel offload information",
    	},
    	{
    		.opts	= "--show-module",
    		.json	= true,
    		.nlfunc	= nl_gmodule,
    		.help	= "Show transceiver module settings",
    	},
    	{
    		.opts	= "--set-module",
    		.nlfunc	= nl_smodule,
    		.help	= "Set transceiver module settings",
    		.xhelp	= "		[ power-mode-policy high|auto ]\n"
    	},
    	{
    		.opts	= "--get-plca-cfg",
    		.nlfunc	= nl_plca_get_cfg,
    		.help	= "Get PLCA configuration",
    	},
    	{
    		.opts	= "--set-plca-cfg",
    		.nlfunc	= nl_plca_set_cfg,
    		.help	= "Set PLCA configuration",
    		.xhelp  = "		[ enable on|off ]\n"
    			  "		[ node-id N ]\n"
    			  "		[ node-cnt N ]\n"
    			  "		[ to-tmr N ]\n"
    			  "		[ burst-cnt N ]\n"
    			  "		[ burst-tmr N ]\n"
    	},
    	{
    		.opts	= "--get-plca-status",
    		.nlfunc	= nl_plca_get_status,
    		.help	= "Get PLCA status information",
    	},
    	{
    		.opts	= "--show-mm",
    		.json	= true,
    		.nlfunc	= nl_get_mm,
    		.help	= "Show MAC merge layer state",
    	},
    	{
    		.opts	= "--set-mm",
    		.nlfunc	= nl_set_mm,
    		.help	= "Set MAC merge layer parameters",
    			  "		[ verify-enabled on|off ]\n"
    			  "		[ verify-time N ]\n"
    			  "		[ tx-enabled on|off ]\n"
    			  "		[ pmac-enabled on|off ]\n"
    			  "		[ tx-min-frag-size 60-252 ]\n"
    	},
    	{
    		.opts	= "--show-pse",
    		.json	= true,
    		.nlfunc	= nl_gpse,
    		.help	= "Show settings for Power Sourcing Equipment",
    	},
    	{
    		.opts	= "--set-pse",
    		.nlfunc	= nl_spse,
    		.help	= "Set Power Sourcing Equipment settings",
    		.xhelp	= "		[ podl-pse-admin-control enable|disable ]\n"
    	},
    	{
    		.opts	= "-h|--help",
    		.no_dev	= true,
    		.func	= show_usage,
    		.help	= "Show this help"
    	},
    	{
    		.opts	= "--version",
    		.no_dev	= true,
    		.func	= do_version,
    		.help	= "Show version number"
    	},
    	{}
    };
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503

    读操作

    这里以 .opts = “-i|–driver” 为例:读取网卡信息

    #使用:ethtool -i ethX
    do_gdrv
    	--> send_ioctl(ETHTOOL_GDRVINFO)
    		--> ioctl(SIOCETHTOOL);
    
    • 1
    • 2
    • 3
    • 4

    写操作

    这里以 .opts = "-p|–identify"为例,设置网卡点灯时间

    #使用:ethtool -p ethX 10
    do_phys_id
    	--> send_ioctl(ETHTOOL_PHYS_ID);
    		--> ioctl(SIOCETHTOOL);
    
    • 1
    • 2
    • 3
    • 4

    应用层调用到 ioctl ,到此为止!

    3. 内核层

    继续上面示例,应用层 ioctl 继续调用内核层 dev_ioctl:

    读操作:读取网卡信息

    dev_ioctl case SIOCETHTOOL:-->
    	--> dev_ethtool
    		--> ethtool_get_drvinfo
    			--> ops->get_drvinfo  #这个函数是 struct ethtool_ops 结构体中,需要自己实现
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    写操作:设置网卡点灯时间

    dev_ioctl case SIOCETHTOOL:-->
    	--> dev_ethtool
    		--> ethtool_phys_id
    			--> ops->set_phys_id  #这个函数是 struct ethtool_ops 结构体中,需要自己实现
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    struct ethtool_ops 内容(linux/ethtool.h)

    struct ethtool_ops {
     {
    	int	(*get_settings)(struct net_device *, struct ethtool_cmd *);
    	int	(*set_settings)(struct net_device *, struct ethtool_cmd *);
    	void	(*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
    	int	(*get_regs_len)(struct net_device *);
    	void	(*get_regs)(struct net_device *, struct ethtool_regs *, void *);
    	void	(*get_wol)(struct net_device *, struct ethtool_wolinfo *);
    	int	(*set_wol)(struct net_device *, struct ethtool_wolinfo *);
    	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 *);
    	int	(*get_eeprom_len)(struct net_device *);
    	int	(*get_eeprom)(struct net_device *,
    			      struct ethtool_eeprom *, u8 *);
    	int	(*set_eeprom)(struct net_device *,
    			      struct ethtool_eeprom *, u8 *);
    	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 *);
    	int	(*set_ringparam)(struct net_device *,
    				 struct ethtool_ringparam *);
    	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 *);
    	u32	(*get_priv_flags)(struct net_device *);
    	int	(*set_priv_flags)(struct net_device *, u32);
    	int	(*get_sset_count)(struct net_device *, int);
    	int	(*get_rxnfc)(struct net_device *,
    			     struct ethtool_rxnfc *, u32 *rule_locs);
    	int	(*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
    	int	(*flash_device)(struct net_device *, struct ethtool_flash *);
    	int	(*reset)(struct net_device *, u32 *);
    	u32	(*get_rxfh_key_size)(struct net_device *);
    	u32	(*get_rxfh_indir_size)(struct net_device *);
    	int	(*get_rxfh)(struct net_device *, u32 *indir, u8 *key,
    			    u8 *hfunc);
    	int	(*set_rxfh)(struct net_device *, const u32 *indir,
    			    const u8 *key, const u8 hfunc);
    	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 *);
    	int     (*get_module_eeprom)(struct net_device *,
    				     struct ethtool_eeprom *, u8 *);
    	int	(*get_eee)(struct net_device *, struct ethtool_eee *);
    	int	(*set_eee)(struct net_device *, struct ethtool_eee *);
    	int	(*get_tunable)(struct net_device *,
    			       const struct ethtool_tunable *, void *);
    	int	(*set_tunable)(struct net_device *,
    			       const struct ethtool_tunable *, const void *);
    
    
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    ethtool_ops使用的典型参考:dm9000.c

    在内核源码中,VScode–【ctrl+p】,输入 dm9000.c

    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_wol		= dm9000_get_wol,
    	.set_wol		= dm9000_set_wol,
    	.get_eeprom_len		= dm9000_get_eeprom_len,
    	.get_eeprom		= dm9000_get_eeprom,
    	.set_eeprom		= dm9000_set_eeprom,
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    博客变现的15种方式大盘点
    HTML网页设计制作——响应式网页影视动漫资讯bootstrap网页(9页)
    第七章:最新版零基础学习 PYTHON 教程—Python 列表(第三节 -Python程序访问列表中的索引和值)
    oracle安装介绍
    【统计学习方法】学习笔记——逻辑斯谛回归和最大熵模型
    数学建模之线性规划(含MATLAB代码)
    2023年【通信安全员ABC证】找解析及通信安全员ABC证考试总结
    【离散数学】命题逻辑
    3. 一级缓存解析
    项目集成七牛云存储sdk
  • 原文地址:https://blog.csdn.net/dijkstar/article/details/133793448