STRUCT ETHTOOL_OPS(9)
π struct ethtool_ops π
okay bestie, welcome to section 9 of the Kernel API Manual β this is the page for struct ethtool_ops, and it is literally giving βoptional netdev operationsβ main character energy. part 1, no cap, letβs get into it π«Άβ¨
πΈ NAME πΈ
struct ethtool_ops β optional netdev operations π
β¨ SYNOPSIS β¨
hereβs the whole struct, bestie β every field, exactly as it is, no edits, no vibes-based rewriting π₯
struct ethtool_ops {
u32 supported_input_xfrm:8;
u32 cap_link_lanes_supported:1;
u32 rxfh_per_ctx_fields:1;
u32 rxfh_per_ctx_key:1;
u32 cap_rss_rxnfc_adds:1;
u32 rxfh_indir_space;
u16 rxfh_key_space;
u16 rxfh_priv_size;
u32 rxfh_max_num_contexts;
u32 supported_coalesce_params;
u32 supported_ring_params;
u32 supported_hwtstamp_qualifiers;
u32 op_needs_rtnl;
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_link_ext_state)(struct net_device *, struct
ethtool_link_ext_state_info *);
void (*get_link_ext_stats)(struct net_device *dev, struct
ethtool_link_ext_stats *stats);
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 *,
struct kernel_ethtool_coalesce *, struct netlink_ext_ack *);
int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *,
struct kernel_ethtool_coalesce *, struct netlink_ext_ack *);
void (*get_ringparam)(struct net_device *, struct ethtool_ringparam
*, struct kernel_ethtool_ringparam *, struct netlink_ext_ack *);
int (*set_ringparam)(struct net_device *, struct ethtool_ringparam
*, struct kernel_ethtool_ringparam *, struct netlink_ext_ack *);
void (*get_pause_stats)(struct net_device *dev, struct
ethtool_pause_stats *pause_stats);
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_rx_ring_count)(struct net_device *dev);
u32 (*get_rxfh_key_size)(struct net_device *);
u32 (*get_rxfh_indir_size)(struct net_device *);
int (*get_rxfh)(struct net_device *, struct ethtool_rxfh_param *);
int (*set_rxfh)(struct net_device *, struct ethtool_rxfh_param *,
struct netlink_ext_ack *extack);
int (*get_rxfh_fields)(struct net_device *, struct
ethtool_rxfh_fields *);
int (*set_rxfh_fields)(struct net_device *, const struct
ethtool_rxfh_fields *, struct netlink_ext_ack *extack);
int (*create_rxfh_context)(struct net_device *, struct
ethtool_rxfh_context *ctx, const struct ethtool_rxfh_param *rxfh, struct
netlink_ext_ack *extack);
int (*modify_rxfh_context)(struct net_device *, struct
ethtool_rxfh_context *ctx, const struct ethtool_rxfh_param *rxfh, struct
netlink_ext_ack *extack);
int (*remove_rxfh_context)(struct net_device *, struct
ethtool_rxfh_context *ctx, u32 rss_context, struct netlink_ext_ack
*extack);
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
kernel_ethtool_ts_info *);
void (*get_ts_stats)(struct net_device *dev, struct ethtool_ts_stats
*ts_stats);
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 *dev, struct ethtool_keee *eee);
int (*set_eee)(struct net_device *dev, struct ethtool_keee *eee);
int (*get_tunable)(struct net_device *, const struct ethtool_tunable
*, void *);
int (*set_tunable)(struct net_device *, const struct ethtool_tunable
*, const void *);
int (*get_per_queue_coalesce)(struct net_device *, u32, struct
ethtool_coalesce *);
int (*set_per_queue_coalesce)(struct net_device *, u32, struct
ethtool_coalesce *);
int (*get_link_ksettings)(struct net_device *, struct
ethtool_link_ksettings *);
int (*set_link_ksettings)(struct net_device *, const struct
ethtool_link_ksettings *);
void (*get_fec_stats)(struct net_device *dev, struct
ethtool_fec_stats *fec_stats, struct ethtool_fec_hist *hist);
int (*get_fecparam)(struct net_device *, struct ethtool_fecparam *);
int (*set_fecparam)(struct net_device *, struct ethtool_fecparam *);
void (*get_ethtool_phy_stats)(struct net_device *, struct
ethtool_stats *, u64 *);
int (*get_phy_tunable)(struct net_device *, const struct
ethtool_tunable *, void *);
int (*set_phy_tunable)(struct net_device *, const struct
ethtool_tunable *, const void *);
int (*get_module_eeprom_by_page)(struct net_device *dev, const
struct ethtool_module_eeprom *page, struct netlink_ext_ack *extack);
int (*set_module_eeprom_by_page)(struct net_device *dev, const
struct ethtool_module_eeprom *page, struct netlink_ext_ack *extack);
void (*get_eth_phy_stats)(struct net_device *dev, struct
ethtool_eth_phy_stats *phy_stats);
void (*get_eth_mac_stats)(struct net_device *dev, struct
ethtool_eth_mac_stats *mac_stats);
void (*get_eth_ctrl_stats)(struct net_device *dev, struct
ethtool_eth_ctrl_stats *ctrl_stats);
void (*get_rmon_stats)(struct net_device *dev, struct
ethtool_rmon_stats *rmon_stats, const struct ethtool_rmon_hist_range
**ranges);
int (*get_module_power_mode)(struct net_device *dev, struct
ethtool_module_power_mode_params *params, struct netlink_ext_ack
*extack);
int (*set_module_power_mode)(struct net_device *dev, const struct
ethtool_module_power_mode_params *params, struct netlink_ext_ack
*extack);
int (*get_mm)(struct net_device *dev, struct ethtool_mm_state
*state);
int (*set_mm)(struct net_device *dev, struct ethtool_mm_cfg *cfg,
struct netlink_ext_ack *extack);
void (*get_mm_stats)(struct net_device *dev, struct ethtool_mm_stats
*stats);
};
π«Ά Members π«Ά
okay so hereβs the member-by-member tea, bestie β all the details are staying, weβre just making it cute πΈ
supported_input_xfrmβ supported types of input xfrm fromRXH_XFRM_*. β¨cap_link_lanes_supportedβ indicates if the driver supports lanes parameter. π£οΈrxfh_per_ctx_fieldsβ device supports selecting different header fields for Rx hash calculation and RSS for each additional context. πrxfh_per_ctx_keyβ device supports setting different RSS key for each additional context. Netlink API should report hfunc, key, and input_xfrm for every context, not just context 0. πcap_rss_rxnfc_addsβ device supports nonzero ring_cookie in filters with FLOW_RSS flag; the queue ID from the filter is added to the value from the indirection table to determine the delivery queue. πrxfh_indir_spaceβ max size of RSS indirection tables, if indirection table size as returned by get_rxfh_indir_size may change during lifetime of the device. Leave as 0 if the table size is constant. πrxfh_key_spaceβ same as rxfh_indir_space, but for the key. πrxfh_priv_sizeβ size of the driver private data area the core should allocate for an RSS context (in struct ethtool_rxfh_context). π§Ίrxfh_max_num_contextsβ maximum (exclusive) supported RSS context ID. If this is zero then the core may choose any (nonzero) ID, otherwise the core will only use IDs strictly less than this value, as the rss_context argument to create_rxfh_context and friends. π¦supported_coalesce_paramsβ supported types of interrupt coalescing. β‘supported_ring_paramsβ supported ring params. πsupported_hwtstamp_qualifiersβ bitfield of supported hwtstamp qualifier. β±οΈop_needs_rtnlβ mask ofETHTOOL_OP_NEEDS_RTNL_*bits. For use with ops-locked drivers (ignored otherwise). Selects which ethtool callbacks driver needs to still be executed underrtnl_lock(in addition to the netdev instance lock). The following commonly used core APIs currently requirertnl_lock(this list may not be exhaustive):- phylink helpers (note that phydev is currently unsupported!)
- netdev_update_features
- netif_set_real_num_tx_queues
- ethtool_op_get_link (syncs link watch under
rtnl_lock) - netif_open / netif_close (used by self_test)
get_drvinfoβ Report driver/device information. Modern drivers no longer have to implement this callback. Most fields are correctly filled in by the core using system information, or populated using other driver operations. πget_regs_lenβ Get buffer length required for get_regs. πget_regsβ Get device registers. π§Ύget_wolβ Report whether Wake-on-Lan is enabled. πset_wolβ Turn Wake-on-Lan on or off. Returns a negative error code or zero. πget_msglevelβ Report driver message level. This should be the value of themsg_enablefield used by netif logging functions. π£οΈset_msglevelβ Set driver message level. ποΈnway_resetβ Restart autonegotiation. Returns a negative error code or zero. πget_linkβ tells you whether the physical link is actually up π. It only ever gets called if the netdev is up, so no worries about it firing at weird times. Ngl you should usually just point this atethtool_op_get_link, which does the whole thing vianetif_carrier_ok. slay, less work for you.get_link_ext_stateβ reports the link's extended state β¨. You setlink_ext_stateandlink_ext_substateβ and heads up, alink_ext_substateof 0 means the substate is unknown, and in that case do not attach theext_substateattribute to the netlink message. If bothlink_ext_stateandlink_ext_substateare unknown, return-ENODATA. And if this op just isn't implemented at all, thenlink_ext_stateandlink_ext_substatesimply won't be sent to userspace. iykyk.get_link_ext_statsβ reads the extra link-related counters π¦. cute lil bonus stats.get_eeprom_lenβ reads the range of EEPROM addresses so the kernel can validateget_eepromandset_eepromrequests π. Returns 0 if the device doesn't support EEPROM access at all.get_eepromβ reads data straight out of the device EEPROM π . Fill in the magic field, bestie. You don't need to checklenfor zero or wraparound β the kernel's got you. Fill thedataargument with the EEPROM values fromoffsettooffset + len, then updatelento the amount actually read. Returns an error or zero.set_eepromβ writes data to the device EEPROM π₯. This one should validate the magic field (yes, really). Again, no need to checklenfor zero or wraparound. Updatelento the amount written. Returns an error or zero.get_coalesceβ gets the interrupt coalescing parameters β. Returns a negative error code or zero, the usual deal.set_coalesceβ sets the interrupt coalescing parameters π. The coalescing types you actually support should be set insupported_coalesce_params. Returns a negative error code or zero.get_ringparamβ reports ring sizes πΈ. that's it, that's the whole vibe.set_ringparamβ sets ring sizes π«Ά. Returns a negative error code or zero.get_pause_statsβ reports pause frame statistics π. Important: drivers must not zero statistics they don't report β the stats structure is initialized toETHTOOL_STAT_NOT_SET, which is the signal that the driver doesn't report those statistics. Don't be out here lying with zeros, fr fr.get_pauseparamβ reports pause parameters π«.set_pauseparamβ sets pause parameters π. Returns a negative error code or zero.self_testβ runs the specified self-tests π₯. go little device go.get_stringsβ returns a set of strings that describe the requested objects β¨.set_phys_idβ identifies the physical devices, like by flashing an LED attached to it π‘. The implementation may update the indicator asynchronously or synchronously, but either way it must return quickly. Here's the whole choreography: it's initially called with the argumentETHTOOL_ID_ACTIVE, and it must either activate asynchronous updates and return zero, return a negative error, or return a positive frequency for synchronous indication (e.g.1for one on/off cycle per second). If it returns a frequency, then it'll get called again at intervals with the argumentETHTOOL_ID_ONorETHTOOL_ID_OFF, and it should set the state of the indicator accordingly. Finally, it's called with the argumentETHTOOL_ID_INACTIVEand must deactivate the indicator. Returns a negative error code or zero. main character LED energy, honestly.get_ethtool_statsβ returns extended statistics about the device π. This is only useful if the device maintains statistics that aren't already included instruct rtnl_link_stats64.beginβ the function called before any other operation π¦. Returns a negative error code or zero.completeβ the function called after any other operation exceptbeginπ . And yes, it will be called even if the other operation failed. cleanup queen.get_priv_flagsβ reports driver-specific feature flags β.set_priv_flagsβ sets driver-specific feature flags π. Returns a negative error code or zero.get_sset_countβ gets the number of strings thatget_stringswill write πΈ.get_rxnfcβ gets the RX flow classification rules π¦. Returns a negative error code or zero. Now pay attention, because this one's got lore: forETHTOOL_GRXCLSRLALL,rule_cntand the size of the arrays are user-provided, and are not guaranteed to match what the driver would have reported viaETHTOOL_GRXCLSRLCNT. Drivers must return-EMSGSIZEwhenrule_cntis too small.rule_locsisNULLwhenrule_cntis zero. On success, drivers must setrule_cntto the number of locations they filled in, and the core copies out exactly that many. no cap, read it twice.set_rxnfcβ sets the RX flow classification rules π. Returns a negative error code or zero.flash_deviceβ writes a firmware image to the device's flash memory π₯. Returns a negative error code or zero.resetβ resets (part of) the device, as specified by a bitmask of flags fromenum ethtool_reset_flagsβ¨. Returns a negative error code or zero.get_rx_ring_countβ returns the number of RX rings π.get_rxfh_key_sizeβ gets the size of the RX flow hash key π. Returns zero if it's not supported for this specific device.get_rxfh_indir_sizeβ gets the size of the RX flow hash indirection table π . Returns zero if it's not supported for this specific device.get_rxfhβ gets the contents of the RX flow hash indirection table, hash key and/or hash function π. Returns a negative error code or zero.set_rxfhβ sets the contents of the RX flow hash indirection table, hash key, and/or hash function π«Ά. Arguments which are set toNULLor zero will remain unchanged. Returns a negative error code or zero. And an error code must be returned if at least one unsupported change was requested β don't silently swallow it, bestie.get_rxfh_fieldsβ gets the header fields used for flow hashing πΈ.set_rxfh_fieldsβ sets the header fields used for flow hashing π.create_rxfh_contextβ creates a new RSS context with the specified RX flow hash indirection table, hash key, and hash function β. Thestruct ethtool_rxfh_contextfor this context is passed inctxβ and note that as of this call, the indir table, hkey and hfunc are not yet populated. The driver doesn't need to update these; the core will do so if this op succeeds. However, ifrxfh.indiris set toNULL, the driver must update the indir table inctxwith the (default or inherited) table actually in use; similarly, ifrxfh.keyisNULL,rxfh.hfuncisETH_RSS_HASH_NO_CHANGE, orrxfh.input_xfrmisRXH_XFRM_NO_CHANGE, the driver should update the corresponding information inctx. If the driver provides this method, it must also providemodify_rxfh_contextandremove_rxfh_context. Returns a negative error code or zero. it's giving package deal, fr fr.modify_rxfh_contextβ reconfigures the specified RSS context π«. Lets you set the contents of the RX flow hash indirection table, hash key, and/or hash function associated with the given context. Parameters which are set toNULLor zero will remain unchanged. Thestruct ethtool_rxfh_contextfor this context is passed inctxβ and note that it will still contain the old settings. The driver doesn't need to update these; the core will do so if this op succeeds. Returns a negative error code or zero. An error code must be returned if at least one unsupported change was requested. same rules as before, no skipping.remove_rxfh_contextβ removes the specified RSS context π. Thestruct ethtool_rxfh_contextfor this context is passed inctx. Returns a negative error code or zero.get_channelsβ gets the number of channels πΈ.set_channelsβ sets the number of channels π¦. Returns a negative error code or zero.get_dump_flagβ gets the dump flag indicating the current dump length, version, and flag of the device π.get_dump_dataβ gets dump data β¨.set_dumpβ sets dump specific flags to the device π .get_ts_infoβ gets the time stamping and PTP hardware clock capabilities β°. It may be called with RCU, or rtnl, or a reference on the device. Drivers supporting transmit time stamps in software should set this toethtool_op_get_ts_info.get_ts_statsβ queries the device hardware timestamping statistics π₯. Same rule as the pause stats: drivers must not zero statistics they don't report β the stats structure is initialized toETHTOOL_STAT_NOT_SET, which indicates the driver doesn't report statistics. consistency is iconic.get_module_infoβ gets the size and type of the EEPROM contained within a plug-in module π§.get_module_eepromβ gets the EEPROM information from the plug-in module π.get_eeeβ gets Energy-Efficient (EEE) supported and status π±.set_eeeβ sets EEE status (enable/disable) as well as LPI timers β‘.get_tunableβ reads the value of a driver / device tunable ποΈ.set_tunableβ sets the value of a driver / device tunable ποΈ.get_per_queue_coalesceβ gets interrupt coalescing parameters per queue π. It must check that the given queue number is valid. If neither an RX nor a TX queue has this number, return-EINVAL. If only an RX queue or a TX queue has this number, set the inapplicable fields to~0and return 0. Returns a negative error code or zero. precision, bestie.set_per_queue_coalesceβ sets interrupt coalescing parameters per queue π. It must check that the given queue number is valid. If neither an RX nor a TX queue has this number, return-EINVAL. If only an RX queue or a TX queue has this number, ignore the inapplicable fields. Supported coalescing types should be set insupported_coalesce_params. Returns a negative error code or zero.get_link_ksettingsβ gets various device settings including Ethernet link settings π₯. Heads up: thecmdandlink_mode_masks_nwordsfields should be ignored (use__ETHTOOL_LINK_MODE_MASK_NBITSinstead of the latter), and any change to them will be overwritten by the kernel. Returns a negative error code or zero. so like, don't bother touching them, it's not giving what you think it's giving π.set_link_ksettingsβ sets various device settings, including Ethernet link settings. Thecmdandlink_mode_masks_nwordsfields should be ignored (use__ETHTOOL_LINK_MODE_MASK_NBITSinstead of the latter), and any change to them will be overwritten by kernel. Returns a negative error code or zero. πget_fec_statsβ reports FEC statistics. Core will sum up per-lane stats to get the total. Drivers must not zero statistics which they don't report. The stats structure is initialized toETHTOOL_STAT_NOT_SET, indicating the driver does not report statistics. π«Άget_fecparamβ get the network device Forward Error Correction parameters. β¨set_fecparamβ set the network device Forward Error Correction parameters. πget_ethtool_phy_statsβ return extended statistics about the PHY device. This is only useful if the device maintains PHY statistics and cannot use the standard PHY library helpers. π¦get_phy_tunableβ read the value of a PHY tunable. πΈset_phy_tunableβ set the value of a PHY tunable. πΈget_module_eeprom_by_pageβ get a region of plug-in module EEPROM data from the specified page. Returns a negative error code or the amount of bytes read. πset_module_eeprom_by_pageβ write to a region of plug-in module EEPROM, from kernel space only. Returns a negative error code or zero. π₯get_eth_phy_statsβ query some of the IEEE 802.3 PHY statistics. πget_eth_mac_statsβ query some of the IEEE 802.3 MAC statistics. πget_eth_ctrl_statsβ query some of the IEEE 802.3 MAC Ctrl statistics. πget_rmon_statsβ query some of the RMON (RFC 2819) statistics. Set ranges to a pointer to zero-terminated array of byte ranges. πget_module_power_modeβ get the power mode policy for the plug-in module used by the network device and its operational power mode, if plugged-in. βset_module_power_modeβ set the power mode policy for the plug-in module used by the network device. βget_mmβ query the 802.3 MAC Merge layer state. π§set_mmβ set the 802.3 MAC Merge layer parameters. π§get_mm_statsβ query the 802.3 MAC Merge layer statistics. π§
π Description π
Okay so real talk, bestie: all operations are optional β the function pointer may literally be set to NULL β and callers must take this into account. No assumptions, no cap. π
For traditional drivers, callers hold rtnl_lock across the call. For "ops locked" drivers (see Documentation/networking/netdevices.rst), callers instead hold the netdev instance lock (netdev_lock_ops); rtnl_lock is additionally held only for callbacks for which the driver opts in via the matching ETHTOOL_OP_NEEDS_RTNL_* bit in op_needs_rtnl. π
See the structures used by these operations for further documentation. Note that for all operations using a structure ending with a zero-length array, the array is allocated separately in the kernel and is passed to the driver as an additional parameter. π§ β¨
See struct net_device and struct net_device_ops for documentation of the generic netdev features interface. π«Ά
π SEE ALSO π
The whole extended friendship circle, no skips:
- Kernel file
./include/linux/ethtool.h enum ethtool_phys_id_state(9)struct kernel_ethtool_ringparam(9)enum ethtool_supported_ring_param(9)ethtool_rxfh_indir_default(9)struct ethtool_rxfh_context(9)ethtool_link_ksettings_zero_link_mode(9)ethtool_link_ksettings_add_link_mode(9)ethtool_link_ksettings_del_link_mode(9)ethtool_link_ksettings_test_link_mode(9)ethtool_intersect_link_masks(9)struct ethtool_phy_stats(9)struct ethtool_pause_stats(9)struct ethtool_fec_hist_range(9)struct ethtool_fec_stats(9)struct ethtool_rmon_hist_range(9)struct ethtool_rmon_stats(9)struct ethtool_ts_stats(9)struct ethtool_module_eeprom(9)struct ethtool_module_power_mode_params(9)struct ethtool_mm_state(9)struct ethtool_mm_cfg(9)struct ethtool_mm_stats(9)struct ethtool_mmsv_ops(9)struct ethtool_mmsv(9)struct ethtool_rxfh_param(9)struct ethtool_rxfh_fields(9)struct kernel_ethtool_ts_info(9)struct ethtool_netdev_state(9)struct ethtool_phy_ops(9)ethtool_set_ethtool_phy_ops(9)ethtool_params_from_link_mode(9)ethtool_get_phc_vclocks(9)ethtool_mm_frag_size_add_to_min(9)ethtool_mm_frag_size_min_to_add(9)ethtool_get_ts_info_by_layer(9)ethtool_sprintf(9)ethtool_puts(9)ethtool_cpy(9)
That's the whole page, bestie π source lives at ./include/linux, the version date is October 2026, and this iconic little manual is struct ethtool_ops(9). Go forth and slay your driver ops π
β¨
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms