Received: by 2002:a05:7412:b10a:b0:f3:1519:9f41 with SMTP id az10csp1168185rdb; Fri, 1 Dec 2023 08:38:08 -0800 (PST) X-Google-Smtp-Source: AGHT+IEGnRLZuJk3xpW5x8W2lOTZG6CWZ2MHfMtpeNBZZTyfszNgmMdxSKVsoFH5d44wvax5VCWw X-Received: by 2002:a05:6358:78c:b0:16b:c63d:5dfe with SMTP id n12-20020a056358078c00b0016bc63d5dfemr30286844rwj.16.1701448688047; Fri, 01 Dec 2023 08:38:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701448688; cv=none; d=google.com; s=arc-20160816; b=aLjCNLxga2pJJk70anpVGWajGRP2TcXgrksvNJsAOJvgBCsOpdtLcjrJyacajC/7QP r9j+ZsNRFAdozvk97PoLE7UU835+16mgHyiAKxeAir4peN8s7MEqYu1WlBflvslH4RHQ eNRlolDRiujyTm24MqcRN8Y7TTg4J0hIBpbZYjsfyYM69WsREJPcMwozooqIFr+WH6Yq GsHEoGrfjDbreggi6wHF/TsRRTe55c4fWRmnVzpckNcHT0VMXf2DW+s78UWj/QGe8J9I UgSHCaZssv0gmSneyeR/JLfd0syqgG7TP+GZ8ceo9JBM6xWqeOZylBbrekhA3bC4GFUo Yj3Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=UUPrERWVmZXfJBxo+Ko10zUTpdUI1iWcuWQHSDOYj1w=; fh=01/i7K9ues3Vkkz8uyECvnCPITXmGs/30yOh5FbyFgY=; b=rw3QUin1PLbGrtJ0s7jDjMDsCr/4ggbyp/d/375XH141oEMMgYEtf0WE6OaqThtdWT hG631M35sIIY8Ytk6GaY9MghOxHnQTUBP9MjvkzuomeN2nHHvGuZVa2GpVRc/mGdHCBj stm7uoZERIUCQPbg4y+d1IolnMWw7vEechbue3a+fu+GG1nEgFgtcWYO2QnTas7C34Rv Vp/zpf498/vQolRiweW5j6HQN1ErmYHBTxQ/LJ238V6NU65rKPjqzP1efCmg8msBOyn9 trbWbeXRauYYppdjOHJqZTlsFhl3Kk8wdWXeO9MdU6Rbr6DPKmUi5MOxmC5pT+m6VvDc P5QA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=WIv8nj2Z; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Return-Path: Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id w66-20020a636245000000b00584e65212d4si3472354pgb.609.2023.12.01.08.38.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Dec 2023 08:38:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=WIv8nj2Z; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 4A1D28129ADE; Fri, 1 Dec 2023 08:38:06 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378772AbjLAQhn (ORCPT + 99 others); Fri, 1 Dec 2023 11:37:43 -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: 8bit X-GND-Sasl: maxime.chevallier@bootlin.com X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_PASS,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Fri, 01 Dec 2023 08:38:06 -0800 (PST) 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/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 = ðtool_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 = ðtool_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 = ðtool_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 = ðtool_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 = ðtool_phy_nest; + yrs.yarg.rsp_policy = ðtool_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 = ðtool_phy_nest; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PHY_GET, 1); + ys->req_policy = ðtool_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