Skip to content

Commit 152c75e

Browse files
kmaincentdavem330
authored andcommitted
net: ethtool: ts: Let the active time stamping layer be selectable
Now that the current timestamp is saved in a variable lets add the ETHTOOL_MSG_TS_SET ethtool netlink socket to make it selectable. Signed-off-by: Kory Maincent <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 091fab1 commit 152c75e

File tree

5 files changed

+126
-0
lines changed

5 files changed

+126
-0
lines changed

Documentation/networking/ethtool-netlink.rst

+17
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ Userspace to kernel:
227227
``ETHTOOL_MSG_MM_SET`` set MAC merge layer parameters
228228
``ETHTOOL_MSG_TS_GET`` get current timestamping
229229
``ETHTOOL_MSG_TS_LIST_GET`` list available timestampings
230+
``ETHTOOL_MSG_TS_SET`` set current timestamping
230231
===================================== =================================
231232

232233
Kernel to userspace:
@@ -2038,6 +2039,21 @@ Kernel response contents:
20382039

20392040
This command lists all the possible timestamp layer available.
20402041

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+
20412057
Request translation
20422058
===================
20432059

@@ -2146,4 +2162,5 @@ are netlink only.
21462162
n/a ``ETHTOOL_MSG_MM_SET``
21472163
n/a ``ETHTOOL_MSG_TS_GET``
21482164
n/a ``ETHTOOL_MSG_TS_LIST_GET``
2165+
n/a ``ETHTOOL_MSG_TS_SET``
21492166
=================================== =====================================

include/uapi/linux/ethtool_netlink.h

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ enum {
5959
ETHTOOL_MSG_MM_SET,
6060
ETHTOOL_MSG_TS_GET,
6161
ETHTOOL_MSG_TS_LIST_GET,
62+
ETHTOOL_MSG_TS_SET,
6263

6364
/* add new constants above here */
6465
__ETHTOOL_MSG_USER_CNT,

net/ethtool/netlink.c

+8
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = {
308308
[ETHTOOL_MSG_MM_SET] = &ethnl_mm_request_ops,
309309
[ETHTOOL_MSG_TS_GET] = &ethnl_ts_request_ops,
310310
[ETHTOOL_MSG_TS_LIST_GET] = &ethnl_ts_list_request_ops,
311+
[ETHTOOL_MSG_TS_SET] = &ethnl_ts_request_ops,
311312
};
312313

313314
static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
@@ -1148,6 +1149,13 @@ static const struct genl_ops ethtool_genl_ops[] = {
11481149
.policy = ethnl_ts_get_policy,
11491150
.maxattr = ARRAY_SIZE(ethnl_ts_get_policy) - 1,
11501151
},
1152+
{
1153+
.cmd = ETHTOOL_MSG_TS_SET,
1154+
.flags = GENL_UNS_ADMIN_PERM,
1155+
.doit = ethnl_default_set_doit,
1156+
.policy = ethnl_ts_set_policy,
1157+
.maxattr = ARRAY_SIZE(ethnl_ts_set_policy) - 1,
1158+
},
11511159
};
11521160

