Skip to content

Commit

Permalink
net: ethtool: Add support for tsconfig command to get/set hwtstamp co…
Browse files Browse the repository at this point in the history
…nfig

Introduce support for ETHTOOL_MSG_TSCONFIG_GET/SET ethtool netlink socket
to read and configure hwtstamp configuration of a PHC provider. Note that
simultaneous hwtstamp isn't supported; configuring a new one disables the
previous setting.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Kory Maincent authored and David S. Miller committed Dec 16, 2024
1 parent b9e3f7d commit 6e9e2ee
Showing 10 changed files with 655 additions and 26 deletions.
56 changes: 56 additions & 0 deletions Documentation/netlink/specs/ethtool.yaml
Original file line number Diff line number Diff line change
@@ -1489,6 +1489,33 @@ attribute-sets:
-
name: downstream-sfp-name
type: string
-
name: tsconfig
attr-cnt-name: __ethtool-a-tsconfig-cnt
attributes:
-
name: unspec
type: unused
value: 0
-
name: header
type: nest
nested-attributes: header
-
name: hwtstamp-provider
type: nest
nested-attributes: ts-hwtstamp-provider
-
name: tx-types
type: nest
nested-attributes: bitset
-
name: rx-filters
type: nest
nested-attributes: bitset
-
name: hwtstamp-flags
type: u32

operations:
enum-model: directional
@@ -2314,3 +2341,32 @@ operations:
name: phy-ntf
doc: Notification for change in PHY devices.
notify: phy-get
-
name: tsconfig-get
doc: Get hwtstamp config.

attribute-set: tsconfig

do: &tsconfig-get-op
request:
attributes:
- header
reply:
attributes: &tsconfig
- header
- hwtstamp-provider
- tx-types
- rx-filters
- hwtstamp-flags
dump: *tsconfig-get-op
-
name: tsconfig-set
doc: Set hwtstamp config.

attribute-set: tsconfig

do:
request:
attributes: *tsconfig
reply:
attributes: *tsconfig
75 changes: 75 additions & 0 deletions Documentation/networking/ethtool-netlink.rst
Original file line number Diff line number Diff line change
@@ -237,6 +237,8 @@ Userspace to kernel:
``ETHTOOL_MSG_MM_SET`` set MAC merge layer parameters
``ETHTOOL_MSG_MODULE_FW_FLASH_ACT`` flash transceiver module firmware
``ETHTOOL_MSG_PHY_GET`` get Ethernet PHY information
``ETHTOOL_MSG_TSCONFIG_GET`` get hw timestamping configuration
``ETHTOOL_MSG_TSCONFIG_SET`` set hw timestamping configuration
===================================== =================================

Kernel to userspace:
@@ -286,6 +288,8 @@ Kernel to userspace:
``ETHTOOL_MSG_MODULE_FW_FLASH_NTF`` transceiver module flash updates
``ETHTOOL_MSG_PHY_GET_REPLY`` Ethernet PHY information
``ETHTOOL_MSG_PHY_NTF`` Ethernet PHY information change
``ETHTOOL_MSG_TSCONFIG_GET_REPLY`` hw timestamping configuration
``ETHTOOL_MSG_TSCONFIG_SET_REPLY`` new hw timestamping configuration
======================================== =================================

``GET`` requests are sent by userspace applications to retrieve device
@@ -2244,6 +2248,75 @@ Kernel response contents:
When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
another PHY.

TSCONFIG_GET
============

Retrieves the information about the current hardware timestamping source and
configuration.

It is similar to the deprecated ``SIOCGHWTSTAMP`` ioctl request.

Request contents:

==================================== ====== ==========================
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
==================================== ====== ==========================

Kernel response contents:

======================================== ====== ============================
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
======================================== ====== ============================

When set the ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` attribute identifies the
source of the hw timestamping provider. It is composed by
``ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX`` attribute which describe the index of
the PTP device and ``ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER`` which describe
the qualifier of the timestamp.

When set the ``ETHTOOL_A_TSCONFIG_TX_TYPES``, ``ETHTOOL_A_TSCONFIG_RX_FILTERS``
and the ``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` attributes identify the Tx
type, the Rx filter and the flags configured for the current hw timestamping
provider. The attributes are propagated to the driver through the following
structure:

