diff options
author | Michal Kubecek <mkubecek@suse.cz> | 2023-02-21 21:38:23 +0100 |
---|---|---|
committer | Michal Kubecek <mkubecek@suse.cz> | 2023-02-21 21:38:23 +0100 |
commit | 5cea67304a3c13e7757a0946aa1a0bff4989b899 (patch) | |
tree | 411b2c6099397ed5cd8bfc0f8dccb089a4a1e5cc | |
parent | 82642de0751cb0122c73757a906a63f2a272a2d1 (diff) | |
parent | a0d1bd673c16652a2074cc3889193ef482f8b5d5 (diff) | |
download | ethtool-5cea67304a3c13e7757a0946aa1a0bff4989b899.tar.gz |
Merge branch 'next' into master
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | ethtool.8.in | 194 | ||||
-rw-r--r-- | ethtool.c | 89 | ||||
-rw-r--r-- | netlink/desc-ethtool.c | 50 | ||||
-rw-r--r-- | netlink/extapi.h | 10 | ||||
-rw-r--r-- | netlink/mm.c | 270 | ||||
-rw-r--r-- | netlink/pause.c | 33 | ||||
-rw-r--r-- | netlink/plca.c | 296 | ||||
-rw-r--r-- | netlink/rings.c | 7 | ||||
-rw-r--r-- | netlink/settings.c | 81 | ||||
-rw-r--r-- | netlink/stats.c | 14 | ||||
-rw-r--r-- | uapi/linux/ethtool.h | 48 | ||||
-rw-r--r-- | uapi/linux/ethtool_netlink.h | 79 | ||||
-rw-r--r-- | uapi/linux/if_link.h | 5 | ||||
-rw-r--r-- | uapi/linux/rtnetlink.h | 1 |
15 files changed, 1151 insertions, 29 deletions
diff --git a/Makefile.am b/Makefile.am index 999e769..c83cb18 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,10 +38,11 @@ ethtool_SOURCES += \ netlink/features.c netlink/privflags.c netlink/rings.c \ netlink/channels.c netlink/coalesce.c netlink/pause.c \ netlink/eee.c netlink/tsinfo.c netlink/fec.c \ - netlink/stats.c \ + netlink/stats.c netlink/mm.c \ netlink/desc-ethtool.c netlink/desc-genlctrl.c \ netlink/module-eeprom.c netlink/module.c netlink/rss.c \ netlink/desc-rtnl.c netlink/cable_test.c netlink/tunnels.c \ + netlink/plca.c \ uapi/linux/ethtool_netlink.h \ uapi/linux/netlink.h uapi/linux/genetlink.h \ uapi/linux/rtnetlink.h uapi/linux/if_link.h \ diff --git a/ethtool.8.in b/ethtool.8.in index d5d60d5..3672e44 100644 --- a/ethtool.8.in +++ b/ethtool.8.in @@ -201,6 +201,7 @@ ethtool \- query or control network driver and hardware settings .BN rx\-buf\-len .BN cqe\-size .BN tx\-push +.BN rx\-push .HP .B ethtool \-i|\-\-driver .I devname @@ -468,7 +469,6 @@ ethtool \- query or control network driver and hardware settings .IR %x ] .I sub_command .RB ... - . .HP .B ethtool \-\-cable\-test .I devname @@ -490,6 +490,38 @@ ethtool \- query or control network driver and hardware settings .I devname .RB [ power\-mode\-policy .BR high | auto ] +.HP +.B ethtool \-\-get\-plca\-cfg +.I devname +.HP +.B ethtool \-\-set\-plca\-cfg +.I devname +.RB [ enable +.BR on | off ] +.BN node\-id N +.BN node\-cnt N +.BN to\-tmr N +.BN burst\-cnt N +.BN burst\-tmr N +.HP +.B ethtool \-\-get\-plca\-status +.I devname +.HP +.B ethtool \-\-show\-mm +.I devname +.HP +.B ethtool \-\-set\-mm +.I devname +.RB [ verify\-enabled +.BR on | off ] +.RB [ verify\-time +.BR N ] +.RB [ tx\-enabled +.BR on | off ] +.RB [ pmac\-enabled +.BR on | off ] +.RB [ tx\-min\-frag\-size +.BR N ] . .\" Adjust lines (i.e. full justification) and hyphenate. .ad @@ -533,6 +565,15 @@ displaying relevant device statistics for selected get commands. .TP .B \-a \-\-show\-pause Queries the specified Ethernet device for pause parameter information. +.RS 4 +.TP +.A3 \fB\-\-src \fBaggregate\fP \fBemac\fP \fBpmac\fP +If the MAC Merge layer is supported, request a particular source of device +statistics (eMAC or pMAC, or their aggregate). Only valid if ethtool was +invoked with the +.B \-I \-\-include\-statistics +argument. +.RE .TP .B \-A \-\-pause Changes the pause parameters of the specified Ethernet device. @@ -581,6 +622,9 @@ Changes the size of completion queue event. .TP .BI tx\-push \ on|off Specifies whether TX push should be enabled. +.TP +.BI rx\-push \ on|off +Specifies whether RX push should be enabled. .RE .TP .B \-i \-\-driver @@ -698,6 +742,10 @@ naming of NIC- and driver-specific statistics across vendors. .TP .B \fB\-\-groups [\fBeth\-phy\fP] [\fBeth\-mac\fP] [\fBeth\-ctrl\fP] [\fBrmon\fP] Request groups of standard device statistics. +.TP +.A3 \fB\-\-src \fBaggregate\fP \fBemac\fP \fBpmac\fP +If the MAC Merge layer is supported, request a particular source of device +statistics (eMAC or pMAC, or their aggregate). .RE .TP .B \-\-phy\-statistics @@ -776,6 +824,9 @@ lB l lB. 0x001 10baseT Half 0x002 10baseT Full 0x100000000000000000000000 10baseT1L Full +0x8000000000000000000000000 10baseT1S Full +0x10000000000000000000000000 10baseT1S Half +0x20000000000000000000000000 10baseT1S_P2MP Half 0x004 100baseT Half 0x008 100baseT Full 0x80000000000000000 100baseT1 Full @@ -1511,6 +1562,147 @@ administratively up and to low power mode when the last port using it is put administratively down. The power mode policy can be set before a module is plugged-in. .RE +.TP +.B \-\-get\-plca\-cfg +Show the current PLCA parameters for the given interface. +.RE +.TP +.B \-\-set\-plca\-cfg +Change the PLCA settings for the given interface. +.RS 4 +.TP +.A2 enable on off +Enables or disables the PLCA function. When the PLCA RS is disabled (default), +the PHY operates in plain CSMA/CD mode. To enable PLCA, the PHY must be assigned +a unique \fBplca\-id\fR other than 255. This one can be configured concurrently +with the enable parameter. The \fBenable\fR parameter maps to IEEE 802.3cg-2019 +clause 30.16.1.1.1 (aPLCAAdminState) and clause 30.16.1.2.1 (acPLCAAdminControl). +.TP +.BI node\-id \ N +The unique node identifier in the range [0 .. 255]. Node ID 0 is reserved for +the coordinator node, the one generating the BEACON signal. There must be +exactly one coordinator on a PLCA network. Setting the node ID to 255 (default) +disables the node. This parameter maps to IEEE 802.3cg-2019 clause 30.16.1.1.4 +(aPLCALocalNodeID). +.TP +.BI node\-cnt \ N +The node-cnt [1 .. 255] should be set after the maximum number of nodes that +can be plugged to the multi-drop network. This parameter regulates the minimum +length of the PLCA cycle. Therefore, it is only meaningful for the coordinator +node (\fBnod-id\fR = 0). Setting this parameter on a follower node has no +effect. The \fBnode\-cnt\fR parameter maps to IEEE 802.3cg-2019 clause +30.16.1.1.3 (aPLCANodeCount). +.TP +.BI to\-tmr \ N +The TO timer parameter sets the value of the transmit opportunity timer in +bit-times, and shall be set equal across all the nodes sharing the same +medium for PLCA to work. The default value of 32 is enough to cover a link of +roughly 50 mt. This parameter maps to IEEE 802.3cg-2019 clause 30.16.1.1.5 +(aPLCATransmitOpportunityTimer). +.TP +.BI burst\-cnt \ N +The \fBburst\-cnt\fR parameter [0 .. 255] indicates the extra number of packets +that the node is allowed to send during a single transmit opportunity. +By default, this attribute is 0, meaning that the node can send a sigle frame +per TO. When greater than 0, the PLCA RS keeps the TO after any transmission, +waiting for the MAC to send a new frame for up to \fBburst\-tmr\fR BTs. This can +only happen a number of times per PLCA cycle up to the value of this parameter. +After that, the burst is over and the normal counting of TOs resumes. +This parameter maps to IEEE 802.3cg-2019 clause 30.16.1.1.6 (aPLCAMaxBurstCount). +.TP +.BI burst\-tmr \ N +The \fBburst\-tmr\fR parameter [0 .. 255] sets how many bit-times the PLCA RS +waits for the MAC to initiate a new transmission when \fBburst\-cnt\fR is +greater than 0. If the MAC fails to send a new frame within this time, the burst +ends and the counting of TOs resumes. Otherwise, the new frame is sent as part +of the current burst. This parameter maps to IEEE 802.3cg-2019 clause +30.16.1.1.7 (aPLCABurstTimer). The value of \fBburst\-tmr\fR should be set +greater than the Inter-Frame-Gap (IFG) time of the MAC (plus some margin) +for PLCA burst mode to work as intended. +.RE +.TP +.B \-\-get\-plca\-status +Show the current PLCA status for the given interface. If \fBon\fR, the PHY is +successfully receiving or generating the BEACON signal. If \fBoff\fR, the PLCA +function is temporarily disabled and the PHY is operating in plain CSMA/CD mode. +.RE +.TP +.B \-\-show\-mm +Show the MAC Merge layer state. The ethtool argument +.B \-I \-\-include\-statistics +can be used with this command, and MAC Merge layer statistics counters will +also be retrieved. +.RS 4 +.TP +.B pmac-enabled +Shows whether the pMAC is enabled and capable of receiving traffic and SMD-V +frames (and responding to them with SMD-R replies). +.TP +.B tx-enabled +Shows whether transmission on the pMAC is administratively enabled. +.TP +.B tx-active +Shows whether transmission on the pMAC is active (verification is either +successful, or was disabled). +.TP +.B tx-min-frag-size +Shows the minimum size (in octets) of transmitted non-final fragments which +can be received by the link partner. Corresponds to the standard addFragSize +variable using the formula: + +tx-min-frag-size = 64 * (1 + addFragSize) - 4 +.TP +.B rx-min-frag-size +Shows the minimum size (in octets) of non-final fragments which the local +device supports receiving. +.TP +.B verify-enabled +Shows whether the verification state machine is enabled. This process, if +successful, ensures that preemptible frames transmitted by the local device +will not be dropped as error frames by the link partner. +.TP +.B verify-time +Shows the interval in ms between verification attempts, represented as an +integer between 1 and 128 ms. The standard defines a fixed number of +verification attempts (verifyLimit) before failing the verification process. +.TP +.B max-verify-time +Shows the maximum value for verify-time accepted by the local device, which +may be less than 128 ms. +.TP +.B verify-status +Shows the current state of the verification state machine of the local device. +Values can be +.B INITIAL, +.B VERIFYING, +.B SUCCEEDED, +.B FAILED +or +.B DISABLED. + +.RE +.TP +.B \-\-set\-mm +Set the MAC Merge layer parameters. +.RS 4 +.TP +.A2 pmac-enabled \ on off +Enable reception for the pMAC. +.TP +.A2 tx-enabled \ on off +Administatively enable transmission for the pMAC. +.TP +.B tx-min-frag-size \ N +Set the minimum size (in octets) of transmitted non-final fragments which can +be received by the link partner. +.TP +.A2 verify-enabled \ on off +Enable or disable the verification state machine. +.TP +.B verify-time \ N +Set the interval in ms between verification attempts. + +.RE .SH BUGS Not supported (in part or whole) on all network drivers. .SH AUTHOR @@ -484,6 +484,9 @@ static void init_global_link_mode_masks(void) ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT, ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT, ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT, + ETHTOOL_LINK_MODE_10baseT1S_Full_BIT, + ETHTOOL_LINK_MODE_10baseT1S_Half_BIT, + ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT, }; static const enum ethtool_link_mode_bit_indices additional_advertised_flags_bits[] = { @@ -738,6 +741,12 @@ static void dump_link_caps(const char *prefix, const char *an_prefix, "800000baseSR8/Full" }, { 0, ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT, "800000baseVR8/Full" }, + { 0, ETHTOOL_LINK_MODE_10baseT1S_Full_BIT, + "10baseT1S/Full" }, + { 1, ETHTOOL_LINK_MODE_10baseT1S_Half_BIT, + "10baseT1S/Half" }, + { 0, ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT, + "10baseT1S/Half" }, }; int indent; int did1, new_line_pend; @@ -5673,7 +5682,8 @@ static const struct option args[] = { .json = true, .func = do_gpause, .nlfunc = nl_gpause, - .help = "Show pause options" + .help = "Show pause options", + .xhelp = " [ --src aggregate | emac | pmac ]\n" }, { .opts = "-A|--pause", @@ -5737,9 +5747,10 @@ static const struct option args[] = { " [ rx-mini N ]\n" " [ rx-jumbo N ]\n" " [ tx N ]\n" - " [ rx-buf-len N]\n" - " [ cqe-size N]\n" - " [ tx-push on|off]\n" + " [ rx-buf-len N ]\n" + " [ cqe-size N ]\n" + " [ tx-push on|off ]\n" + " [ rx-push on|off ]\n" }, { .opts = "-k|--show-features|--show-offload", @@ -5793,13 +5804,13 @@ static const struct option args[] = { .opts = "-p|--identify", .func = do_phys_id, .help = "Show visible port identification (e.g. blinking)", - .xhelp = " [ TIME-IN-SECONDS ]\n" + .xhelp = " [ TIME-IN-SECONDS ]\n" }, { .opts = "-t|--test", .func = do_test, .help = "Execute adapter self test", - .xhelp = " [ online | offline | external_lb ]\n" + .xhelp = " [ online | offline | external_lb ]\n" }, { .opts = "-S|--statistics", @@ -5808,7 +5819,8 @@ static const struct option args[] = { .nlchk = nl_gstats_chk, .nlfunc = nl_gstats, .help = "Show adapter statistics", - .xhelp = " [ --all-groups | --groups [eth-phy] [eth-mac] [eth-ctrl] [rmon] ]\n" + .xhelp = " [ --all-groups | --groups [eth-phy] [eth-mac] [eth-ctrl] [rmon] ]\n" + " [ --src aggregate | emac | pmac ]\n" }, { .opts = "--phy-statistics", @@ -5848,7 +5860,7 @@ static const struct option args[] = { " [ dst-mac %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n" " [ action %d ] | [ vf %d queue %d ]\n" " [ context %d ]\n" - " [ loc %d]] |\n" + " [ loc %d ] |\n" " delete %d\n" }, { @@ -5879,7 +5891,7 @@ static const struct option args[] = { .opts = "-f|--flash", .func = do_flash, .help = "Flash firmware image from the specified file to a region on the device", - .xhelp = " FILENAME [ REGION-NUMBER-TO-FLASH ]\n" + .xhelp = " FILENAME [ REGION-NUMBER-TO-FLASH ]\n" }, { .opts = "-P|--show-permaddr", @@ -5910,10 +5922,10 @@ static const struct option args[] = { .func = do_schannels, .nlfunc = nl_schannels, .help = "Set Channels", - .xhelp = " [ rx N ]\n" - " [ tx N ]\n" - " [ other N ]\n" - " [ combined N ]\n" + .xhelp = " [ rx N ]\n" + " [ tx N ]\n" + " [ other N ]\n" + " [ combined N ]\n" }, { .opts = "--show-priv-flags", @@ -5980,16 +5992,16 @@ static const struct option args[] = { .xhelp = " [ rx-copybreak ]\n" " [ tx-copybreak ]\n" " [ tx-buf-size ]\n" - " [ pfc-precention-tout ]\n" + " [ pfc-prevention-tout ]\n" }, { .opts = "--set-tunable", .func = do_stunable, .help = "Set tunable", - .xhelp = " [ rx-copybreak N]\n" - " [ tx-copybreak N]\n" - " [ tx-buf-size N]\n" - " [ pfc-precention-tout N]\n" + .xhelp = " [ rx-copybreak N ]\n" + " [ tx-copybreak N ]\n" + " [ tx-buf-size N ]\n" + " [ pfc-prevention-tout N ]\n" }, { .opts = "--reset", @@ -6029,14 +6041,14 @@ static const struct option args[] = { .func = do_sfec, .nlfunc = nl_sfec, .help = "Set FEC settings", - .xhelp = " [ encoding auto|off|rs|baser|llrs [...]]\n" + .xhelp = " [ encoding auto|off|rs|baser|llrs [...] ]\n" }, { .opts = "-Q|--per-queue", .func = do_perqueue, .help = "Apply per-queue command. ", .xhelp = "The supported sub commands include --show-coalesce, --coalesce" - " [queue_mask %x] SUB_COMMAND\n", + " [queue_mask %x] SUB_COMMAND\n", }, { .opts = "--cable-test", @@ -6072,6 +6084,43 @@ static const struct option args[] = { .xhelp = " [ power-mode-policy high|auto ]\n" }, { + .opts = "--get-plca-cfg", + .nlfunc = nl_plca_get_cfg, + .help = "Get PLCA configuration", + }, + { + .opts = "--set-plca-cfg", + .nlfunc = nl_plca_set_cfg, + .help = "Set PLCA configuration", + .xhelp = " [ enable on|off ]\n" + " [ node-id N ]\n" + " [ node-cnt N ]\n" + " [ to-tmr N ]\n" + " [ burst-cnt N ]\n" + " [ burst-tmr N ]\n" + }, + { + .opts = "--get-plca-status", + .nlfunc = nl_plca_get_status, + .help = "Get PLCA status information", + }, + { + .opts = "--show-mm", + .json = true, + .nlfunc = nl_get_mm, + .help = "Show MAC merge layer state", + }, + { + .opts = "--set-mm", + .nlfunc = nl_set_mm, + .help = "Set MAC merge layer parameters", + " [ verify-enabled on|off ]\n" + " [ verify-time N ]\n" + " [ tx-enabled on|off ]\n" + " [ pmac-enabled on|off ]\n" + " [ tx-min-frag-size 60-252 ]\n" + }, + { .opts = "-h|--help", .no_dev = true, .func = show_usage, diff --git a/netlink/desc-ethtool.c b/netlink/desc-ethtool.c index 737196f..2d8aa39 100644 --- a/netlink/desc-ethtool.c +++ b/netlink/desc-ethtool.c @@ -158,6 +158,7 @@ static const struct pretty_nla_desc __rings_desc[] = { NLATTR_DESC_U8_ENUM(ETHTOOL_A_RINGS_TCP_DATA_SPLIT, rings_tcp_data_split), NLATTR_DESC_U32(ETHTOOL_A_RINGS_CQE_SIZE), NLATTR_DESC_BOOL(ETHTOOL_A_RINGS_TX_PUSH), + NLATTR_DESC_BOOL(ETHTOOL_A_RINGS_RX_PUSH), }; static const struct pretty_nla_desc __channels_desc[] = { @@ -451,6 +452,45 @@ static const struct pretty_nla_desc __rss_desc[] = { NLATTR_DESC_BINARY(ETHTOOL_A_RSS_HKEY), }; +static const struct pretty_nla_desc __plca_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_PLCA_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_PLCA_HEADER, header), + NLATTR_DESC_U16(ETHTOOL_A_PLCA_VERSION), + NLATTR_DESC_U8(ETHTOOL_A_PLCA_ENABLED), + NLATTR_DESC_U8(ETHTOOL_A_PLCA_STATUS), + NLATTR_DESC_U32(ETHTOOL_A_PLCA_NODE_CNT), + NLATTR_DESC_U32(ETHTOOL_A_PLCA_NODE_ID), + NLATTR_DESC_U32(ETHTOOL_A_PLCA_TO_TMR), + NLATTR_DESC_U32(ETHTOOL_A_PLCA_BURST_CNT), + NLATTR_DESC_U32(ETHTOOL_A_PLCA_BURST_TMR), +}; + +static const struct pretty_nla_desc __mm_stat_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_MM_STAT_UNSPEC), + NLATTR_DESC_BINARY(ETHTOOL_A_MM_STAT_PAD), + NLATTR_DESC_U64(ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS), + NLATTR_DESC_U64(ETHTOOL_A_MM_STAT_SMD_ERRORS), + NLATTR_DESC_U64(ETHTOOL_A_MM_STAT_REASSEMBLY_OK), + NLATTR_DESC_U64(ETHTOOL_A_MM_STAT_RX_FRAG_COUNT), + NLATTR_DESC_U64(ETHTOOL_A_MM_STAT_TX_FRAG_COUNT), + NLATTR_DESC_U64(ETHTOOL_A_MM_STAT_HOLD_COUNT), +}; + +static const struct pretty_nla_desc __mm_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_MM_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_MM_HEADER, header), + NLATTR_DESC_U8(ETHTOOL_A_MM_PMAC_ENABLED), + NLATTR_DESC_U8(ETHTOOL_A_MM_TX_ENABLED), + NLATTR_DESC_U8(ETHTOOL_A_MM_TX_ACTIVE), + NLATTR_DESC_U32(ETHTOOL_A_MM_TX_MIN_FRAG_SIZE), + NLATTR_DESC_U32(ETHTOOL_A_MM_RX_MIN_FRAG_SIZE), + NLATTR_DESC_U8(ETHTOOL_A_MM_VERIFY_ENABLED), + NLATTR_DESC_U8(ETHTOOL_A_MM_VERIFY_STATUS), + NLATTR_DESC_U32(ETHTOOL_A_MM_VERIFY_TIME), + NLATTR_DESC_U32(ETHTOOL_A_MM_MAX_VERIFY_TIME), + NLATTR_DESC_NESTED(ETHTOOL_A_MM_STATS, mm_stat), +}; + const struct pretty_nlmsg_desc ethnl_umsg_desc[] = { NLMSG_DESC_INVALID(ETHTOOL_MSG_USER_NONE), NLMSG_DESC(ETHTOOL_MSG_STRSET_GET, strset), @@ -491,6 +531,11 @@ const struct pretty_nlmsg_desc ethnl_umsg_desc[] = { NLMSG_DESC(ETHTOOL_MSG_PSE_GET, pse), NLMSG_DESC(ETHTOOL_MSG_PSE_SET, pse), NLMSG_DESC(ETHTOOL_MSG_RSS_GET, rss), + NLMSG_DESC(ETHTOOL_MSG_PLCA_GET_CFG, plca), + NLMSG_DESC(ETHTOOL_MSG_PLCA_SET_CFG, plca), + NLMSG_DESC(ETHTOOL_MSG_PLCA_GET_STATUS, plca), + NLMSG_DESC(ETHTOOL_MSG_MM_GET, mm), + NLMSG_DESC(ETHTOOL_MSG_MM_SET, mm), }; const unsigned int ethnl_umsg_n_desc = ARRAY_SIZE(ethnl_umsg_desc); @@ -535,6 +580,11 @@ const struct pretty_nlmsg_desc ethnl_kmsg_desc[] = { NLMSG_DESC(ETHTOOL_MSG_MODULE_NTF, module), NLMSG_DESC(ETHTOOL_MSG_PSE_GET_REPLY, pse), NLMSG_DESC(ETHTOOL_MSG_RSS_GET_REPLY, rss), + NLMSG_DESC(ETHTOOL_MSG_PLCA_GET_CFG_REPLY, plca), + NLMSG_DESC(ETHTOOL_MSG_PLCA_GET_STATUS_REPLY, plca), + NLMSG_DESC(ETHTOOL_MSG_PLCA_NTF, plca), + NLMSG_DESC(ETHTOOL_MSG_MM_GET_REPLY, mm), + NLMSG_DESC(ETHTOOL_MSG_MM_NTF, mm), }; const unsigned int ethnl_kmsg_n_desc = ARRAY_SIZE(ethnl_kmsg_desc); diff --git a/netlink/extapi.h b/netlink/extapi.h index 9b6dd1a..bbe0633 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -48,6 +48,11 @@ int nl_smodule(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); int nl_getmodule(struct cmd_context *ctx); int nl_grss(struct cmd_context *ctx); +int nl_plca_get_cfg(struct cmd_context *ctx); +int nl_plca_set_cfg(struct cmd_context *ctx); +int nl_plca_get_status(struct cmd_context *ctx); +int nl_get_mm(struct cmd_context *ctx); +int nl_set_mm(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -116,6 +121,11 @@ nl_get_eeprom_page(struct cmd_context *ctx __maybe_unused, #define nl_gmodule NULL #define nl_smodule NULL #define nl_grss NULL +#define nl_plca_get_cfg NULL +#define nl_plca_set_cfg NULL +#define nl_plca_get_status NULL +#define nl_get_mm NULL +#define nl_set_mm NULL #endif /* ETHTOOL_ENABLE_NETLINK */ diff --git a/netlink/mm.c b/netlink/mm.c new file mode 100644 index 0000000..d026bc3 --- /dev/null +++ b/netlink/mm.c @@ -0,0 +1,270 @@ +/* + * mm.c - netlink implementation of MAC merge layer settings + * + * Implementation of "ethtool --show-mm <dev>" and "ethtool --set-mm <dev> ..." + */ + +#include <errno.h> +#include <inttypes.h> +#include <string.h> +#include <stdio.h> + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "bitset.h" +#include "parser.h" + +/* MM_GET */ + +static const char * +mm_verify_state_to_string(enum ethtool_mm_verify_status state) +{ + switch (state) { + case ETHTOOL_MM_VERIFY_STATUS_INITIAL: + return "INITIAL"; + case ETHTOOL_MM_VERIFY_STATUS_VERIFYING: + return "VERIFYING"; + case ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED: + return "SUCCEEDED"; + case ETHTOOL_MM_VERIFY_STATUS_FAILED: + return "FAILED"; + case ETHTOOL_MM_VERIFY_STATUS_DISABLED: + return "DISABLED"; + default: + return "UNKNOWN"; + } +} + +static int show_mm_stats(const struct nlattr *nest) +{ + const struct nlattr *tb[ETHTOOL_A_MM_STAT_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + static const struct { + unsigned int attr; + char *name; + } stats[] = { + { ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS, "MACMergeFrameAssErrorCount" }, + { ETHTOOL_A_MM_STAT_SMD_ERRORS, "MACMergeFrameSmdErrorCount" }, + { ETHTOOL_A_MM_STAT_REASSEMBLY_OK, "MACMergeFrameAssOkCount" }, + { ETHTOOL_A_MM_STAT_RX_FRAG_COUNT, "MACMergeFragCountRx" }, + { ETHTOOL_A_MM_STAT_TX_FRAG_COUNT, "MACMergeFragCountTx" }, + { ETHTOOL_A_MM_STAT_HOLD_COUNT, "MACMergeHoldCount" }, + }; + bool header = false; + unsigned int i; + size_t n; + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0) + return ret; + + open_json_object("statistics"); + for (i = 0; i < ARRAY_SIZE(stats); i++) { + char fmt[64]; + + if (!tb[stats[i].attr]) + continue; + + if (!header && !is_json_context()) { + printf("Statistics:\n"); + header = true; + } + + if (mnl_attr_validate(tb[stats[i].attr], MNL_TYPE_U64)) { + fprintf(stderr, "malformed netlink message (statistic)\n"); + goto err_close_stats; + } + + n = snprintf(fmt, sizeof(fmt), " %s: %%" PRIu64 "\n", + stats[i].name); + if (n >= sizeof(fmt)) { + fprintf(stderr, "internal error - malformed label\n"); + continue; + } + + print_u64(PRINT_ANY, stats[i].name, fmt, + mnl_attr_get_u64(tb[stats[i].attr])); + } + close_json_object(); + + return 0; + +err_close_stats: + close_json_object(); + return -1; +} + +int mm_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_MM_MAX + 1] = {}; + struct nl_context *nlctx = data; + DECLARE_ATTR_TB_INFO(tb); + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_MM_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + print_nl(); + + open_json_object(NULL); + + print_string(PRINT_ANY, "ifname", "MAC Merge layer state for %s:\n", + nlctx->devname); + + show_bool("pmac-enabled", "pMAC enabled: %s\n", + tb[ETHTOOL_A_MM_PMAC_ENABLED]); + show_bool("tx-enabled", "TX enabled: %s\n", + tb[ETHTOOL_A_MM_TX_ENABLED]); + show_bool("tx-active", "TX active: %s\n", tb[ETHTOOL_A_MM_TX_ACTIVE]); + show_u32("tx-min-frag-size", "TX minimum fragment size: ", + tb[ETHTOOL_A_MM_TX_MIN_FRAG_SIZE]); + show_u32("rx-min-frag-size", "RX minimum fragment size: ", + tb[ETHTOOL_A_MM_RX_MIN_FRAG_SIZE]); + show_bool("verify-enabled", "Verify enabled: %s\n", + tb[ETHTOOL_A_MM_VERIFY_ENABLED]); + show_u32("verify-time", "Verify time: ", + tb[ETHTOOL_A_MM_VERIFY_TIME]); + show_u32("max-verify-time", "Max verify time: ", + tb[ETHTOOL_A_MM_MAX_VERIFY_TIME]); + + if (tb[ETHTOOL_A_MM_VERIFY_STATUS]) { + u8 val = mnl_attr_get_u8(tb[ETHTOOL_A_MM_VERIFY_STATUS]); + + print_string(PRINT_ANY, "verify-status", "Verification status: %s\n", + mm_verify_state_to_string(val)); + } + + if (tb[ETHTOOL_A_MM_STATS]) { + ret = show_mm_stats(tb[ETHTOOL_A_MM_STATS]); + if (ret) { + fprintf(stderr, "Failed to print stats: %d\n", ret); + goto err; + } + } + + if (!silent) + print_nl(); + + close_json_object(); + + return MNL_CB_OK; + +err: + close_json_object(); + return err_ret; +} + +int nl_get_mm(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + u32 flags; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_MM_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + flags = get_stats_flag(nlctx, ETHTOOL_MSG_MM_GET, ETHTOOL_A_MM_HEADER); + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_MM_GET, + ETHTOOL_A_MM_HEADER, flags); + if (ret) + return ret; + + new_json_obj(ctx->json); + ret = nlsock_send_get_request(nlsk, mm_reply_cb); + delete_json_obj(); + return ret; +} + +/* MM_SET */ + +static const struct param_parser mm_set_params[] = { + { + .arg = "verify-enabled", + .type = ETHTOOL_A_MM_VERIFY_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "verify-time", + .type = ETHTOOL_A_MM_VERIFY_TIME, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-enabled", + .type = ETHTOOL_A_MM_TX_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "pmac-enabled", + .type = ETHTOOL_A_MM_PMAC_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "tx-min-frag-size", + .type = ETHTOOL_A_MM_TX_MIN_FRAG_SIZE, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + {} +}; + +int nl_set_mm(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_MM_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "--set-mm"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_MM_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret) + return ret; + + if (ethnla_fill_header(msgbuff, ETHTOOL_A_MM_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, mm_set_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret) + return ret; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return ret; + + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret) + return nlctx->exit_code; + + return 0; +} diff --git a/netlink/pause.c b/netlink/pause.c index 867d0da..da444bd 100644 --- a/netlink/pause.c +++ b/netlink/pause.c @@ -216,6 +216,24 @@ err_close_dev: return err_ret; } +static const struct lookup_entry_u32 stats_src_values[] = { + { .arg = "aggregate", .val = ETHTOOL_MAC_STATS_SRC_AGGREGATE }, + { .arg = "emac", .val = ETHTOOL_MAC_STATS_SRC_EMAC }, + { .arg = "pmac", .val = ETHTOOL_MAC_STATS_SRC_PMAC }, + {} +}; + +static const struct param_parser gpause_params[] = { + { + .arg = "--src", + .type = ETHTOOL_A_PAUSE_STATS_SRC, + .handler = nl_parse_lookup_u32, + .handler_data = stats_src_values, + .min_argc = 1, + }, + {} +}; + int nl_gpause(struct cmd_context *ctx) { struct nl_context *nlctx = ctx->nlctx; @@ -225,11 +243,6 @@ int nl_gpause(struct cmd_context *ctx) if (netlink_cmd_check(ctx, ETHTOOL_MSG_PAUSE_GET, true)) return -EOPNOTSUPP; - if (ctx->argc > 0) { - fprintf(stderr, "ethtool: unexpected parameter '%s'\n", - *ctx->argp); - return 1; - } flags = get_stats_flag(nlctx, ETHTOOL_MSG_PAUSE_GET, ETHTOOL_A_PAUSE_HEADER); @@ -238,6 +251,16 @@ int nl_gpause(struct cmd_context *ctx) if (ret < 0) return ret; + nlctx->cmd = "-a"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + + ret = nl_parser(nlctx, gpause_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + new_json_obj(ctx->json); ret = nlsock_send_get_request(nlsk, pause_reply_cb); delete_json_obj(); diff --git a/netlink/plca.c b/netlink/plca.c new file mode 100644 index 0000000..7d61e3b --- /dev/null +++ b/netlink/plca.c @@ -0,0 +1,296 @@ +/* + * plca.c - netlink implementation of plca command + * + * Implementation of "ethtool --show-plca <dev>" and + * "ethtool --set-plca <dev> ..." + */ + +#include <errno.h> +#include <string.h> +#include <stdio.h> + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "bitset.h" +#include "parser.h" + +/* PLCA_GET_CFG */ + +int plca_get_cfg_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PLCA_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int idv = 255; + int err_ret; + int val; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + + nlctx->devname = get_dev_name(tb[ETHTOOL_A_PLCA_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + + printf("PLCA settings for %s:\n", nlctx->devname); + + // check if PLCA is enabled + printf("\tEnabled: "); + + if (!tb[ETHTOOL_A_PLCA_ENABLED]) { + printf("not supported"); + } else { + val = mnl_attr_get_u8(tb[ETHTOOL_A_PLCA_ENABLED]); + printf(val ? "Yes" : "No"); + } + putchar('\n'); + + // get node ID + printf("\tlocal node ID: "); + + if (!tb[ETHTOOL_A_PLCA_NODE_ID]) { + printf("not supported"); + } else { + idv = mnl_attr_get_u32(tb[ETHTOOL_A_PLCA_NODE_ID]); + printf("%u (%s)", idv, + idv == 0 ? "coordinator" : + idv == 255 ? "unconfigured" : "follower"); + } + putchar('\n'); + + // get node count + printf("\tNode count: "); + if (!tb[ETHTOOL_A_PLCA_NODE_CNT]) { + printf("not supported"); + } else { + val = mnl_attr_get_u32(tb[ETHTOOL_A_PLCA_NODE_CNT]); + printf("%u", val); + + // The node count is ignored by follower nodes. However, it can + // be pre-set to enable fast coordinator role switchover. + // Therefore, on a follower node we still wanto to show it, + // indicating it is not currently used. + if (tb[ETHTOOL_A_PLCA_NODE_ID] && idv != 0) + printf(" (ignored)"); + } + putchar('\n'); + + // get TO timer (transmit opportunity timer) + printf("\tTO timer: "); + if (!tb[ETHTOOL_A_PLCA_TO_TMR]) { + printf("not supported"); + } else { + val = mnl_attr_get_u32(tb[ETHTOOL_A_PLCA_TO_TMR]); + printf("%u BT", val); + } + putchar('\n'); + + // get burst count + printf("\tBurst count: "); + if (!tb[ETHTOOL_A_PLCA_BURST_CNT]) { + printf("not supported"); + } else { + val = mnl_attr_get_u32(tb[ETHTOOL_A_PLCA_BURST_CNT]); + printf("%u (%s)", val, + val > 0 ? "enabled" : "disabled"); + } + putchar('\n'); + + // get burst timer + printf("\tBurst timer: "); + if (!tb[ETHTOOL_A_PLCA_BURST_TMR]) { + printf("not supported"); + } else { + val = mnl_attr_get_u32(tb[ETHTOOL_A_PLCA_BURST_TMR]); + printf("%u BT", val); + } + putchar('\n'); + + return MNL_CB_OK; +} + + +int nl_plca_get_cfg(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PLCA_GET_CFG, true)) + return -EOPNOTSUPP; + + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PLCA_GET_CFG, + ETHTOOL_A_PLCA_HEADER, 0); + + if (ret < 0) + return ret; + + return nlsock_send_get_request(nlsk, plca_get_cfg_reply_cb); +} + +/* PLCA_SET_CFG */ + +static const struct param_parser set_plca_params[] = { + { + .arg = "enable", + .type = ETHTOOL_A_PLCA_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "node-id", + .type = ETHTOOL_A_PLCA_NODE_ID, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "node-cnt", + .type = ETHTOOL_A_PLCA_NODE_CNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "to-tmr", + .type = ETHTOOL_A_PLCA_TO_TMR, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "burst-cnt", + .type = ETHTOOL_A_PLCA_BURST_CNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "burst-tmr", + .type = ETHTOOL_A_PLCA_BURST_TMR, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + {} +}; + +int nl_plca_set_cfg(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PLCA_SET_CFG, false)) + return -EOPNOTSUPP; + if (!ctx->argc) { + fprintf(stderr, + "ethtool (--set-plca-cfg): parameters missing\n"); + return 1; + } + + nlctx->cmd = "--set-plca-cfg"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_PLCA_SET_CFG, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_PLCA_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, set_plca_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 76; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 76; +} + +/* PLCA_GET_STATUS */ + +int plca_get_status_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PLCA_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + u8 val; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + + nlctx->devname = get_dev_name(tb[ETHTOOL_A_PLCA_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + + printf("PLCA status of %s:\n", nlctx->devname); + + // check whether the Open Alliance TC14 standard memory map is supported + printf("\tStatus: "); + + if (!tb[ETHTOOL_A_PLCA_STATUS]) { + printf("not supported"); + } else { + val = mnl_attr_get_u8(tb[ETHTOOL_A_PLCA_STATUS]); + printf(val ? "on" : "off"); + } + putchar('\n'); + + return MNL_CB_OK; +} + + +int nl_plca_get_status(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PLCA_GET_STATUS, true)) + return -EOPNOTSUPP; + + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PLCA_GET_STATUS, + ETHTOOL_A_PLCA_HEADER, 0); + + if (ret < 0) + return ret; + + return nlsock_send_get_request(nlsk, plca_get_status_reply_cb); +} diff --git a/netlink/rings.c b/netlink/rings.c index d51ef78..57bfb36 100644 --- a/netlink/rings.c +++ b/netlink/rings.c @@ -57,6 +57,7 @@ int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data) show_u32("rx-buf-len", "RX Buf Len:\t", tb[ETHTOOL_A_RINGS_RX_BUF_LEN]); show_u32("cqe-size", "CQE Size:\t", tb[ETHTOOL_A_RINGS_CQE_SIZE]); show_bool("tx-push", "TX Push:\t%s\n", tb[ETHTOOL_A_RINGS_TX_PUSH]); + show_bool("rx-push", "RX Push:\t%s\n", tb[ETHTOOL_A_RINGS_RX_PUSH]); tcp_hds_fmt = "TCP data split:\t%s\n"; tcp_hds_key = "tcp-data-split"; @@ -154,6 +155,12 @@ static const struct param_parser sring_params[] = { .handler = nl_parse_u8bool, .min_argc = 1, }, + { + .arg = "rx-push", + .type = ETHTOOL_A_RINGS_RX_PUSH, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, {} }; diff --git a/netlink/settings.c b/netlink/settings.c index f96f324..168b182 100644 --- a/netlink/settings.c +++ b/netlink/settings.c @@ -172,6 +172,9 @@ static const struct link_mode_info link_modes[] = { [ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT] = __REAL(800000), [ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT] = __REAL(800000), [ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT] = __REAL(800000), + [ETHTOOL_LINK_MODE_10baseT1S_Full_BIT] = __REAL(10), + [ETHTOOL_LINK_MODE_10baseT1S_Half_BIT] = __HALF_DUPLEX(10), + [ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT] = __HALF_DUPLEX(10), }; const unsigned int link_modes_count = ARRAY_SIZE(link_modes); @@ -896,6 +899,70 @@ int debug_reply_cb(const struct nlmsghdr *nlhdr, void *data) return MNL_CB_OK; } +int plca_cfg_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PLCA_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + int ret; + + if (nlctx->is_dump || nlctx->is_monitor) + nlctx->no_banner = false; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_PLCA_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + print_banner(nlctx); + printf("\tPLCA support: "); + + if (tb[ETHTOOL_A_PLCA_VERSION]) { + uint16_t val = mnl_attr_get_u16(tb[ETHTOOL_A_PLCA_VERSION]); + + printf("OPEN Alliance v%u.%u", + (unsigned int)((val >> 4) & 0xF), + (unsigned int)(val & 0xF)); + } else + printf("non-standard"); + + printf("\n"); + + return MNL_CB_OK; +} + +int plca_status_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PLCA_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + int ret; + + if (nlctx->is_dump || nlctx->is_monitor) + nlctx->no_banner = false; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_PLCA_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + print_banner(nlctx); + printf("\tPLCA status: "); + + if (tb[ETHTOOL_A_PLCA_STATUS]) { + uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_PLCA_STATUS]); + + printf(val ? "up" : "down"); + } else + printf("unknown"); + + printf("\n"); + + return MNL_CB_OK; +} + static int gset_request(struct nl_context *nlctx, uint8_t msg_type, uint16_t hdr_attr, mnl_cb_t cb) { @@ -920,7 +987,9 @@ int nl_gset(struct cmd_context *ctx) netlink_cmd_check(ctx, ETHTOOL_MSG_LINKINFO_GET, true) || netlink_cmd_check(ctx, ETHTOOL_MSG_WOL_GET, true) || netlink_cmd_check(ctx, ETHTOOL_MSG_DEBUG_GET, true) || - netlink_cmd_check(ctx, ETHTOOL_MSG_LINKSTATE_GET, true)) + netlink_cmd_check(ctx, ETHTOOL_MSG_LINKSTATE_GET, true) || + netlink_cmd_check(ctx, ETHTOOL_MSG_PLCA_GET_CFG, true) || + netlink_cmd_check(ctx, ETHTOOL_MSG_PLCA_GET_STATUS, true)) return -EOPNOTSUPP; nlctx->suppress_nlerr = 1; @@ -940,6 +1009,11 @@ int nl_gset(struct cmd_context *ctx) if (ret == -ENODEV) return ret; + ret = gset_request(nlctx, ETHTOOL_MSG_PLCA_GET_CFG, + ETHTOOL_A_PLCA_HEADER, plca_cfg_reply_cb); + if (ret == -ENODEV) + return ret; + ret = gset_request(nlctx, ETHTOOL_MSG_DEBUG_GET, ETHTOOL_A_DEBUG_HEADER, debug_reply_cb); if (ret == -ENODEV) @@ -950,6 +1024,11 @@ int nl_gset(struct cmd_context *ctx) if (ret == -ENODEV) return ret; + ret = gset_request(nlctx, ETHTOOL_MSG_PLCA_GET_STATUS, + ETHTOOL_A_PLCA_HEADER, plca_status_reply_cb); + if (ret == -ENODEV) + return ret; + if (!nlctx->no_banner) { printf("No data available\n"); return 75; diff --git a/netlink/stats.c b/netlink/stats.c index 9f609a4..8620d8d 100644 --- a/netlink/stats.c +++ b/netlink/stats.c @@ -268,6 +268,13 @@ err_free: return ret; } +static const struct lookup_entry_u32 stats_src_values[] = { + { .arg = "aggregate", .val = ETHTOOL_MAC_STATS_SRC_AGGREGATE }, + { .arg = "emac", .val = ETHTOOL_MAC_STATS_SRC_EMAC }, + { .arg = "pmac", .val = ETHTOOL_MAC_STATS_SRC_PMAC }, + {} +}; + static const struct param_parser stats_params[] = { { .arg = "--groups", @@ -283,6 +290,13 @@ static const struct param_parser stats_params[] = { .handler = stats_parse_all_groups, .alt_group = 1, }, + { + .arg = "--src", + .type = ETHTOOL_A_STATS_SRC, + .handler = nl_parse_lookup_u32, + .handler_data = stats_src_values, + .min_argc = 1, + }, {} }; diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h index d174870..1d0731b 100644 --- a/uapi/linux/ethtool.h +++ b/uapi/linux/ethtool.h @@ -710,6 +710,24 @@ enum ethtool_stringset { }; /** + * enum ethtool_mac_stats_src - source of ethtool MAC statistics + * @ETHTOOL_MAC_STATS_SRC_AGGREGATE: + * if device supports a MAC merge layer, this retrieves the aggregate + * statistics of the eMAC and pMAC. Otherwise, it retrieves just the + * statistics of the single (express) MAC. + * @ETHTOOL_MAC_STATS_SRC_EMAC: + * if device supports a MM layer, this retrieves the eMAC statistics. + * Otherwise, it retrieves the statistics of the single (express) MAC. + * @ETHTOOL_MAC_STATS_SRC_PMAC: + * if device supports a MM layer, this retrieves the pMAC statistics. + */ +enum ethtool_mac_stats_src { + ETHTOOL_MAC_STATS_SRC_AGGREGATE, + ETHTOOL_MAC_STATS_SRC_EMAC, + ETHTOOL_MAC_STATS_SRC_PMAC, +}; + +/** * enum ethtool_module_power_mode_policy - plug-in module power mode policy * @ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH: Module is always in high power mode. * @ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO: Module is transitioned by the host @@ -778,6 +796,31 @@ enum ethtool_podl_pse_pw_d_status { }; /** + * enum ethtool_mm_verify_status - status of MAC Merge Verify function + * @ETHTOOL_MM_VERIFY_STATUS_UNKNOWN: + * verification status is unknown + * @ETHTOOL_MM_VERIFY_STATUS_INITIAL: + * the 802.3 Verify State diagram is in the state INIT_VERIFICATION + * @ETHTOOL_MM_VERIFY_STATUS_VERIFYING: + * the Verify State diagram is in the state VERIFICATION_IDLE, + * SEND_VERIFY or WAIT_FOR_RESPONSE + * @ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED: + * indicates that the Verify State diagram is in the state VERIFIED + * @ETHTOOL_MM_VERIFY_STATUS_FAILED: + * the Verify State diagram is in the state VERIFY_FAIL + * @ETHTOOL_MM_VERIFY_STATUS_DISABLED: + * verification of preemption operation is disabled + */ +enum ethtool_mm_verify_status { + ETHTOOL_MM_VERIFY_STATUS_UNKNOWN, + ETHTOOL_MM_VERIFY_STATUS_INITIAL, + ETHTOOL_MM_VERIFY_STATUS_VERIFYING, + ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED, + ETHTOOL_MM_VERIFY_STATUS_FAILED, + ETHTOOL_MM_VERIFY_STATUS_DISABLED, +}; + +/** * struct ethtool_gstrings - string set for data tagging * @cmd: Command number = %ETHTOOL_GSTRINGS * @string_set: String set ID; one of &enum ethtool_stringset @@ -1181,7 +1224,7 @@ struct ethtool_rxnfc { __u32 rule_cnt; __u32 rss_context; }; - __u32 rule_locs[0]; + __u32 rule_locs[]; }; @@ -1739,6 +1782,9 @@ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT = 96, ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT = 97, ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT = 98, + ETHTOOL_LINK_MODE_10baseT1S_Full_BIT = 99, + ETHTOOL_LINK_MODE_10baseT1S_Half_BIT = 100, + ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT = 101, /* must be last entry */ __ETHTOOL_LINK_MODE_MASK_NBITS diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h index 0d553ec..13493c9 100644 --- a/uapi/linux/ethtool_netlink.h +++ b/uapi/linux/ethtool_netlink.h @@ -52,6 +52,11 @@ enum { ETHTOOL_MSG_PSE_GET, ETHTOOL_MSG_PSE_SET, ETHTOOL_MSG_RSS_GET, + ETHTOOL_MSG_PLCA_GET_CFG, + ETHTOOL_MSG_PLCA_SET_CFG, + ETHTOOL_MSG_PLCA_GET_STATUS, + ETHTOOL_MSG_MM_GET, + ETHTOOL_MSG_MM_SET, /* add new constants above here */ __ETHTOOL_MSG_USER_CNT, @@ -99,6 +104,11 @@ enum { ETHTOOL_MSG_MODULE_NTF, ETHTOOL_MSG_PSE_GET_REPLY, ETHTOOL_MSG_RSS_GET_REPLY, + ETHTOOL_MSG_PLCA_GET_CFG_REPLY, + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY, + ETHTOOL_MSG_PLCA_NTF, + ETHTOOL_MSG_MM_GET_REPLY, + ETHTOOL_MSG_MM_NTF, /* add new constants above here */ __ETHTOOL_MSG_KERNEL_CNT, @@ -346,6 +356,7 @@ enum { ETHTOOL_A_RINGS_TCP_DATA_SPLIT, /* u8 */ ETHTOOL_A_RINGS_CQE_SIZE, /* u32 */ ETHTOOL_A_RINGS_TX_PUSH, /* u8 */ + ETHTOOL_A_RINGS_RX_PUSH, /* u8 */ /* add new constants above here */ __ETHTOOL_A_RINGS_CNT, @@ -400,6 +411,9 @@ enum { ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, /* u32 */ ETHTOOL_A_COALESCE_USE_CQE_MODE_TX, /* u8 */ ETHTOOL_A_COALESCE_USE_CQE_MODE_RX, /* u8 */ + ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES, /* u32 */ + ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS, /* u32 */ /* add new constants above here */ __ETHTOOL_A_COALESCE_CNT, @@ -415,6 +429,7 @@ enum { ETHTOOL_A_PAUSE_RX, /* u8 */ ETHTOOL_A_PAUSE_TX, /* u8 */ ETHTOOL_A_PAUSE_STATS, /* nest - _PAUSE_STAT_* */ + ETHTOOL_A_PAUSE_STATS_SRC, /* u32 */ /* add new constants above here */ __ETHTOOL_A_PAUSE_CNT, @@ -731,6 +746,8 @@ enum { ETHTOOL_A_STATS_GRP, /* nest - _A_STATS_GRP_* */ + ETHTOOL_A_STATS_SRC, /* u32 */ + /* add new constants above here */ __ETHTOOL_A_STATS_CNT, ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1) @@ -894,6 +911,68 @@ enum { ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1), }; +/* PLCA */ + +enum { + ETHTOOL_A_PLCA_UNSPEC, + ETHTOOL_A_PLCA_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PLCA_VERSION, /* u16 */ + ETHTOOL_A_PLCA_ENABLED, /* u8 */ + ETHTOOL_A_PLCA_STATUS, /* u8 */ + ETHTOOL_A_PLCA_NODE_CNT, /* u32 */ + ETHTOOL_A_PLCA_NODE_ID, /* u32 */ + ETHTOOL_A_PLCA_TO_TMR, /* u32 */ + ETHTOOL_A_PLCA_BURST_CNT, /* u32 */ + ETHTOOL_A_PLCA_BURST_TMR, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_PLCA_CNT, + ETHTOOL_A_PLCA_MAX = (__ETHTOOL_A_PLCA_CNT - 1) +}; + +/* MAC Merge (802.3) */ + +enum { + ETHTOOL_A_MM_STAT_UNSPEC, + ETHTOOL_A_MM_STAT_PAD, + + /* aMACMergeFrameAssErrorCount */ + ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS, /* u64 */ + /* aMACMergeFrameSmdErrorCount */ + ETHTOOL_A_MM_STAT_SMD_ERRORS, /* u64 */ + /* aMACMergeFrameAssOkCount */ + ETHTOOL_A_MM_STAT_REASSEMBLY_OK, /* u64 */ + /* aMACMergeFragCountRx */ + ETHTOOL_A_MM_STAT_RX_FRAG_COUNT, /* u64 */ + /* aMACMergeFragCountTx */ + ETHTOOL_A_MM_STAT_TX_FRAG_COUNT, /* u64 */ + /* aMACMergeHoldCount */ + ETHTOOL_A_MM_STAT_HOLD_COUNT, /* u64 */ + + /* add new constants above here */ + __ETHTOOL_A_MM_STAT_CNT, + ETHTOOL_A_MM_STAT_MAX = (__ETHTOOL_A_MM_STAT_CNT - 1) +}; + +enum { + ETHTOOL_A_MM_UNSPEC, + ETHTOOL_A_MM_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_MM_PMAC_ENABLED, /* u8 */ + ETHTOOL_A_MM_TX_ENABLED, /* u8 */ + ETHTOOL_A_MM_TX_ACTIVE, /* u8 */ + ETHTOOL_A_MM_TX_MIN_FRAG_SIZE, /* u32 */ + ETHTOOL_A_MM_RX_MIN_FRAG_SIZE, /* u32 */ + ETHTOOL_A_MM_VERIFY_ENABLED, /* u8 */ + ETHTOOL_A_MM_VERIFY_STATUS, /* u8 */ + ETHTOOL_A_MM_VERIFY_TIME, /* u32 */ + ETHTOOL_A_MM_MAX_VERIFY_TIME, /* u32 */ + ETHTOOL_A_MM_STATS, /* nest - _A_MM_STAT_* */ + + /* add new constants above here */ + __ETHTOOL_A_MM_CNT, + ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1) +}; + /* generic netlink info */ #define ETHTOOL_GENL_NAME "ethtool" #define ETHTOOL_GENL_VERSION 1 diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h index 147ad0a..d61bd32 100644 --- a/uapi/linux/if_link.h +++ b/uapi/linux/if_link.h @@ -374,6 +374,9 @@ enum { IFLA_DEVLINK_PORT, + IFLA_GSO_IPV4_MAX_SIZE, + IFLA_GRO_IPV4_MAX_SIZE, + __IFLA_MAX }; @@ -562,6 +565,8 @@ enum { IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, IFLA_BRPORT_LOCKED, IFLA_BRPORT_MAB, + IFLA_BRPORT_MCAST_N_GROUPS, + IFLA_BRPORT_MCAST_MAX_GROUPS, __IFLA_BRPORT_MAX }; #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) diff --git a/uapi/linux/rtnetlink.h b/uapi/linux/rtnetlink.h index f4a540c..217b25b 100644 --- a/uapi/linux/rtnetlink.h +++ b/uapi/linux/rtnetlink.h @@ -635,6 +635,7 @@ enum { TCA_INGRESS_BLOCK, TCA_EGRESS_BLOCK, TCA_DUMP_FLAGS, + TCA_EXT_WARN_MSG, __TCA_MAX }; |