11531161
static const struct genl_multicast_group ethtool_nl_mcgrps[] = {

net/ethtool/netlink.h

+1
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ extern const struct nla_policy ethnl_plca_get_status_policy[ETHTOOL_A_PLCA_HEADE
444444
extern const struct nla_policy ethnl_mm_get_policy[ETHTOOL_A_MM_HEADER + 1];
445445
extern const struct nla_policy ethnl_mm_set_policy[ETHTOOL_A_MM_MAX + 1];
446446
extern const struct nla_policy ethnl_ts_get_policy[ETHTOOL_A_TS_HEADER + 1];
447+
extern const struct nla_policy ethnl_ts_set_policy[ETHTOOL_A_TS_MAX + 1];
447448

448449
int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
449450
int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);

net/ethtool/ts.c

+99
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,102 @@ static int ts_fill_reply(struct sk_buff *skb,
5959
return nla_put_u32(skb, ETHTOOL_A_TS_LAYER, data->ts_layer);
6060
}
6161

62+
/* TS_SET */
63+
const struct nla_policy ethnl_ts_set_policy[] = {
64+
[ETHTOOL_A_TS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
65+
[ETHTOOL_A_TS_LAYER] = NLA_POLICY_RANGE(NLA_U32, 0,
66+
__TIMESTAMPING_COUNT - 1)
67+
};
68+
69+
static int ethnl_set_ts_validate(struct ethnl_req_info *req_info,
70+
struct genl_info *info)
71+
{
72+
struct nlattr **tb = info->attrs;
73+
const struct net_device_ops *ops = req_info->dev->netdev_ops;
74+
75+
if (!ops->ndo_hwtstamp_set)
76+
return -EOPNOTSUPP;
77+
78+
if (!tb[ETHTOOL_A_TS_LAYER])
79+
return 0;
80+
81+
return 1;
82+
}
83+
84+
static int ethnl_set_ts(struct ethnl_req_info *req_info, struct genl_info *info)
85+
{
86+
struct net_device *dev = req_info->dev;
87+
const struct ethtool_ops *ops = dev->ethtool_ops;
88+
struct kernel_hwtstamp_config config = {0};
89+
struct nlattr **tb = info->attrs;
90+
enum timestamping_layer ts_layer;
91+
bool mod = false;
92+
int ret;
93+
94+
ts_layer = dev->ts_layer;
95+
ethnl_update_u32(&ts_layer, tb[ETHTOOL_A_TS_LAYER], &mod);
96+
97+
if (!mod)
98+
return 0;
99+
100+
if (ts_layer == SOFTWARE_TIMESTAMPING) {
101+
struct ethtool_ts_info ts_info = {0};
102+
103+
if (!ops->get_ts_info) {
104+
NL_SET_ERR_MSG_ATTR(info->extack,
105+
tb[ETHTOOL_A_TS_LAYER],
106+
"this net device cannot support timestamping");
107+
return -EINVAL;
108+
}
109+
110+
ops->get_ts_info(dev, &ts_info);
111+
if ((ts_info.so_timestamping &
112+
SOF_TIMESTAMPING_SOFTWARE_MASK) !=
113+
SOF_TIMESTAMPING_SOFTWARE_MASK) {
114+
NL_SET_ERR_MSG_ATTR(info->extack,
115+
tb[ETHTOOL_A_TS_LAYER],
116+
"this net device cannot support software timestamping");
117+
return -EINVAL;
118+
}
119+
} else if (ts_layer == MAC_TIMESTAMPING) {
120+
struct ethtool_ts_info ts_info = {0};
121+
122+
if (!ops->get_ts_info) {
123+
NL_SET_ERR_MSG_ATTR(info->extack,
124+
tb[ETHTOOL_A_TS_LAYER],
125+
"this net device cannot support timestamping");
126+
return -EINVAL;
127+
}
128+
129+
ops->get_ts_info(dev, &ts_info);
130+
if ((ts_info.so_timestamping &
131+
SOF_TIMESTAMPING_HARDWARE_MASK) !=
132+
SOF_TIMESTAMPING_HARDWARE_MASK) {
133+
NL_SET_ERR_MSG_ATTR(info->extack,
134+
tb[ETHTOOL_A_TS_LAYER],
135+
"this net device cannot support hardware timestamping");
136+
return -EINVAL;
137+
}
138+
} else if (ts_layer == PHY_TIMESTAMPING && !phy_has_tsinfo(dev->phydev)) {
139+
NL_SET_ERR_MSG_ATTR(info->extack, tb[ETHTOOL_A_TS_LAYER],
140+
"this phy device cannot support timestamping");
141+
return -EINVAL;
142+
}
143+
144+
/* Disable time stamping in the current layer. */
145+
if (netif_device_present(dev) &&
146+
(dev->ts_layer == PHY_TIMESTAMPING ||
147+
dev->ts_layer == MAC_TIMESTAMPING)) {
148+
ret = dev_set_hwtstamp_phylib(dev, &config, info->extack);
149+
if (ret < 0)
150+
return ret;
151+
}
152+
153+
dev->ts_layer = ts_layer;
154+
155+
return 1;
156+
}
157+
62158
const struct ethnl_request_ops ethnl_ts_request_ops = {
63159
.request_cmd = ETHTOOL_MSG_TS_GET,
64160
.reply_cmd = ETHTOOL_MSG_TS_GET_REPLY,
@@ -69,6 +165,9 @@ const struct ethnl_request_ops ethnl_ts_request_ops = {
69165
.prepare_data = ts_prepare_data,
70166
.reply_size = ts_reply_size,
71167
.fill_reply = ts_fill_reply,
168+
169+
.set_validate = ethnl_set_ts_validate,
170+
.set = ethnl_set_ts,
72171
};
73172

74173
/* TS_LIST_GET */

0 commit comments

Comments
 (0)