Commit f9672265 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-make-timestamping-selectable'

Kory Maincent says:

====================
net: Make timestamping selectable

Up until now, there was no way to let the user select the layer at
which time stamping occurs. The stack assumed that PHY time stamping
is always preferred, but some MAC/PHY combinations were buggy.

This series updates the default MAC/PHY default timestamping and aims to
allow the user to select the desired layer administratively.

Changes in v2:
- Move selected_timestamping_layer variable of the concerned patch.
- Use sysfs_streq instead of strmcmp.
- Use the PHY timestamp only if available.

Changes in v3:
- Expose the PTP choice to ethtool instead of sysfs.
  You can test it with the ethtool source on branch feature_ptp of:
  https://github.com/kmaincent/ethtool
- Added a devicetree binding to select the preferred timestamp.

Changes in v4:
- Move on to ethtool netlink instead of ioctl.
- Add a netdev notifier to allow packet trapping by the MAC in case of PHY
  time stamping.
- Add a PHY whitelist to not break the old PHY default time-stamping
  preference API.

Changes in v5:
- Update to ndo_hwstamp_get/set. This bring several new patches.
- Add few patches to make the glue.
- Convert macb to ndo_hwstamp_get/set.
- Add netlink specs description of new ethtool commands.
- Removed netdev notifier.
- Split the patches that expose the timestamping to userspace to separate
  the core and ethtool development.
- Add description of software timestamping.
- Convert PHYs hwtstamp callback to use kernel_hwtstamp_config.

Changes in v6:
- Few fixes from the reviews.
- Replace the allowlist to default_timestamp flag to know which phy is
  using old API behavior.
- Rename the timestamping layer enum values.
- Move to a simple enum instead of the mix between enum and bitfield.
- Update ts_info and ts-set in software timestamping case.

Changes in v7:
- Fix a temporary build error.
- Link to v6: https://lore.kernel.org/r/20231019-feature_ptp_netnext-v6-0-71affc27b0e5@bootlin.com


====================

Signed-off-by: default avatarKory Maincent <kory.maincent@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 18de1e51 ee60ea6b
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -939,6 +939,26 @@ attribute-sets:
      -
        name: burst-tmr
        type: u32
  -
    name: ts
    attributes:
      -
        name: header
        type: nest
        nested-attributes: header
      -
        name: ts-layer
        type: u32
  -
    name: ts-list
    attributes:
      -
        name: header
        type: nest
        nested-attributes: header
      -
        name: ts-list-layer
        type: binary

operations:
  enum-model: directional
@@ -1689,3 +1709,40 @@ operations:
      name: mm-ntf
      doc: Notification for change in MAC Merge configuration.
      notify: mm-get
    -
      name: ts-get
      doc: Get current timestamp

      attribute-set: ts

      do:
        request:
          attributes:
            - header
        reply:
          attributes: &ts
            - header
            - ts-layer
    -
      name: ts-list-get
      doc: Get list of timestamp devices available on an interface

      attribute-set: ts-list

      do:
        request:
          attributes:
            - header
        reply:
          attributes:
            - header
            - ts-list-layer
    -
      name: ts-set
      doc: Set the timestamp device

      attribute-set: ts

      do:
        request:
          attributes: *ts
+63 −0
Original line number Diff line number Diff line
@@ -225,6 +225,9 @@ Userspace to kernel:
  ``ETHTOOL_MSG_RSS_GET``               get RSS settings
  ``ETHTOOL_MSG_MM_GET``                get MAC merge layer state
  ``ETHTOOL_MSG_MM_SET``                set MAC merge layer parameters
  ``ETHTOOL_MSG_TS_GET``                get current timestamping
  ``ETHTOOL_MSG_TS_LIST_GET``           list available timestampings
  ``ETHTOOL_MSG_TS_SET``                set current timestamping
  ===================================== =================================

