]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: ethtool: tsconfig: Fix netlink type of hwtstamp flags
authorKory Maincent <kory.maincent@bootlin.com>
Wed, 5 Feb 2025 11:03:01 +0000 (12:03 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 7 Feb 2025 00:35:21 +0000 (16:35 -0800)
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>
Documentation/netlink/specs/ethtool.yaml
include/uapi/linux/ethtool.h
net/ethtool/common.c
net/ethtool/common.h
net/ethtool/strset.c
net/ethtool/tsconfig.c

index 259cb211a3382fd5f52a53232907915a3e29c00c..655d8d10fe248d91a6a247f05648b94b1cb4656c 100644 (file)
@@ -1524,7 +1524,8 @@ attribute-sets:
         nested-attributes: bitset
       -
         name: hwtstamp-flags
-        type: u32
+        type: nest
+        nested-attributes: bitset
 
 operations:
   enum-model: directional
index d1089b88efc7d92f9c2a0003be27bc876793ade5..9b18c4cfe56f87c700a865436221a0d8fbc7e1e1 100644 (file)
@@ -682,6 +682,7 @@ enum ethtool_link_ext_substate_module {
  * @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics
  * @ETH_SS_STATS_RMON: names of RMON statistics
  * @ETH_SS_STATS_PHY: names of PHY(dev) statistics
+ * @ETH_SS_TS_FLAGS: hardware timestamping flags
  *
  * @ETH_SS_COUNT: number of defined string sets
  */
@@ -708,6 +709,7 @@ enum ethtool_stringset {
        ETH_SS_STATS_ETH_CTRL,
        ETH_SS_STATS_RMON,
        ETH_SS_STATS_PHY,
+       ETH_SS_TS_FLAGS,
 
        /* add new constants above here */
        ETH_SS_COUNT
index 2bd77c94f9f1addaf5559e652f09cca715ca308e..d88e9080643b843d18e15a486d8e94cdadbe3b53 100644 (file)
@@ -462,6 +462,11 @@ const char ts_rx_filter_names[][ETH_GSTRING_LEN] = {
 };
 static_assert(ARRAY_SIZE(ts_rx_filter_names) == __HWTSTAMP_FILTER_CNT);
 
+const char ts_flags_names[][ETH_GSTRING_LEN] = {
+       [const_ilog2(HWTSTAMP_FLAG_BONDED_PHC_INDEX)] = "bonded-phc-index",
+};
+static_assert(ARRAY_SIZE(ts_flags_names) == __HWTSTAMP_FLAG_CNT);
+
 const char udp_tunnel_type_names[][ETH_GSTRING_LEN] = {
        [ETHTOOL_UDP_TUNNEL_TYPE_VXLAN]         = "vxlan",
        [ETHTOOL_UDP_TUNNEL_TYPE_GENEVE]        = "geneve",
index 850eadde4bfcc80c3dddd34d7f51f72da2e7ef6c..58e9e7db06f90d6e41197a88de89da2645aa5348 100644 (file)
@@ -13,6 +13,7 @@
        ETHTOOL_LINK_MODE_ ## speed ## base ## type ## _ ## duplex ## _BIT
 
 #define __SOF_TIMESTAMPING_CNT (const_ilog2(SOF_TIMESTAMPING_LAST) + 1)
+#define __HWTSTAMP_FLAG_CNT (const_ilog2(HWTSTAMP_FLAG_LAST) + 1)
 
 struct link_mode_info {
        int                             speed;
@@ -38,6 +39,7 @@ extern const char wol_mode_names[][ETH_GSTRING_LEN];
 extern const char sof_timestamping_names[][ETH_GSTRING_LEN];
 extern const char ts_tx_type_names[][ETH_GSTRING_LEN];
 extern const char ts_rx_filter_names[][ETH_GSTRING_LEN];
+extern const char ts_flags_names[][ETH_GSTRING_LEN];
 extern const char udp_tunnel_type_names[][ETH_GSTRING_LEN];
 
 int __ethtool_get_link(struct net_device *dev);
index 818cf01f091109ad75cdb92761a29ee8f3f8140b..6b76c05caba4d8f0fb23adb3414a92b4e636aed8 100644 (file)
@@ -75,6 +75,11 @@ static const struct strset_info info_template[] = {
                .count          = __HWTSTAMP_FILTER_CNT,
                .strings        = ts_rx_filter_names,
        },
+       [ETH_SS_TS_FLAGS] = {
+               .per_dev        = false,
+               .count          = __HWTSTAMP_FLAG_CNT,
+               .strings        = ts_flags_names,
+       },
        [ETH_SS_UDP_TUNNEL_TYPES] = {
                .per_dev        = false,
                .count          = __ETHTOOL_UDP_TUNNEL_TYPE_CNT,
index 9188e088fb2f9547561f988cf1fd601fa704517b..2be356bdfe8737fe2a37eecb1ff1cfdaee30df67 100644 (file)
@@ -54,7 +54,7 @@ static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,
 
        data->hwtst_config.tx_type = BIT(cfg.tx_type);
        data->hwtst_config.rx_filter = BIT(cfg.rx_filter);
-       data->hwtst_config.flags = BIT(cfg.flags);
+       data->hwtst_config.flags = cfg.flags;
 
        data->hwprov_desc.index = -1;
        hwprov = rtnl_dereference(dev->hwprov);
@@ -91,10 +91,16 @@ static int tsconfig_reply_size(const struct ethnl_req_info *req_base,
 
        BUILD_BUG_ON(__HWTSTAMP_TX_CNT > 32);
        BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT > 32);
+       BUILD_BUG_ON(__HWTSTAMP_FLAG_CNT > 32);
 
-       if (data->hwtst_config.flags)
-               /* _TSCONFIG_HWTSTAMP_FLAGS */
-               len += nla_total_size(sizeof(u32));
+       if (data->hwtst_config.flags) {
+               ret = ethnl_bitset32_size(&data->hwtst_config.flags,
+                                         NULL, __HWTSTAMP_FLAG_CNT,
+                                         ts_flags_names, compact);
+               if (ret < 0)
+                       return ret;
+               len += ret;     /* _TSCONFIG_HWTSTAMP_FLAGS */
+       }
 
        if (data->hwtst_config.tx_type) {
                ret = ethnl_bitset32_size(&data->hwtst_config.tx_type,
@@ -130,8 +136,10 @@ static int tsconfig_fill_reply(struct sk_buff *skb,
        int ret;
 
        if (data->hwtst_config.flags) {
-               ret = nla_put_u32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS,
-                                 data->hwtst_config.flags);
+               ret = ethnl_put_bitset32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS,
+                                        &data->hwtst_config.flags, NULL,
+                                        __HWTSTAMP_FLAG_CNT,
+                                        ts_flags_names, compact);
                if (ret < 0)
                        return ret;
        }
@@ -180,7 +188,7 @@ const struct nla_policy ethnl_tsconfig_set_policy[ETHTOOL_A_TSCONFIG_MAX + 1] =
        [ETHTOOL_A_TSCONFIG_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
        [ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER] =
                NLA_POLICY_NESTED(ethnl_ts_hwtst_prov_policy),
-       [ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_U32 },
+       [ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_NESTED },
        [ETHTOOL_A_TSCONFIG_RX_FILTERS] = { .type = NLA_NESTED },
        [ETHTOOL_A_TSCONFIG_TX_TYPES] = { .type = NLA_NESTED },
 };
@@ -296,6 +304,7 @@ static int ethnl_set_tsconfig(struct ethnl_req_info *req_base,
 
        BUILD_BUG_ON(__HWTSTAMP_TX_CNT >= 32);
        BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT >= 32);
+       BUILD_BUG_ON(__HWTSTAMP_FLAG_CNT > 32);
 
        if (!netif_device_present(dev))
                return -ENODEV;
@@ -377,9 +386,13 @@ static int ethnl_set_tsconfig(struct ethnl_req_info *req_base,
        }
 
        if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS]) {
-               ethnl_update_u32(&hwtst_config.flags,
-                                tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS],
-                                &config_mod);
+               ret = ethnl_update_bitset32(&hwtst_config.flags,
+                                           __HWTSTAMP_FLAG_CNT,
+                                           tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS],
+                                           ts_flags_names, info->extack,
+                                           &config_mod);
+               if (ret < 0)
+                       goto err_free_hwprov;
        }
 
        ret = net_hwtstamp_validate(&hwtst_config);