All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
To: davem@davemloft.net
Cc: "Maxime Chevallier" <maxime.chevallier@bootlin.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	thomas.petazzoni@bootlin.com, "Andrew Lunn" <andrew@lunn.ch>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Eric Dumazet" <edumazet@google.com>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Russell King" <linux@armlinux.org.uk>,
	linux-arm-kernel@lists.infradead.org,
	"Christophe Leroy" <christophe.leroy@csgroup.eu>,
	"Herve Codina" <herve.codina@bootlin.com>,
	"Florian Fainelli" <f.fainelli@gmail.com>,
	"Heiner Kallweit" <hkallweit1@gmail.com>,
	"Vladimir Oltean" <vladimir.oltean@nxp.com>,
	"Köry Maincent" <kory.maincent@bootlin.com>,
	"Jesse Brandeburg" <jesse.brandeburg@intel.com>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Marek Behún" <kabel@kernel.org>,
	"Piergiorgio Beruto" <piergiorgio.beruto@gmail.com>,
	"Oleksij Rempel" <o.rempel@pengutronix.de>,
	"Nicolò Veronese" <nicveronese@gmail.com>
Subject: [RFC PATCH net-next v3 08/13] netlink: specs: add ethnl PHY_GET command set
Date: Fri,  1 Dec 2023 17:36:58 +0100	[thread overview]
Message-ID: <20231201163704.1306431-9-maxime.chevallier@bootlin.com> (raw)
In-Reply-To: <20231201163704.1306431-1-maxime.chevallier@bootlin.com>

The PHY_GET command, supporting both DUMP and GET operations, is used to
retrieve the list of PHYs connected to a netdevice, and get topology
information to know where exactly it sits on the physical link.

Add the netlink specs corresponding to that command, and bump the
ethtool-user.c|h autogenerated files.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: New patch

 Documentation/netlink/specs/ethtool.yaml |  65 ++++++
 tools/net/ynl/generated/ethtool-user.c   | 257 +++++++++++++++++++++++
 tools/net/ynl/generated/ethtool-user.h   | 153 ++++++++++++++
 3 files changed, 475 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 4e0790648913..280b090b5f7c 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -16,6 +16,11 @@ definitions:
     name: stringset
     type: enum
     entries: []
+  -
+    name: phy-upstream-type
+    enum-name:
+    type: enum
+    entries: [ mac, phy ]
 
 attribute-sets:
   -
@@ -942,6 +947,45 @@ attribute-sets:
       -
         name: burst-tmr
         type: u32
+  -
+    name: phy-upstream
+    attributes:
+      -
+        name: index
+        type: u32
+      -
+        name: sfp-name
+        type: string
+  -
+    name: phy
+    attributes:
+      -
+        name: header
+        type: nest
+        nested-attributes: header
+      -
+        name: index
+        type: u32
+      -
+        name: drvname
+        type: string
+      -
+        name: name
+        type: string
+      -
+        name: upstream-type
+        type: u8
+        enum: phy-upstream-type
+      -
+        name: upstream
+        type: nest
+        nested-attributes: phy-upstream
+      -
+        name: downstream-sfp-name
+        type: string
+      -
+        name: id
+        type: u32
 
 operations:
   enum-model: directional
@@ -1692,3 +1736,24 @@ operations:
       name: mm-ntf
       doc: Notification for change in MAC Merge configuration.
       notify: mm-get
+    -
+      name: phy-get
+      doc: Get PHY devices attached to an interface
+
+      attribute-set: phy
+
+      do: &phy-get-op
+        request:
+          attributes:
+            - header
+        reply:
+          attributes:
+            - header
+            - index
+            - drvname
+            - name
+            - upstream-type
+            - upstream
+            - downstream-sfp-name
+            - id
+      dump: *phy-get-op
diff --git a/tools/net/ynl/generated/ethtool-user.c b/tools/net/ynl/generated/ethtool-user.c
index 295661eb3a3e..b63ba2d2e25e 100644
--- a/tools/net/ynl/generated/ethtool-user.c
+++ b/tools/net/ynl/generated/ethtool-user.c
@@ -59,6 +59,7 @@ static const char * const ethtool_op_strmap[] = {
 	[41] = "plca-ntf",
 	[ETHTOOL_MSG_MM_GET] = "mm-get",
 	[43] = "mm-ntf",
+	[ETHTOOL_MSG_PHY_GET] = "phy-get",
 };
 
 const char *ethtool_op_str(int op)
@@ -91,6 +92,18 @@ const char *ethtool_stringset_str(enum ethtool_stringset value)
 	return ethtool_stringset_strmap[value];
 }
 
