Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ethtool: tsconfig: Fix netlink type of hwtstamp flags

Fix the netlink type for hardware timestamp flags, which are represented
as a bitset of flags. Although only one flag is supported currently, the
correct netlink bitset type should be used instead of u32 to keep
consistency with other fields. Address this by adding a new named string
set description for the hwtstamp flag structure.

The code has been introduced in the current release so the uAPI change is
still okay.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
Fixes: 6e9e2eed4f39 ("net: ethtool: Add support for tsconfig command to get/set hwtstamp config")
Link: https://patch.msgid.link/20250205110304.375086-1-kory.maincent@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kory Maincent and committed by
Jakub Kicinski
6a774228 3da81cb9

+39 -11
+2 -1
Documentation/netlink/specs/ethtool.yaml
··· 1524 1524 nested-attributes: bitset 1525 1525 - 1526 1526 name: hwtstamp-flags 1527 - type: u32 1527 + type: nest 1528 + nested-attributes: bitset 1528 1529 1529 1530 operations: 1530 1531 enum-model: directional
+2
include/uapi/linux/ethtool.h
··· 682 682 * @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics 683 683 * @ETH_SS_STATS_RMON: names of RMON statistics 684 684 * @ETH_SS_STATS_PHY: names of PHY(dev) statistics 685 + * @ETH_SS_TS_FLAGS: hardware timestamping flags 685 686 * 686 687 * @ETH_SS_COUNT: number of defined string sets 687 688 */ ··· 709 708 ETH_SS_STATS_ETH_CTRL, 710 709 ETH_SS_STATS_RMON, 711 710 ETH_SS_STATS_PHY, 711 + ETH_SS_TS_FLAGS, 712 712 713 713 /* add new constants above here */ 714 714 ETH_SS_COUNT
+5
net/ethtool/common.c
··· 462 462 }; 463 463 static_assert(ARRAY_SIZE(ts_rx_filter_names) == __HWTSTAMP_FILTER_CNT); 464 464 465 + const char ts_flags_names[][ETH_GSTRING_LEN] = { 466 + [const_ilog2(HWTSTAMP_FLAG_BONDED_PHC_INDEX)] = "bonded-phc-index", 467 + }; 468 + static_assert(ARRAY_SIZE(ts_flags_names) == __HWTSTAMP_FLAG_CNT); 469 + 465 470 const char udp_tunnel_type_names[][ETH_GSTRING_LEN] = { 466 471 [ETHTOOL_UDP_TUNNEL_TYPE_VXLAN] = "vxlan", 467 472 [ETHTOOL_UDP_TUNNEL_TYPE_GENEVE] = "geneve",
+2
net/ethtool/common.h
··· 13 13 ETHTOOL_LINK_MODE_ ## speed ## base ## type ## _ ## duplex ## _BIT 14 14 15 15 #define __SOF_TIMESTAMPING_CNT (const_ilog2(SOF_TIMESTAMPING_LAST) + 1) 16 + #define __HWTSTAMP_FLAG_CNT (const_ilog2(HWTSTAMP_FLAG_LAST) + 1) 16 17 17 18 struct link_mode_info { 18 19 int speed; ··· 39 38 extern const char sof_timestamping_names[][ETH_GSTRING_LEN]; 40 39 extern const char ts_tx_type_names[][ETH_GSTRING_LEN]; 41 40 extern const char ts_rx_filter_names[][ETH_GSTRING_LEN]; 41 + extern const char ts_flags_names[][ETH_GSTRING_LEN]; 42 42 extern const char udp_tunnel_type_names[][ETH_GSTRING_LEN]; 43 43 44 44 int __ethtool_get_link(struct net_device *dev);
+5
net/ethtool/strset.c
··· 75 75 .count = __HWTSTAMP_FILTER_CNT, 76 76 .strings = ts_rx_filter_names, 77 77 }, 78 + [ETH_SS_TS_FLAGS] = { 79 + .per_dev = false, 80 + .count = __HWTSTAMP_FLAG_CNT, 81 + .strings = ts_flags_names, 82 + }, 78 83 [ETH_SS_UDP_TUNNEL_TYPES] = { 79 84 .per_dev = false, 80 85 .count = __ETHTOOL_UDP_TUNNEL_TYPE_CNT,
+23 -10
net/ethtool/tsconfig.c
··· 54 54 55 55 data->hwtst_config.tx_type = BIT(cfg.tx_type); 56 56 data->hwtst_config.rx_filter = BIT(cfg.rx_filter); 57 - data->hwtst_config.flags = BIT(cfg.flags); 57 + data->hwtst_config.flags = cfg.flags; 58 58 59 59 data->hwprov_desc.index = -1; 60 60 hwprov = rtnl_dereference(dev->hwprov); ··· 91 91 92 92 BUILD_BUG_ON(__HWTSTAMP_TX_CNT > 32); 93 93 BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT > 32); 94 + BUILD_BUG_ON(__HWTSTAMP_FLAG_CNT > 32); 94 95 95 - if (data->hwtst_config.flags) 96 - /* _TSCONFIG_HWTSTAMP_FLAGS */ 97 - len += nla_total_size(sizeof(u32)); 96 + if (data->hwtst_config.flags) { 97 + ret = ethnl_bitset32_size(&data->hwtst_config.flags, 98 + NULL, __HWTSTAMP_FLAG_CNT, 99 + ts_flags_names, compact); 100 + if (ret < 0) 101 + return ret; 102 + len += ret; /* _TSCONFIG_HWTSTAMP_FLAGS */ 103 + } 98 104 99 105 if (data->hwtst_config.tx_type) { 100 106 ret = ethnl_bitset32_size(&data->hwtst_config.tx_type, ··· 136 130 int ret; 137 131 138 132 if (data->hwtst_config.flags) { 139 - ret = nla_put_u32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS, 140 - data->hwtst_config.flags); 133 + ret = ethnl_put_bitset32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS, 134 + &data->hwtst_config.flags, NULL, 135 + __HWTSTAMP_FLAG_CNT, 136 + ts_flags_names, compact); 141 137 if (ret < 0) 142 138 return ret; 143 139 } ··· 188 180 [ETHTOOL_A_TSCONFIG_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), 189 181 [ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER] = 190 182 NLA_POLICY_NESTED(ethnl_ts_hwtst_prov_policy), 191 - [ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_U32 }, 183 + [ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_NESTED }, 192 184 [ETHTOOL_A_TSCONFIG_RX_FILTERS] = { .type = NLA_NESTED }, 193 185 [ETHTOOL_A_TSCONFIG_TX_TYPES] = { .type = NLA_NESTED }, 194 186 }; ··· 304 296 305 297 BUILD_BUG_ON(__HWTSTAMP_TX_CNT >= 32); 306 298 BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT >= 32); 299 + BUILD_BUG_ON(__HWTSTAMP_FLAG_CNT > 32); 307 300 308 301 if (!netif_device_present(dev)) 309 302 return -ENODEV; ··· 386 377 } 387 378 388 379 if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS]) { 389 - ethnl_update_u32(&hwtst_config.flags, 390 - tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS], 391 - &config_mod); 380 + ret = ethnl_update_bitset32(&hwtst_config.flags, 381 + __HWTSTAMP_FLAG_CNT, 382 + tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS], 383 + ts_flags_names, info->extack, 384 + &config_mod); 385 + if (ret < 0) 386 + goto err_free_hwprov; 392 387 } 393 388 394 389 ret = net_hwtstamp_validate(&hwtst_config);