Commit 17194be4 authored by Maxime Chevallier's avatar Maxime Chevallier Committed by David S. Miller
Browse files

net: ethtool: Introduce a command to list PHYs on an interface



As we have the ability to track the PHYs connected to a net_device
through the link_topology, we can expose this list to userspace. This
allows userspace to use these identifiers for phy-specific commands and
take the decision of which PHY to target by knowing the link topology.

Add PHY_GET and PHY_DUMP, which can be a filtered DUMP operation to list
devices on only one interface.

Signed-off-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Tested-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9af0e89d
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -2191,6 +2191,46 @@ string.
The ``ETHTOOL_A_MODULE_FW_FLASH_DONE`` and ``ETHTOOL_A_MODULE_FW_FLASH_TOTAL``
attributes encode the completed and total amount of work, respectively.

PHY_GET
=======

Retrieve information about a given Ethernet PHY sitting on the link. The DO
operation returns all available information about dev->phydev. User can also
specify a PHY_INDEX, in which case the DO request returns information about that
specific PHY.
As there can be more than one PHY, the DUMP operation can be used to list the PHYs
present on a given interface, by passing an interface index or name in
the dump request.

Request contents:

  ====================================  ======  ==========================
  ``ETHTOOL_A_PHY_HEADER``              nested  request header
  ====================================  ======  ==========================

Kernel response contents:

  ===================================== ======  ===============================
  ``ETHTOOL_A_PHY_HEADER``              nested  request header
  ``ETHTOOL_A_PHY_INDEX``               u32     the phy's unique index, that can
                                                be used for phy-specific
                                                requests
  ``ETHTOOL_A_PHY_DRVNAME``             string  the phy driver name
  ``ETHTOOL_A_PHY_NAME``                string  the phy device name
  ``ETHTOOL_A_PHY_UPSTREAM_TYPE``       u32     the type of device this phy is
                                                connected to
  ``ETHTOOL_A_PHY_UPSTREAM_INDEX``      u32     the PHY index of the upstream
                                                PHY
  ``ETHTOOL_A_PHY_UPSTREAM_SFP_NAME``   string  if this PHY is connected to
                                                its parent PHY through an SFP
                                                bus, the name of this sfp bus
  ``ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME`` string  if the phy controls an sfp bus,
                                                the name of the sfp bus
  ===================================== ======  ===============================

When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
another PHY.

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

@@ -2298,4 +2338,5 @@ are netlink only.
  n/a                                 ``ETHTOOL_MSG_MM_GET``
  n/a                                 ``ETHTOOL_MSG_MM_SET``
  n/a                                 ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT``
  n/a                                 ``ETHTOOL_MSG_PHY_GET``
  =================================== =====================================
+19 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ enum {
	ETHTOOL_MSG_MM_GET,
	ETHTOOL_MSG_MM_SET,
	ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
	ETHTOOL_MSG_PHY_GET,

	/* add new constants above here */
	__ETHTOOL_MSG_USER_CNT,
@@ -111,6 +112,8 @@ enum {
	ETHTOOL_MSG_MM_GET_REPLY,
	ETHTOOL_MSG_MM_NTF,
	ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
	ETHTOOL_MSG_PHY_GET_REPLY,
	ETHTOOL_MSG_PHY_NTF,

	/* add new constants above here */
	__ETHTOOL_MSG_KERNEL_CNT,
@@ -1055,6 +1058,22 @@ enum {
	ETHTOOL_A_MODULE_FW_FLASH_MAX = (__ETHTOOL_A_MODULE_FW_FLASH_CNT - 1)
};

enum {
	ETHTOOL_A_PHY_UNSPEC,
	ETHTOOL_A_PHY_HEADER,			/* nest - _A_HEADER_* */
	ETHTOOL_A_PHY_INDEX,			/* u32 */
	ETHTOOL_A_PHY_DRVNAME,			/* string */
	ETHTOOL_A_PHY_NAME,			/* string */
	ETHTOOL_A_PHY_UPSTREAM_TYPE,		/* u32 */
	ETHTOOL_A_PHY_UPSTREAM_INDEX,		/* u32 */
	ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,	/* string */
	ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,	/* string */

	/* add new constants above here */
	__ETHTOOL_A_PHY_CNT,
	ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)
};

/* generic netlink info */
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1
+2 −1
Original line number Diff line number Diff line
@@ -8,4 +8,5 @@ ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o rss.o \
		   linkstate.o debug.o wol.o features.o privflags.o rings.o \
		   channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
		   tunnels.o fec.o eeprom.o stats.o phc_vclocks.o mm.o \
		   module.o cmis_fw_update.o cmis_cdb.o pse-pd.o plca.o mm.o
		   module.o cmis_fw_update.o cmis_cdb.o pse-pd.o plca.o mm.o \
		   phy.o
+9 −0
Original line number Diff line number Diff line
@@ -1234,6 +1234,15 @@ static const struct genl_ops ethtool_genl_ops[] = {
		.policy	= ethnl_module_fw_flash_act_policy,
		.maxattr = ARRAY_SIZE(ethnl_module_fw_flash_act_policy) - 1,
	},
	{
		.cmd	= ETHTOOL_MSG_PHY_GET,
		.doit	= ethnl_phy_doit,
		.start	= ethnl_phy_start,
		.dumpit	= ethnl_phy_dumpit,
		.done	= ethnl_phy_done,
		.policy = ethnl_phy_get_policy,
		.maxattr = ARRAY_SIZE(ethnl_phy_get_policy) - 1,
	},
};

static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
+5 −0
Original line number Diff line number Diff line
@@ -484,6 +484,7 @@ extern const struct nla_policy ethnl_plca_get_status_policy[ETHTOOL_A_PLCA_HEADE
extern const struct nla_policy ethnl_mm_get_policy[ETHTOOL_A_MM_HEADER + 1];
extern const struct nla_policy ethnl_mm_set_policy[ETHTOOL_A_MM_MAX + 1];
extern const struct nla_policy ethnl_module_fw_flash_act_policy[ETHTOOL_A_MODULE_FW_FLASH_PASSWORD + 1];
extern const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1];

int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
@@ -494,6 +495,10 @@ int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
int ethnl_act_module_fw_flash(struct sk_buff *skb, struct genl_info *info);
int ethnl_rss_dump_start(struct netlink_callback *cb);
int ethnl_rss_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
int ethnl_phy_start(struct netlink_callback *cb);
int ethnl_phy_doit(struct sk_buff *skb, struct genl_info *info);
int ethnl_phy_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
int ethnl_phy_done(struct netlink_callback *cb);

extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN];
extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN];
Loading