Kernel to userspace:
@@ -268,6 +271,8 @@ Kernel to userspace:
  ``ETHTOOL_MSG_PSE_GET_REPLY``            PSE parameters
  ``ETHTOOL_MSG_RSS_GET_REPLY``            RSS settings
  ``ETHTOOL_MSG_MM_GET_REPLY``             MAC merge layer status
  ``ETHTOOL_MSG_TS_GET_REPLY``             current timestamping
  ``ETHTOOL_MSG_TS_LIST_GET_REPLY``        available timestampings
  ======================================== =================================

``GET`` requests are sent by userspace applications to retrieve device
@@ -1994,6 +1999,61 @@ The attributes are propagated to the driver through the following structure:
.. kernel-doc:: include/linux/ethtool.h
    :identifiers: ethtool_mm_cfg

TS_GET
======

Gets current timestamping.

Request contents:

  =================================  ======  ====================
  ``ETHTOOL_A_TS_HEADER``            nested  request header
  =================================  ======  ====================

Kernel response contents:

  =======================  ======  ==============================
  ``ETHTOOL_A_TS_HEADER``  nested  reply header
  ``ETHTOOL_A_TS_LAYER``   u32     current timestamping
  =======================  ======  ==============================

This command get the current timestamp layer.

TS_LIST_GET
===========

Get the list of available timestampings.

Request contents:

  =================================  ======  ====================
  ``ETHTOOL_A_TS_HEADER``            nested  request header
  =================================  ======  ====================

Kernel response contents:

  ===========================  ======  ==============================
  ``ETHTOOL_A_TS_HEADER``      nested  reply header
  ``ETHTOOL_A_TS_LIST_LAYER``  binary  available timestampings
  ===========================  ======  ==============================

This command lists all the possible timestamp layer available.

TS_SET
======

Modify the selected timestamping.

Request contents:

  =======================  ======  ===================
  ``ETHTOOL_A_TS_HEADER``  nested  reply header
  ``ETHTOOL_A_TS_LAYER``   u32     timestamping
  =======================  ======  ===================

This command set the timestamping with one that should be listed by the
TSLIST_GET command.

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

@@ -2100,4 +2160,7 @@ are netlink only.
  n/a                                 ``ETHTOOL_MSG_PLCA_GET_STATUS``
  n/a                                 ``ETHTOOL_MSG_MM_GET``
  n/a                                 ``ETHTOOL_MSG_MM_SET``
  n/a                                 ``ETHTOOL_MSG_TS_GET``
  n/a                                 ``ETHTOOL_MSG_TS_LIST_GET``
  n/a                                 ``ETHTOOL_MSG_TS_SET``
  =================================== =====================================
+2 −27
Original line number Diff line number Diff line
@@ -5755,10 +5755,8 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
{
	struct bonding *bond = netdev_priv(bond_dev);
	struct ethtool_ts_info ts_info;
	const struct ethtool_ops *ops;
	struct net_device *real_dev;
	bool sw_tx_support = false;
	struct phy_device *phydev;
	struct list_head *iter;
	struct slave *slave;
	int ret = 0;
@@ -5769,29 +5767,12 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
	rcu_read_unlock();

	if (real_dev) {
		ops = real_dev->ethtool_ops;
		phydev = real_dev->phydev;

		if (phy_has_tsinfo(phydev)) {
			ret = phy_ts_info(phydev, info);
			goto out;
		} else if (ops->get_ts_info) {
			ret = ops->get_ts_info(real_dev, info);
			goto out;
		}
		ret = ethtool_get_ts_info_by_layer(real_dev, info);
	} else {
		/* Check if all slaves support software tx timestamping */
		rcu_read_lock();
		bond_for_each_slave_rcu(bond, slave, iter) {
			ret = -1;
			ops = slave->dev->ethtool_ops;
			phydev = slave->dev->phydev;

			if (phy_has_tsinfo(phydev))
				ret = phy_ts_info(phydev, &ts_info);
			else if (ops->get_ts_info)
				ret = ops->get_ts_info(slave->dev, &ts_info);

			ret = ethtool_get_ts_info_by_layer(slave->dev, &ts_info);
			if (!ret && (ts_info.so_timestamping & SOF_TIMESTAMPING_TX_SOFTWARE)) {
				sw_tx_support = true;
				continue;
@@ -5803,15 +5784,9 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
		rcu_read_unlock();
	}

	ret = 0;
	info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
				SOF_TIMESTAMPING_SOFTWARE;
	if (sw_tx_support)
		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;

	info->phc_index = -1;

out:
	dev_put(real_dev);
	return ret;
}
+10 −5
Original line number Diff line number Diff line
@@ -1165,9 +1165,10 @@ struct macb_ptp_info {
	int (*get_ts_info)(struct net_device *dev,
			   struct ethtool_ts_info *info);
	int (*get_hwtst)(struct net_device *netdev,
			 struct ifreq *ifr);
			 struct kernel_hwtstamp_config *tstamp_config);
	int (*set_hwtst)(struct net_device *netdev,
			 struct ifreq *ifr, int cmd);
			 struct kernel_hwtstamp_config *tstamp_config,
			 struct netlink_ext_ack *extack);
};

