STRUCT ETHTOOL_CMD(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

🌸 struct ethtool_cmd(9) β€” the Kernel API Manual, but make it make sense 🌸

okay bestie, sit down, grab a boba, because we're talking about struct ethtool_cmd from the Linux kernel API manual. and listen β€” she's gorgeous, she's historic, and she is, unfortunately, DEPRECATED πŸ˜­πŸ’€ like a limited-edition item that got discontinued. this whole structure is DEPRECATED, so please, for the love of everything, use struct ethtool_link_settings instead. periodt. πŸ’…


✨ NAME ✨

struct ethtool_cmd β€” DEPRECATED, link control and status. This structure is DEPRECATED, please use struct ethtool_link_settings. (yes i said it twice, it's important, don't @ me πŸ™ˆ)


πŸ¦‹ SYNOPSIS πŸ¦‹

here's the whole fit, laid out:

struct ethtool_cmd {
    __u32 cmd;
    __u32 supported;
    __u32 advertising;
    __u16 speed;
    __u8 duplex;
    __u8 port;
    __u8 phy_address;
    __u8 transceiver;
    __u8 autoneg;
    __u8 mdio_support;
    __u32 maxtxpkt;
    __u32 maxrxpkt;
    __u16 speed_hi;
    __u8 eth_tp_mdix;
    __u8 eth_tp_mdix_ctrl;
    __u32 lp_advertising;
    __u32 reserved[2];
 };

πŸ’– Members πŸ’–

okay now the cast of characters, one by one, no skipping πŸ‘‘

  • cmd β€” the command number, and it's either ETHTOOL_GSET or ETHTOOL_SSET. that's it. that's the whole vibe check.
  • supported β€” a bitmask of SUPPORTED_* flags covering the link modes, physical connectors and other link features that this interface actually supports autonegotiation or auto-detection for. read-only, so don't even try it, bestie. πŸ”’
  • advertising β€” a bitmask of ADVERTISED_* flags for the link modes, physical connectors and other link features that are advertised through autonegotiation, or enabled for auto-detection. it's giving "what i'm putting on my profile" energy ✨
  • speed β€” the low bits of the speed, in 1Mb units, ranging 0 to INT_MAX or SPEED_UNKNOWN. lowkey only half the story, more on that in a sec πŸ‘€
  • duplex β€” duplex mode; one of DUPLEX_*
  • port β€” physical connector type; one of PORT_*
  • phy_address β€” the MDIO address of the PHY (transceiver); 0 or 255 if it's not applicable. for clause 45 PHYs this is the PRTAD. fancy πŸŽ€
  • transceiver β€” historically used to tell different possible PHY types apart, but honestly not in a consistent way. Deprecated. we don't stan anymore πŸ’€
  • autoneg β€” enable/disable autonegotiation and auto-detection; either AUTONEG_DISABLE or AUTONEG_ENABLE. the on/off switch of the whole situation πŸ”₯
  • mdio_support β€” a bitmask of ETH_MDIO_SUPPORTS_* flags for the MDIO protocols the interface supports; 0 if it's unknown. read-only. πŸ”’
  • maxtxpkt β€” historically used to report TX IRQ coalescing; now obsoleted by struct ethtool_coalesce. read-only; deprecated. she had her moment, she's retired πŸ™ˆ
  • maxrxpkt β€” historically used to report RX IRQ coalescing; now obsoleted by struct ethtool_coalesce. read-only; deprecated. same energy, other direction 🫢
  • speed_hi β€” the high bits of the speed, in 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN. see? i told you speed was only half of it 😌
  • eth_tp_mdix β€” Ethernet twisted-pair MDI(-X) status; one of ETH_TP_MDI_*. if the status is unknown or not applicable, the value will be ETH_TP_MDI_INVALID. read-only. πŸ”’
  • eth_tp_mdix_ctrl β€” Ethernet twisted pair MDI(-X) control; one of ETH_TP_MDI_*. if MDI(-X) control isn't implemented, reads yield ETH_TP_MDI_INVALID and writes may be ignored or rejected. when written successfully, the link should be renegotiated if necessary. no cap, that last part matters πŸ’…
  • lp_advertising β€” a bitmask of ADVERTISED_* flags for the link modes and other link features that the link partner advertised through autonegotiation; 0 if unknown or not applicable. read-only. that's your partner's profile, not yours πŸ‘€βœ¨
  • reserved β€” reserved for future use; see the note on reserved space. mind your business, it's not for you yet πŸŽ€

🌈 Description 🌈

so the link speed in Mbps is split between speed and speed_hi. yes, split, like a friendship bracelet. 🫢 use the ethtool_cmd_speed and ethtool_cmd_speed_set functions to actually access it β€” do not go poking at the halves yourself, i'm begging.

if autonegotiation is disabled, speed and duplex represent the fixed link mode and are writable if the driver supports multiple link modes. if autonegotiation is enabled, then they're read-only β€” and:

  • if the link is up, they represent the negotiated link mode 🌸
  • if the link is down, the speed is 0, SPEED_UNKNOWN or the highest enabled speed, and duplex is DUPLEX_UNKNOWN or the best enabled duplex mode. 😭 it's giving "we tried our best"

some hardware interfaces may have multiple PHYs and/or physical connectors fitted, or they just don't let the driver detect which are fitted. for these interfaces port and/or phy_address may be writable, possibly dependent on autoneg being AUTONEG_DISABLE. otherwise, attempts to write different values may be ignored or rejected β€” so like, don't be shocked, bestie πŸ’€

users should assume that all fields not marked read-only are writable and subject to validation by the driver. so if you write something unhinged and it gets rejected, that's on you, not the kernel. πŸ™ˆ

the correct move, always: use ETHTOOL_GSET to get the current values first, then make your specific changes, then apply them with ETHTOOL_SSET. get β†’ tweak β†’ set. that's the whole choreography πŸ’…πŸ”₯

and Deprecated fields should be ignored by both users and drivers. both. everyone. ignore them. periodt. πŸ‘‘


⭐ SEE ALSO ⭐

go read the Kernel file ./include/uapi/linux/ethtool.h, plus literally the entire extended universe: struct ethtool_drvinfo(9), struct ethtool_wolinfo(9), struct ethtool_regs(9), struct ethtool_eeprom(9), struct ethtool_eee(9), struct ethtool_modinfo(9), struct ethtool_coalesce(9), struct ethtool_ringparam(9), struct ethtool_channels(9), struct ethtool_pauseparam(9), enum ethtool_stringset(9), enum ethtool_mac_stats_src(9), enum ethtool_module_power_mode_policy(9), enum ethtool_module_power_mode(9), enum ethtool_c33_pse_ext_state(9), enum ethtool_c33_pse_ext_substate_mr_mps_valid(9), enum ethtool_c33_pse_ext_substate_error_condition(9), enum ethtool_c33_pse_ext_substate_mr_pse_enable(9), enum ethtool_c33_pse_ext_substate_option_detect_ted(9), enum ethtool_c33_pse_ext_substate_option_vport_lim(9), enum ethtool_c33_pse_ext_substate_ovld_detected(9), enum ethtool_c33_pse_ext_substate_power_not_available(9), enum ethtool_c33_pse_ext_substate_short_detected(9), enum ethtool_pse_types(9), enum ethtool_c33_pse_admin_state(9), enum ethtool_c33_pse_pw_d_status(9), enum ethtool_podl_pse_admin_state(9), enum ethtool_podl_pse_pw_d_status(9), enum ethtool_mm_verify_status(9), enum ethtool_module_fw_flash_status(9), struct ethtool_gstrings(9), struct ethtool_sset_info(9), enum ethtool_test_flags(9), struct ethtool_test(9), struct ethtool_stats(9), struct ethtool_perm_addr(9), struct ethtool_tcpip4_spec(9), struct ethtool_ah_espip4_spec(9), struct ethtool_usrip4_spec(9), struct ethtool_tcpip6_spec(9), struct ethtool_ah_espip6_spec(9), struct ethtool_usrip6_spec(9), struct ethtool_flow_ext(9), struct ethtool_rx_flow_spec(9), struct ethtool_rxnfc(9), struct ethtool_rxfh_indir(9), struct ethtool_rxfh(9), struct ethtool_rx_ntuple_flow_spec(9), struct ethtool_rx_ntuple(9), struct ethtool_dump(9), struct ethtool_get_features_block(9), struct ethtool_gfeatures(9), struct ethtool_set_features_block(9), struct ethtool_sfeatures(9), struct ethtool_ts_info(9), struct ethtool_per_queue_op(9), struct ethtool_fecparam(9), enum ethtool_fec_config_bits(9), struct ethtool_link_settings(9), enum phy_upstream(9).

that's the whole group chat, all tagged. iykyk πŸ§šπŸ’œ


mwah, that's the whole page! 🫢 this lil love letter lives in ./include/uapi/linux, dated October 2026, and it's filed under struct ethtool_cmd(9) β€” go stan struct ethtool_link_settings instead tho, fr fr πŸ’…βœ¨

πŸ“¦ where this page comes from