Skip to content

Commit f967226

Browse files
committed
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/[email protected] ==================== Signed-off-by: Kory Maincent <[email protected]> Signed-off-by: David S. Miller <[email protected]>
2 parents 18de1e5 + ee60ea6 commit f967226

33 files changed

+732
-201
lines changed

Documentation/netlink/specs/ethtool.yaml

+57
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,26 @@ attribute-sets:
939939
-
940940
name: burst-tmr
941941
type: u32
942+
-
943+
name: ts
944+
attributes:
945+
-
946+
name: header
947+
type: nest
948+
nested-attributes: header
949+
-
950+
name: ts-layer
951+
type: u32
952+
-
953+
name: ts-list
954+
attributes:
955+
-
956+
name: header
957+
type: nest
958+
nested-attributes: header
959+
-
960+
name: ts-list-layer
961+
type: binary
942962

943963
operations:
944964
enum-model: directional
@@ -1689,3 +1709,40 @@ operations:
16891709
name: mm-ntf
16901710
doc: Notification for change in MAC Merge configuration.
16911711
notify: mm-get
1712+
-
1713+
name: ts-get
1714+
doc: Get current timestamp
1715+
1716+
attribute-set: ts
1717+
1718+
do:
1719+
request:
1720+
attributes:
1721+
- header
1722+
reply:
1723+
attributes: &ts
1724+
- header
1725+
- ts-layer
1726+
-
1727+
name: ts-list-get
1728+
doc: Get list of timestamp devices available on an interface
1729+
1730+
attribute-set: ts-list
1731+
1732+
do:
1733+
request:
1734+
attributes:
1735+
- header
1736+
reply:
1737+
attributes:
1738+
- header
1739+
- ts-list-layer
1740+
-
1741+
name: ts-set
1742+
doc: Set the timestamp device
1743+
1744+
attribute-set: ts
1745+
1746+
do:
1747+
request:
1748+
attributes: *ts

Documentation/networking/ethtool-netlink.rst

+63
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ Userspace to kernel:
225225
``ETHTOOL_MSG_RSS_GET`` get RSS settings
226226
``ETHTOOL_MSG_MM_GET`` get MAC merge layer state
227227
``ETHTOOL_MSG_MM_SET`` set MAC merge layer parameters
228+
``ETHTOOL_MSG_TS_GET`` get current timestamping
229+
``ETHTOOL_MSG_TS_LIST_GET`` list available timestampings
230+
``ETHTOOL_MSG_TS_SET`` set current timestamping
228231
===================================== =================================
229232

230233
Kernel to userspace:
@@ -268,6 +271,8 @@ Kernel to userspace:
268271
``ETHTOOL_MSG_PSE_GET_REPLY`` PSE parameters
269272
``ETHTOOL_MSG_RSS_GET_REPLY`` RSS settings
270273
``ETHTOOL_MSG_MM_GET_REPLY`` MAC merge layer status
274+
``ETHTOOL_MSG_TS_GET_REPLY`` current timestamping
275+
``ETHTOOL_MSG_TS_LIST_GET_REPLY`` available timestampings
271276
======================================== =================================
272277

273278
``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:
19941999
.. kernel-doc:: include/linux/ethtool.h
19952000
:identifiers: ethtool_mm_cfg
19962001

2002+
TS_GET
2003+
======
2004+
2005+
Gets current timestamping.
2006+
2007+
Request contents:
2008+
2009+
================================= ====== ====================
2010+
``ETHTOOL_A_TS_HEADER`` nested request header
2011+
================================= ====== ====================
2012+
2013+
Kernel response contents:
2014+
2015+
======================= ====== ==============================
2016+
``ETHTOOL_A_TS_HEADER`` nested reply header
2017+
``ETHTOOL_A_TS_LAYER`` u32 current timestamping
2018+
======================= ====== ==============================
2019+
2020+
This command get the current timestamp layer.
2021+
2022+
TS_LIST_GET
2023+
===========
2024+
2025+
Get the list of available timestampings.
2026+
2027+
Request contents:
2028+
2029+
================================= ====== ====================
2030+
``ETHTOOL_A_TS_HEADER`` nested request header
2031+
================================= ====== ====================
2032+
2033+
Kernel response contents:
2034+
2035+
=========================== ====== ==============================
2036+
``ETHTOOL_A_TS_HEADER`` nested reply header
2037+
``ETHTOOL_A_TS_LIST_LAYER`` binary available timestampings
2038+
=========================== ====== ==============================
2039+
2040+
This command lists all the possible timestamp layer available.
2041+
2042+
TS_SET
2043+
======
2044+
2045+
Modify the selected timestamping.
2046+
2047+
Request contents:
2048+
2049+
======================= ====== ===================
2050+
``ETHTOOL_A_TS_HEADER`` nested reply header
2051+
``ETHTOOL_A_TS_LAYER`` u32 timestamping
2052+
======================= ====== ===================
2053+
2054+
This command set the timestamping with one that should be listed by the
2055+
TSLIST_GET command.
2056+
19972057
Request translation
19982058
===================
19992059