+static const char * const ethtool_phy_upstream_type_strmap[] = {
+	[0] = "mac",
+	[1] = "phy",
+};
+
+const char *ethtool_phy_upstream_type_str(int value)
+{
+	if (value < 0 || value >= (int)MNL_ARRAY_SIZE(ethtool_phy_upstream_type_strmap))
+		return NULL;
+	return ethtool_phy_upstream_type_strmap[value];
+}
+
 /* Policies */
 struct ynl_policy_attr ethtool_header_policy[ETHTOOL_A_HEADER_MAX + 1] = {
 	[ETHTOOL_A_HEADER_DEV_INDEX] = { .name = "dev-index", .type = YNL_PT_U32, },
@@ -154,6 +167,16 @@ struct ynl_policy_nest ethtool_mm_stat_nest = {
 	.table = ethtool_mm_stat_policy,
 };
 
+struct ynl_policy_attr ethtool_phy_upstream_policy[ETHTOOL_A_PHY_UPSTREAM_MAX + 1] = {
+	[ETHTOOL_A_PHY_UPSTREAM_INDEX] = { .name = "index", .type = YNL_PT_U32, },
+	[ETHTOOL_A_PHY_UPSTREAM_SFP_NAME] = { .name = "sfp-name", .type = YNL_PT_NUL_STR, },
+};
+
+struct ynl_policy_nest ethtool_phy_upstream_nest = {
+	.max_attr = ETHTOOL_A_PHY_UPSTREAM_MAX,
+	.table = ethtool_phy_upstream_policy,
+};
+
 struct ynl_policy_attr ethtool_cable_result_policy[ETHTOOL_A_CABLE_RESULT_MAX + 1] = {
 	[ETHTOOL_A_CABLE_RESULT_PAIR] = { .name = "pair", .type = YNL_PT_U8, },
 	[ETHTOOL_A_CABLE_RESULT_CODE] = { .name = "code", .type = YNL_PT_U8, },
@@ -667,6 +690,22 @@ struct ynl_policy_nest ethtool_mm_nest = {
 	.table = ethtool_mm_policy,
 };
 
+struct ynl_policy_attr ethtool_phy_policy[ETHTOOL_A_PHY_MAX + 1] = {
+	[ETHTOOL_A_PHY_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
+	[ETHTOOL_A_PHY_INDEX] = { .name = "index", .type = YNL_PT_U32, },
+	[ETHTOOL_A_PHY_DRVNAME] = { .name = "drvname", .type = YNL_PT_NUL_STR, },
+	[ETHTOOL_A_PHY_NAME] = { .name = "name", .type = YNL_PT_NUL_STR, },
+	[ETHTOOL_A_PHY_UPSTREAM_TYPE] = { .name = "upstream-type", .type = YNL_PT_U8, },
+	[ETHTOOL_A_PHY_UPSTREAM] = { .name = "upstream", .type = YNL_PT_NEST, .nest = &ethtool_phy_upstream_nest, },
+	[ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME] = { .name = "downstream-sfp-name", .type = YNL_PT_NUL_STR, },
+	[ETHTOOL_A_PHY_ID] = { .name = "id", .type = YNL_PT_U32, },
+};
+
+struct ynl_policy_nest ethtool_phy_nest = {
+	.max_attr = ETHTOOL_A_PHY_MAX,
+	.table = ethtool_phy_policy,
+};
+
 /* Common nested types */
 void ethtool_header_free(struct ethtool_header *obj)
 {
@@ -899,6 +938,42 @@ int ethtool_mm_stat_parse(struct ynl_parse_arg *yarg,
 	return 0;
 }
 
+void ethtool_phy_upstream_free(struct ethtool_phy_upstream *obj)
+{
+	free(obj->sfp_name);
+}
+
+int ethtool_phy_upstream_parse(struct ynl_parse_arg *yarg,
+			       const struct nlattr *nested)
+{
+	struct ethtool_phy_upstream *dst = yarg->data;
+	const struct nlattr *attr;
+
+	mnl_attr_for_each_nested(attr, nested) {
+		unsigned int type = mnl_attr_get_type(attr);
+
+		if (type == ETHTOOL_A_PHY_UPSTREAM_INDEX) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.index = 1;
+			dst->index = mnl_attr_get_u32(attr);
+		} else if (type == ETHTOOL_A_PHY_UPSTREAM_SFP_NAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.sfp_name_len = len;
+			dst->sfp_name = malloc(len + 1);
+			memcpy(dst->sfp_name, mnl_attr_get_str(attr), len);
+			dst->sfp_name[len] = 0;
+		}
+	}
+
+	return 0;
+}
+
 void ethtool_cable_result_free(struct ethtool_cable_result *obj)
 {
 }
@@ -6158,6 +6233,188 @@ int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req)
 	return 0;
 }
 
+/* ============== ETHTOOL_MSG_PHY_GET ============== */
+/* ETHTOOL_MSG_PHY_GET - do */
+void ethtool_phy_get_req_free(struct ethtool_phy_get_req *req)
+{
+	ethtool_header_free(&req->header);
+	free(req);
+}
+
+void ethtool_phy_get_rsp_free(struct ethtool_phy_get_rsp *rsp)
+{
+	ethtool_header_free(&rsp->header);
+	free(rsp->drvname);
+	free(rsp->name);
+	ethtool_phy_upstream_free(&rsp->upstream);
+	free(rsp->downstream_sfp_name);
+	free(rsp);
+}
+
+int ethtool_phy_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
+{
+	struct ynl_parse_arg *yarg = data;
+	struct ethtool_phy_get_rsp *dst;
+	const struct nlattr *attr;
+	struct ynl_parse_arg parg;
+
+	dst = yarg->data;
+	parg.ys = yarg->ys;
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		unsigned int type = mnl_attr_get_type(attr);
+
+		if (type == ETHTOOL_A_PHY_HEADER) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.header = 1;
+
+			parg.rsp_policy = &ethtool_header_nest;
+			parg.data = &dst->header;
+			if (ethtool_header_parse(&parg, attr))
+				return MNL_CB_ERROR;
+		} else if (type == ETHTOOL_A_PHY_INDEX) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.index = 1;
+			dst->index = mnl_attr_get_u32(attr);
+		} else if (type == ETHTOOL_A_PHY_DRVNAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.drvname_len = len;
+			dst->drvname = malloc(len + 1);
+			memcpy(dst->drvname, mnl_attr_get_str(attr), len);
+			dst->drvname[len] = 0;
+		} else if (type == ETHTOOL_A_PHY_NAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.name_len = len;
+			dst->name = malloc(len + 1);
+			memcpy(dst->name, mnl_attr_get_str(attr), len);
+			dst->name[len] = 0;
+		} else if (type == ETHTOOL_A_PHY_UPSTREAM_TYPE) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.upstream_type = 1;
+			dst->upstream_type = mnl_attr_get_u8(attr);
+		} else if (type == ETHTOOL_A_PHY_UPSTREAM) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.upstream = 1;
+
+			parg.rsp_policy = &ethtool_phy_upstream_nest;
+			parg.data = &dst->upstream;
+			if (ethtool_phy_upstream_parse(&parg, attr))
+				return MNL_CB_ERROR;
+		} else if (type == ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.downstream_sfp_name_len = len;
+			dst->downstream_sfp_name = malloc(len + 1);
+			memcpy(dst->downstream_sfp_name, mnl_attr_get_str(attr), len);
+			dst->downstream_sfp_name[len] = 0;
+		} else if (type == ETHTOOL_A_PHY_ID) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.id = 1;
+			dst->id = mnl_attr_get_u32(attr);
+		}
+	}
+
+	return MNL_CB_OK;
+}
+
+struct ethtool_phy_get_rsp *
+ethtool_phy_get(struct ynl_sock *ys, struct ethtool_phy_get_req *req)
+{
+	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
+	struct ethtool_phy_get_rsp *rsp;
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PHY_GET, 1);
+	ys->req_policy = &ethtool_phy_nest;
+	yrs.yarg.rsp_policy = &ethtool_phy_nest;
+
+	if (req->_present.header)
+		ethtool_header_put(nlh, ETHTOOL_A_PHY_HEADER, &req->header);
+
+	rsp = calloc(1, sizeof(*rsp));
+	yrs.yarg.data = rsp;
+	yrs.cb = ethtool_phy_get_rsp_parse;
+	yrs.rsp_cmd = ETHTOOL_MSG_PHY_GET;
+
+	err = ynl_exec(ys, nlh, &yrs);
+	if (err < 0)
+		goto err_free;
+
+	return rsp;
+
+err_free:
+	ethtool_phy_get_rsp_free(rsp);
+	return NULL;
+}
+
+/* ETHTOOL_MSG_PHY_GET - dump */
+void ethtool_phy_get_list_free(struct ethtool_phy_get_list *rsp)
+{
+	struct ethtool_phy_get_list *next = rsp;
+
+	while ((void *)next != YNL_LIST_END) {
+		rsp = next;
+		next = rsp->next;
+
+		ethtool_header_free(&rsp->obj.header);
+		free(rsp->obj.drvname);
+		free(rsp->obj.name);
+		ethtool_phy_upstream_free(&rsp->obj.upstream);
+		free(rsp->obj.downstream_sfp_name);
+		free(rsp);
+	}
+}
+
+struct ethtool_phy_get_list *
+ethtool_phy_get_dump(struct ynl_sock *ys, struct ethtool_phy_get_req_dump *req)
+{
+	struct ynl_dump_state yds = {};
+	struct nlmsghdr *nlh;
+	int err;
+
+	yds.ys = ys;
+	yds.alloc_sz = sizeof(struct ethtool_phy_get_list);
+	yds.cb = ethtool_phy_get_rsp_parse;
+	yds.rsp_cmd = ETHTOOL_MSG_PHY_GET;
+	yds.rsp_policy = &ethtool_phy_nest;
+
+	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PHY_GET, 1);
+	ys->req_policy = &ethtool_phy_nest;
+
+	if (req->_present.header)
+		ethtool_header_put(nlh, ETHTOOL_A_PHY_HEADER, &req->header);
+
+	err = ynl_exec_dump(ys, nlh, &yds);
+	if (err < 0)
+		goto free_list;
+
+	return yds.first;
+
+free_list:
+	ethtool_phy_get_list_free(yds.first);
+	return NULL;
+}
+
 /* ETHTOOL_MSG_CABLE_TEST_NTF - event */
 int ethtool_cable_test_ntf_rsp_parse(const struct nlmsghdr *nlh, void *data)
 {
diff --git a/tools/net/ynl/generated/ethtool-user.h b/tools/net/ynl/generated/ethtool-user.h
index 97c079c0f332..59ebb0a1a09f 100644
--- a/tools/net/ynl/generated/ethtool-user.h
+++ b/tools/net/ynl/generated/ethtool-user.h
@@ -20,6 +20,7 @@ extern const struct ynl_family ynl_ethtool_family;
 const char *ethtool_op_str(int op);
 const char *ethtool_udp_tunnel_type_str(int value);
 const char *ethtool_stringset_str(enum ethtool_stringset value);
+const char *ethtool_phy_upstream_type_str(int value);
 
 /* Common nested types */
 struct ethtool_header {
@@ -90,6 +91,16 @@ struct ethtool_mm_stat {
 	__u64 hold_count;
 };
 
+struct ethtool_phy_upstream {
+	struct {
+		__u32 index:1;
+		__u32 sfp_name_len;
+	} _present;
+
+	__u32 index;
+	char *sfp_name;
+};
+
 struct ethtool_cable_result {
 	struct {
 		__u32 pair:1;
@@ -6018,6 +6029,148 @@ ethtool_mm_set_req_set_tx_min_frag_size(struct ethtool_mm_set_req *req,
  */
 int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req);
 
+/* ============== ETHTOOL_MSG_PHY_GET ============== */
+/* ETHTOOL_MSG_PHY_GET - do */
+struct ethtool_phy_get_req {
+	struct {
+		__u32 header:1;
+	} _present;
+
+	struct ethtool_header header;
+};
+
+static inline struct ethtool_phy_get_req *ethtool_phy_get_req_alloc(void)
+{
+	return calloc(1, sizeof(struct ethtool_phy_get_req));
+}
+void ethtool_phy_get_req_free(struct ethtool_phy_get_req *req);
+
+static inline void
+ethtool_phy_get_req_set_header_dev_index(struct ethtool_phy_get_req *req,
+					 __u32 dev_index)
+{
+	req->_present.header = 1;
+	req->header._present.dev_index = 1;
+	req->header.dev_index = dev_index;
+}
+static inline void
+ethtool_phy_get_req_set_header_dev_name(struct ethtool_phy_get_req *req,
+					const char *dev_name)
+{
+	free(req->header.dev_name);
+	req->header._present.dev_name_len = strlen(dev_name);
+	req->header.dev_name = malloc(req->header._present.dev_name_len + 1);
+	memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len);
+	req->header.dev_name[req->header._present.dev_name_len] = 0;
+}
+static inline void
+ethtool_phy_get_req_set_header_flags(struct ethtool_phy_get_req *req,
+				     __u32 flags)
+{
+	req->_present.header = 1;
+	req->header._present.flags = 1;
+	req->header.flags = flags;
+}
+static inline void
+ethtool_phy_get_req_set_header_phy_index(struct ethtool_phy_get_req *req,
+					 __u32 phy_index)
+{
+	req->_present.header = 1;
+	req->header._present.phy_index = 1;
+	req->header.phy_index = phy_index;
+}
+
+struct ethtool_phy_get_rsp {
+	struct {
+		__u32 header:1;
+		__u32 index:1;
+		__u32 drvname_len;
+		__u32 name_len;
+		__u32 upstream_type:1;
+		__u32 upstream:1;
+		__u32 downstream_sfp_name_len;
+		__u32 id:1;
+	} _present;
+
+	struct ethtool_header header;
+	__u32 index;
+	char *drvname;
+	char *name;
+	__u8 upstream_type;
+	struct ethtool_phy_upstream upstream;
+	char *downstream_sfp_name;
+	__u32 id;
+};
+
+void ethtool_phy_get_rsp_free(struct ethtool_phy_get_rsp *rsp);
+
+/*
+ * Get PHY devices attached to an interface
+ */
+struct ethtool_phy_get_rsp *
+ethtool_phy_get(struct ynl_sock *ys, struct ethtool_phy_get_req *req);
+
+/* ETHTOOL_MSG_PHY_GET - dump */
+struct ethtool_phy_get_req_dump {
+	struct {
+		__u32 header:1;
+	} _present;
+
+	struct ethtool_header header;
+};
+
+static inline struct ethtool_phy_get_req_dump *
+ethtool_phy_get_req_dump_alloc(void)
+{
+	return calloc(1, sizeof(struct ethtool_phy_get_req_dump));
+}
+void ethtool_phy_get_req_dump_free(struct ethtool_phy_get_req_dump *req);
+
+static inline void
+ethtool_phy_get_req_dump_set_header_dev_index(struct ethtool_phy_get_req_dump *req,
+					      __u32 dev_index)
+{
+	req->_present.header = 1;
+	req->header._present.dev_index = 1;
+	req->header.dev_index = dev_index;
+}
+static inline void
+ethtool_phy_get_req_dump_set_header_dev_name(struct ethtool_phy_get_req_dump *req,
+					     const char *dev_name)
+{
+	free(req->header.dev_name);
+	req->header._present.dev_name_len = strlen(dev_name);
+	req->header.dev_name = malloc(req->header._present.dev_name_len + 1);
+	memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len);
+	req->header.dev_name[req->header._present.dev_name_len] = 0;
+}
+static inline void
+ethtool_phy_get_req_dump_set_header_flags(struct ethtool_phy_get_req_dump *req,
+					  __u32 flags)
+{
+	req->_present.header = 1;
+	req->header._present.flags = 1;
+	req->header.flags = flags;
+}
+static inline void
+ethtool_phy_get_req_dump_set_header_phy_index(struct ethtool_phy_get_req_dump *req,
+					      __u32 phy_index)
+{
+	req->_present.header = 1;
+	req->header._present.phy_index = 1;
+	req->header.phy_index = phy_index;
+}
+
+struct ethtool_phy_get_list {
+	struct ethtool_phy_get_list *next;
+	struct ethtool_phy_get_rsp obj __attribute__((aligned(8)));
+};
+
+void ethtool_phy_get_list_free(struct ethtool_phy_get_list *rsp);
+
+struct ethtool_phy_get_list *
+ethtool_phy_get_dump(struct ynl_sock *ys, struct ethtool_phy_get_req_dump *req);
+
 /* ETHTOOL_MSG_CABLE_TEST_NTF - event */
 struct ethtool_cable_test_ntf_rsp {
 	struct {
-- 
2.42.0


WARNING: multiple messages have this Message-ID (diff)
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
To: davem@davemloft.net
Cc: "Maxime Chevallier" <maxime.chevallier@bootlin.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	thomas.petazzoni@bootlin.com, "Andrew Lunn" <andrew@lunn.ch>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Eric Dumazet" <edumazet@google.com>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Russell King" <linux@armlinux.org.uk>,
	linux-arm-kernel@lists.infradead.org,
	"Christophe Leroy" <christophe.leroy@csgroup.eu>,
	"Herve Codina" <herve.codina@bootlin.com>,
	"Florian Fainelli" <f.fainelli@gmail.com>,
	"Heiner Kallweit" <hkallweit1@gmail.com>,
	"Vladimir Oltean" <vladimir.oltean@nxp.com>,
	"Köry Maincent" <kory.maincent@bootlin.com>,
	"Jesse Brandeburg" <jesse.brandeburg@intel.com>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Marek Behún" <kabel@kernel.org>,
	"Piergiorgio Beruto" <piergiorgio.beruto@gmail.com>,
	"Oleksij Rempel" <o.rempel@pengutronix.de>,
	"Nicolò Veronese" <nicveronese@gmail.com>
Subject: [RFC PATCH net-next v3 08/13] netlink: specs: add ethnl PHY_GET command set
Date: Fri,  1 Dec 2023 17:36:58 +0100	[thread overview]
Message-ID: <20231201163704.1306431-9-maxime.chevallier@bootlin.com> (raw)
In-Reply-To: <20231201163704.1306431-1-maxime.chevallier@bootlin.com>

The PHY_GET command, supporting both DUMP and GET operations, is used to
retrieve the list of PHYs connected to a netdevice, and get topology
information to know where exactly it sits on the physical link.

Add the netlink specs corresponding to that command, and bump the
ethtool-user.c|h autogenerated files.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: New patch

 Documentation/netlink/specs/ethtool.yaml |  65 ++++++
 tools/net/ynl/generated/ethtool-user.c   | 257 +++++++++++++++++++++++
 tools/net/ynl/generated/ethtool-user.h   | 153 ++++++++++++++
 3 files changed, 475 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 4e0790648913..280b090b5f7c 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -16,6 +16,11 @@ definitions:
     name: stringset
     type: enum
     entries: []
+  -
+    name: phy-upstream-type
+    enum-name:
+    type: enum
+    entries: [ mac, phy ]
 
 attribute-sets:
   -
@@ -942,6 +947,45 @@ attribute-sets:
       -
         name: burst-tmr
         type: u32
+  -
+    name: phy-upstream
+    attributes:
+      -
+        name: index
+        type: u32
+      -
+        name: sfp-name
+        type: string
+  -
+    name: phy
+    attributes:
+      -
+        name: header
+        type: nest
+        nested-attributes: header
+      -
+        name: index
+        type: u32
+      -
+        name: drvname
+        type: string
+      -
+        name: name
+        type: string
+      -
+        name: upstream-type
+        type: u8
+        enum: phy-upstream-type
+      -
+        name: upstream
+        type: nest
+        nested-attributes: phy-upstream
+      -
+        name: downstream-sfp-name
+        type: string
+      -
+        name: id
+        type: u32
 
 operations:
   enum-model: directional
@@ -1692,3 +1736,24 @@ operations:
       name: mm-ntf
       doc: Notification for change in MAC Merge configuration.
       notify: mm-get
+    -
+      name: phy-get
+      doc: Get PHY devices attached to an interface
+
+      attribute-set: phy
+
+      do: &phy-get-op
+        request:
+          attributes:
+            - header
+        reply:
+          attributes:
+            - header
+            - index
+            - drvname
+            - name
+            - upstream-type
+            - upstream
+            - downstream-sfp-name
+            - id
+      dump: *phy-get-op
diff --git a/tools/net/ynl/generated/ethtool-user.c b/tools/net/ynl/generated/ethtool-user.c
index 295661eb3a3e..b63ba2d2e25e 100644
--- a/tools/net/ynl/generated/ethtool-user.c
+++ b/tools/net/ynl/generated/ethtool-user.c
@@ -59,6 +59,7 @@ static const char * const ethtool_op_strmap[] = {
 	[41] = "plca-ntf",
 	[ETHTOOL_MSG_MM_GET] = "mm-get",
 	[43] = "mm-ntf",
+	[ETHTOOL_MSG_PHY_GET] = "phy-get",
 };
 
 const char *ethtool_op_str(int op)
@@ -91,6 +92,18 @@ const char *ethtool_stringset_str(enum ethtool_stringset value)
 	return ethtool_stringset_strmap[value];
 }
 
+static const char * const ethtool_phy_upstream_type_strmap[] = {
+	[0] = "mac",
+	[1] = "phy",
+};
+
+const char *ethtool_phy_upstream_type_str(int value)
+{
+	if (value < 0 || value >= (int)MNL_ARRAY_SIZE(ethtool_phy_upstream_type_strmap))
+		return NULL;
+	return ethtool_phy_upstream_type_strmap[value];
+}
+
 /* Policies */
 struct ynl_policy_attr ethtool_header_policy[ETHTOOL_A_HEADER_MAX + 1] = {
 	[ETHTOOL_A_HEADER_DEV_INDEX] = { .name = "dev-index", .type = YNL_PT_U32, },
@@ -154,6 +167,16 @@ struct ynl_policy_nest ethtool_mm_stat_nest = {
 	.table = ethtool_mm_stat_policy,
 };
 
+struct ynl_policy_attr ethtool_phy_upstream_policy[ETHTOOL_A_PHY_UPSTREAM_MAX + 1] = {
+	[ETHTOOL_A_PHY_UPSTREAM_INDEX] = { .name = "index", .type = YNL_PT_U32, },
+	[ETHTOOL_A_PHY_UPSTREAM_SFP_NAME] = { .name = "sfp-name", .type = YNL_PT_NUL_STR, },
+};
+
+struct ynl_policy_nest ethtool_phy_upstream_nest = {
+	.max_attr = ETHTOOL_A_PHY_UPSTREAM_MAX,
+	.table = ethtool_phy_upstream_policy,
+};
+
 struct ynl_policy_attr ethtool_cable_result_policy[ETHTOOL_A_CABLE_RESULT_MAX + 1] = {
 	[ETHTOOL_A_CABLE_RESULT_PAIR] = { .name = "pair", .type = YNL_PT_U8, },
 	[ETHTOOL_A_CABLE_RESULT_CODE] = { .name = "code", .type = YNL_PT_U8, },
@@ -667,6 +690,22 @@ struct ynl_policy_nest ethtool_mm_nest = {
 	.table = ethtool_mm_policy,
 };
 
+struct ynl_policy_attr ethtool_phy_policy[ETHTOOL_A_PHY_MAX + 1] = {
+	[ETHTOOL_A_PHY_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
+	[ETHTOOL_A_PHY_INDEX] = { .name = "index", .type = YNL_PT_U32, },
+	[ETHTOOL_A_PHY_DRVNAME] = { .name = "drvname", .type = YNL_PT_NUL_STR, },
+	[ETHTOOL_A_PHY_NAME] = { .name = "name", .type = YNL_PT_NUL_STR, },
+	[ETHTOOL_A_PHY_UPSTREAM_TYPE] = { .name = "upstream-type", .type = YNL_PT_U8, },
+	[ETHTOOL_A_PHY_UPSTREAM] = { .name = "upstream", .type = YNL_PT_NEST, .nest = &ethtool_phy_upstream_nest, },
+	[ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME] = { .name = "downstream-sfp-name", .type = YNL_PT_NUL_STR, },
+	[ETHTOOL_A_PHY_ID] = { .name = "id", .type = YNL_PT_U32, },
+};
+
+struct ynl_policy_nest ethtool_phy_nest = {
+	.max_attr = ETHTOOL_A_PHY_MAX,
+	.table = ethtool_phy_policy,
+};
+
 /* Common nested types */
 void ethtool_header_free(struct ethtool_header *obj)
 {
@@ -899,6 +938,42 @@ int ethtool_mm_stat_parse(struct ynl_parse_arg *yarg,
 	return 0;
 }
 
+void ethtool_phy_upstream_free(struct ethtool_phy_upstream *obj)
+{
+	free(obj->sfp_name);
+}
+
+int ethtool_phy_upstream_parse(struct ynl_parse_arg *yarg,
+			       const struct nlattr *nested)
+{
+	struct ethtool_phy_upstream *dst = yarg->data;
+	const struct nlattr *attr;
+
+	mnl_attr_for_each_nested(attr, nested) {
+		unsigned int type = mnl_attr_get_type(attr);
+
+		if (type == ETHTOOL_A_PHY_UPSTREAM_INDEX) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.index = 1;
+			dst->index = mnl_attr_get_u32(attr);
+		} else if (type == ETHTOOL_A_PHY_UPSTREAM_SFP_NAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.sfp_name_len = len;
+			dst->sfp_name = malloc(len + 1);
+			memcpy(dst->sfp_name, mnl_attr_get_str(attr), len);
+			dst->sfp_name[len] = 0;
+		}
+	}
+
+	return 0;
+}
+
 void ethtool_cable_result_free(struct ethtool_cable_result *obj)
 {
 }
@@ -6158,6 +6233,188 @@ int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req)
 	return 0;
 }
 
+/* ============== ETHTOOL_MSG_PHY_GET ============== */
+/* ETHTOOL_MSG_PHY_GET - do */
+void ethtool_phy_get_req_free(struct ethtool_phy_get_req *req)
+{
+	ethtool_header_free(&req->header);
+	free(req);
+}
+
+void ethtool_phy_get_rsp_free(struct ethtool_phy_get_rsp *rsp)
+{
+	ethtool_header_free(&rsp->header);
+	free(rsp->drvname);
+	free(rsp->name);
+	ethtool_phy_upstream_free(&rsp->upstream);
+	free(rsp->downstream_sfp_name);
+	free(rsp);
+}
+
+int ethtool_phy_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
+{
+	struct ynl_parse_arg *yarg = data;
+	struct ethtool_phy_get_rsp *dst;
+	const struct nlattr *attr;
+	struct ynl_parse_arg parg;
+
+	dst = yarg->data;
+	parg.ys = yarg->ys;
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		unsigned int type = mnl_attr_get_type(attr);
+
+		if (type == ETHTOOL_A_PHY_HEADER) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.header = 1;
+
+			parg.rsp_policy = &ethtool_header_nest;
+			parg.data = &dst->header;
+			if (ethtool_header_parse(&parg, attr))
+				return MNL_CB_ERROR;
+		} else if (type == ETHTOOL_A_PHY_INDEX) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.index = 1;
+			dst->index = mnl_attr_get_u32(attr);
+		} else if (type == ETHTOOL_A_PHY_DRVNAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.drvname_len = len;
+			dst->drvname = malloc(len + 1);
+			memcpy(dst->drvname, mnl_attr_get_str(attr), len);
+			dst->drvname[len] = 0;
+		} else if (type == ETHTOOL_A_PHY_NAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.name_len = len;
+			dst->name = malloc(len + 1);
+			memcpy(dst->name, mnl_attr_get_str(attr), len);
+			dst->name[len] = 0;
+		} else if (type == ETHTOOL_A_PHY_UPSTREAM_TYPE) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.upstream_type = 1;
+			dst->upstream_type = mnl_attr_get_u8(attr);
+		} else if (type == ETHTOOL_A_PHY_UPSTREAM) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.upstream = 1;
+
+			parg.rsp_policy = &ethtool_phy_upstream_nest;
+			parg.data = &dst->upstream;
+			if (ethtool_phy_upstream_parse(&parg, attr))
+				return MNL_CB_ERROR;
+		} else if (type == ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
+			dst->_present.downstream_sfp_name_len = len;
+			dst->downstream_sfp_name = malloc(len + 1);
+			memcpy(dst->downstream_sfp_name, mnl_attr_get_str(attr), len);
+			dst->downstream_sfp_name[len] = 0;
+		} else if (type == ETHTOOL_A_PHY_ID) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.id = 1;
+			dst->id = mnl_attr_get_u32(attr);
+		}
+	}
+
+	return MNL_CB_OK;
+}
+
+struct ethtool_phy_get_rsp *
+ethtool_phy_get(struct ynl_sock *ys, struct ethtool_phy_get_req *req)
+{
+	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
+	struct ethtool_phy_get_rsp *rsp;
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PHY_GET, 1);
+	ys->req_policy = &ethtool_phy_nest;
+	yrs.yarg.rsp_policy = &ethtool_phy_nest;
+
+	if (req->_present.header)
+		ethtool_header_put(nlh, ETHTOOL_A_PHY_HEADER, &req->header);
+
+	rsp = calloc(1, sizeof(*rsp));
+	yrs.yarg.data = rsp;
+	yrs.cb = ethtool_phy_get_rsp_parse;
+	yrs.rsp_cmd = ETHTOOL_MSG_PHY_GET;
+
+	err = ynl_exec(ys, nlh, &yrs);
+	if (err < 0)
+		goto err_free;
+
+	return rsp;
+
+err_free:
+	ethtool_phy_get_rsp_free(rsp);
+	return NULL;
+}
+
+/* ETHTOOL_MSG_PHY_GET - dump */
+void ethtool_phy_get_list_free(struct ethtool_phy_get_list *rsp)
+{
+	struct ethtool_phy_get_list *next = rsp;
+
+	while ((void *)next != YNL_LIST_END) {
+		rsp = next;
+		next = rsp->next;
+
+		ethtool_header_free(&rsp->obj.header);
+		free(rsp->obj.drvname);
+		free(rsp->obj.name);
+		ethtool_phy_upstream_free(&rsp->obj.upstream);
+		free(rsp->obj.downstream_sfp_name);
+		free(rsp);
+	}
+}
+
+struct ethtool_phy_get_list *
+ethtool_phy_get_dump(struct ynl_sock *ys, struct ethtool_phy_get_req_dump *req)
+{
+	struct ynl_dump_state yds = {};
+	struct nlmsghdr *nlh;
+	int err;
+
+	yds.ys = ys;
+	yds.alloc_sz = sizeof(struct ethtool_phy_get_list);
+	yds.cb = ethtool_phy_get_rsp_parse;
+	yds.rsp_cmd = ETHTOOL_MSG_PHY_GET;
+	yds.rsp_policy = &ethtool_phy_nest;
+
+	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PHY_GET, 1);
+	ys->req_policy = &ethtool_phy_nest;
+
+	if (req->_present.header)
+		ethtool_header_put(nlh, ETHTOOL_A_PHY_HEADER, &req->header);
+
+	err = ynl_exec_dump(ys, nlh, &yds);
+	if (err < 0)
+		goto free_list;
+
+	return yds.first;
+
+free_list:
+	ethtool_phy_get_list_free(yds.first);
+	return NULL;
+}
+
 /* ETHTOOL_MSG_CABLE_TEST_NTF - event */
 int ethtool_cable_test_ntf_rsp_parse(const struct nlmsghdr *nlh, void *data)
 {
diff --git a/tools/net/ynl/generated/ethtool-user.h b/tools/net/ynl/generated/ethtool-user.h
index 97c079c0f332..59ebb0a1a09f 100644
--- a/tools/net/ynl/generated/ethtool-user.h
+++ b/tools/net/ynl/generated/ethtool-user.h
@@ -20,6 +20,7 @@ extern const struct ynl_family ynl_ethtool_family;
 const char *ethtool_op_str(int op);
 const char *ethtool_udp_tunnel_type_str(int value);
 const char *ethtool_stringset_str(enum ethtool_stringset value);
+const char *ethtool_phy_upstream_type_str(int value);
 
 /* Common nested types */
 struct ethtool_header {
@@ -90,6 +91,16 @@ struct ethtool_mm_stat {
 	__u64 hold_count;
 };
 
+struct ethtool_phy_upstream {
+	struct {
+		__u32 index:1;
+		__u32 sfp_name_len;
+	} _present;
+
+	__u32 index;
+	char *sfp_name;
+};
+
 struct ethtool_cable_result {
 	struct {
 		__u32 pair:1;
@@ -6018,6 +6029,148 @@ ethtool_mm_set_req_set_tx_min_frag_size(struct ethtool_mm_set_req *req,
  */
 int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req);
 
+/* ============== ETHTOOL_MSG_PHY_GET ============== */
+/* ETHTOOL_MSG_PHY_GET - do */
+struct ethtool_phy_get_req {
+	struct {
+		__u32 header:1;
+	} _present;
+
+	struct ethtool_header header;
+};
+
+static inline struct ethtool_phy_get_req *ethtool_phy_get_req_alloc(void)
+{
+	return calloc(1, sizeof(struct ethtool_phy_get_req));
+}
+void ethtool_phy_get_req_free(struct ethtool_phy_get_req *req);
+
+static inline void
+ethtool_phy_get_req_set_header_dev_index(struct ethtool_phy_get_req *req,
+					 __u32 dev_index)
+{
+	req->_present.header = 1;
+	req->header._present.dev_index = 1;
+	req->header.dev_index = dev_index;
+}
+static inline void
+ethtool_phy_get_req_set_header_dev_name(struct ethtool_phy_get_req *req,
+					const char *dev_name)
+{
+	free(req->header.dev_name);
+	req->header._present.dev_name_len = strlen(dev_name);
+	req->header.dev_name = malloc(req->header._present.dev_name_len + 1);
+	memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len);
+	req->header.dev_name[req->header._present.dev_name_len] = 0;
+}
+static inline void
+ethtool_phy_get_req_set_header_flags(struct ethtool_phy_get_req *req,
+				     __u32 flags)
+{
+	req->_present.header = 1;
+	req->header._present.flags = 1;
+	req->header.flags = flags;
+}
+static inline void
+ethtool_phy_get_req_set_header_phy_index(struct ethtool_phy_get_req *req,
+					 __u32 phy_index)
+{
+	req->_present.header = 1;
+	req->header._present.phy_index = 1;
+	req->header.phy_index = phy_index;
+}
+
+struct ethtool_phy_get_rsp {
+	struct {
+		__u32 header:1;
+		__u32 index:1;
+		__u32 drvname_len;
+		__u32 name_len;
+		__u32 upstream_type:1;
+		__u32 upstream:1;
+		__u32 downstream_sfp_name_len;
+		__u32 id:1;
+	} _present;
+
+	struct ethtool_header header;
+	__u32 index;
+	char *drvname;
+	char *name;
+	__u8 upstream_type;
+	struct ethtool_phy_upstream upstream;
+	char *downstream_sfp_name;
+	__u32 id;
+};
+
+void ethtool_phy_get_rsp_free(struct ethtool_phy_get_rsp *rsp);
+
+/*
+ * Get PHY devices attached to an interface
+ */
+struct ethtool_phy_get_rsp *
+ethtool_phy_get(struct ynl_sock *ys, struct ethtool_phy_get_req *req);
+
+/* ETHTOOL_MSG_PHY_GET - dump */
+struct ethtool_phy_get_req_dump {
+	struct {
+		__u32 header:1;
+	} _present;
+
+	struct ethtool_header header;
+};
+
+static inline struct ethtool_phy_get_req_dump *
+ethtool_phy_get_req_dump_alloc(void)
+{
+	return calloc(1, sizeof(struct ethtool_phy_get_req_dump));
+}
+void ethtool_phy_get_req_dump_free(struct ethtool_phy_get_req_dump *req);
+
+static inline void
+ethtool_phy_get_req_dump_set_header_dev_index(struct ethtool_phy_get_req_dump *req,
+					      __u32 dev_index)
+{
+	req->_present.header = 1;
+	req->header._present.dev_index = 1;
+	req->header.dev_index = dev_index;
+}
+static inline void
+ethtool_phy_get_req_dump_set_header_dev_name(struct ethtool_phy_get_req_dump *req,
+					     const char *dev_name)
+{
+	free(req->header.dev_name);
+	req->header._present.dev_name_len = strlen(dev_name);
+	req->header.dev_name = malloc(req->header._present.dev_name_len + 1);
+	memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len);
+	req->header.dev_name[req->header._present.dev_name_len] = 0;
+}
+static inline void
+ethtool_phy_get_req_dump_set_header_flags(struct ethtool_phy_get_req_dump *req,
+					  __u32 flags)
+{
+	req->_present.header = 1;
+	req->header._present.flags = 1;
+	req->header.flags = flags;
+}
+static inline void
+ethtool_phy_get_req_dump_set_header_phy_index(struct ethtool_phy_get_req_dump *req,
+					      __u32 phy_index)
+{
+	req->_present.header = 1;
+	req->header._present.phy_index = 1;
+	req->header.phy_index = phy_index;
+}
+
+struct ethtool_phy_get_list {
+	struct ethtool_phy_get_list *next;
+	struct ethtool_phy_get_rsp obj __attribute__((aligned(8)));
+};
+
+void ethtool_phy_get_list_free(struct ethtool_phy_get_list *rsp);
+
+struct ethtool_phy_get_list *
+ethtool_phy_get_dump(struct ynl_sock *ys, struct ethtool_phy_get_req_dump *req);
+
 /* ETHTOOL_MSG_CABLE_TEST_NTF - event */
 struct ethtool_cable_test_ntf_rsp {
 	struct {
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2023-12-01 16:37 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-01 16:36 [RFC PATCH net-next v3 00/13] Introduce PHY listing and link_topology tracking Maxime Chevallier
2023-12-01 16:36 ` Maxime Chevallier
2023-12-01 16:36 ` [RFC PATCH net-next v3 01/13] net: phy: Introduce ethernet link topology representation Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-05 14:49   ` kernel test robot
2023-12-05 15:31   ` kernel test robot
2023-12-09 17:02   ` Simon Horman
2023-12-09 17:02     ` Simon Horman
2023-12-11 11:06     ` Maxime Chevallier
2023-12-11 11:06       ` Maxime Chevallier
2023-12-11 14:09       ` Andrew Lunn
2023-12-11 14:09         ` Andrew Lunn
2023-12-12 13:10         ` Maxime Chevallier
2023-12-12 13:10           ` Maxime Chevallier
2023-12-01 16:36 ` [RFC PATCH net-next v3 02/13] net: sfp: pass the phy_device when disconnecting an sfp module's PHY Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-01 16:36 ` [RFC PATCH net-next v3 03/13] net: phy: add helpers to handle sfp phy connect/disconnect Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-01 16:36 ` [RFC PATCH net-next v3 04/13] net: sfp: Add helper to return the SFP bus name Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-01 16:36 ` [RFC PATCH net-next v3 05/13] net: ethtool: Allow passing a phy index for some commands Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-05 16:35   ` kernel test robot
2023-12-01 16:36 ` [RFC PATCH net-next v3 06/13] netlink: specs: add phy-index as a header parameter Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-04 10:36   ` Maxime Chevallier
2023-12-04 10:36     ` Maxime Chevallier
2023-12-01 16:36 ` [RFC PATCH net-next v3 07/13] net: ethtool: Introduce a command to list PHYs on an interface Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-09 17:04   ` Simon Horman
2023-12-09 17:04     ` Simon Horman
2023-12-11 11:07     ` Maxime Chevallier
2023-12-11 11:07       ` Maxime Chevallier
2023-12-01 16:36 ` Maxime Chevallier [this message]
2023-12-01 16:36   ` [RFC PATCH net-next v3 08/13] netlink: specs: add ethnl PHY_GET command set Maxime Chevallier
2023-12-04 10:37   ` Maxime Chevallier
2023-12-04 10:37     ` Maxime Chevallier
2023-12-01 16:36 ` [RFC PATCH net-next v3 09/13] net: ethtool: plca: Target the command to the requested PHY Maxime Chevallier
2023-12-01 16:36   ` Maxime Chevallier
2023-12-01 16:37 ` [RFC PATCH net-next v3 10/13] net: ethtool: pse-pd: " Maxime Chevallier
2023-12-01 16:37   ` Maxime Chevallier
2023-12-01 16:37 ` [RFC PATCH net-next v3 11/13] net: ethtool: cable-test: " Maxime Chevallier
2023-12-01 16:37   ` Maxime Chevallier
2023-12-01 16:37 ` [RFC PATCH net-next v3 12/13] net: ethtool: strset: Allow querying phy stats by index Maxime Chevallier
2023-12-01 16:37   ` Maxime Chevallier
2023-12-01 16:37 ` [RFC PATCH net-next v3 13/13] Documentation: networking: document phy_link_topology Maxime Chevallier
2023-12-01 16:37   ` Maxime Chevallier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231201163704.1306431-9-maxime.chevallier@bootlin.com \
    --to=maxime.chevallier@bootlin.com \
    --cc=andrew@lunn.ch \
    --cc=christophe.leroy@csgroup.eu \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=f.fainelli@gmail.com \
    --cc=herve.codina@bootlin.com \
    --cc=hkallweit1@gmail.com \
    --cc=jesse.brandeburg@intel.com \
    --cc=kabel@kernel.org \
    --cc=kory.maincent@bootlin.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=nicveronese@gmail.com \
    --cc=o.rempel@pengutronix.de \
    --cc=pabeni@redhat.com \
    --cc=piergiorgio.beruto@gmail.com \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vladimir.oltean@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.