From nobody Fri Dec 19 00:21:17 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75ABEC4167B for ; Fri, 1 Dec 2023 16:37:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378787AbjLAQhp (ORCPT ); Fri, 1 Dec 2023 11:37:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1378516AbjLAQh2 (ORCPT ); Fri, 1 Dec 2023 11:37:28 -0500 Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::226]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 900111713; Fri, 1 Dec 2023 08:37:20 -0800 (PST) Received: by mail.gandi.net (Postfix) with ESMTPSA id 0BD2DC0008; Fri, 1 Dec 2023 16:37:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1701448639; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UUPrERWVmZXfJBxo+Ko10zUTpdUI1iWcuWQHSDOYj1w=; b=WIv8nj2ZV2CZjYIhBAxYUu/IOA8Kx2/sL3iIPGhlNOJhAmmi8q1Zke4hJKrnt0XhuVI1nj E9NS8SSDORWSOkCbnwb22kS+RwcE7J/YHAIWiHm8GeVsj2jG/UPiyA8gKKstAeTPCPXxQB Nbdr+C8lam3L17dAw6gmJKSKW7OPpShOXfFvSx+TCIBQ6AoBaWxPQ1pdiHuH23usOLdZGs 2O/TqFC89hEVak1t1Xo+G5+yOvhHv1TZKPWRXnWjGeqXRpquIQWuVch4l4y1GUDnUgZEpo aIVxgHobgw/gjaFUoRuWVGUhtPKOu2H+v7tsCjJah7OyQRBIrN5lduJ7EM3VfA== From: Maxime Chevallier To: davem@davemloft.net Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , linux-arm-kernel@lists.infradead.org, Christophe Leroy , Herve Codina , Florian Fainelli , Heiner Kallweit , Vladimir Oltean , =?UTF-8?q?K=C3=B6ry=20Maincent?= , Jesse Brandeburg , Jonathan Corbet , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Piergiorgio Beruto , Oleksij Rempel , =?UTF-8?q?Nicol=C3=B2=20Veronese?= 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 Message-ID: <20231201163704.1306431-9-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231201163704.1306431-1-maxime.chevallier@bootlin.com> References: <20231201163704.1306431-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-GND-Sasl: maxime.chevallier@bootlin.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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/netli= nk/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 ] =20 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 =20 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/generat= ed/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[] =3D { [41] =3D "plca-ntf", [ETHTOOL_MSG_MM_GET] =3D "mm-get", [43] =3D "mm-ntf", + [ETHTOOL_MSG_PHY_GET] =3D "phy-get", }; =20 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]; } =20 +static const char * const ethtool_phy_upstream_type_strmap[] =3D { + [0] =3D "mac", + [1] =3D "phy", +}; + +const char *ethtool_phy_upstream_type_str(int value) +{ + if (value < 0 || value >=3D (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] =3D= { [ETHTOOL_A_HEADER_DEV_INDEX] =3D { .name =3D "dev-index", .type =3D YNL_P= T_U32, }, @@ -154,6 +167,16 @@ struct ynl_policy_nest ethtool_mm_stat_nest =3D { .table =3D ethtool_mm_stat_policy, }; =20 +struct ynl_policy_attr ethtool_phy_upstream_policy[ETHTOOL_A_PHY_UPSTREAM_= MAX + 1] =3D { + [ETHTOOL_A_PHY_UPSTREAM_INDEX] =3D { .name =3D "index", .type =3D YNL_PT_= U32, }, + [ETHTOOL_A_PHY_UPSTREAM_SFP_NAME] =3D { .name =3D "sfp-name", .type =3D Y= NL_PT_NUL_STR, }, +}; + +struct ynl_policy_nest ethtool_phy_upstream_nest =3D { + .max_attr =3D ETHTOOL_A_PHY_UPSTREAM_MAX, + .table =3D ethtool_phy_upstream_policy, +}; + struct ynl_policy_attr ethtool_cable_result_policy[ETHTOOL_A_CABLE_RESULT_= MAX + 1] =3D { [ETHTOOL_A_CABLE_RESULT_PAIR] =3D { .name =3D "pair", .type =3D YNL_PT_U8= , }, [ETHTOOL_A_CABLE_RESULT_CODE] =3D { .name =3D "code", .type =3D YNL_PT_U8= , }, @@ -667,6 +690,22 @@ struct ynl_policy_nest ethtool_mm_nest =3D { .table =3D ethtool_mm_policy, }; =20 +struct ynl_policy_attr ethtool_phy_policy[ETHTOOL_A_PHY_MAX + 1] =3D { + [ETHTOOL_A_PHY_HEADER] =3D { .name =3D "header", .type =3D YNL_PT_NEST, .= nest =3D ðtool_header_nest, }, + [ETHTOOL_A_PHY_INDEX] =3D { .name =3D "index", .type =3D YNL_PT_U32, }, + [ETHTOOL_A_PHY_DRVNAME] =3D { .name =3D "drvname", .type =3D YNL_PT_NUL_S= TR, }, + [ETHTOOL_A_PHY_NAME] =3D { .name =3D "name", .type =3D YNL_PT_NUL_STR, }, + [ETHTOOL_A_PHY_UPSTREAM_TYPE] =3D { .name =3D "upstream-type", .type =3D = YNL_PT_U8, }, + [ETHTOOL_A_PHY_UPSTREAM] =3D { .name =3D "upstream", .type =3D YNL_PT_NES= T, .nest =3D ðtool_phy_upstream_nest, }, + [ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME] =3D { .name =3D "downstream-sfp-name"= , .type =3D YNL_PT_NUL_STR, }, + [ETHTOOL_A_PHY_ID] =3D { .name =3D "id", .type =3D YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_phy_nest =3D { + .max_attr =3D ETHTOOL_A_PHY_MAX, + .table =3D 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; } =20 +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 =3D yarg->data; + const struct nlattr *attr; + + mnl_attr_for_each_nested(attr, nested) { + unsigned int type =3D mnl_attr_get_type(attr); + + if (type =3D=3D ETHTOOL_A_PHY_UPSTREAM_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + dst->_present.index =3D 1; + dst->index =3D mnl_attr_get_u32(attr); + } else if (type =3D=3D ETHTOOL_A_PHY_UPSTREAM_SFP_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + + len =3D strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); + dst->_present.sfp_name_len =3D len; + dst->sfp_name =3D malloc(len + 1); + memcpy(dst->sfp_name, mnl_attr_get_str(attr), len); + dst->sfp_name[len] =3D 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 etht= ool_mm_set_req *req) return 0; } =20 +/* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D ETHTOOL_MSG_PHY_GET =3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ +/* 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 =3D data; + struct ethtool_phy_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst =3D yarg->data; + parg.ys =3D yarg->ys; + + mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { + unsigned int type =3D mnl_attr_get_type(attr); + + if (type =3D=3D ETHTOOL_A_PHY_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + dst->_present.header =3D 1; + + parg.rsp_policy =3D ðtool_header_nest; + parg.data =3D &dst->header; + if (ethtool_header_parse(&parg, attr)) + return MNL_CB_ERROR; + } else if (type =3D=3D ETHTOOL_A_PHY_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + dst->_present.index =3D 1; + dst->index =3D mnl_attr_get_u32(attr); + } else if (type =3D=3D ETHTOOL_A_PHY_DRVNAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + + len =3D strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); + dst->_present.drvname_len =3D len; + dst->drvname =3D malloc(len + 1); + memcpy(dst->drvname, mnl_attr_get_str(attr), len); + dst->drvname[len] =3D 0; + } else if (type =3D=3D ETHTOOL_A_PHY_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + + len =3D strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); + dst->_present.name_len =3D len; + dst->name =3D malloc(len + 1); + memcpy(dst->name, mnl_attr_get_str(attr), len); + dst->name[len] =3D 0; + } else if (type =3D=3D ETHTOOL_A_PHY_UPSTREAM_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + dst->_present.upstream_type =3D 1; + dst->upstream_type =3D mnl_attr_get_u8(attr); + } else if (type =3D=3D ETHTOOL_A_PHY_UPSTREAM) { + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + dst->_present.upstream =3D 1; + + parg.rsp_policy =3D ðtool_phy_upstream_nest; + parg.data =3D &dst->upstream; + if (ethtool_phy_upstream_parse(&parg, attr)) + return MNL_CB_ERROR; + } else if (type =3D=3D ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + + len =3D strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); + dst->_present.downstream_sfp_name_len =3D len; + dst->downstream_sfp_name =3D malloc(len + 1); + memcpy(dst->downstream_sfp_name, mnl_attr_get_str(attr), len); + dst->downstream_sfp_name[len] =3D 0; + } else if (type =3D=3D ETHTOOL_A_PHY_ID) { + if (ynl_attr_validate(yarg, attr)) + return MNL_CB_ERROR; + dst->_present.id =3D 1; + dst->id =3D 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 =3D { .yarg =3D { .ys =3D ys, }, }; + struct ethtool_phy_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh =3D ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PHY_GET, 1); + ys->req_policy =3D ðtool_phy_nest; + yrs.yarg.rsp_policy =3D ðtool_phy_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PHY_HEADER, &req->header); + + rsp =3D calloc(1, sizeof(*rsp)); + yrs.yarg.data =3D rsp; + yrs.cb =3D ethtool_phy_get_rsp_parse; + yrs.rsp_cmd =3D ETHTOOL_MSG_PHY_GET; + + err =3D 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 =3D rsp; + + while ((void *)next !=3D YNL_LIST_END) { + rsp =3D next; + next =3D 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 =3D {}; + struct nlmsghdr *nlh; + int err; + + yds.ys =3D ys; + yds.alloc_sz =3D sizeof(struct ethtool_phy_get_list); + yds.cb =3D ethtool_phy_get_rsp_parse; + yds.rsp_cmd =3D ETHTOOL_MSG_PHY_GET; + yds.rsp_policy =3D ðtool_phy_nest; + + nlh =3D ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PHY_GET, 1); + ys->req_policy =3D ðtool_phy_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PHY_HEADER, &req->header); + + err =3D 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 *dat= a) { diff --git a/tools/net/ynl/generated/ethtool-user.h b/tools/net/ynl/generat= ed/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); =20 /* Common nested types */ struct ethtool_header { @@ -90,6 +91,16 @@ struct ethtool_mm_stat { __u64 hold_count; }; =20 +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 etht= ool_mm_set_req *req, */ int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req); =20 +/* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D ETHTOOL_MSG_PHY_GET =3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ +/* 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 =3D 1; + req->header._present.dev_index =3D 1; + req->header.dev_index =3D 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 =3D strlen(dev_name); + req->header.dev_name =3D 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] =3D 0; +} +static inline void +ethtool_phy_get_req_set_header_flags(struct ethtool_phy_get_req *req, + __u32 flags) +{ + req->_present.header =3D 1; + req->header._present.flags =3D 1; + req->header.flags =3D flags; +} +static inline void +ethtool_phy_get_req_set_header_phy_index(struct ethtool_phy_get_req *req, + __u32 phy_index) +{ + req->_present.header =3D 1; + req->header._present.phy_index =3D 1; + req->header.phy_index =3D 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_d= ump *req, + __u32 dev_index) +{ + req->_present.header =3D 1; + req->header._present.dev_index =3D 1; + req->header.dev_index =3D dev_index; +} +static inline void +ethtool_phy_get_req_dump_set_header_dev_name(struct ethtool_phy_get_req_du= mp *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len =3D strlen(dev_name); + req->header.dev_name =3D 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] =3D 0; +} +static inline void +ethtool_phy_get_req_dump_set_header_flags(struct ethtool_phy_get_req_dump = *req, + __u32 flags) +{ + req->_present.header =3D 1; + req->header._present.flags =3D 1; + req->header.flags =3D flags; +} +static inline void +ethtool_phy_get_req_dump_set_header_phy_index(struct ethtool_phy_get_req_d= ump *req, + __u32 phy_index) +{ + req->_present.header =3D 1; + req->header._present.phy_index =3D 1; + req->header.phy_index =3D 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 { --=20 2.42.0