@@ -2100,4 +2160,7 @@ are netlink only.
21002160
n/a ``ETHTOOL_MSG_PLCA_GET_STATUS``
21012161
n/a ``ETHTOOL_MSG_MM_GET``
21022162
n/a ``ETHTOOL_MSG_MM_SET``
2163+
n/a ``ETHTOOL_MSG_TS_GET``
2164+
n/a ``ETHTOOL_MSG_TS_LIST_GET``
2165+
n/a ``ETHTOOL_MSG_TS_SET``
21032166
=================================== =====================================

drivers/net/bonding/bond_main.c

+2-27
Original file line numberDiff line numberDiff line change
@@ -5755,10 +5755,8 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
57555755
{
57565756
struct bonding *bond = netdev_priv(bond_dev);
57575757
struct ethtool_ts_info ts_info;
5758-
const struct ethtool_ops *ops;
57595758
struct net_device *real_dev;
57605759
bool sw_tx_support = false;
5761-
struct phy_device *phydev;
57625760
struct list_head *iter;
57635761
struct slave *slave;
57645762
int ret = 0;
@@ -5769,29 +5767,12 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
57695767
rcu_read_unlock();
57705768

57715769
if (real_dev) {
5772-
ops = real_dev->ethtool_ops;
5773-
phydev = real_dev->phydev;
5774-
5775-
if (phy_has_tsinfo(phydev)) {
5776-
ret = phy_ts_info(phydev, info);
5777-
goto out;
5778-
} else if (ops->get_ts_info) {
5779-
ret = ops->get_ts_info(real_dev, info);
5780-
goto out;
5781-
}
5770+
ret = ethtool_get_ts_info_by_layer(real_dev, info);
57825771
} else {
57835772
/* Check if all slaves support software tx timestamping */
57845773
rcu_read_lock();
57855774
bond_for_each_slave_rcu(bond, slave, iter) {
5786-
ret = -1;
5787-
ops = slave->dev->ethtool_ops;
5788-
phydev = slave->dev->phydev;
5789-
5790-
if (phy_has_tsinfo(phydev))
5791-
ret = phy_ts_info(phydev, &ts_info);
5792-
else if (ops->get_ts_info)
5793-
ret = ops->get_ts_info(slave->dev, &ts_info);
5794-
5775+
ret = ethtool_get_ts_info_by_layer(slave->dev, &ts_info);
57955776
if (!ret && (ts_info.so_timestamping & SOF_TIMESTAMPING_TX_SOFTWARE)) {
57965777
sw_tx_support = true;
57975778
continue;
@@ -5803,15 +5784,9 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
58035784
rcu_read_unlock();
58045785
}
58055786

5806-
ret = 0;
5807-
info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
5808-
SOF_TIMESTAMPING_SOFTWARE;
58095787
if (sw_tx_support)
58105788
info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;
58115789

5812-
info->phc_index = -1;
5813-
5814-
out:
58155790
dev_put(real_dev);
58165791
return ret;
58175792
}

drivers/net/ethernet/cadence/macb.h

+10-5
Original file line numberDiff line numberDiff line change
@@ -1165,9 +1165,10 @@ struct macb_ptp_info {
11651165
int (*get_ts_info)(struct net_device *dev,
11661166
struct ethtool_ts_info *info);
11671167
int (*get_hwtst)(struct net_device *netdev,
1168-
struct ifreq *ifr);
1168+
struct kernel_hwtstamp_config *tstamp_config);
11691169
int (*set_hwtst)(struct net_device *netdev,
1170-
struct ifreq *ifr, int cmd);
1170+
struct kernel_hwtstamp_config *tstamp_config,
1171+
struct netlink_ext_ack *extack);
11711172
};
11721173

11731174
struct macb_pm_data {
@@ -1314,7 +1315,7 @@ struct macb {
13141315
struct ptp_clock *ptp_clock;
13151316
struct ptp_clock_info ptp_clock_info;
13161317
struct tsu_incr tsu_incr;
1317-
struct hwtstamp_config tstamp_config;
1318+
struct kernel_hwtstamp_config tstamp_config;
13181319

13191320
/* RX queue filer rule set*/
13201321
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
13631364

13641365
gem_ptp_rxstamp(bp, skb, desc);
13651366
}
1366-
int gem_get_hwtst(struct net_device *dev, struct ifreq *rq);
1367-
int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd);
1367+
1368+
int gem_get_hwtst(struct net_device *dev,
1369+
struct kernel_hwtstamp_config *tstamp_config);
1370+
int gem_set_hwtst(struct net_device *dev,
1371+
struct kernel_hwtstamp_config *tstamp_config,
1372+
struct netlink_ext_ack *extack);
13681373
#else
13691374
static inline void gem_ptp_init(struct net_device *ndev) { }
13701375
static inline void gem_ptp_remove(struct net_device *ndev) { }

drivers/net/ethernet/cadence/macb_main.c