.. kernel-doc:: include/linux/net_tstamp.h
:identifiers: kernel_hwtstamp_config

TSCONFIG_SET
============

Set the information about the current hardware timestamping source and
configuration.

It is similar to the deprecated ``SIOCSHWTSTAMP`` ioctl request.

Request contents:

======================================== ====== ============================
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
======================================== ====== ============================

Kernel response contents:

======================================== ====== ============================
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
======================================== ====== ============================

For a description of each attribute, see ``TSCONFIG_GET``.

Request translation
===================

@@ -2352,4 +2425,6 @@ are netlink only.
n/a ``ETHTOOL_MSG_MM_SET``
n/a ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT``
n/a ``ETHTOOL_MSG_PHY_GET``
``SIOCGHWTSTAMP`` ``ETHTOOL_MSG_TSCONFIG_GET``
``SIOCSHWTSTAMP`` ``ETHTOOL_MSG_TSCONFIG_SET``
=================================== =====================================
38 changes: 24 additions & 14 deletions Documentation/networking/timestamping.rst
Original file line number Diff line number Diff line change
@@ -525,8 +525,8 @@ implicitly defined. ts[0] holds a software timestamp if set, ts[1]
is again deprecated and ts[2] holds a hardware timestamp if set.


3. Hardware Timestamping configuration: SIOCSHWTSTAMP and SIOCGHWTSTAMP
=======================================================================
3. Hardware Timestamping configuration: ETHTOOL_MSG_TSCONFIG_SET/GET
====================================================================

Hardware time stamping must also be initialized for each device driver
that is expected to do hardware time stamping. The parameter is defined in
@@ -539,12 +539,14 @@ include/uapi/linux/net_tstamp.h as::
};

Desired behavior is passed into the kernel and to a specific device by
calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose
ifr_data points to a struct hwtstamp_config. The tx_type and
rx_filter are hints to the driver what it is expected to do. If
the requested fine-grained filtering for incoming packets is not
supported, the driver may time stamp more than just the requested types
of packets.
calling the tsconfig netlink socket ``ETHTOOL_MSG_TSCONFIG_SET``.
The ``ETHTOOL_A_TSCONFIG_TX_TYPES``, ``ETHTOOL_A_TSCONFIG_RX_FILTERS`` and
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` netlink attributes are then used to set
the struct hwtstamp_config accordingly.

The ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` netlink nested attribute is used
to select the source of the hardware time stamping. It is composed of an index
for the device source and a qualifier for the type of time stamping.

Drivers are free to use a more permissive configuration than the requested
configuration. It is expected that drivers should only implement directly the
@@ -563,9 +565,16 @@ Only a processes with admin rights may change the configuration. User
space is responsible to ensure that multiple processes don't interfere
with each other and that the settings are reset.

Any process can read the actual configuration by passing this
structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has
not been implemented in all drivers.
Any process can read the actual configuration by requesting tsconfig netlink
socket ``ETHTOOL_MSG_TSCONFIG_GET``.

The legacy configuration is the use of the ioctl(SIOCSHWTSTAMP) with a pointer
to a struct ifreq whose ifr_data points to a struct hwtstamp_config.
The tx_type and rx_filter are hints to the driver what it is expected to do.
If the requested fine-grained filtering for incoming packets is not
supported, the driver may time stamp more than just the requested types
of packets. ioctl(SIOCGHWTSTAMP) is used in the same way as the
ioctl(SIOCSHWTSTAMP). However, this has not been implemented in all drivers.

::

@@ -610,9 +619,10 @@ not been implemented in all drivers.
--------------------------------------------------------

A driver which supports hardware time stamping must support the
SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
the actual values as described in the section on SIOCSHWTSTAMP. It
should also support SIOCGHWTSTAMP.
ndo_hwtstamp_set NDO or the legacy SIOCSHWTSTAMP ioctl and update the
supplied struct hwtstamp_config with the actual values as described in
the section on SIOCSHWTSTAMP. It should also support ndo_hwtstamp_get or
the legacy SIOCGHWTSTAMP.

