mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 04:45:43 +01:00
net: ethtool: let tsconfig reach a PHY-only timestamp provider
TSCONFIG_GET and TSCONFIG_SET reject a device that implements neither
hwtstamp NDO, even when its PHY can serve the request. The ioctls they
meant to replace handle it, so the two interfaces disagree on the same
hardware and user space has to pick one.
Accept the default timestamping PHY and an already installed provider on
both sides. On the set side the test moves into ethnl_set_tsconfig() as
the validate callback runs without rtnl. On the get side it stays ahead
of ethnl_ops_begin(), so a device that can serve nothing keeps failing
with EOPNOTSUPP and a dump still skips it rather than stopping there.
A netdev provider needs ndo_hwtstamp_set to be programmed at all, so
don't pick that source without it, and test for ndo_hwtstamp_get before
calling it.
Fixes: 6e9e2eed4f ("net: ethtool: Add support for tsconfig command to get/set hwtstamp config")
Signed-off-by: Nicolai Buchwitz <[email protected]>
Reviewed-by: Maxime Chevallier <[email protected]>
Reviewed-by: Kory Maincent <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
This commit is contained in:
1 parent
8ae3f4067b
commit
036778a4fa
2 files changed
+12
-15
No files matched your search
@@ -267,7 +267,8 @@ int dev_get_hwtstamp_phylib(struct net_device *dev,
|
||||
hwprov->phydev)
|
||||
return phy_hwtstamp_get(hwprov->phydev, cfg);
|
||||
|
||||
if (hwprov->source == HWTSTAMP_SOURCE_NETDEV)
|
||||
if (hwprov->source == HWTSTAMP_SOURCE_NETDEV &&
|
||||
dev->netdev_ops->ndo_hwtstamp_get)
|
||||
return dev->netdev_ops->ndo_hwtstamp_get(dev, cfg);
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
+10
-14
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/net_tstamp.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/ptp_clock_kernel.h>
|
||||
#include <net/netdev_lock.h>
|
||||
|
||||
@@ -42,7 +43,9 @@ static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,
|
||||
struct kernel_hwtstamp_config cfg = {};
|
||||
int ret;
|
||||
|
||||
if (!dev->netdev_ops->ndo_hwtstamp_get)
|
||||
if (!dev->netdev_ops->ndo_hwtstamp_get &&
|
||||
!phy_is_default_hwtstamp(dev->phydev) &&
|
||||
!netdev_ops_lock_dereference(dev->hwprov, dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = ethnl_ops_begin(dev);
|
||||
@@ -248,17 +251,6 @@ err_cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ethnl_set_tsconfig_validate(struct ethnl_req_info *req_base,
|
||||
struct genl_info *info)
|
||||
{
|
||||
const struct net_device_ops *ops = req_base->dev->netdev_ops;
|
||||
|
||||
if (!ops->ndo_hwtstamp_set || !ops->ndo_hwtstamp_get)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct hwtstamp_provider *
|
||||
tsconfig_set_hwprov_from_desc(struct net_device *dev,
|
||||
struct genl_info *info,
|
||||
@@ -272,7 +264,7 @@ tsconfig_set_hwprov_from_desc(struct net_device *dev,
|
||||
int ret;
|
||||
|
||||
ret = ethtool_net_get_ts_info_by_phc(dev, &ts_info, hwprov_desc);
|
||||
if (!ret) {
|
||||
if (!ret && dev->netdev_ops->ndo_hwtstamp_set) {
|
||||
/* Found */
|
||||
source = HWTSTAMP_SOURCE_NETDEV;
|
||||
} else {
|
||||
@@ -313,6 +305,11 @@ static int ethnl_set_tsconfig(struct ethnl_req_info *req_base,
|
||||
if (!netif_device_present(dev))
|
||||
return -ENODEV;
|
||||
|
||||
if (!dev->netdev_ops->ndo_hwtstamp_set &&
|
||||
!phy_is_default_hwtstamp(dev->phydev) &&
|
||||
!netdev_ops_lock_dereference(dev->hwprov, dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER]) {
|
||||
struct hwtstamp_provider_desc __hwprov_desc = {.index = -1};
|
||||
struct hwtstamp_provider *__hwprov;
|
||||
@@ -459,6 +456,5 @@ const struct ethnl_request_ops ethnl_tsconfig_request_ops = {
|
||||
.reply_size = tsconfig_reply_size,
|
||||
.fill_reply = tsconfig_fill_reply,
|
||||
|
||||
.set_validate = ethnl_set_tsconfig_validate,
|
||||
.set = ethnl_set_tsconfig,
|
||||
};
|
||||
Reference in new issue
Block a user