Commit 63d5eaf3 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>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c29451ae
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -2011,6 +2011,49 @@ The attributes are propagated to the driver through the following structure:
.. kernel-doc:: include/linux/ethtool.h
    :identifiers: ethtool_mm_cfg

PHY_GET
=======

Retrieve information about a given Ethernet PHY sitting on the link. 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_PHY``        nested  if the phy is connected to another
                                                phy, this nest contains info on
                                                that connection
  ``ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME`` string  if the phy controls an sfp bus,
                                                the name of the sfp bus
  ``ETHTOOL_A_PHY_ID``                  u32     the phy id if the phy is C22
  ===================================== ======  ==========================

When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
another PHY. Information on the parent PHY will be set in the
``ETHTOOL_A_PHY_UPSTREAM_PHY`` nest, which has the following structure :

  =================================== ======  ==========================
  ``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 it's
                                                parent PHY through an SFP bus, the
                                                name of this sfp bus
  =================================== ======  ==========================

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

@@ -2117,4 +2160,5 @@ are netlink only.
  n/a                                 ``ETHTOOL_MSG_PLCA_GET_STATUS``
  n/a                                 ``ETHTOOL_MSG_MM_GET``
  n/a                                 ``ETHTOOL_MSG_MM_SET``
  n/a                                 ``ETHTOOL_MSG_PHY_GET``
  =================================== =====================================
+29 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ enum {
	ETHTOOL_MSG_PLCA_GET_STATUS,
	ETHTOOL_MSG_MM_GET,
	ETHTOOL_MSG_MM_SET,
	ETHTOOL_MSG_PHY_GET,

	/* add new constants above here */
	__ETHTOOL_MSG_USER_CNT,
@@ -109,6 +110,8 @@ enum {
	ETHTOOL_MSG_PLCA_NTF,
	ETHTOOL_MSG_MM_GET_REPLY,
	ETHTOOL_MSG_MM_NTF,
	ETHTOOL_MSG_PHY_GET_REPLY,
	ETHTOOL_MSG_PHY_NTF,

	/* add new constants above here */
	__ETHTOOL_MSG_KERNEL_CNT,
@@ -977,6 +980,32 @@ enum {
	ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1)
};

enum {
	ETHTOOL_A_PHY_UPSTREAM_UNSPEC,
	ETHTOOL_A_PHY_UPSTREAM_INDEX,			/* u32 */
	ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,		/* string */

	/* add new constants above here */
	__ETHTOOL_A_PHY_UPSTREAM_CNT,
	ETHTOOL_A_PHY_UPSTREAM_MAX = (__ETHTOOL_A_PHY_UPSTREAM_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,		/* u8 */
	ETHTOOL_A_PHY_UPSTREAM,			/* nest - _A_PHY_UPSTREAM_* */
	ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,	/* string */
	ETHTOOL_A_PHY_ID,			/* u32 */

	/* 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
+1 −1
Original line number Diff line number Diff line
@@ -8,4 +8,4 @@ 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 pse-pd.o plca.o mm.o
		   module.o pse-pd.o plca.o mm.o phy.o
+9 −0
Original line number Diff line number Diff line
@@ -1153,6 +1153,15 @@ static const struct genl_ops ethtool_genl_ops[] = {
		.policy = ethnl_mm_set_policy,
		.maxattr = ARRAY_SIZE(ethnl_mm_set_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
@@ -444,6 +444,7 @@ extern const struct nla_policy ethnl_plca_set_cfg_policy[ETHTOOL_A_PLCA_MAX + 1]
extern const struct nla_policy ethnl_plca_get_status_policy[ETHTOOL_A_PLCA_HEADER + 1];
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_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);
@@ -451,6 +452,10 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info);
int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info);
int ethnl_tunnel_info_start(struct netlink_callback *cb);
int ethnl_tunnel_info_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