+33-9
Original file line numberDiff line numberDiff line change
@@ -3773,18 +3773,38 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
37733773
if (!netif_running(dev))
37743774
return -EINVAL;
37753775

3776-
if (bp->ptp_info) {
3777-
switch (cmd) {
3778-
case SIOCSHWTSTAMP:
3779-
return bp->ptp_info->set_hwtst(dev, rq, cmd);
3780-
case SIOCGHWTSTAMP:
3781-
return bp->ptp_info->get_hwtst(dev, rq);
3782-
}
3783-
}
3784-
37853776
return phylink_mii_ioctl(bp->phylink, rq, cmd);
37863777
}
37873778

3779+
static int macb_hwtstamp_get(struct net_device *dev,
3780+
struct kernel_hwtstamp_config *cfg)
3781+
{
3782+
struct macb *bp = netdev_priv(dev);
3783+
3784+
if (!netif_running(dev))
3785+
return -EINVAL;
3786+
3787+
if (!bp->ptp_info)
3788+
return -EOPNOTSUPP;
3789+
3790+
return bp->ptp_info->get_hwtst(dev, cfg);
3791+
}
3792+
3793+
static int macb_hwtstamp_set(struct net_device *dev,
3794+
struct kernel_hwtstamp_config *cfg,
3795+
struct netlink_ext_ack *extack)
3796+
{
3797+
struct macb *bp = netdev_priv(dev);
3798+
3799+
if (!netif_running(dev))
3800+
return -EINVAL;
3801+
3802+
if (!bp->ptp_info)
3803+
return -EOPNOTSUPP;
3804+
3805+
return bp->ptp_info->set_hwtst(dev, cfg, extack);
3806+
}
3807+
37883808
static inline void macb_set_txcsum_feature(struct macb *bp,
37893809
netdev_features_t features)
37903810
{
@@ -3884,6 +3904,8 @@ static const struct net_device_ops macb_netdev_ops = {
38843904
#endif
38853905
.ndo_set_features = macb_set_features,
38863906
.ndo_features_check = macb_features_check,
3907+
.ndo_hwtstamp_set = macb_hwtstamp_set,
3908+
.ndo_hwtstamp_get = macb_hwtstamp_get,
38873909
};
38883910

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

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

drivers/net/ethernet/cadence/macb_ptp.c

+10-18
Original file line numberDiff line numberDiff line change
@@ -374,19 +374,16 @@ static int gem_ptp_set_ts_mode(struct macb *bp,
374374
return 0;
375375
}
376376

377-
int gem_get_hwtst(struct net_device *dev, struct ifreq *rq)
377+
int gem_get_hwtst(struct net_device *dev,
378+
struct kernel_hwtstamp_config *tstamp_config)
378379
{
379-
struct hwtstamp_config *tstamp_config;
380380
struct macb *bp = netdev_priv(dev);
381381

382-
tstamp_config = &bp->tstamp_config;
382+
*tstamp_config = bp->tstamp_config;
383383
if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0)
384384
return -EOPNOTSUPP;
385385

386-
if (copy_to_user(rq->ifr_data, tstamp_config, sizeof(*tstamp_config)))
387-
return -EFAULT;
388-
else
389-
return 0;
386+
return 0;
390387
}
391388

392389
static void gem_ptp_set_one_step_sync(struct macb *bp, u8 enable)
@@ -401,22 +398,18 @@ static void gem_ptp_set_one_step_sync(struct macb *bp, u8 enable)
401398
macb_writel(bp, NCR, reg_val & ~MACB_BIT(OSSMODE));
402399
}
403400

404-
int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd)
401+
int gem_set_hwtst(struct net_device *dev,
402+
struct kernel_hwtstamp_config *tstamp_config,
403+
struct netlink_ext_ack *extack)
405404
{
406405
enum macb_bd_control tx_bd_control = TSTAMP_DISABLED;
407406
enum macb_bd_control rx_bd_control = TSTAMP_DISABLED;
408-
struct hwtstamp_config *tstamp_config;
409407
struct macb *bp = netdev_priv(dev);
410408
u32 regval;
411409

412-
tstamp_config = &bp->tstamp_config;
413410
if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0)
414411
return -EOPNOTSUPP;
415412

416-
if (copy_from_user(tstamp_config, ifr->ifr_data,
417-
sizeof(*tstamp_config)))
418-
return -EFAULT;
419-
420413
switch (tstamp_config->tx_type) {
421414
case HWTSTAMP_TX_OFF:
422415
break;
@@ -463,12 +456,11 @@ int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd)
463456
return -ERANGE;
464457
}
465458

459+
bp->tstamp_config = *tstamp_config;
460+
466461
if (gem_ptp_set_ts_mode(bp, tx_bd_control, rx_bd_control) != 0)
467462
return -ERANGE;
468463

469-
if (copy_to_user(ifr->ifr_data, tstamp_config, sizeof(*tstamp_config)))
470-
return -EFAULT;
471-
else
472-
return 0;
464+
return 0;
473465
}
474466

0 commit comments

Comments
 (0)