Skip to content

Commit 2ab0edb

Browse files
minimaxwelldavem330
authored andcommitted
net: ethtool: Allow passing a phy index for some commands
Some netlink commands are target towards ethernet PHYs, to control some of their features. As there's several such commands, add the ability to pass a PHY index in the ethnl request, which will populate the generic ethnl_req_info with the relevant phydev when the command targets a PHY. Signed-off-by: Maxime Chevallier <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent dedd702 commit 2ab0edb

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Structure of this header is
5757
``ETHTOOL_A_HEADER_DEV_INDEX`` u32 device ifindex
5858
``ETHTOOL_A_HEADER_DEV_NAME`` string device name
5959
``ETHTOOL_A_HEADER_FLAGS`` u32 flags common for all requests
60+
``ETHTOOL_A_HEADER_PHY_INDEX`` u32 phy device index
6061
============================== ====== =============================
6162

6263
``ETHTOOL_A_HEADER_DEV_INDEX`` and ``ETHTOOL_A_HEADER_DEV_NAME`` identify the
@@ -81,6 +82,12 @@ the behaviour is backward compatible, i.e. requests from old clients not aware
8182
of the flag should be interpreted the way the client expects. A client must
8283
not set flags it does not understand.
8384

85+
``ETHTOOL_A_HEADER_PHY_INDEX`` identify the ethernet PHY the message relates to.
86+
As there are numerous commands that are related to PHY configuration, and because
87+
we can have more than one PHY on the link, the PHY index can be passed in the
88+
request for the commands that needs it. It is however not mandatory, and if it
89+
is not passed for commands that target a PHY, the net_device.phydev pointer
90+
is used, as a fallback that keeps the legacy behaviour.
8491

8592
Bit sets
8693
========

include/uapi/linux/ethtool_netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ enum {
133133
ETHTOOL_A_HEADER_DEV_INDEX, /* u32 */
134134
ETHTOOL_A_HEADER_DEV_NAME, /* string */
135135
ETHTOOL_A_HEADER_FLAGS, /* u32 - ETHTOOL_FLAG_* */
136+
ETHTOOL_A_HEADER_PHY_INDEX, /* u32 */
136137

137138
/* add new constants above here */
138139
__ETHTOOL_A_HEADER_CNT,

net/ethtool/netlink.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <linux/ethtool_netlink.h>
55
#include <linux/pm_runtime.h>
66
#include "netlink.h"
7+
#include <linux/phy_link_topology.h>
78

89
static struct genl_family ethtool_genl_family;
910

@@ -20,6 +21,7 @@ const struct nla_policy ethnl_header_policy[] = {
2021
.len = ALTIFNAMSIZ - 1 },
2122
[ETHTOOL_A_HEADER_FLAGS] = NLA_POLICY_MASK(NLA_U32,
2223
ETHTOOL_FLAGS_BASIC),
24+
[ETHTOOL_A_HEADER_PHY_INDEX] = NLA_POLICY_MIN(NLA_U32, 1),
2325
};
2426

2527
const struct nla_policy ethnl_header_policy_stats[] = {
@@ -28,6 +30,7 @@ const struct nla_policy ethnl_header_policy_stats[] = {
2830
.len = ALTIFNAMSIZ - 1 },
2931
[ETHTOOL_A_HEADER_FLAGS] = NLA_POLICY_MASK(NLA_U32,
3032
ETHTOOL_FLAGS_STATS),
33+
[ETHTOOL_A_HEADER_PHY_INDEX] = NLA_POLICY_MIN(NLA_U32, 1),
3134
};
3235

3336
int ethnl_ops_begin(struct net_device *dev)
@@ -91,6 +94,7 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
9194
{
9295
struct nlattr *tb[ARRAY_SIZE(ethnl_header_policy)];
9396
const struct nlattr *devname_attr;
97+
struct phy_device *phydev = NULL;
9498
struct net_device *dev = NULL;
9599
u32 flags = 0;
96100
int ret;
@@ -145,6 +149,26 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
145149
return -EINVAL;
146150
}
147151

152+
if (dev) {
153+
if (tb[ETHTOOL_A_HEADER_PHY_INDEX]) {
154+
u32 phy_index = nla_get_u32(tb[ETHTOOL_A_HEADER_PHY_INDEX]);
155+
156+
phydev = phy_link_topo_get_phy(&dev->link_topo,
157+
phy_index);
158+
if (!phydev) {
159+
NL_SET_ERR_MSG_ATTR(extack, header,
160+
"no phy matches phy index");
161+
return -EINVAL;
162+
}
163+
} else {
164+
/* If we need a PHY but no phy index is specified, fallback
165+
* to dev->phydev
166+
*/
167+
phydev = dev->phydev;
168+
}
169+
}
170+
171+
req_info->phydev = phydev;
148172
req_info->dev = dev;
149173
req_info->flags = flags;
150174
return 0;

net/ethtool/netlink.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ static inline unsigned int ethnl_reply_header_size(void)
250250
* @dev: network device the request is for (may be null)
251251
* @dev_tracker: refcount tracker for @dev reference
252252
* @flags: request flags common for all request types
253+
* @phydev: phy_device connected to @dev this request is for (may be null)
253254
*
254255
* This is a common base for request specific structures holding data from
255256
* parsed userspace request. These always embed struct ethnl_req_info at
@@ -259,6 +260,7 @@ struct ethnl_req_info {
259260
struct net_device *dev;
260261
netdevice_tracker dev_tracker;
261262
u32 flags;
263+
struct phy_device *phydev;
262264
};
263265

264266
static inline void ethnl_parse_header_dev_put(struct ethnl_req_info *req_info)
@@ -395,9 +397,10 @@ extern const struct ethnl_request_ops ethnl_rss_request_ops;
395397
extern const struct ethnl_request_ops ethnl_plca_cfg_request_ops;
396398
extern const struct ethnl_request_ops ethnl_plca_status_request_ops;
397399
extern const struct ethnl_request_ops ethnl_mm_request_ops;
400+
extern const struct ethnl_request_ops ethnl_phy_request_ops;
398401

399-
extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
400-
extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
402+
extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_PHY_INDEX + 1];
403+
extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_PHY_INDEX + 1];
401404
extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_ONLY + 1];
402405
extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1];
403406
extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1];

0 commit comments

Comments
 (0)