Time stamps for received packets must be stored in the skb. To get a pointer
to the shared time stamp structure of the skb call skb_hwtstamps(). Then
16 changes: 16 additions & 0 deletions include/uapi/linux/ethtool_netlink_generated.h
Original file line number Diff line number Diff line change
@@ -694,6 +694,18 @@ enum {
ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)
};

enum {
ETHTOOL_A_TSCONFIG_UNSPEC,
ETHTOOL_A_TSCONFIG_HEADER,
ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER,
ETHTOOL_A_TSCONFIG_TX_TYPES,
ETHTOOL_A_TSCONFIG_RX_FILTERS,
ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS,

__ETHTOOL_A_TSCONFIG_CNT,
ETHTOOL_A_TSCONFIG_MAX = (__ETHTOOL_A_TSCONFIG_CNT - 1)
};

enum {
ETHTOOL_MSG_USER_NONE = 0,
ETHTOOL_MSG_STRSET_GET = 1,
@@ -741,6 +753,8 @@ enum {
ETHTOOL_MSG_MM_SET,
ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
ETHTOOL_MSG_PHY_GET,
ETHTOOL_MSG_TSCONFIG_GET,
ETHTOOL_MSG_TSCONFIG_SET,

__ETHTOOL_MSG_USER_CNT,
ETHTOOL_MSG_USER_MAX = (__ETHTOOL_MSG_USER_CNT - 1)
@@ -794,6 +808,8 @@ enum {
ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
ETHTOOL_MSG_PHY_GET_REPLY,
ETHTOOL_MSG_PHY_NTF,
ETHTOOL_MSG_TSCONFIG_GET_REPLY,
ETHTOOL_MSG_TSCONFIG_SET_REPLY,

__ETHTOOL_MSG_KERNEL_CNT,
ETHTOOL_MSG_KERNEL_MAX = (__ETHTOOL_MSG_KERNEL_CNT - 1)
2 changes: 1 addition & 1 deletion net/ethtool/Makefile
Original file line number Diff line number Diff line change
@@ -9,4 +9,4 @@ ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o rss.o \
channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
tunnels.o fec.o eeprom.o stats.o phc_vclocks.o mm.o \
module.o cmis_fw_update.o cmis_cdb.o pse-pd.o plca.o mm.o \
phy.o
phy.o tsconfig.o
27 changes: 17 additions & 10 deletions net/ethtool/common.c
Original file line number Diff line number Diff line change
@@ -797,7 +797,7 @@ int ethtool_net_get_ts_info_by_phc(struct net_device *dev,
return -ENODEV;
}

int
struct phy_device *
ethtool_phy_get_ts_info_by_phc(struct net_device *dev,
struct kernel_ethtool_ts_info *info,
struct hwtstamp_provider_desc *hwprov_desc)
@@ -806,7 +806,7 @@ ethtool_phy_get_ts_info_by_phc(struct net_device *dev,

/* Only precise qualifier is supported in phydev */
if (hwprov_desc->qualifier != HWTSTAMP_PROVIDER_QUALIFIER_PRECISE)
return -ENODEV;
return ERR_PTR(-ENODEV);

/* Look in the phy topology */
if (dev->link_topo) {
@@ -820,26 +820,26 @@ ethtool_phy_get_ts_info_by_phc(struct net_device *dev,
ethtool_init_tsinfo(info);
err = phy_ts_info(pdn->phy, info);
if (err)
return err;
return ERR_PTR(err);

if (info->phc_index == hwprov_desc->index)
return 0;
return pdn->phy;
}
return -ENODEV;
return ERR_PTR(-ENODEV);
}

/* Look on the dev->phydev */
if (phy_has_tsinfo(dev->phydev)) {
ethtool_init_tsinfo(info);
err = phy_ts_info(dev->phydev, info);
if (err)
return err;
return ERR_PTR(err);

if (info->phc_index == hwprov_desc->index)
return 0;
return dev->phydev;
}

return -ENODEV;
return ERR_PTR(-ENODEV);
}

int ethtool_get_ts_info_by_phc(struct net_device *dev,
@@ -849,8 +849,15 @@ int ethtool_get_ts_info_by_phc(struct net_device *dev,
int err;

err = ethtool_net_get_ts_info_by_phc(dev, info, hwprov_desc);
if (err == -ENODEV)
err = ethtool_phy_get_ts_info_by_phc(dev, info, hwprov_desc);
if (err == -ENODEV) {
struct phy_device *phy;

phy = ethtool_phy_get_ts_info_by_phc(dev, info, hwprov_desc);
if (IS_ERR(phy))
err = PTR_ERR(phy);
else
err = 0;
}

info->so_timestamping |= SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE;
2 changes: 1 addition & 1 deletion net/ethtool/common.h
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ int ethtool_get_ts_info_by_phc(struct net_device *dev,
int ethtool_net_get_ts_info_by_phc(struct net_device *dev,
struct kernel_ethtool_ts_info *info,
struct hwtstamp_provider_desc *hwprov_desc);
int
struct phy_device *
ethtool_phy_get_ts_info_by_phc(struct net_device *dev,
struct kernel_ethtool_ts_info *info,
struct hwtstamp_provider_desc *hwprov_desc);
18 changes: 18 additions & 0 deletions net/ethtool/netlink.c
Original file line number Diff line number Diff line change
@@ -394,6 +394,8 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = {
[ETHTOOL_MSG_PLCA_GET_STATUS] = &ethnl_plca_status_request_ops,
[ETHTOOL_MSG_MM_GET] = &ethnl_mm_request_ops,
[ETHTOOL_MSG_MM_SET] = &ethnl_mm_request_ops,
[ETHTOOL_MSG_TSCONFIG_GET] = &ethnl_tsconfig_request_ops,
[ETHTOOL_MSG_TSCONFIG_SET] = &ethnl_tsconfig_request_ops,
};

static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
@@ -1243,6 +1245,22 @@ static const struct genl_ops ethtool_genl_ops[] = {
.policy = ethnl_phy_get_policy,
.maxattr = ARRAY_SIZE(ethnl_phy_get_policy) - 1,
},
{
.cmd = ETHTOOL_MSG_TSCONFIG_GET,
.doit = ethnl_default_doit,
.start = ethnl_default_start,
.dumpit = ethnl_default_dumpit,
.done = ethnl_default_done,
.policy = ethnl_tsconfig_get_policy,
.maxattr = ARRAY_SIZE(ethnl_tsconfig_get_policy) - 1,
},
{
.cmd = ETHTOOL_MSG_TSCONFIG_SET,
.flags = GENL_UNS_ADMIN_PERM,
.doit = ethnl_default_set_doit,
.policy = ethnl_tsconfig_set_policy,
.maxattr = ARRAY_SIZE(ethnl_tsconfig_set_policy) - 1,
},
};

static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
3 changes: 3 additions & 0 deletions net/ethtool/netlink.h
Original file line number Diff line number Diff line change
@@ -435,6 +435,7 @@ extern const struct ethnl_request_ops ethnl_plca_cfg_request_ops;
extern const struct ethnl_request_ops ethnl_plca_status_request_ops;
extern const struct ethnl_request_ops ethnl_mm_request_ops;
extern const struct ethnl_request_ops ethnl_phy_request_ops;
extern const struct ethnl_request_ops ethnl_tsconfig_request_ops;

extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
@@ -485,6 +486,8 @@ extern const struct nla_policy ethnl_mm_get_policy[ETHTOOL_A_MM_HEADER + 1];
extern const struct nla_policy ethnl_mm_set_policy[ETHTOOL_A_MM_MAX + 1];
extern const struct nla_policy ethnl_module_fw_flash_act_policy[ETHTOOL_A_MODULE_FW_FLASH_PASSWORD + 1];
extern const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1];
extern const struct nla_policy ethnl_tsconfig_get_policy[ETHTOOL_A_TSCONFIG_HEADER + 1];
extern const struct nla_policy ethnl_tsconfig_set_policy[ETHTOOL_A_TSCONFIG_MAX + 1];

int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
444 changes: 444 additions & 0 deletions net/ethtool/tsconfig.c

Large diffs are not rendered by default.

0 comments on commit 6e9e2ee

Please sign in to comment.