struct macb_pm_data {
@@ -1314,7 +1315,7 @@ struct macb {
	struct ptp_clock *ptp_clock;
	struct ptp_clock_info ptp_clock_info;
	struct tsu_incr tsu_incr;
	struct hwtstamp_config tstamp_config;
	struct kernel_hwtstamp_config tstamp_config;

	/* RX queue filer rule set*/
	struct ethtool_rx_fs_list rx_fs_list;
@@ -1363,8 +1364,12 @@ static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, stru

	gem_ptp_rxstamp(bp, skb, desc);
}
int gem_get_hwtst(struct net_device *dev, struct ifreq *rq);
int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd);

int gem_get_hwtst(struct net_device *dev,
		  struct kernel_hwtstamp_config *tstamp_config);
int gem_set_hwtst(struct net_device *dev,
		  struct kernel_hwtstamp_config *tstamp_config,
		  struct netlink_ext_ack *extack);
#else
static inline void gem_ptp_init(struct net_device *ndev) { }
static inline void gem_ptp_remove(struct net_device *ndev) { }
+33 −9
Original line number Diff line number Diff line
@@ -3773,16 +3773,36 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
	if (!netif_running(dev))
		return -EINVAL;

	if (bp->ptp_info) {
		switch (cmd) {
		case SIOCSHWTSTAMP:
			return bp->ptp_info->set_hwtst(dev, rq, cmd);
		case SIOCGHWTSTAMP:
			return bp->ptp_info->get_hwtst(dev, rq);
	return phylink_mii_ioctl(bp->phylink, rq, cmd);
}

static int macb_hwtstamp_get(struct net_device *dev,
			     struct kernel_hwtstamp_config *cfg)
{
	struct macb *bp = netdev_priv(dev);

	if (!netif_running(dev))
		return -EINVAL;

	if (!bp->ptp_info)
		return -EOPNOTSUPP;

	return bp->ptp_info->get_hwtst(dev, cfg);
}

	return phylink_mii_ioctl(bp->phylink, rq, cmd);
static int macb_hwtstamp_set(struct net_device *dev,
			     struct kernel_hwtstamp_config *cfg,
			     struct netlink_ext_ack *extack)
{
	struct macb *bp = netdev_priv(dev);

	if (!netif_running(dev))
		return -EINVAL;

	if (!bp->ptp_info)
		return -EOPNOTSUPP;

	return bp->ptp_info->set_hwtst(dev, cfg, extack);
}

static inline void macb_set_txcsum_feature(struct macb *bp,
@@ -3884,6 +3904,8 @@ static const struct net_device_ops macb_netdev_ops = {
#endif
	.ndo_set_features	= macb_set_features,
	.ndo_features_check	= macb_features_check,
	.ndo_hwtstamp_set	= macb_hwtstamp_set,
	.ndo_hwtstamp_get	= macb_hwtstamp_get,
};

/* Configure peripheral capabilities according to device tree
@@ -4539,6 +4561,8 @@ static const struct net_device_ops at91ether_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= at91ether_poll_controller,
#endif
	.ndo_hwtstamp_set	= macb_hwtstamp_set,
	.ndo_hwtstamp_get	= macb_hwtstamp_get,
};

static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk,
Loading