bump version to 6.1 am: 4afca79c73 am: 9224755e53 am: f4c84a49b9
Original change: https://android-review.googlesource.com/c/platform/external/ethtool/+/2804541
Change-Id: I1a77d6e472fcac4e9cf5621cbfbd639b866dbc9f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index 181beb4..54e04d3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,9 +57,9 @@
"-Wno-gnu-variable-sized-type-not-at-end",
"-Wno-unused-parameter",
"-DETHTOOL_ENABLE_NETLINK",
- "-DETHTOOL_ENABLE_PRETTY_DUMP",
+ // causes a fair bit of binary bloat: "-DETHTOOL_ENABLE_PRETTY_DUMP",
"-DPACKAGE=\"ethtool\"",
- "-DVERSION=\"6.1\"",
+ "-DVERSION=\"6.5\"",
],
apex_available: [
"com.android.tethering",
diff --git a/Makefile.am b/Makefile.am
index 663f40a..ae3b667 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,8 @@
sbin_PROGRAMS = ethtool
ethtool_SOURCES = ethtool.c uapi/linux/ethtool.h internal.h \
- uapi/linux/net_tstamp.h rxclass.c common.c common.h \
+ uapi/linux/net_tstamp.h uapi/linux/if.h uapi/linux/hdlc/ioctl.h \
+ rxclass.c common.c common.h \
json_writer.c json_writer.h json_print.c json_print.h \
list.h
if ETHTOOL_ENABLE_PRETTY_DUMP
@@ -18,7 +19,7 @@
smsc911x.c at76c50x-usb.c sfc.c stmmac.c \
sff-common.c sff-common.h sfpid.c sfpdiag.c \
ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h fjes.c lan78xx.c \
- igc.c cmis.c cmis.h bnxt.c cpsw.c lan743x.c
+ igc.c cmis.c cmis.h bnxt.c cpsw.c lan743x.c hns3.c
endif
if ENABLE_BASH_COMPLETION
@@ -37,13 +38,16 @@
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/module-eeprom.c netlink/module.c netlink/rss.c \
netlink/desc-rtnl.c netlink/cable_test.c netlink/tunnels.c \
+ netlink/plca.c \
+ netlink/pse-pd.c \
uapi/linux/ethtool_netlink.h \
uapi/linux/netlink.h uapi/linux/genetlink.h \
- uapi/linux/rtnetlink.h uapi/linux/if_link.h
+ uapi/linux/rtnetlink.h uapi/linux/if_link.h \
+ uapi/linux/if.h uapi/linux/hdlc/ioctl.h
AM_CPPFLAGS += @MNL_CFLAGS@
LDADD += @MNL_LIBS@
endif
diff --git a/NEWS b/NEWS
index 5687c69..e5eca95 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,38 @@
+Version 6.5 - September 12, 2023
+ * Feature: register dump for hns3 driver (-d)
+ * Fix: fix fallback to ioctl for sset (-s)
+ * Fix: fix empty slot search in rmgr (-N)
+
+Version 6.4 - July 1, 2023
+ * Feature: get/set Tx push buffer length (-G)
+ * Feature: sff-8636 and cmis: report LOL / LOS / Tx Fault (-m)
+ * Fix: fix duplex setting parser (-s)
+ * Misc: check and require C11 language standard
+ * Misc: clean up obsolete pre-build checks
+
+Version 6.3 - May 8, 2023
+ * Feature: PLCA support (--[gs]et-plca-cfg, --get-plca-status)
+ * Feature: MAC Merge layer support (--show-mm, --set-mm)
+ * Feature: pass source of statistics for port stats
+ * Feature: get/set rx push in ringparams (-g and -G)
+ * Feature: coalesce tx aggregation parameters (-c and -C)
+ * Feature: PSE and PD devices (--show-pse, --set-pse)
+ * Fix: minor fixes of help text (--help)
+ * Fix: fix build on systems with older system headers
+ * Fix: fix netlink support when PLCA is not present (no option)
+ * Fix: fixes for issues found with gcc13 -fanalyzer
+ * Fix: fix return code in rxclass_rule_ins (-N)
+ * Fix: more robust argc/argv handling
+
+Version 6.2 - February 21, 2023
+ * Feature: link down event statistics (no option)
+ * Feature: JSON output for coalesce (-c)
+ * Feature: new link modes (no option)
+ * Feature: JSON output for ring (-g)
+ * Feature: netlink handler for RSS get (-x)
+ * Fix: fix boolean value output in JSON output
+ * Fix: fix build errors and warnings
+
Version 6.1 - December 19, 2022
* Feature: update link mode tables
* Feature: register dump for NXP ENETC driver (-d)
diff --git a/cmis.c b/cmis.c
index d0b6272..531932e 100644
--- a/cmis.c
+++ b/cmis.c
@@ -139,6 +139,44 @@
printf("\t%-41s : Rev. %d.%d\n", "Revision compliance", major, minor);
}
+static void
+cmis_show_signals_one(const struct cmis_memory_map *map, const char *name,
+ int off, int ioff, unsigned int imask)
+{
+ unsigned int v;
+ int i;
+
+ if (!map->page_01h)
+ return;
+
+ v = 0;
+ for (i = 0; i < CMIS_MAX_BANKS && map->upper_memory[i][0x11]; i++)
+ v |= map->upper_memory[i][0x11][off] << (i * 8);
+
+ if (map->page_01h[ioff] & imask)
+ sff_show_lane_status(name, i * 8, "Yes", "No", v);
+}
+
+static void cmis_show_signals(const struct cmis_memory_map *map)
+{
+ cmis_show_signals_one(map, "Rx loss of signal", CMIS_RX_LOS_OFFSET,
+ CMIS_DIAG_FLAGS_RX_OFFSET, CMIS_DIAG_FL_RX_LOS);
+ cmis_show_signals_one(map, "Tx loss of signal", CMIS_TX_LOS_OFFSET,
+ CMIS_DIAG_FLAGS_TX_OFFSET, CMIS_DIAG_FL_TX_LOS);
+
+ cmis_show_signals_one(map, "Rx loss of lock", CMIS_RX_LOL_OFFSET,
+ CMIS_DIAG_FLAGS_RX_OFFSET, CMIS_DIAG_FL_RX_LOL);
+ cmis_show_signals_one(map, "Tx loss of lock", CMIS_TX_LOL_OFFSET,
+ CMIS_DIAG_FLAGS_TX_OFFSET, CMIS_DIAG_FL_TX_LOL);
+
+ cmis_show_signals_one(map, "Tx fault", CMIS_TX_FAIL_OFFSET,
+ CMIS_DIAG_FLAGS_TX_OFFSET, CMIS_DIAG_FL_TX_FAIL);
+
+ cmis_show_signals_one(map, "Tx adaptive eq fault",
+ CMIS_TX_EQ_FAIL_OFFSET, CMIS_DIAG_FLAGS_TX_OFFSET,
+ CMIS_DIAG_FL_TX_ADAPTIVE_EQ_FAIL);
+}
+
/**
* Print information about the device's power consumption.
* Relevant documents:
@@ -857,6 +895,7 @@
cmis_show_link_len(map);
cmis_show_vendor_info(map);
cmis_show_rev_compliance(map);
+ cmis_show_signals(map);
cmis_show_mod_state(map);
cmis_show_mod_fault_cause(map);
cmis_show_mod_lvl_controls(map);
diff --git a/cmis.h b/cmis.h
index 4679708..8d66f92 100644
--- a/cmis.h
+++ b/cmis.h
@@ -158,6 +158,17 @@
#define CMIS_DIAG_TYPE_OFFSET 0x97
#define CMIS_RX_PWR_TYPE_MASK 0x10
+/* Supported Flags Advertisement (Page 1) */
+#define CMIS_DIAG_FLAGS_TX_OFFSET 0x9d
+#define CMIS_DIAG_FL_TX_ADAPTIVE_EQ_FAIL (1 << 3)
+#define CMIS_DIAG_FL_TX_LOL (1 << 2)
+#define CMIS_DIAG_FL_TX_LOS (1 << 1)
+#define CMIS_DIAG_FL_TX_FAIL (1 << 0)
+
+#define CMIS_DIAG_FLAGS_RX_OFFSET 0x9e
+#define CMIS_DIAG_FL_RX_LOL (1 << 2)
+#define CMIS_DIAG_FL_RX_LOS (1 << 1)
+
/* Supported Monitors Advertisement (Page 1) */
#define CMIS_DIAG_CHAN_ADVER_OFFSET 0xA0
#define CMIS_TX_BIAS_MON_MASK 0x01
@@ -207,6 +218,10 @@
*/
/* Media Lane-Specific Flags (Page 0x11) */
+#define CMIS_TX_FAIL_OFFSET 0x87
+#define CMIS_TX_LOS_OFFSET 0x88
+#define CMIS_TX_LOL_OFFSET 0x89
+#define CMIS_TX_EQ_FAIL_OFFSET 0x8a
#define CMIS_TX_PWR_AW_HALARM_OFFSET 0x8B
#define CMIS_TX_PWR_AW_LALARM_OFFSET 0x8C
#define CMIS_TX_PWR_AW_HWARN_OFFSET 0x8D
@@ -215,6 +230,8 @@
#define CMIS_TX_BIAS_AW_LALARM_OFFSET 0x90
#define CMIS_TX_BIAS_AW_HWARN_OFFSET 0x91
#define CMIS_TX_BIAS_AW_LWARN_OFFSET 0x92
+#define CMIS_RX_LOS_OFFSET 0x93
+#define CMIS_RX_LOL_OFFSET 0x94
#define CMIS_RX_PWR_AW_HALARM_OFFSET 0x95
#define CMIS_RX_PWR_AW_LALARM_OFFSET 0x96
#define CMIS_RX_PWR_AW_HWARN_OFFSET 0x97
diff --git a/common.c b/common.c
index 2630e73..b8fd4d5 100644
--- a/common.c
+++ b/common.c
@@ -173,3 +173,39 @@
fprintf(stdout, "\n");
}
}
+
+void print_indir_table(struct cmd_context *ctx, u64 ring_count,
+ u32 indir_size, u32 *indir)
+{
+ u32 i;
+
+ printf("RX flow hash indirection table for %s with %llu RX ring(s):\n",
+ ctx->devname, ring_count);
+
+ if (!indir_size)
+ printf("Operation not supported\n");
+
+ for (i = 0; i < indir_size; i++) {
+ if (i % 8 == 0)
+ printf("%5u: ", i);
+ printf(" %5u", indir[i]);
+ if (i % 8 == 7 || i == indir_size - 1)
+ fputc('\n', stdout);
+ }
+}
+
+void print_rss_hkey(u8 *hkey, u32 hkey_size)
+{
+ u32 i;
+
+ printf("RSS hash key:\n");
+ if (!hkey_size || !hkey)
+ printf("Operation not supported\n");
+
+ for (i = 0; i < hkey_size; i++) {
+ if (i == (hkey_size - 1))
+ printf("%02x\n", hkey[i]);
+ else
+ printf("%02x:", hkey[i]);
+ }
+}
diff --git a/common.h b/common.h
index b74fdfa..f975407 100644
--- a/common.h
+++ b/common.h
@@ -8,6 +8,8 @@
#define ETHTOOL_COMMON_H__
#include "internal.h"
+#include <stddef.h>
+#include <errno.h>
#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
@@ -41,5 +43,7 @@
void print_flags(const struct flag_info *info, unsigned int n_info, u32 value);
int dump_wol(struct ethtool_wolinfo *wol);
void dump_mdix(u8 mdix, u8 mdix_ctrl);
-
+void print_indir_table(struct cmd_context *ctx, u64 ring_count,
+ u32 indir_size, u32 *indir);
+void print_rss_hkey(u8 *hkey, u32 hkey_size);
#endif /* ETHTOOL_COMMON_H__ */
diff --git a/configure.ac b/configure.ac
index 3eb4e7b..11efb99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,7 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(ethtool, 6.1, netdev@vger.kernel.org)
+AC_INIT(ethtool, 6.5, netdev@vger.kernel.org)
AC_PREREQ(2.52)
+AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([ethtool.c])
AM_INIT_AUTOMAKE([gnu subdir-objects])
AC_CONFIG_HEADERS([ethtool-config.h])
@@ -13,22 +14,25 @@
AM_PROG_CC_C_O
PKG_PROG_PKG_CONFIG
+AC_DEFUN([AX_CHECK_STDC],
+ [AX_CHECK_COMPILE_FLAG([-std=gnu11],
+ [AX_APPEND_FLAG([-std=gnu11])],
+ [AX_CHECK_COMPILE_FLAG([-std=c11],
+ [AX_APPEND_FLAG([-std=c11])],
+ [AC_MSG_ERROR([$PACKAGE requires a C11 compiler])])
+ ])
+ ])
+AX_CHECK_STDC
+
dnl Checks for libraries.
dnl Checks for header files.
dnl Checks for typedefs, structures, and compiler characteristics.
-AC_MSG_CHECKING([whether <linux/types.h> defines big-endian types])
-AC_TRY_COMPILE([#include <linux/types.h>],
- [__be16 foo;__be32 bar;],
- [AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_BE_TYPES], [1],
- [Define to 1 if <linux/types.h> defines big-endian types])],
- [AC_MSG_RESULT(no)])
dnl Checks for library functions.
AC_HEADER_STDC
-AC_CHECK_FUNCS(socket strtol)
+AC_CHECK_FUNCS(socket)
dnl Check for options
AC_ARG_ENABLE(pretty-dump,
diff --git a/ethtool.8.in b/ethtool.8.in
index bee47f2..c0c37a4 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -117,7 +117,7 @@
. hy \\n(HY
..
.
-.TH ETHTOOL 8 "December 2022" "Ethtool version @VERSION@"
+.TH ETHTOOL 8 "September 2023" "Ethtool version @VERSION@"
.SH NAME
ethtool \- query or control network driver and hardware settings
.
@@ -188,6 +188,9 @@
.BN sample\-interval
.B2 cqe\-mode\-rx on off
.B2 cqe\-mode\-tx on off
+.BN tx\-aggr\-max\-bytes
+.BN tx\-aggr\-max\-frames
+.BN tx\-aggr\-time\-usecs
.HP
.B ethtool \-g|\-\-show\-ring
.I devname
@@ -201,6 +204,8 @@
.BN rx\-buf\-len
.BN cqe\-size
.BN tx\-push
+.BN rx\-push
+.BN tx\-push\-buf\-len
.HP
.B ethtool \-i|\-\-driver
.I devname
@@ -468,7 +473,6 @@
.IR %x ]
.I sub_command
.RB ...
- .
.HP
.B ethtool \-\-cable\-test
.I devname
@@ -490,6 +494,46 @@
.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 ]
+.HP
+.B ethtool \-\-show\-pse
+.I devname
+.HP
+.B ethtool \-\-set\-pse
+.I devname
+.RB [ podl\-pse\-admin\-control
+.BR enable | disable ]
.
.\" Adjust lines (i.e. full justification) and hyphenate.
.ad
@@ -533,6 +577,15 @@
.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 +634,13 @@
.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.
+.TP
+.BI tx\-push\-buf\-len \ N
+Specifies the maximum number of bytes of a transmitted packet a driver can push
+directly to the underlying device
.RE
.TP
.B \-i \-\-driver
@@ -698,6 +758,10 @@
.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 +840,9 @@
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
@@ -853,6 +920,12 @@
0x8000000000000000000000 400000baseLR4_ER4_FR4 Full
0x10000000000000000000000 400000baseDR4 Full
0x20000000000000000000000 400000baseCR4 Full
+0x200000000000000000000000 800000baseCR8 Full
+0x400000000000000000000000 800000baseKR8 Full
+0x800000000000000000000000 800000baseDR8 Full
+0x1000000000000000000000000 800000baseDR8_2 Full
+0x2000000000000000000000000 800000baseSR8 Full
+0x4000000000000000000000000 800000baseVR8 Full
.TE
.TP
.BI phyad \ N
@@ -1505,6 +1578,178 @@
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
+.TP
+.B \-\-show\-pse
+Show the current Power Sourcing Equipment (PSE) status for the given interface.
+.RS 4
+.TP
+.B podl-pse-admin-state
+This attribute indicates the operational status of PoDL PSE functions, which
+can be modified using the
+.B podl-pse-admin-control
+parameter. It corresponds to IEEE 802.3-2018 30.15.1.1.2 (aPoDLPSEAdminState),
+with potential values being
+.B enabled, disabled
+.TP
+.B podl-pse-power-detection-status
+This attribute indicates the power detection status of the PoDL PSE. The
+status depend on internal PSE state machine and automatic PD classification
+support. It corresponds to IEEE 802.3-2018 30.15.1.1.3
+(aPoDLPSEPowerDetectionStatus) with potential values being
+.B disabled, searching, delivering power, sleep, idle, error
+.RE
+
+.RE
+.TP
+.B \-\-set\-pse
+Set Power Sourcing Equipment (PSE) parameters.
+.RS 4
+.TP
+.A2 podl-pse-admin-control \ enable disable
+This parameter manages PoDL PSE Admin operations in accordance with the IEEE
+802.3-2018 30.15.1.2.1 (acPoDLPSEAdminControl) specification.
+
.SH BUGS
Not supported (in part or whole) on all network drivers.
.SH AUTHOR
diff --git a/ethtool.c b/ethtool.c
index 526be4c..af51220 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -58,10 +58,6 @@
#define MAX_ADDR_LEN 32
#endif
-#ifndef NETLINK_GENERIC
-#define NETLINK_GENERIC 16
-#endif
-
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
static void exit_bad_args(void) __attribute__((noreturn));
@@ -478,6 +474,15 @@
ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
ETHTOOL_LINK_MODE_10baseT1L_Full_BIT,
+ ETHTOOL_LINK_MODE_800000baseCR8_Full_BIT,
+ ETHTOOL_LINK_MODE_800000baseKR8_Full_BIT,
+ ETHTOOL_LINK_MODE_800000baseDR8_Full_BIT,
+ 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[] = {
@@ -720,6 +725,24 @@
"100baseFX/Full" },
{ 0, ETHTOOL_LINK_MODE_10baseT1L_Full_BIT,
"10baseT1L/Full" },
+ { 0, ETHTOOL_LINK_MODE_800000baseCR8_Full_BIT,
+ "800000baseCR8/Full" },
+ { 0, ETHTOOL_LINK_MODE_800000baseKR8_Full_BIT,
+ "800000baseKR8/Full" },
+ { 0, ETHTOOL_LINK_MODE_800000baseDR8_Full_BIT,
+ "800000baseDR8/Full" },
+ { 0, ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT,
+ "800000baseDR8_2/Full" },
+ { 0, ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT,
+ "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;
@@ -1138,6 +1161,7 @@
{ "lan743x", lan743x_dump_regs },
{ "fsl_enetc", fsl_enetc_dump_regs },
{ "fsl_enetc_vf", fsl_enetc_dump_regs },
+ { "hns3", hns3_dump_regs },
};
#endif
@@ -3882,27 +3906,6 @@
return err ? 1 : 0;
}
-static void print_indir_table(struct cmd_context *ctx,
- struct ethtool_rxnfc *ring_count,
- u32 indir_size, u32 *indir)
-{
- u32 i;
-
- printf("RX flow hash indirection table for %s with %llu RX ring(s):\n",
- ctx->devname, ring_count->data);
-
- if (!indir_size)
- printf("Operation not supported\n");
-
- for (i = 0; i < indir_size; i++) {
- if (i % 8 == 0)
- printf("%5u: ", i);
- printf(" %5u", indir[i]);
- if (i % 8 == 7 || i == indir_size - 1)
- fputc('\n', stdout);
- }
-}
-
static int do_grxfhindir(struct cmd_context *ctx,
struct ethtool_rxnfc *ring_count)
{
@@ -3934,7 +3937,8 @@
return 1;
}
- print_indir_table(ctx, ring_count, indir->size, indir->ring_index);
+ print_indir_table(ctx, ring_count->data, indir->size,
+ indir->ring_index);
free(indir);
return 0;
@@ -3949,7 +3953,7 @@
u32 rss_context = 0;
u32 i, indir_bytes;
unsigned int arg_num = 0;
- char *hkey;
+ u8 *hkey;
int err;
while (arg_num < ctx->argc) {
@@ -3999,21 +4003,13 @@
return 1;
}
- print_indir_table(ctx, &ring_count, rss->indir_size, rss->rss_config);
+ print_indir_table(ctx, ring_count.data, rss->indir_size,
+ rss->rss_config);
indir_bytes = rss->indir_size * sizeof(rss->rss_config[0]);
- hkey = ((char *)rss->rss_config + indir_bytes);
+ hkey = ((u8 *)rss->rss_config + indir_bytes);
- printf("RSS hash key:\n");
- if (!rss->key_size)
- printf("Operation not supported\n");
-
- for (i = 0; i < rss->key_size; i++) {
- if (i == (rss->key_size - 1))
- printf("%02x\n", (u8) hkey[i]);
- else
- printf("%02x:", (u8) hkey[i]);
- }
+ print_rss_hkey(hkey, rss->key_size);
printf("RSS hash function:\n");
if (!rss->hfunc) {
@@ -5683,7 +5679,8 @@
.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",
@@ -5696,6 +5693,7 @@
},
{
.opts = "-c|--show-coalesce",
+ .json = true,
.func = do_gcoalesce,
.nlfunc = nl_gcoalesce,
.help = "Show coalesce options"
@@ -5729,9 +5727,13 @@
" [sample-interval N]\n"
" [cqe-mode-rx on|off]\n"
" [cqe-mode-tx on|off]\n"
+ " [tx-aggr-max-bytes N]\n"
+ " [tx-aggr-max-frames N]\n"
+ " [tx-aggr-time-usecs N]\n"
},
{
.opts = "-g|--show-ring",
+ .json = true,
.func = do_gring,
.nlfunc = nl_gring,
.help = "Query RX/TX ring parameters"
@@ -5745,9 +5747,11 @@
" [ 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"
+ " [ tx-push-buf-len N]\n"
},
{
.opts = "-k|--show-features|--show-offload",
@@ -5801,13 +5805,13 @@
.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",
@@ -5816,7 +5820,8 @@
.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",
@@ -5856,7 +5861,7 @@
" [ 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"
},
{
@@ -5867,7 +5872,9 @@
},
{
.opts = "-x|--show-rxfh-indir|--show-rxfh",
+ .json = true,
.func = do_grxfh,
+ .nlfunc = nl_grss,
.help = "Show Rx flow hash indirection table and/or RSS hash key",
.xhelp = " [ context %d ]\n"
},
@@ -5885,7 +5892,7 @@
.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",
@@ -5916,10 +5923,10 @@
.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",
@@ -5986,16 +5993,16 @@
.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",
@@ -6035,14 +6042,14 @@
.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",
@@ -6078,6 +6085,55 @@
.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 = "--show-pse",
+ .json = true,
+ .nlfunc = nl_gpse,
+ .help = "Show settings for Power Sourcing Equipment",
+ },
+ {
+ .opts = "--set-pse",
+ .nlfunc = nl_spse,
+ .help = "Set Power Sourcing Equipment settings",
+ .xhelp = " [ podl-pse-admin-control enable|disable ]\n"
+ },
+ {
.opts = "-h|--help",
.no_dev = true,
.func = show_usage,
@@ -6347,6 +6403,9 @@
init_global_link_mode_masks();
+ if (argc < 2)
+ exit_bad_args();
+
/* Skip command name */
argp++;
argc--;
@@ -6391,7 +6450,7 @@
* name to get settings for (which we don't expect to begin
* with '-').
*/
- if (argc == 0)
+ if (!*argp)
exit_bad_args();
k = find_option(*argp);
diff --git a/hns3.c b/hns3.c
new file mode 100644
index 0000000..7199426
--- /dev/null
+++ b/hns3.c
@@ -0,0 +1,829 @@
+/* Copyright (c) 2023 Huawei Corporation */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "internal.h"
+
+/* distinguish drive register data of earlier versions */
+#define HNS3_REG_MAGIC_NUMBER 0x686e733372656773 /* hns3regs */
+#define HNS3_REG_RSV_NAME "reserved"
+#define HNS3_REG_UNKNOW_NAME "unknown"
+#define HNS3_REG_UNKNOW_VALUE_LEN 4
+
+struct hns3_reg_tlv {
+ u16 tag;
+ u16 len;
+};
+
+struct hns3_reg_header {
+ u64 magic_number;
+ u8 is_vf;
+ u8 rsv[7];
+};
+
+struct hns3_reg_info {
+ const char *name;
+ u16 value_len;
+};
+
+struct hns3_regs_group {
+ const char *group_name;
+ const struct hns3_reg_info *regs;
+ u16 regs_count;
+};
+
+enum hns3_reg_tag {
+ HNS3_TAG_CMDQ = 0,
+ HNS3_TAG_COMMON,
+ HNS3_TAG_RING,
+ HNS3_TAG_TQP_INTR,
+ HNS3_TAG_QUERY_32_BIT,
+ HNS3_TAG_QUERY_64_BIT,
+ HNS3_TAG_DFX_BIOS_COMMON,
+ HNS3_TAG_DFX_SSU_0,
+ HNS3_TAG_DFX_SSU_1,
+ HNS3_TAG_DFX_IGU_EGU,
+ HNS3_TAG_DFX_RPU_0,
+ HNS3_TAG_DFX_RPU_1,
+ HNS3_TAG_DFX_NCSI,
+ HNS3_TAG_DFX_RTC,
+ HNS3_TAG_DFX_PPP,
+ HNS3_TAG_DFX_RCB,
+ HNS3_TAG_DFX_TQP,
+ HNS3_TAG_DFX_SSU_2,
+ HNS3_TAG_DFX_RPU_TNL,
+ HNS3_TAG_MAX,
+};
+
+const bool hns3_reg_is_repeat_tag_array[] = {
+ [HNS3_TAG_RING] = true,
+ [HNS3_TAG_TQP_INTR] = true,
+ [HNS3_TAG_DFX_RPU_TNL] = true,
+};
+
+const struct hns3_reg_info pf_cmdq_regs[] = {
+ {"comm_nic_csq_baseaddr_l", 4},
+ {"comm_nic_csq_baseaddr_h", 4},
+ {"comm_nic_csq_depth", 4},
+ {"comm_nic_csq_tail", 4},
+ {"comm_nic_csq_head", 4},
+ {"comm_nic_crq_baseaddr_l", 4},
+ {"comm_nic_crq_baseaddr_h", 4},
+ {"comm_nic_crq_depth", 4},
+ {"comm_nic_crq_tail", 4},
+ {"comm_nic_crq_head", 4},
+ {"comm_vector0_cmdq_src", 4},
+ {"comm_cmdq_intr_sts", 4},
+ {"comm_cmdq_intr_en", 4},
+ {"comm_cmdq_intr_gen", 4},
+};
+
+const struct hns3_reg_info pf_common_regs[] = {
+ {"misc_vector_base", 4},
+ {"pf_other_int", 4},
+ {"misc_reset_sts", 4},
+ {"misc_vector_int_sts", 4},
+ {"global_reset", 4},
+ {"fun_rst_ing", 4},
+ {"gro_en", 4},
+};
+
+const struct hns3_reg_info pf_ring_regs[] = {
+ {"ring_rx_addr_l", 4},
+ {"ring_rx_addr_h", 4},
+ {"ring_rx_bd_num", 4},
+ {"ring_rx_bd_length", 4},
+ {"ring_rx_merge_en", 4},
+ {"ring_rx_tail", 4},
+ {"ring_rx_head", 4},
+ {"ring_rx_fbd_num", 4},
+ {"ring_rx_offset", 4},
+ {"ring_rx_fbd_offset", 4},
+ {"ring_rx_stash", 4},
+ {"ring_rx_bd_err", 4},
+ {"ring_tx_addr_l", 4},
+ {"ring_tx_addr_h", 4},
+ {"ring_tx_bd_num", 4},
+ {"ring_tx_priority", 4},
+ {"ring_tx_tc", 4},
+ {"ring_tx_merge_en", 4},
+ {"ring_tx_tail", 4},
+ {"ring_tx_head", 4},
+ {"ring_tx_fbd_num", 4},
+ {"ring_tx_offset", 4},
+ {"ring_tx_ebd_num", 4},
+ {"ring_tx_ebd_offset", 4},
+ {"ring_tx_bd_err", 4},
+ {"ring_en", 4},
+};
+
+const struct hns3_reg_info pf_tqp_intr_regs[] = {
+ {"tqp_intr_ctrl", 4},
+ {"tqp_intr_gl0", 4},
+ {"tqp_intr_gl1", 4},
+ {"tqp_intr_gl2", 4},
+ {"tqp_intr_rl", 4},
+};
+
+const struct hns3_reg_info query_32_bit_regs[] = {
+ {"ssu_common_err_int", 4},
+ {"ssu_port_based_err_int", 4},
+ {"ssu_fifo_overflow_int", 4},
+ {"ssu_ets_tcg_int", 4},
+ {"ssu_bp_status_0", 4},
+ {"ssu_bp_status_1", 4},
+ {"ssu_bp_status_2", 4},
+ {"ssu_bp_status_3", 4},
+ {"ssu_bp_status_4", 4},
+ {"ssu_bp_status_5", 4},
+ {"ssu_mac_tx_pfc_ind", 4},
+ {"ssu_mac_rx_pfc_ind", 4},
+ {"ssu_rx_oq_drop_pkt_cnt", 4},
+ {"ssu_tx_oq_drop_pkt_cnt", 4},
+};
+
+const struct hns3_reg_info query_64_bit_regs[] = {
+ {"ppp_get_rx_pkt_cnt", 8},
+ {"ppp_get_tx_pkt_cnt", 8},
+ {"ppp_send_uc_prt2host_pkt_cnt", 8},
+ {"ppp_send_uc_prt2prt_pkt_cnt", 8},
+ {"ppp_send_uc_host2host_pkt_cnt", 8},
+ {"ppp_send_uc_host2prt_pkt_cnt", 8},
+ {"ppp_send_mc_from_prt_cnt", 8},
+};
+
+const struct hns3_reg_info dfx_bios_common_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"bp_cpu_state", 4},
+ {"dfx_msix_info_nic_0", 4},
+ {"dfx_msix_info_nic_1", 4},
+ {"dfx_msix_info_nic_2", 4},
+ {"dfx_msix_info_nic_3", 4},
+ {"dfx_msix_info_roc_0", 4},
+ {"dfx_msix_info_roc_1", 4},
+ {"dfx_msix_info_roc_2", 4},
+ {"dfx_msix_info_roc_3", 4},
+ {HNS3_REG_RSV_NAME, 8},
+};
+
+const struct hns3_reg_info dfx_ssu_0_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"ssu_ets_port_status", 4},
+ {"ssu_ets_tcg_status", 4},
+ {HNS3_REG_RSV_NAME, 4},
+ {HNS3_REG_RSV_NAME, 4},
+ {"ssu_bp_status_0", 4},
+ {"ssu_bp_status_1", 4},
+ {"ssu_bp_status_2", 4},
+ {"ssu_bp_status_3", 4},
+ {"ssu_bp_status_4", 4},
+ {"ssu_bp_status_5", 4},
+ {"ssu_mac_tx_pfc_ind", 4},
+ {"mac_ssu_rx_pfc_ind", 4},
+ {"btmp_ageing_st_b0", 4},
+ {"btmp_ageing_st_b1", 4},
+ {"btmp_ageing_st_b2", 4},
+ {HNS3_REG_RSV_NAME, 8},
+ {"full_drop_num", 4},
+ {"part_drop_num", 4},
+ {"ppp_key_drop_num", 4},
+ {"ppp_rlt_drop_num", 4},
+ {"lo_pri_unicast_rlt_drop_num", 4},
+ {"hi_pri_multicast_rlt_drop_num", 4},
+ {"lo_pri_multicast_rlt_drop_num", 4},
+ {"ncsi_packet_curr_buffer_cnt", 4},
+ {HNS3_REG_RSV_NAME, 12},
+ {"ssu_mb_rd_rlt_drop_cnt", 4},
+ {"ssu_ppp_mac_key_num", 8},
+ {"ssu_ppp_host_key_num", 8},
+ {"ppp_ssu_mac_rlt_num", 8},
+ {"ppp_ssu_host_rlt_num", 8},
+ {"ncsi_rx_packet_in_cnt", 8},
+ {"ncsi_tx_packet_out_cnt", 8},
+ {"ssu_key_drop_num", 4},
+ {"mb_uncopy_num", 4},
+ {"rx_oq_drop_pkt_cnt", 4},
+ {"tx_oq_drop_pkt_cnt", 4},
+ {"bank_unbalance_drop_cnt", 4},
+ {"bank_unbalance_rx_drop_cnt", 4},
+ {"nic_l2_err_drop_pkt_cnt", 4},
+ {"roc_l2_err_drop_pkt_cnt", 4},
+ {"nic_l2_err_drop_pkt_cnt_rx", 4},
+ {"roc_l2_err_drop_pkt_cnt_rx", 4},
+ {"rx_oq_glb_drop_pkt_cnt", 4},
+ {HNS3_REG_RSV_NAME, 4},
+ {"lo_pri_unicast_cur_cnt", 4},
+ {"hi_pri_multicast_cur_cnt", 4},
+ {"lo_pri_multicast_cur_cnt", 4},
+ {HNS3_REG_RSV_NAME, 12},
+};
+
+const struct hns3_reg_info dfx_ssu_1_regs[] = {
+ {"prt_id", 4},
+ {"packet_tc_curr_buffer_cnt_0", 4},
+ {"packet_tc_curr_buffer_cnt_1", 4},
+ {"packet_tc_curr_buffer_cnt_2", 4},
+ {"packet_tc_curr_buffer_cnt_3", 4},
+ {"packet_tc_curr_buffer_cnt_4", 4},
+ {"packet_tc_curr_buffer_cnt_5", 4},
+ {"packet_tc_curr_buffer_cnt_6", 4},
+ {"packet_tc_curr_buffer_cnt_7", 4},
+ {"packet_curr_buffer_cnt", 4},
+ {HNS3_REG_RSV_NAME, 8},
+ {"rx_packet_in_cnt", 8},
+ {"rx_packet_out_cnt", 8},
+ {"tx_packet_in_cnt", 8},
+ {"tx_packet_out_cnt", 8},
+ {"roc_rx_packet_in_cnt", 8},
+ {"roc_tx_packet_out_cnt", 8},
+ {"rx_packet_tc_in_cnt_0", 8},
+ {"rx_packet_tc_in_cnt_1", 8},
+ {"rx_packet_tc_in_cnt_2", 8},
+ {"rx_packet_tc_in_cnt_3", 8},
+ {"rx_packet_tc_in_cnt_4", 8},
+ {"rx_packet_tc_in_cnt_5", 8},
+ {"rx_packet_tc_in_cnt_6", 8},
+ {"rx_packet_tc_in_cnt_7", 8},
+ {"rx_packet_tc_out_cnt_0", 8},
+ {"rx_packet_tc_out_cnt_1", 8},
+ {"rx_packet_tc_out_cnt_2", 8},
+ {"rx_packet_tc_out_cnt_3", 8},
+ {"rx_packet_tc_out_cnt_4", 8},
+ {"rx_packet_tc_out_cnt_5", 8},
+ {"rx_packet_tc_out_cnt_6", 8},
+ {"rx_packet_tc_out_cnt_7", 8},
+ {"tx_packet_tc_in_cnt_0", 8},
+ {"tx_packet_tc_in_cnt_1", 8},
+ {"tx_packet_tc_in_cnt_2", 8},
+ {"tx_packet_tc_in_cnt_3", 8},
+ {"tx_packet_tc_in_cnt_4", 8},
+ {"tx_packet_tc_in_cnt_5", 8},
+ {"tx_packet_tc_in_cnt_6", 8},
+ {"tx_packet_tc_in_cnt_7", 8},
+ {"tx_packet_tc_out_cnt_0", 8},
+ {"tx_packet_tc_out_cnt_1", 8},
+ {"tx_packet_tc_out_cnt_2", 8},
+ {"tx_packet_tc_out_cnt_3", 8},
+ {"tx_packet_tc_out_cnt_4", 8},
+ {"tx_packet_tc_out_cnt_5", 8},
+ {"tx_packet_tc_out_cnt_6", 8},
+ {"tx_packet_tc_out_cnt_7", 8},
+ {HNS3_REG_RSV_NAME, 8},
+};
+
+const struct hns3_reg_info dfx_igu_egu_regs[] = {
+ {"prt_id", 4},
+ {"igu_rx_err_pkt", 4},
+ {"igu_rx_no_sof_pkt", 4},
+ {"egu_tx_1588_short_pkt", 4},
+ {"egu_tx_1588_pkt", 4},
+ {"egu_tx_err_pkt", 4},
+ {"igu_rx_out_l2_pkt", 4},
+ {"igu_rx_out_l3_pkt", 4},
+ {"igu_rx_out_l4_pkt", 4},
+ {"igu_rx_in_l2_pkt", 4},
+ {"igu_rx_in_l3_pkt", 4},
+ {"igu_rx_in_l4_pkt", 4},
+ {"igu_rx_el3e_pkt", 4},
+ {"igu_rx_el4e_pkt", 4},
+ {"igu_rx_l3e_pkt", 4},
+ {"igu_rx_l4e_pkt", 4},
+ {"igu_rx_rocee_pkt", 4},
+ {"igu_rx_out_udp0_pkt", 4},
+ {"igu_rx_in_udp0_pkt", 4},
+ {"mul_car_drop_pkt_cnt", 8},
+ {"bro_car_drop_pkt_cnt", 8},
+ {HNS3_REG_RSV_NAME, 4},
+ {"igu_rx_oversize_pkt", 8},
+ {"igu_rx_undersize_pkt", 8},
+ {"igu_rx_out_all_pkt", 8},
+ {"igu_tx_out_all_pkt", 8},
+ {"igu_rx_uni_pkt", 8},
+ {"igu_rx_multi_pkt", 8},
+ {"igu_rx_broad_pkt", 8},
+ {"egu_tx_out_all_pkt", 8},
+ {"egu_tx_uni_pkt", 8},
+ {"egu_tx_multi_pkt", 8},
+ {"egu_tx_broad_pkt", 8},
+ {"igu_tx_key_num", 8},
+ {"igu_rx_non_tun_pkt", 8},
+ {"igu_rx_tun_pkt", 8},
+ {HNS3_REG_RSV_NAME, 8},
+};
+
+const struct hns3_reg_info dfx_rpu_0_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"fsm_dfx_st0", 4},
+ {"fsm_dfx_st1", 4},
+ {"rpu_rx_pkt_drop_cnt", 4},
+ {"buf_wait_timeout", 4},
+ {"buf_wait_timeout_qid", 4},
+};
+
+const struct hns3_reg_info dfx_rpu_1_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"fifo_dfx_st0", 4},
+ {"fifo_dfx_st1", 4},
+ {"fifo_dfx_st2", 4},
+ {"fifo_dfx_st3", 4},
+ {"fifo_dfx_st4", 4},
+ {"fifo_dfx_st5", 4},
+ {HNS3_REG_RSV_NAME, 20},
+};
+
+const struct hns3_reg_info dfx_ncsi_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"ncsi_egu_tx_fifo_sts", 4},
+ {"ncsi_pause_status", 4},
+ {"ncsi_rx_ctrl_dmac_err_cnt", 4},
+ {"ncsi_rx_ctrl_smac_err_cnt", 4},
+ {"ncsi_rx_ctrl_cks_err_cnt", 4},
+ {"ncsi_rx_ctrl_pkt_cnt", 4},
+ {"ncsi_rx_pt_dmac_err_cnt", 4},
+ {"ncsi_rx_pt_smac_err_cnt", 4},
+ {"ncsi_rx_pt_pkt_cnt", 4},
+ {"ncsi_rx_fcs_err_cnt", 4},
+ {"ncsi_tx_ctrl_dmac_err_cnt", 4},
+ {"ncsi_tx_ctrl_smac_err_cnt", 4},
+ {"ncsi_tx_ctrl_pkt_cnt", 4},
+ {"ncsi_tx_pt_dmac_err_cnt", 4},
+ {"ncsi_tx_pt_smac_err_cnt", 4},
+ {"ncsi_tx_pt_pkt_cnt", 4},
+ {"ncsi_tx_pt_pkt_trun_cnt", 4},
+ {"ncsi_tx_pt_pkt_err_cnt", 4},
+ {"ncsi_tx_ctrl_pkt_err_cnt", 4},
+ {"ncsi_rx_ctrl_pkt_trun_cnt", 4},
+ {"ncsi_rx_ctrl_pkt_cflit_cnt", 4},
+ {HNS3_REG_RSV_NAME, 8},
+ {"ncsi_mac_rx_octets_ok", 4},
+ {"ncsi_mac_rx_octets_bad", 4},
+ {"ncsi_mac_rx_uc_pkts", 4},
+ {"ncsi_mac_rx_mc_pkts", 4},
+ {"ncsi_mac_rx_bc_pkts", 4},
+ {"ncsi_mac_rx_pkts_64octets", 4},
+ {"ncsi_mac_rx_pkts_65to127octets", 4},
+ {"ncsi_mac_rx_pkts_128to255octets", 4},
+ {"ncsi_mac_rx_pkts_256to511octets", 4},
+ {"ncsi_mac_rx_pkts_512to1023octets", 4},
+ {"ncsi_mac_rx_pkts_1024to1518octets", 4},
+ {"ncsi_mac_rx_pkts_1519tomaxoctets", 4},
+ {"ncsi_mac_rx_fcs_errors", 4},
+ {"ncsi_mac_rx_long_errors", 4},
+ {"ncsi_mac_rx_jabber_errors", 4},
+ {"ncsi_mac_rx_runt_err_cnt", 4},
+ {"ncsi_mac_rx_short_err_cnt", 4},
+ {"ncsi_mac_rx_filt_pkt_cnt", 4},
+ {"ncsi_mac_rx_octets_total_filt", 4},
+ {"ncsi_mac_tx_octets_ok", 4},
+ {"ncsi_mac_tx_octets_bad", 4},
+ {"ncsi_mac_tx_uc_pkts", 4},
+ {"ncsi_mac_tx_mc_pkts", 4},
+ {"ncsi_mac_tx_bc_pkts", 4},
+ {"ncsi_mac_tx_pkts_64octets", 4},
+ {"ncsi_mac_tx_pkts_65to127octets", 4},
+ {"ncsi_mac_tx_pkts_128to255octets", 4},
+ {"ncsi_mac_tx_pkts_256to511octets", 4},
+ {"ncsi_mac_tx_pkts_512to1023octets", 4},
+ {"ncsi_mac_tx_pkts_1024to1518octets", 4},
+ {"ncsi_mac_tx_pkts_1519tomaxoctets", 4},
+ {"ncsi_mac_tx_underrun", 4},
+ {"ncsi_mac_tx_crc_error", 4},
+ {"ncsi_mac_tx_pause_frames", 4},
+ {"ncsi_mac_rx_pad_pkts", 4},
+ {"ncsi_mac_rx_pause_frames", 4},
+};
+
+const struct hns3_reg_info dfx_rtc_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"lge_igu_afifo_dfx_0", 4},
+ {"lge_igu_afifo_dfx_1", 4},
+ {"lge_igu_afifo_dfx_2", 4},
+ {"lge_igu_afifo_dfx_3", 4},
+ {"lge_igu_afifo_dfx_4", 4},
+ {"lge_igu_afifo_dfx_5", 4},
+ {"lge_igu_afifo_dfx_6", 4},
+ {"lge_igu_afifo_dfx_7", 4},
+ {"lge_egu_afifo_dfx_0", 4},
+ {"lge_egu_afifo_dfx_1", 4},
+ {"lge_egu_afifo_dfx_2", 4},
+ {"lge_egu_afifo_dfx_3", 4},
+ {"lge_egu_afifo_dfx_4", 4},
+ {"lge_egu_afifo_dfx_5", 4},
+ {"lge_egu_afifo_dfx_6", 4},
+ {"lge_egu_afifo_dfx_7", 4},
+ {"cge_igu_afifo_dfx_0", 4},
+ {"cge_igu_afifo_dfx_1", 4},
+ {"cge_egu_afifo_dfx_0", 4},
+ {"cge_egu_afifo_dfx_1", 4},
+ {HNS3_REG_RSV_NAME, 12},
+};
+
+const struct hns3_reg_info dfx_ppp_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"drop_from_prt_pkt_cnt", 4},
+ {"drop_from_host_pkt_cnt", 4},
+ {"drop_tx_vlan_proc_cnt", 4},
+ {"drop_mng_cnt", 4},
+ {"drop_fd_cnt", 4},
+ {"drop_no_dst_cnt", 4},
+ {"drop_mc_mbid_full_cnt", 4},
+ {"drop_sc_filtered", 4},
+ {"ppp_mc_drop_pkt_cnt", 4},
+ {"drop_pt_cnt", 4},
+ {"drop_mac_anti_spoof_cnt", 4},
+ {"drop_ig_vfv_cnt", 4},
+ {"drop_ig_prtv_cnt", 4},
+ {"drop_cnm_pfc_pause_cnt", 4},
+ {"drop_torus_tc_cnt", 4},
+ {"drop_torus_lpbk_cnt", 4},
+ {"ppp_hfs_sts", 4},
+ {"ppp_mc_rslt_sts", 4},
+ {"ppp_p3u_sts", 4},
+ {HNS3_REG_RSV_NAME, 4},
+ {"ppp_umv_sts_0", 4},
+ {"ppp_umv_sts_1", 4},
+ {"ppp_vfv_sts", 4},
+ {"ppp_gro_key_cnt", 4},
+ {"ppp_gro_info_cnt", 4},
+ {"ppp_gro_drop_cnt", 4},
+ {"ppp_gro_out_cnt", 4},
+ {"ppp_gro_key_match_data_cnt", 4},
+ {"ppp_gro_key_match_tcam_cnt", 4},
+ {"ppp_gro_info_match_cnt", 4},
+ {"ppp_gro_free_entry_cnt", 4},
+ {"ppp_gro_inner_dfx_signal", 4},
+ {HNS3_REG_RSV_NAME, 12},
+ {"get_rx_pkt_cnt", 8},
+ {"get_tx_pkt_cnt", 8},
+ {"send_uc_prt2host_pkt_cnt", 8},
+ {"send_uc_prt2prt_pkt_cnt", 8},
+ {"send_uc_host2host_pkt_cnt", 8},
+ {"send_uc_host2prt_pkt_cnt", 8},
+ {"send_mc_from_prt_cnt", 8},
+ {"send_mc_from_host_cnt", 8},
+ {"ssu_mc_rd_cnt", 8},
+ {"ssu_mc_drop_cnt", 8},
+ {"ssu_mc_rd_pkt_cnt", 8},
+ {"ppp_mc_2host_pkt_cnt", 8},
+ {"ppp_mc_2prt_pkt_cnt", 8},
+ {"ntsnos_pkt_cnt", 8},
+ {"ntup_pkt_cnt", 8},
+ {"ntlcl_pkt_cnt", 8},
+ {"nttgt_pkt_cnt", 8},
+ {"rtns_pkt_cnt", 8},
+ {"rtlpbk_pkt_cnt", 8},
+ {"nr_pkt_cnt", 8},
+ {"rr_pkt_cnt", 8},
+ {"mng_tbl_hit_cnt", 8},
+ {"fd_tbl_hit_cnt", 8},
+ {"fd_lkup_cnt", 8},
+ {"bc_hit_cnt", 8},
+ {"um_tbl_uc_hit_cnt", 8},
+ {"um_tbl_mc_hit_cnt", 8},
+ {"um_tbl_snq_hit_cnt", 8},
+ {HNS3_REG_RSV_NAME, 8},
+ {"fwd_bonding_hit_cnt", 8},
+ {"promis_tbl_hit_cnt", 8},
+ {"get_tunl_pkt_cnt", 8},
+ {"get_bmc_pkt_cnt", 8},
+ {"send_uc_prt2bmc_pkt_cnt", 8},
+ {"send_uc_host2bmc_pkt_cnt", 8},
+ {"send_uc_bmc2host_pkt_cnt", 8},
+ {"send_uc_bmc2prt_pkt_cnt", 8},
+ {"ppp_mc_2bmc_pkt_cnt", 8},
+ {HNS3_REG_RSV_NAME, 24},
+ {"rx_default_host_hit_cnt", 8},
+ {"lan_pair_cnt", 8},
+ {"um_tbl_mc_hit_pkt_cnt", 8},
+ {"mta_tbl_hit_pkt_cnt", 8},
+ {"promis_tbl_hit_pkt_cnt", 8},
+ {HNS3_REG_RSV_NAME, 16},
+};
+
+const struct hns3_reg_info dfx_rcb_regs[] = {
+ {HNS3_REG_RSV_NAME, 4},
+ {"fsm_dfx_st0", 4},
+ {"fsm_dfx_st1", 4},
+ {"fsm_dfx_st2", 4},
+ {"fifo_dfx_st0", 4},
+ {"fifo_dfx_st1", 4},
+ {"fifo_dfx_st2", 4},
+ {"fifo_dfx_st3", 4},
+ {"fifo_dfx_st4", 4},
+ {"fifo_dfx_st5", 4},
+ {"fifo_dfx_st6", 4},
+ {"fifo_dfx_st7", 4},
+ {"fifo_dfx_st8", 4},
+ {"fifo_dfx_st9", 4},
+ {"fifo_dfx_st10", 4},
+ {"fifo_dfx_st11", 4},
+ {"q_credit_vld_0", 4},
+ {"q_credit_vld_1", 4},
+ {"q_credit_vld_2", 4},
+ {"q_credit_vld_3", 4},
+ {"q_credit_vld_4", 4},
+ {"q_credit_vld_5", 4},
+ {"q_credit_vld_6", 4},
+ {"q_credit_vld_7", 4},
+ {"q_credit_vld_8", 4},
+ {"q_credit_vld_9", 4},
+ {"q_credit_vld_10", 4},
+ {"q_credit_vld_11", 4},
+ {"q_credit_vld_12", 4},
+ {"q_credit_vld_13", 4},
+ {"q_credit_vld_14", 4},
+ {"q_credit_vld_15", 4},
+ {"q_credit_vld_16", 4},
+ {"q_credit_vld_17", 4},
+ {"q_credit_vld_18", 4},
+ {"q_credit_vld_19", 4},
+ {"q_credit_vld_20", 4},
+ {"q_credit_vld_21", 4},
+ {"q_credit_vld_22", 4},
+ {"q_credit_vld_23", 4},
+ {"q_credit_vld_24", 4},
+ {"q_credit_vld_25", 4},
+ {"q_credit_vld_26", 4},
+ {"q_credit_vld_27", 4},
+ {"q_credit_vld_28", 4},
+ {"q_credit_vld_29", 4},
+ {"q_credit_vld_30", 4},
+ {"q_credit_vld_31", 4},
+ {"gro_bd_serr_cnt", 4},
+ {"gro_context_serr_cnt", 4},
+ {"rx_stash_cfg_serr_cnt", 4},
+ {"rcb_tx_mem_serr_cnt", 4},
+ {"gro_bd_merr_cnt", 4},
+ {"gro_context_merr_cnt", 4},
+ {"rx_stash_cfg_merr_cnt", 4},
+ {"rcb_tx_mem_merr_cnt", 4},
+ {HNS3_REG_RSV_NAME, 16},
+};
+
+const struct hns3_reg_info dfx_tqp_regs[] = {
+ {"q_num", 4},
+ {"rcb_cfg_rx_ring_tail", 4},
+ {"rcb_cfg_rx_ring_head", 4},
+ {"rcb_cfg_rx_ring_fbdnum", 4},
+ {"rcb_cfg_rx_ring_offset", 4},
+ {"rcb_cfg_rx_ring_fbdoffset", 4},
+ {"rcb_cfg_rx_ring_pktnum_record", 4},
+ {"rcb_cfg_tx_ring_tail", 4},
+ {"rcb_cfg_tx_ring_head", 4},
+ {"rcb_cfg_tx_ring_fbdnum", 4},
+ {"rcb_cfg_tx_ring_offset", 4},
+ {"rcb_cfg_tx_ring_ebdnum", 4},
+};
+
+const struct hns3_reg_info dfx_ssu_2_regs[] = {
+ {"oq_index", 4},
+ {"queue_cnt", 4},
+ {HNS3_REG_RSV_NAME, 16},
+};
+
+const struct hns3_reg_info vf_cmdq_regs[] = {
+ {"comm_nic_csq_baseaddr_l", 4},
+ {"comm_nic_csq_baseaddr_h", 4},
+ {"comm_nic_csq_depth", 4},
+ {"comm_nic_csq_tail", 4},
+ {"comm_nic_csq_head", 4},
+ {"comm_nic_crq_baseaddr_l", 4},
+ {"comm_nic_crq_baseaddr_h", 4},
+ {"comm_nic_crq_depth", 4},
+ {"comm_nic_crq_tail", 4},
+ {"comm_nic_crq_head", 4},
+ {"comm_vector0_cmdq_src", 4},
+ {"comm_vector0_cmdq_state", 4},
+ {"comm_cmdq_intr_en", 4},
+ {"comm_cmdq_intr_gen", 4},
+};
+
+const struct hns3_reg_info vf_common_regs[] = {
+ {"misc_vector_base", 4},
+ {"rst_ing", 4},
+ {"gro_en", 4},
+};
+
+const struct hns3_reg_info vf_ring_regs[] = {
+ {"ring_rx_addr_l", 4},
+ {"ring_rx_addr_h", 4},
+ {"ring_rx_bd_num", 4},
+ {"ring_rx_bd_length", 4},
+ {"ring_rx_merge_en", 4},
+ {"ring_rx_tail", 4},
+ {"ring_rx_head", 4},
+ {"ring_rx_fbd_num", 4},
+ {"ring_rx_offset", 4},
+ {"ring_rx_fbd_offset", 4},
+ {"ring_rx_stash", 4},
+ {"ring_rx_bd_err", 4},
+ {"ring_tx_addr_l", 4},
+ {"ring_tx_addr_h", 4},
+ {"ring_tx_bd_num", 4},
+ {"ring_tx_priority", 4},
+ {"ring_tx_tc", 4},
+ {"ring_tx_merge_en", 4},
+ {"ring_tx_tail", 4},
+ {"ring_tx_head", 4},
+ {"ring_tx_fbd_num", 4},
+ {"ring_tx_offset", 4},
+ {"ring_tx_ebd_num", 4},
+ {"ring_tx_ebd_offset", 4},
+ {"ring_tx_bd_err", 4},
+ {"ring_en", 4},
+};
+
+const struct hns3_reg_info vf_tqp_intr_regs[] = {
+ {"tqp_intr_ctrl", 4},
+ {"tqp_intr_gl0", 4},
+ {"tqp_intr_gl1", 4},
+ {"tqp_intr_gl2", 4},
+ {"tqp_intr_rl", 4},
+};
+
+const struct hns3_regs_group pf_regs_groups[] = {
+ [HNS3_TAG_CMDQ] = {"cmdq_regs", pf_cmdq_regs, ARRAY_SIZE(pf_cmdq_regs)},
+ [HNS3_TAG_COMMON] = {"common_regs", pf_common_regs,
+ ARRAY_SIZE(pf_common_regs)},
+ [HNS3_TAG_RING] = {"ring_regs", pf_ring_regs, ARRAY_SIZE(pf_ring_regs)},
+ [HNS3_TAG_TQP_INTR] = {"tqp_intr_regs", pf_tqp_intr_regs,
+ ARRAY_SIZE(pf_tqp_intr_regs)},
+ [HNS3_TAG_QUERY_32_BIT] = {"dfx_32_regs", query_32_bit_regs,
+ ARRAY_SIZE(query_32_bit_regs)},
+ [HNS3_TAG_QUERY_64_BIT] = {"dfx_64_regs", query_64_bit_regs,
+ ARRAY_SIZE(query_64_bit_regs)},
+ [HNS3_TAG_DFX_BIOS_COMMON] = {"dfx_bios_common_regs",
+ dfx_bios_common_regs,
+ ARRAY_SIZE(dfx_bios_common_regs)},
+ [HNS3_TAG_DFX_SSU_0] = {"dfx_ssu_0_regs", dfx_ssu_0_regs,
+ ARRAY_SIZE(dfx_ssu_0_regs)},
+ [HNS3_TAG_DFX_SSU_1] = {"dfx_ssu_1_regs", dfx_ssu_1_regs,
+ ARRAY_SIZE(dfx_ssu_1_regs)},
+ [HNS3_TAG_DFX_IGU_EGU] = {"dfx_igu_egu_regs", dfx_igu_egu_regs,
+ ARRAY_SIZE(dfx_igu_egu_regs)},
+ [HNS3_TAG_DFX_RPU_0] = {"dfx_rpu_0_regs", dfx_rpu_0_regs,
+ ARRAY_SIZE(dfx_rpu_0_regs)},
+ [HNS3_TAG_DFX_RPU_1] = {"dfx_rpu_1_regs", dfx_rpu_1_regs,
+ ARRAY_SIZE(dfx_rpu_1_regs)},
+ [HNS3_TAG_DFX_NCSI] = {"dfx_ncsi_regs", dfx_ncsi_regs,
+ ARRAY_SIZE(dfx_ncsi_regs)},
+ [HNS3_TAG_DFX_RTC] = {"dfx_rtc_regs", dfx_rtc_regs,
+ ARRAY_SIZE(dfx_rtc_regs)},
+ [HNS3_TAG_DFX_PPP] = {"dfx_ppp_regs", dfx_ppp_regs,
+ ARRAY_SIZE(dfx_ppp_regs)},
+ [HNS3_TAG_DFX_RCB] = {"dfx_rcb_regs", dfx_rcb_regs,
+ ARRAY_SIZE(dfx_rcb_regs)},
+ [HNS3_TAG_DFX_TQP] = {"dfx_tqp_regs", dfx_tqp_regs,
+ ARRAY_SIZE(dfx_tqp_regs)},
+ [HNS3_TAG_DFX_SSU_2] = {"dfx_ssu_2_regs", dfx_ssu_2_regs,
+ ARRAY_SIZE(dfx_ssu_2_regs)},
+ [HNS3_TAG_DFX_RPU_TNL] = {"dfx_rpu_tnl", dfx_rpu_0_regs,
+ ARRAY_SIZE(dfx_rpu_0_regs)},
+};
+
+const struct hns3_regs_group vf_regs_groups[] = {
+ [HNS3_TAG_CMDQ] = {"cmdq_regs", vf_cmdq_regs, ARRAY_SIZE(vf_cmdq_regs)},
+ [HNS3_TAG_COMMON] = {"common_regs", vf_common_regs,
+ ARRAY_SIZE(vf_common_regs)},
+ [HNS3_TAG_RING] = {"ring_regs", vf_ring_regs, ARRAY_SIZE(vf_ring_regs)},
+ [HNS3_TAG_TQP_INTR] = {"tqp_intr_regs", vf_tqp_intr_regs,
+ ARRAY_SIZE(vf_tqp_intr_regs)},
+};
+
+static void hns3_dump_reg_hex(const char *regs_name, const u8 *regs_data,
+ u16 value_len, u32 name_max_len)
+{
+ if (strcmp(regs_name, HNS3_REG_RSV_NAME) == 0)
+ return;
+
+ fprintf(stdout, " %-*s : ", name_max_len, regs_name);
+ if (value_len == 4) /* 4 bytes register */
+ fprintf(stdout, "0x%08x\n", *(u32 *)regs_data);
+ if (value_len == 8) /* 8 bytes register */
+ fprintf(stdout, "0x%016llx\n", *(u64 *)regs_data);
+}
+
+static u32 hns3_get_group_regs_name_max_len(const struct hns3_regs_group *group)
+{
+ const struct hns3_reg_info *reg;
+ u32 max_len = 0;
+ u16 i;
+
+ for (i = 0; i < group->regs_count; i++) {
+ reg = &group->regs[i];
+ max_len = strlen(reg->name) > max_len ?
+ strlen(reg->name) : max_len;
+ }
+
+ return max_len;
+}
+
+static const char *hns3_get_group_name(const struct hns3_regs_group *group,
+ u32 tag)
+{
+ static u32 pre_tag = HNS3_TAG_MAX;
+ static char group_name[256];
+ static u32 index;
+
+ if (!hns3_reg_is_repeat_tag_array[tag])
+ return group->group_name;
+
+ if (tag != pre_tag)
+ index = 0;
+
+ pre_tag = tag;
+ sprintf(group_name, "%s_%u", group->group_name, index++);
+ return group_name;
+}
+
+static void hns3_dump_reg_group(const struct hns3_regs_group *group, u32 tag,
+ u32 expected_len, const u8 *regs_data)
+{
+ u32 name_max_len = hns3_get_group_regs_name_max_len(group);
+ const struct hns3_reg_info *reg;
+ u32 dump_offset = 0;
+ u16 i;
+
+ fprintf(stdout, "[%s]\n", hns3_get_group_name(group, tag));
+ for (i = 0; i < group->regs_count && dump_offset < expected_len; i++) {
+ reg = &group->regs[i];
+ hns3_dump_reg_hex(reg->name, regs_data + dump_offset,
+ reg->value_len, name_max_len);
+ dump_offset += reg->value_len;
+ }
+
+ /* the driver may add new register.
+ * In this case, the register name is unknown.
+ * The register can be parsed as unknown:value format.
+ */
+ while (dump_offset < expected_len) {
+ hns3_dump_reg_hex(HNS3_REG_UNKNOW_NAME, regs_data + dump_offset,
+ HNS3_REG_UNKNOW_VALUE_LEN, name_max_len);
+ dump_offset += HNS3_REG_UNKNOW_VALUE_LEN;
+ }
+}
+
+static void hns3_dump_as_groups(const struct hns3_regs_group *groups,
+ const u8 *regs_data, u32 regs_len)
+{
+ u32 tlv_size = sizeof(struct hns3_reg_tlv);
+ const struct hns3_reg_tlv *tlv;
+ u32 dump_offset = 0;
+
+ while (dump_offset < regs_len) {
+ tlv = (const struct hns3_reg_tlv *)(regs_data + dump_offset);
+ hns3_dump_reg_group(&groups[tlv->tag], tlv->tag,
+ tlv->len - tlv_size,
+ regs_data + dump_offset + tlv_size);
+ dump_offset += tlv->len;
+ }
+}
+
+static bool hns3_dump_validate(const u8 *regs_data, u32 regs_len)
+{
+ u32 tlv_size = sizeof(struct hns3_reg_tlv);
+ const struct hns3_reg_tlv *tlv;
+ u32 dump_offset = 0;
+
+ while (dump_offset < regs_len) {
+ tlv = (const struct hns3_reg_tlv *)(regs_data + dump_offset);
+
+ /* register value length is 4 bytes or 8 bytes */
+ if ((tlv->len - tlv_size) % 4)
+ return false;
+
+ if (tlv->tag >= HNS3_TAG_MAX)
+ return false;
+
+ dump_offset += tlv->len;
+ }
+
+ return dump_offset == regs_len;
+}
+
+int hns3_dump_regs(struct ethtool_drvinfo *info __maybe_unused,
+ struct ethtool_regs *regs)
+{
+ const struct hns3_regs_group *groups = pf_regs_groups;
+ u32 header_len = sizeof(struct hns3_reg_header);
+ const struct hns3_reg_header *header;
+
+ /* must contain header and register data */
+ if (regs->len <= header_len)
+ return -ENODATA;
+
+ header = (struct hns3_reg_header *)regs->data;
+ if (header->magic_number != HNS3_REG_MAGIC_NUMBER)
+ return -EOPNOTSUPP;
+
+ if (!hns3_dump_validate(regs->data + header_len,
+ regs->len - header_len))
+ return -EINVAL;
+
+ if (header->is_vf)
+ groups = vf_regs_groups;
+
+ hns3_dump_as_groups(groups, regs->data + header_len,
+ regs->len - header_len);
+ return 0;
+}
diff --git a/internal.h b/internal.h
index b80f77a..4b994f5 100644
--- a/internal.h
+++ b/internal.h
@@ -21,6 +21,9 @@
#include <unistd.h>
#include <endian.h>
#include <sys/ioctl.h>
+#define __UAPI_DEF_IF_IFNAMSIZ 1
+#define __UAPI_DEF_IF_IFMAP 1
+#define __UAPI_DEF_IF_IFREQ 1
#include <linux/if.h>
#include "json_writer.h"
@@ -33,29 +36,12 @@
struct nl_context;
#endif
-/* ethtool.h expects these to be defined by <linux/types.h> */
-#ifndef HAVE_BE_TYPES
-typedef uint16_t __be16;
-typedef uint32_t __be32;
-typedef unsigned long long __be64;
-#endif
-
typedef unsigned long long u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int32_t s32;
-/* ethtool.h epxects __KERNEL_DIV_ROUND_UP to be defined by <linux/kernel.h> */
-#include <linux/kernel.h>
-#ifndef __KERNEL_DIV_ROUND_UP
-#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
-#endif
-
-#ifndef ALTIFNAMSIZ
-#define ALTIFNAMSIZ 128
-#endif
-
#include <linux/ethtool.h>
#include <linux/net_tstamp.h>
@@ -374,6 +360,9 @@
/* VMware vmxnet3 ethernet controller */
int vmxnet3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
+/* hns3 ethernet controller */
+int hns3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
+
/* Rx flow classification */
int rxclass_parse_ruleopts(struct cmd_context *ctx,
struct ethtool_rx_flow_spec *fsp, __u32 *rss_context);
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..e8c5312
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+# added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+AC_DEFUN([AX_APPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+ AS_CASE([" AS_VAR_GET(FLAGS) "],
+ [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+ [
+ AS_VAR_APPEND(FLAGS,[" $1"])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+ ],
+ [
+ AS_VAR_SET(FLAGS,[$1])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..dcabb92
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 5
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/marvell.c b/marvell.c
index d3d570e..3f3aed8 100644
--- a/marvell.c
+++ b/marvell.c
@@ -31,23 +31,23 @@
static void dump_queue(const char *name, const void *a, int rx)
{
struct desc {
- u_int32_t ctl;
- u_int32_t next;
- u_int32_t data_lo;
- u_int32_t data_hi;
- u_int32_t status;
- u_int32_t timestamp;
- u_int16_t csum2;
- u_int16_t csum1;
- u_int16_t csum2_start;
- u_int16_t csum1_start;
- u_int32_t addr_lo;
- u_int32_t addr_hi;
- u_int32_t count_lo;
- u_int32_t count_hi;
- u_int32_t byte_count;
- u_int32_t csr;
- u_int32_t flag;
+ uint32_t ctl;
+ uint32_t next;
+ uint32_t data_lo;
+ uint32_t data_hi;
+ uint32_t status;
+ uint32_t timestamp;
+ uint16_t csum2;
+ uint16_t csum1;
+ uint16_t csum2_start;
+ uint16_t csum1_start;
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t count_lo;
+ uint32_t count_hi;
+ uint32_t byte_count;
+ uint32_t csr;
+ uint32_t flag;
};
const struct desc *d = a;
diff --git a/netlink/channels.c b/netlink/channels.c
index 894c74b..5cae227 100644
--- a/netlink/channels.c
+++ b/netlink/channels.c
@@ -37,15 +37,17 @@
putchar('\n');
printf("Channel parameters for %s:\n", nlctx->devname);
printf("Pre-set maximums:\n");
- show_u32(tb[ETHTOOL_A_CHANNELS_RX_MAX], "RX:\t\t");
- show_u32(tb[ETHTOOL_A_CHANNELS_TX_MAX], "TX:\t\t");
- show_u32(tb[ETHTOOL_A_CHANNELS_OTHER_MAX], "Other:\t\t");
- show_u32(tb[ETHTOOL_A_CHANNELS_COMBINED_MAX], "Combined:\t");
+ show_u32("rx-max", "RX:\t\t", tb[ETHTOOL_A_CHANNELS_RX_MAX]);
+ show_u32("tx-max", "TX:\t\t", tb[ETHTOOL_A_CHANNELS_TX_MAX]);
+ show_u32("other-max", "Other:\t\t", tb[ETHTOOL_A_CHANNELS_OTHER_MAX]);
+ show_u32("combined-max", "Combined:\t",
+ tb[ETHTOOL_A_CHANNELS_COMBINED_MAX]);
printf("Current hardware settings:\n");
- show_u32(tb[ETHTOOL_A_CHANNELS_RX_COUNT], "RX:\t\t");
- show_u32(tb[ETHTOOL_A_CHANNELS_TX_COUNT], "TX:\t\t");
- show_u32(tb[ETHTOOL_A_CHANNELS_OTHER_COUNT], "Other:\t\t");
- show_u32(tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT], "Combined:\t");
+ show_u32("rx", "RX:\t\t", tb[ETHTOOL_A_CHANNELS_RX_COUNT]);
+ show_u32("tx", "TX:\t\t", tb[ETHTOOL_A_CHANNELS_TX_COUNT]);
+ show_u32("other", "Other:\t\t", tb[ETHTOOL_A_CHANNELS_OTHER_COUNT]);
+ show_u32("combined", "Combined:\t",
+ tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]);
return MNL_CB_OK;
}
diff --git a/netlink/coalesce.c b/netlink/coalesce.c
index 15037c2..bc34d3d 100644
--- a/netlink/coalesce.c
+++ b/netlink/coalesce.c
@@ -33,43 +33,71 @@
if (!dev_ok(nlctx))
return err_ret;
+ open_json_object(NULL);
+
if (silent)
- putchar('\n');
- printf("Coalesce parameters for %s:\n", nlctx->devname);
+ show_cr();
+ print_string(PRINT_ANY, "ifname", "Coalesce parameters for %s:\n",
+ nlctx->devname);
show_bool("rx", "Adaptive RX: %s ",
tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX]);
show_bool("tx", "TX: %s\n", tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX]);
- show_u32(tb[ETHTOOL_A_COALESCE_STATS_BLOCK_USECS],
- "stats-block-usecs: ");
- show_u32(tb[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL],
- "sample-interval: ");
- show_u32(tb[ETHTOOL_A_COALESCE_PKT_RATE_LOW], "pkt-rate-low: ");
- show_u32(tb[ETHTOOL_A_COALESCE_PKT_RATE_HIGH], "pkt-rate-high: ");
- putchar('\n');
- show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS], "rx-usecs: ");
- show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES], "rx-frames: ");
- show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS_IRQ], "rx-usecs-irq: ");
- show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ], "rx-frames-irq: ");
- putchar('\n');
- show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS], "tx-usecs: ");
- show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES], "tx-frames: ");
- show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS_IRQ], "tx-usecs-irq: ");
- show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ], "tx-frames-irq: ");
- putchar('\n');
- show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS_LOW], "rx-usecs-low: ");
- show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW], "rx-frame-low: ");
- show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS_LOW], "tx-usecs-low: ");
- show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW], "tx-frame-low: ");
- putchar('\n');
- show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS_HIGH], "rx-usecs-high: ");
- show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH], "rx-frame-high: ");
- show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS_HIGH], "tx-usecs-high: ");
- show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH], "tx-frame-high: ");
- putchar('\n');
+ show_u32("stats-block-usecs", "stats-block-usecs:\t",
+ tb[ETHTOOL_A_COALESCE_STATS_BLOCK_USECS]);
+ show_u32("sample-interval", "sample-interval:\t",
+ tb[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL]);
+ show_u32("pkt-rate-low", "pkt-rate-low:\t\t",
+ tb[ETHTOOL_A_COALESCE_PKT_RATE_LOW]);
+ show_u32("pkt-rate-high", "pkt-rate-high:\t\t",
+ tb[ETHTOOL_A_COALESCE_PKT_RATE_HIGH]);
+ show_cr();
+ show_u32("rx-usecs", "rx-usecs:\t", tb[ETHTOOL_A_COALESCE_RX_USECS]);
+ show_u32("rx-frames", "rx-frames:\t",
+ tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES]);
+ show_u32("rx-usecs-irq", "rx-usecs-irq:\t",
+ tb[ETHTOOL_A_COALESCE_RX_USECS_IRQ]);
+ show_u32("rx-frames-irq", "rx-frames-irq:\t",
+ tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ]);
+ show_cr();
+ show_u32("tx-usecs", "tx-usecs:\t", tb[ETHTOOL_A_COALESCE_TX_USECS]);
+ show_u32("tx-frames", "tx-frames:\t",
+ tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES]);
+ show_u32("tx-usecs-irq", "tx-usecs-irq:\t",
+ tb[ETHTOOL_A_COALESCE_TX_USECS_IRQ]);
+ show_u32("tx-frames-irq", "tx-frames-irq:\t",
+ tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ]);
+ show_cr();
+ show_u32("rx-usecs-low", "rx-usecs-low:\t",
+ tb[ETHTOOL_A_COALESCE_RX_USECS_LOW]);
+ show_u32("rx-frame-low", "rx-frame-low:\t",
+ tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW]);
+ show_u32("tx-usecs-low", "tx-usecs-low:\t",
+ tb[ETHTOOL_A_COALESCE_TX_USECS_LOW]);
+ show_u32("tx-frame-low", "tx-frame-low:\t",
+ tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW]);
+ show_cr();
+ show_u32("rx-usecs-high", "rx-usecs-high:\t",
+ tb[ETHTOOL_A_COALESCE_RX_USECS_HIGH]);
+ show_u32("rx-frame-high", "rx-frame-high:\t",
+ tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH]);
+ show_u32("tx-usecs-high", "tx-usecs-high:\t",
+ tb[ETHTOOL_A_COALESCE_TX_USECS_HIGH]);
+ show_u32("tx-frame-high", "tx-frame-high:\t",
+ tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH]);
+ show_cr();
show_bool("rx", "CQE mode RX: %s ",
tb[ETHTOOL_A_COALESCE_USE_CQE_MODE_RX]);
show_bool("tx", "TX: %s\n", tb[ETHTOOL_A_COALESCE_USE_CQE_MODE_TX]);
- putchar('\n');
+ show_cr();
+ show_u32("tx-aggr-max-bytes", "tx-aggr-max-bytes:\t",
+ tb[ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES]);
+ show_u32("tx-aggr-max-frames", "tx-aggr-max-frames:\t",
+ tb[ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES]);
+ show_u32("tx-aggr-time-usecs", "tx-aggr-time-usecs\t",
+ tb[ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS]);
+ show_cr();
+
+ close_json_object();
return MNL_CB_OK;
}
@@ -92,7 +120,11 @@
ETHTOOL_A_COALESCE_HEADER, 0);
if (ret < 0)
return ret;
- return nlsock_send_get_request(nlsk, coalesce_reply_cb);
+
+ new_json_obj(ctx->json);
+ ret = nlsock_send_get_request(nlsk, coalesce_reply_cb);
+ delete_json_obj();
+ return ret;
}
/* COALESCE_SET */
@@ -242,6 +274,24 @@
.handler = nl_parse_u8bool,
.min_argc = 1,
},
+ {
+ .arg = "tx-aggr-max-bytes",
+ .type = ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES,
+ .handler = nl_parse_direct_u32,
+ .min_argc = 1,
+ },
+ {
+ .arg = "tx-aggr-max-frames",
+ .type = ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES,
+ .handler = nl_parse_direct_u32,
+ .min_argc = 1,
+ },
+ {
+ .arg = "tx-aggr-time-usecs",
+ .type = ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS,
+ .handler = nl_parse_direct_u32,
+ .min_argc = 1,
+ },
{}
};
diff --git a/netlink/desc-ethtool.c b/netlink/desc-ethtool.c
index b3ac64d..661de26 100644
--- a/netlink/desc-ethtool.c
+++ b/netlink/desc-ethtool.c
@@ -158,6 +158,9 @@
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),
+ NLATTR_DESC_U32(ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN),
+ NLATTR_DESC_U32(ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX),
};
static const struct pretty_nla_desc __channels_desc[] = {
@@ -200,6 +203,9 @@
NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL),
NLATTR_DESC_BOOL(ETHTOOL_A_COALESCE_USE_CQE_MODE_TX),
NLATTR_DESC_BOOL(ETHTOOL_A_COALESCE_USE_CQE_MODE_RX),
+ NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES),
+ NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES),
+ NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS),
};
static const struct pretty_nla_desc __pause_stats_desc[] = {
@@ -442,6 +448,54 @@
NLATTR_DESC_U32_ENUM(ETHTOOL_A_PODL_PSE_PW_D_STATUS, pse_pw_d_status),
};
+static const struct pretty_nla_desc __rss_desc[] = {
+ NLATTR_DESC_INVALID(ETHTOOL_A_RSS_UNSPEC),
+ NLATTR_DESC_NESTED(ETHTOOL_A_RSS_HEADER, header),
+ NLATTR_DESC_U32(ETHTOOL_A_RSS_CONTEXT),
+ NLATTR_DESC_U32(ETHTOOL_A_RSS_HFUNC),
+ NLATTR_DESC_BINARY(ETHTOOL_A_RSS_INDIR),
+ 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),
@@ -481,6 +535,12 @@
NLMSG_DESC(ETHTOOL_MSG_MODULE_SET, module),
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);
@@ -524,6 +584,12 @@
NLMSG_DESC(ETHTOOL_MSG_MODULE_GET_REPLY, module),
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 1bb580a..e2d6b71 100644
--- a/netlink/extapi.h
+++ b/netlink/extapi.h
@@ -47,6 +47,14 @@
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);
+int nl_gpse(struct cmd_context *ctx);
+int nl_spse(struct cmd_context *ctx);
void nl_monitor_usage(void);
@@ -114,6 +122,14 @@
#define nl_getmodule NULL
#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
+#define nl_gpse NULL
+#define nl_spse NULL
#endif /* ETHTOOL_ENABLE_NETLINK */
diff --git a/netlink/features.c b/netlink/features.c
index a4dae8f..5711ff4 100644
--- a/netlink/features.c
+++ b/netlink/features.c
@@ -266,7 +266,7 @@
struct sfeatures_context {
bool nothing_changed;
- uint32_t req_mask[0];
+ uint32_t req_mask[];
};
static int find_feature(const char *name,
@@ -534,24 +534,36 @@
nlctx->devname = ctx->devname;
ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_FEATURES_SET,
NLM_F_REQUEST | NLM_F_ACK);
- if (ret < 0)
+ if (ret < 0) {
+ free(sfctx);
return 2;
+ }
if (ethnla_fill_header(msgbuff, ETHTOOL_A_FEATURES_HEADER, ctx->devname,
- ETHTOOL_FLAG_COMPACT_BITSETS))
+ ETHTOOL_FLAG_COMPACT_BITSETS)) {
+ free(sfctx);
return -EMSGSIZE;
+ }
ret = fill_sfeatures_bitmap(nlctx, feature_names);
- if (ret < 0)
+ if (ret < 0) {
+ free(sfctx);
return ret;
+ }
ret = nlsock_sendmsg(nlsk, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ free(sfctx);
return 92;
+ }
ret = nlsock_process_reply(nlsk, sfeatures_reply_cb, nlctx);
if (sfctx->nothing_changed) {
fprintf(stderr, "Could not change any device features\n");
+ free(sfctx);
return nlctx->exit_code ?: 1;
}
- if (ret == 0)
+ if (ret == 0) {
+ free(sfctx);
return 0;
+ }
+ free(sfctx);
return nlctx->exit_code ?: 92;
}
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/netlink.h b/netlink/netlink.h
index f43c1bf..1274a3b 100644
--- a/netlink/netlink.h
+++ b/netlink/netlink.h
@@ -100,12 +100,20 @@
const char *between, const char *after,
const char *if_none);
-static inline void show_u32(const struct nlattr *attr, const char *label)
+static inline void show_u32(const char *key,
+ const char *fmt,
+ const struct nlattr *attr)
{
- if (attr)
- printf("%s%u\n", label, mnl_attr_get_u32(attr));
- else
- printf("%sn/a\n", label);
+ if (is_json_context()) {
+ if (attr)
+ print_uint(PRINT_JSON, key, NULL,
+ mnl_attr_get_u32(attr));
+ } else {
+ if (attr)
+ printf("%s%u\n", fmt, mnl_attr_get_u32(attr));
+ else
+ printf("%sn/a\n", fmt);
+ }
}
static inline const char *u8_to_bool(const uint8_t *val)
@@ -120,7 +128,7 @@
{
if (is_json_context()) {
if (val)
- print_bool(PRINT_JSON, key, NULL, val);
+ print_bool(PRINT_JSON, key, NULL, *val);
} else {
print_string(PRINT_FP, NULL, fmt, u8_to_bool(val));
}
@@ -132,6 +140,12 @@
show_bool_val(key, fmt, attr ? mnl_attr_get_payload(attr) : NULL);
}
+static inline void show_cr(void)
+{
+ if (!is_json_context())
+ putchar('\n');
+}
+
/* misc */
static inline void copy_devname(char *dst, const char *src)
diff --git a/netlink/parser.c b/netlink/parser.c
index f982f22..6f86361 100644
--- a/netlink/parser.c
+++ b/netlink/parser.c
@@ -237,7 +237,7 @@
struct nl_msg_buff *msgbuff, void *dest)
{
const char *arg = *nlctx->argp;
- float meters;
+ float meters = 0.0;
uint32_t cm;
int ret;
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 @@
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 @@
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 @@
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/pse-pd.c b/netlink/pse-pd.c
new file mode 100644
index 0000000..d6faff8
--- /dev/null
+++ b/netlink/pse-pd.c
@@ -0,0 +1,193 @@
+/*
+ * pse.c - netlink implementation of pse commands
+ *
+ * Implementation of "ethtool --show-pse <dev>" and
+ * "ethtool --set-pse <dev> ..."
+ */
+
+#include <errno.h>
+#include <ctype.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "../internal.h"
+#include "../common.h"
+#include "netlink.h"
+#include "parser.h"
+
+/* PSE_GET */
+
+static const char *podl_pse_admin_state_name(u32 val)
+{
+ switch (val) {
+ case ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN:
+ return "unknown";
+ case ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED:
+ return "disabled";
+ case ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED:
+ return "enabled";
+ default:
+ return "unsupported";
+ }
+}
+
+static const char *podl_pse_pw_d_status_name(u32 val)
+{
+ switch (val) {
+ case ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN:
+ return "unknown";
+ case ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED:
+ return "disabled";
+ case ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING:
+ return "searching";
+ case ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING:
+ return "delivering power";
+ case ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP:
+ return "sleep";
+ case ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE:
+ return "idle";
+ case ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR:
+ return "error";
+ default:
+ return "unsupported";
+ }
+}
+
+int pse_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+{
+ const struct nlattr *tb[ETHTOOL_A_PSE_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_PSE_HEADER]);
+ if (!dev_ok(nlctx))
+ return err_ret;
+
+ if (silent)
+ print_nl();
+
+ open_json_object(NULL);
+
+ print_string(PRINT_ANY, "ifname", "PSE attributes for %s:\n",
+ nlctx->devname);
+
+ if (tb[ETHTOOL_A_PODL_PSE_ADMIN_STATE]) {
+ u32 val;
+
+ val = mnl_attr_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_STATE]);
+ print_string(PRINT_ANY, "podl-pse-admin-state",
+ "PoDL PSE Admin State: %s\n",
+ podl_pse_admin_state_name(val));
+ }
+
+ if (tb[ETHTOOL_A_PODL_PSE_PW_D_STATUS]) {
+ u32 val;
+
+ val = mnl_attr_get_u32(tb[ETHTOOL_A_PODL_PSE_PW_D_STATUS]);
+ print_string(PRINT_ANY, "podl-pse-power-detection-status",
+ "PoDL PSE Power Detection Status: %s\n",
+ podl_pse_pw_d_status_name(val));
+ }
+
+ close_json_object();
+
+ return MNL_CB_OK;
+}
+
+int nl_gpse(struct cmd_context *ctx)
+{
+ struct nl_context *nlctx = ctx->nlctx;
+ struct nl_socket *nlsk;
+ int ret;
+
+ if (netlink_cmd_check(ctx, ETHTOOL_MSG_PSE_GET, true))
+ return -EOPNOTSUPP;
+ if (ctx->argc > 0) {
+ fprintf(stderr, "ethtool: unexpected parameter '%s'\n",
+ *ctx->argp);
+ return 1;
+ }
+
+ nlsk = nlctx->ethnl_socket;
+ ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PSE_GET,
+ ETHTOOL_A_PSE_HEADER, 0);
+ if (ret < 0)
+ return ret;
+
+ new_json_obj(ctx->json);
+ ret = nlsock_send_get_request(nlsk, pse_reply_cb);
+ delete_json_obj();
+
+ return ret;
+}
+
+/* PSE_SET */
+
+static const struct lookup_entry_u32 podl_pse_admin_control_values[] = {
+ { .arg = "enable", .val = ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED },
+ { .arg = "disable", .val = ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED },
+ {}
+};
+
+static const struct param_parser spse_params[] = {
+ {
+ .arg = "podl-pse-admin-control",
+ .type = ETHTOOL_A_PODL_PSE_ADMIN_CONTROL,
+ .handler = nl_parse_lookup_u32,
+ .handler_data = podl_pse_admin_control_values,
+ .min_argc = 1,
+ },
+ {}
+};
+
+int nl_spse(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_PSE_SET, false))
+ return -EOPNOTSUPP;
+ if (!ctx->argc) {
+ fprintf(stderr, "ethtool (--set-pse): parameters missing\n");
+ return 1;
+ }
+
+ nlctx->cmd = "--set-pse";
+ 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_PSE_SET,
+ NLM_F_REQUEST | NLM_F_ACK);
+ if (ret < 0)
+ return 2;
+ if (ethnla_fill_header(msgbuff, ETHTOOL_A_PSE_HEADER,
+ ctx->devname, 0))
+ return -EMSGSIZE;
+
+ ret = nl_parser(nlctx, spse_params, NULL, PARSER_GROUP_NONE, NULL);
+ if (ret < 0)
+ return 1;
+
+ ret = nlsock_sendmsg(nlsk, NULL);
+ if (ret < 0)
+ return 83;
+ ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx);
+ if (ret == 0)
+ return 0;
+ else
+ return nlctx->exit_code ?: 83;
+}
diff --git a/netlink/rings.c b/netlink/rings.c
index 6284035..51d28c2 100644
--- a/netlink/rings.c
+++ b/netlink/rings.c
@@ -21,6 +21,9 @@
DECLARE_ATTR_TB_INFO(tb);
struct nl_context *nlctx = data;
unsigned char tcp_hds;
+ char *tcp_hds_fmt;
+ char *tcp_hds_key;
+ char tcp_hds_buf[256];
bool silent;
int err_ret;
int ret;
@@ -34,41 +37,55 @@
if (!dev_ok(nlctx))
return err_ret;
- if (silent)
- putchar('\n');
- printf("Ring parameters for %s:\n", nlctx->devname);
- printf("Pre-set maximums:\n");
- show_u32(tb[ETHTOOL_A_RINGS_RX_MAX], "RX:\t\t");
- show_u32(tb[ETHTOOL_A_RINGS_RX_MINI_MAX], "RX Mini:\t");
- show_u32(tb[ETHTOOL_A_RINGS_RX_JUMBO_MAX], "RX Jumbo:\t");
- show_u32(tb[ETHTOOL_A_RINGS_TX_MAX], "TX:\t\t");
- printf("Current hardware settings:\n");
- show_u32(tb[ETHTOOL_A_RINGS_RX], "RX:\t\t");
- show_u32(tb[ETHTOOL_A_RINGS_RX_MINI], "RX Mini:\t");
- show_u32(tb[ETHTOOL_A_RINGS_RX_JUMBO], "RX Jumbo:\t");
- show_u32(tb[ETHTOOL_A_RINGS_TX], "TX:\t\t");
- show_u32(tb[ETHTOOL_A_RINGS_RX_BUF_LEN], "RX Buf Len:\t\t");
- show_u32(tb[ETHTOOL_A_RINGS_CQE_SIZE], "CQE Size:\t\t");
- show_bool("tx-push", "TX Push:\t%s\n", tb[ETHTOOL_A_RINGS_TX_PUSH]);
+ open_json_object(NULL);
+ if (silent)
+ show_cr();
+ print_string(PRINT_ANY, "ifname", "Ring parameters for %s:\n",
+ nlctx->devname);
+ print_string(PRINT_FP, NULL, "Pre-set maximums:\n", NULL);
+ show_u32("rx-max", "RX:\t\t\t", tb[ETHTOOL_A_RINGS_RX_MAX]);
+ show_u32("rx-mini-max", "RX Mini:\t\t", tb[ETHTOOL_A_RINGS_RX_MINI_MAX]);
+ show_u32("rx-jumbo-max", "RX Jumbo:\t\t",
+ tb[ETHTOOL_A_RINGS_RX_JUMBO_MAX]);
+ show_u32("tx-max", "TX:\t\t\t", tb[ETHTOOL_A_RINGS_TX_MAX]);
+ show_u32("tx-push-buff-max-len", "TX push buff len:\t",
+ tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX]);
+ print_string(PRINT_FP, NULL, "Current hardware settings:\n", NULL);
+ show_u32("rx", "RX:\t\t\t", tb[ETHTOOL_A_RINGS_RX]);
+ show_u32("rx-mini", "RX Mini:\t\t", tb[ETHTOOL_A_RINGS_RX_MINI]);
+ show_u32("rx-jumbo", "RX Jumbo:\t\t", tb[ETHTOOL_A_RINGS_RX_JUMBO]);
+ show_u32("tx", "TX:\t\t\t", tb[ETHTOOL_A_RINGS_TX]);
+ show_u32("rx-buf-len", "RX Buf Len:\t\t", tb[ETHTOOL_A_RINGS_RX_BUF_LEN]);
+ show_u32("cqe-size", "CQE Size:\t\t", tb[ETHTOOL_A_RINGS_CQE_SIZE]);
+ show_bool("tx-push", "TX Push:\t\t%s\n", tb[ETHTOOL_A_RINGS_TX_PUSH]);
+ show_bool("rx-push", "RX Push:\t\t%s\n", tb[ETHTOOL_A_RINGS_RX_PUSH]);
+ show_u32("tx-push-buf-len", "TX push buff len:\t",
+ tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN]);
+
+ tcp_hds_fmt = "TCP data split:\t\t%s\n";
+ tcp_hds_key = "tcp-data-split";
tcp_hds = tb[ETHTOOL_A_RINGS_TCP_DATA_SPLIT] ?
mnl_attr_get_u8(tb[ETHTOOL_A_RINGS_TCP_DATA_SPLIT]) : 0;
- printf("TCP data split:\t");
switch (tcp_hds) {
case ETHTOOL_TCP_DATA_SPLIT_UNKNOWN:
- printf("n/a\n");
+ print_string(PRINT_FP, tcp_hds_key, tcp_hds_fmt, "n/a");
break;
case ETHTOOL_TCP_DATA_SPLIT_DISABLED:
- printf("off\n");
+ print_string(PRINT_ANY, tcp_hds_key, tcp_hds_fmt, "off");
break;
case ETHTOOL_TCP_DATA_SPLIT_ENABLED:
- printf("on\n");
+ print_string(PRINT_ANY, tcp_hds_key, tcp_hds_fmt, "on");
break;
default:
- printf("unknown(%d)\n", tcp_hds);
+ snprintf(tcp_hds_buf, sizeof(tcp_hds_buf),
+ "unknown(%d)\n", tcp_hds);
+ print_string(PRINT_ANY, tcp_hds_key, tcp_hds_fmt, tcp_hds_buf);
break;
}
+ close_json_object();
+
return MNL_CB_OK;
}
@@ -90,7 +107,11 @@
ETHTOOL_A_RINGS_HEADER, 0);
if (ret < 0)
return ret;
- return nlsock_send_get_request(nlsk, rings_reply_cb);
+
+ new_json_obj(ctx->json);
+ ret = nlsock_send_get_request(nlsk, rings_reply_cb);
+ delete_json_obj();
+ return ret;
}
/* RINGS_SET */
@@ -121,6 +142,12 @@
.min_argc = 1,
},
{
+ .arg = "tx-push-buf-len",
+ .type = ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
+ .handler = nl_parse_direct_u32,
+ .min_argc = 1,
+ },
+ {
.arg = "rx-buf-len",
.type = ETHTOOL_A_RINGS_RX_BUF_LEN,
.handler = nl_parse_direct_u32,
@@ -138,6 +165,12 @@
.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/rss.c b/netlink/rss.c
new file mode 100644
index 0000000..4ad6065
--- /dev/null
+++ b/netlink/rss.c
@@ -0,0 +1,230 @@
+/*
+ * rss.c - netlink implementation of RSS context commands
+ *
+ * Implementation of "ethtool -x <dev>"
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "../internal.h"
+#include "../common.h"
+#include "netlink.h"
+#include "strset.h"
+#include "parser.h"
+
+struct cb_args {
+ struct nl_context *nlctx;
+ u32 num_rings;
+};
+
+void dump_json_rss_info(struct cmd_context *ctx, u32 *indir_table,
+ u32 indir_size, u8 *hkey, u32 hkey_size,
+ const struct stringset *hash_funcs, u8 hfunc)
+{
+ unsigned int i;
+
+ open_json_object(NULL);
+ print_string(PRINT_JSON, "ifname", NULL, ctx->devname);
+ if (indir_size) {
+ open_json_array("rss-indirection-table", NULL);
+ for (i = 0; i < indir_size; i++)
+ print_uint(PRINT_JSON, NULL, NULL, indir_table[i]);
+ close_json_array("\n");
+ }
+
+ if (hkey_size) {
+ open_json_array("rss-hash-key", NULL);
+ for (i = 0; i < hkey_size; i++)
+ print_uint(PRINT_JSON, NULL, NULL, (u8)hkey[i]);
+ close_json_array("\n");
+ }
+
+ if (hfunc) {
+ for (i = 0; i < get_count(hash_funcs); i++) {
+ if (hfunc & (1 << i)) {
+ print_string(PRINT_JSON, "rss-hash-function",
+ NULL, get_string(hash_funcs, i));
+ break;
+ }
+ }
+ }
+
+ close_json_object();
+}
+
+int get_channels_cb(const struct nlmsghdr *nlhdr, void *data)
+{
+ const struct nlattr *tb[ETHTOOL_A_CHANNELS_MAX + 1] = {};
+ DECLARE_ATTR_TB_INFO(tb);
+ struct cb_args *args = data;
+ struct nl_context *nlctx = args->nlctx;
+ 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_CHANNELS_HEADER]);
+ if (!dev_ok(nlctx))
+ return err_ret;
+ if (tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT])
+ args->num_rings = mnl_attr_get_u32(tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]);
+ if (tb[ETHTOOL_A_CHANNELS_RX_COUNT])
+ args->num_rings += mnl_attr_get_u32(tb[ETHTOOL_A_CHANNELS_RX_COUNT]);
+ return MNL_CB_OK;
+}
+
+int rss_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+{
+ const struct nlattr *tb[ETHTOOL_A_RSS_MAX + 1] = {};
+ unsigned int indir_bytes = 0, hkey_bytes = 0;
+ DECLARE_ATTR_TB_INFO(tb);
+ struct cb_args *args = data;
+ struct nl_context *nlctx = args->nlctx;
+ const struct stringset *hash_funcs;
+ u32 rss_hfunc = 0, indir_size;
+ u32 *indir_table = NULL;
+ u8 *hkey = NULL;
+ 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_RSS_HEADER]);
+ if (!dev_ok(nlctx))
+ return err_ret;
+
+ show_cr();
+
+ if (tb[ETHTOOL_A_RSS_HFUNC])
+ rss_hfunc = mnl_attr_get_u32(tb[ETHTOOL_A_RSS_HFUNC]);
+
+ if (tb[ETHTOOL_A_RSS_INDIR]) {
+ indir_bytes = mnl_attr_get_payload_len(tb[ETHTOOL_A_RSS_INDIR]);
+ indir_table = mnl_attr_get_payload(tb[ETHTOOL_A_RSS_INDIR]);
+ }
+
+ if (tb[ETHTOOL_A_RSS_HKEY]) {
+ hkey_bytes = mnl_attr_get_payload_len(tb[ETHTOOL_A_RSS_HKEY]);
+ hkey = mnl_attr_get_payload(tb[ETHTOOL_A_RSS_HKEY]);
+ }
+
+ /* Fetch RSS hash functions and their status and print */
+ if (!nlctx->is_monitor) {
+ ret = netlink_init_ethnl2_socket(nlctx);
+ if (ret < 0)
+ return MNL_CB_ERROR;
+ }
+ hash_funcs = global_stringset(ETH_SS_RSS_HASH_FUNCS,
+ nlctx->ethnl2_socket);
+
+ ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
+ if (ret < 0)
+ return silent ? MNL_CB_OK : MNL_CB_ERROR;
+
+ nlctx->devname = get_dev_name(tb[ETHTOOL_A_RSS_HEADER]);
+ if (!dev_ok(nlctx))
+ return MNL_CB_OK;
+
+ /* Fetch ring count info into args->num_rings */
+ ret = nlsock_prep_get_request(nlctx->ethnl2_socket,
+ ETHTOOL_MSG_CHANNELS_GET,
+ ETHTOOL_A_CHANNELS_HEADER, 0);
+ if (ret < 0)
+ return MNL_CB_ERROR;
+
+ ret = nlsock_sendmsg(nlctx->ethnl2_socket, NULL);
+ if (ret < 0)
+ return MNL_CB_ERROR;
+
+ ret = nlsock_process_reply(nlctx->ethnl2_socket, get_channels_cb, args);
+ if (ret < 0)
+ return MNL_CB_ERROR;
+
+ indir_size = indir_bytes / sizeof(u32);
+ if (is_json_context()) {
+ dump_json_rss_info(nlctx->ctx, (u32 *)indir_table, indir_size,
+ hkey, hkey_bytes, hash_funcs, rss_hfunc);
+ } else {
+ print_indir_table(nlctx->ctx, args->num_rings,
+ indir_size, (u32 *)indir_table);
+ print_rss_hkey(hkey, hkey_bytes);
+ printf("RSS hash function:\n");
+ if (!rss_hfunc) {
+ printf(" Operation not supported\n");
+ return 0;
+ }
+ for (unsigned int i = 0; i < get_count(hash_funcs); i++) {
+ printf(" %s: %s\n", get_string(hash_funcs, i),
+ (rss_hfunc & (1 << i)) ? "on" : "off");
+ }
+ }
+
+ return MNL_CB_OK;
+}
+
+/* RSS_GET */
+static const struct param_parser grss_params[] = {
+ {
+ .arg = "context",
+ .type = ETHTOOL_A_RSS_CONTEXT,
+ .handler = nl_parse_direct_u32,
+ .min_argc = 1,
+ },
+ {}
+};
+
+int nl_grss(struct cmd_context *ctx)
+{
+ struct nl_context *nlctx = ctx->nlctx;
+ struct nl_socket *nlsk = nlctx->ethnl_socket;
+ struct nl_msg_buff *msgbuff;
+ struct cb_args args = {};
+ int ret;
+
+ nlctx->cmd = "-x";
+ nlctx->argp = ctx->argp;
+ nlctx->argc = ctx->argc;
+ nlctx->devname = ctx->devname;
+ nlsk = nlctx->ethnl_socket;
+ msgbuff = &nlsk->msgbuff;
+
+ if (netlink_cmd_check(ctx, ETHTOOL_MSG_RSS_GET, true))
+ return -EOPNOTSUPP;
+
+ ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_RSS_GET,
+ NLM_F_REQUEST | NLM_F_ACK);
+ if (ret < 0)
+ return 1;
+
+ if (ethnla_fill_header(msgbuff, ETHTOOL_A_RSS_HEADER,
+ ctx->devname, 0))
+ return -EMSGSIZE;
+
+ ret = nl_parser(nlctx, grss_params, NULL, PARSER_GROUP_NONE, NULL);
+ if (ret < 0)
+ goto err;
+
+ ret = nlsock_sendmsg(nlsk, NULL);
+ if (ret < 0)
+ goto err;
+
+ args.nlctx = nlctx;
+ new_json_obj(ctx->json);
+ ret = nlsock_process_reply(nlsk, rss_reply_cb, &args);
+ delete_json_obj();
+
+ if (ret == 0)
+ return 0;
+err:
+ return nlctx->exit_code ?: 1;
+}
diff --git a/netlink/settings.c b/netlink/settings.c
index ea86e36..a506618 100644
--- a/netlink/settings.c
+++ b/netlink/settings.c
@@ -5,6 +5,7 @@
*/
#include <errno.h>
+#include <inttypes.h>
#include <string.h>
#include <stdio.h>
@@ -165,6 +166,15 @@
[ETHTOOL_LINK_MODE_100baseFX_Half_BIT] = __HALF_DUPLEX(100),
[ETHTOOL_LINK_MODE_100baseFX_Full_BIT] = __REAL(100),
[ETHTOOL_LINK_MODE_10baseT1L_Full_BIT] = __REAL(10),
+ [ETHTOOL_LINK_MODE_800000baseCR8_Full_BIT] = __REAL(800000),
+ [ETHTOOL_LINK_MODE_800000baseKR8_Full_BIT] = __REAL(800000),
+ [ETHTOOL_LINK_MODE_800000baseDR8_Full_BIT] = __REAL(800000),
+ [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);
@@ -772,6 +782,13 @@
}
}
+ if (tb[ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT]) {
+ uint32_t val;
+
+ val = mnl_attr_get_u32(tb[ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT]);
+ printf("\tLink Down Events: %u\n", val);
+ }
+
return MNL_CB_OK;
}
@@ -882,12 +899,84 @@
return MNL_CB_OK;
}
-static int gset_request(struct nl_socket *nlsk, uint8_t msg_type,
- uint16_t hdr_attr, mnl_cb_t cb)
+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;
- ret = nlsock_prep_get_request(nlsk, msg_type, hdr_attr, 0);
+ 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 cmd_context *ctx, uint8_t msg_type,
+ uint16_t hdr_attr, mnl_cb_t cb)
+{
+ struct nl_context *nlctx = ctx->nlctx;
+ struct nl_socket *nlsk = nlctx->ethnl_socket;
+ u32 flags;
+ int ret;
+
+ if (netlink_cmd_check(ctx, msg_type, true))
+ return 0;
+
+ flags = get_stats_flag(nlctx, msg_type, hdr_attr);
+
+ ret = nlsock_prep_get_request(nlsk, msg_type, hdr_attr, flags);
if (ret < 0)
return ret;
return nlsock_send_get_request(nlsk, cb);
@@ -895,10 +984,9 @@
int nl_gset(struct cmd_context *ctx)
{
- struct nl_context *nlctx = ctx->nlctx;
- struct nl_socket *nlsk = nlctx->ethnl_socket;
int ret;
+ /* Check for the base set of commands */
if (netlink_cmd_check(ctx, ETHTOOL_MSG_LINKMODES_GET, true) ||
netlink_cmd_check(ctx, ETHTOOL_MSG_LINKINFO_GET, true) ||
netlink_cmd_check(ctx, ETHTOOL_MSG_WOL_GET, true) ||
@@ -906,39 +994,48 @@
netlink_cmd_check(ctx, ETHTOOL_MSG_LINKSTATE_GET, true))
return -EOPNOTSUPP;
- nlctx->suppress_nlerr = 1;
+ ctx->nlctx->suppress_nlerr = 1;
- ret = gset_request(nlsk, ETHTOOL_MSG_LINKMODES_GET,
+ ret = gset_request(ctx, ETHTOOL_MSG_LINKMODES_GET,
ETHTOOL_A_LINKMODES_HEADER, linkmodes_reply_cb);
if (ret == -ENODEV)
return ret;
- ret = gset_request(nlsk, ETHTOOL_MSG_LINKINFO_GET,
+ ret = gset_request(ctx, ETHTOOL_MSG_LINKINFO_GET,
ETHTOOL_A_LINKINFO_HEADER, linkinfo_reply_cb);
if (ret == -ENODEV)
return ret;
- ret = gset_request(nlsk, ETHTOOL_MSG_WOL_GET, ETHTOOL_A_WOL_HEADER,
+ ret = gset_request(ctx, ETHTOOL_MSG_WOL_GET, ETHTOOL_A_WOL_HEADER,
wol_reply_cb);
if (ret == -ENODEV)
return ret;
- ret = gset_request(nlsk, ETHTOOL_MSG_DEBUG_GET, ETHTOOL_A_DEBUG_HEADER,
+ ret = gset_request(ctx, ETHTOOL_MSG_PLCA_GET_CFG,
+ ETHTOOL_A_PLCA_HEADER, plca_cfg_reply_cb);
+ if (ret == -ENODEV)
+ return ret;
+
+ ret = gset_request(ctx, ETHTOOL_MSG_DEBUG_GET, ETHTOOL_A_DEBUG_HEADER,
debug_reply_cb);
if (ret == -ENODEV)
return ret;
- ret = gset_request(nlsk, ETHTOOL_MSG_LINKSTATE_GET,
+ ret = gset_request(ctx, ETHTOOL_MSG_LINKSTATE_GET,
ETHTOOL_A_LINKSTATE_HEADER, linkstate_reply_cb);
if (ret == -ENODEV)
return ret;
- if (!nlctx->no_banner) {
+ ret = gset_request(ctx, ETHTOOL_MSG_PLCA_GET_STATUS,
+ ETHTOOL_A_PLCA_HEADER, plca_status_reply_cb);
+ if (ret == -ENODEV)
+ return ret;
+
+ if (!ctx->nlctx->no_banner) {
printf("No data available\n");
return 75;
}
-
return 0;
}
@@ -992,7 +1089,7 @@
.force_hex = true,
};
-static const struct lookup_entry_u32 duplex_values[] = {
+static const struct lookup_entry_u8 duplex_values[] = {
{ .arg = "half", .val = DUPLEX_HALF },
{ .arg = "full", .val = DUPLEX_FULL },
{}
@@ -1245,6 +1342,9 @@
nlctx->devname = ctx->devname;
ret = nl_parser(nlctx, sset_params, NULL, PARSER_GROUP_MSG, msgbuffs);
+ if (ret == -EOPNOTSUPP)
+ return ret;
+
if (ret < 0) {
ret = 1;
goto out_free;
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 @@
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 @@
.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/qsfp.c b/qsfp.c
index 1fe5de1..5a535c5 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -872,6 +872,35 @@
}
}
+static void sff8636_show_signals(const struct sff8636_memory_map *map)
+{
+ unsigned int v;
+
+ /* There appears to be no Rx LOS support bit, use Tx for both */
+ if (map->page_00h[SFF8636_OPTION_4_OFFSET] & SFF8636_O4_TX_LOS) {
+ v = map->lower_memory[SFF8636_LOS_AW_OFFSET] & 0xf;
+ sff_show_lane_status("Rx loss of signal", 4, "Yes", "No", v);
+ v = map->lower_memory[SFF8636_LOS_AW_OFFSET] >> 4;
+ sff_show_lane_status("Tx loss of signal", 4, "Yes", "No", v);
+ }
+
+ v = map->lower_memory[SFF8636_LOL_AW_OFFSET] & 0xf;
+ if (map->page_00h[SFF8636_OPTION_3_OFFSET] & SFF8636_O3_RX_LOL)
+ sff_show_lane_status("Rx loss of lock", 4, "Yes", "No", v);
+
+ v = map->lower_memory[SFF8636_LOL_AW_OFFSET] >> 4;
+ if (map->page_00h[SFF8636_OPTION_3_OFFSET] & SFF8636_O3_TX_LOL)
+ sff_show_lane_status("Tx loss of lock", 4, "Yes", "No", v);
+
+ v = map->lower_memory[SFF8636_FAULT_AW_OFFSET] & 0xf;
+ if (map->page_00h[SFF8636_OPTION_4_OFFSET] & SFF8636_O4_TX_FAULT)
+ sff_show_lane_status("Tx fault", 4, "Yes", "No", v);
+
+ v = map->lower_memory[SFF8636_FAULT_AW_OFFSET] >> 4;
+ if (map->page_00h[SFF8636_OPTION_2_OFFSET] & SFF8636_O2_TX_EQ_AUTO)
+ sff_show_lane_status("Tx adaptive eq fault", 4, "Yes", "No", v);
+}
+
static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
{
sff8636_show_ext_identifier(map);
@@ -905,6 +934,7 @@
SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
sff_show_revision_compliance(map->lower_memory,
SFF8636_REV_COMPLIANCE_OFFSET);
+ sff8636_show_signals(map);
}
static void sff8636_show_all_common(const struct sff8636_memory_map *map)
diff --git a/qsfp.h b/qsfp.h
index aabf09f..9f0cb0f 100644
--- a/qsfp.h
+++ b/qsfp.h
@@ -55,6 +55,8 @@
#define SFF8636_TX2_FAULT_AW (1 << 1)
#define SFF8636_TX1_FAULT_AW (1 << 0)
+#define SFF8636_LOL_AW_OFFSET 0x05
+
/* Module Monitor Interrupt Flags - 6-8 */
#define SFF8636_TEMP_AW_OFFSET 0x06
#define SFF8636_TEMP_HALARM_STATUS (1 << 7)
@@ -525,9 +527,15 @@
/* 56h-5Fh reserved */
#define SFF8636_OPTION_2_OFFSET 0xC1
+/* Tx input equalizers auto-adaptive */
+#define SFF8636_O2_TX_EQ_AUTO (1 << 3)
/* Rx output amplitude */
#define SFF8636_O2_RX_OUTPUT_AMP (1 << 0)
#define SFF8636_OPTION_3_OFFSET 0xC2
+/* Tx CDR Loss of Lock */
+#define SFF8636_O3_TX_LOL (1 << 5)
+/* Rx CDR Loss of Lock */
+#define SFF8636_O3_RX_LOL (1 << 4)
/* Rx Squelch Disable */
#define SFF8636_O3_RX_SQL_DSBL (1 << 3)
/* Rx Output Disable capable */
diff --git a/rxclass.c b/rxclass.c
index 6cf81fd..f17e3a5 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -446,7 +446,7 @@
* If loc rolls over it should be greater than or equal to rmgr->size
* and as such we know we have reached the end of the list.
*/
- if (!~(rmgr->slot[slot_num] | (~1UL << rmgr->size % BITS_PER_LONG))) {
+ if (!~(rmgr->slot[slot_num] | (~1UL << loc % BITS_PER_LONG))) {
loc -= 1 + (loc % BITS_PER_LONG);
slot_num--;
}
@@ -598,7 +598,7 @@
else if (loc & RX_CLS_LOC_SPECIAL)
printf("Added rule with ID %d\n", nfccmd.fs.location);
- return 0;
+ return err;
}
int rxclass_rule_del(struct cmd_context *ctx, __u32 loc)
diff --git a/scripts/ethtool-import-uapi b/scripts/ethtool-import-uapi
new file mode 100755
index 0000000..a04a9c9
--- /dev/null
+++ b/scripts/ethtool-import-uapi
@@ -0,0 +1,67 @@
+#!/bin/bash -e
+#
+# ethtool-import-uapi [commit]
+#
+# Imports sanitized copies of kernel uapi headers from <commit> (can be
+# a commit id, a tag or a branch name). If the argument is omitted,
+# commit currently checked out in the kernel repository is used.
+
+sn="${0##*/}"
+export ARCH="x86_64"
+mkopt="-j$(nproc)" || mkopt=''
+
+if [ ! -d "$LINUX_GIT" ]; then
+ echo "${sn}: please set LINUX_GIT to the location of kernel git" >&2
+ exit 1
+fi
+
+pushd "$LINUX_GIT"
+if [ -n "$1" ]; then
+ git checkout "$1"
+fi
+desc=$(git describe --exact-match 2>/dev/null \
+ || git show -s --abbrev=12 --pretty='commit %h')
+kobj=$(mktemp -d)
+make $mkopt O="$kobj" allmodconfig
+make $mkopt O="$kobj" prepare
+make $mkopt O="$kobj" INSTALL_HDR_PATH="${kobj}/hdr" headers_install
+popd
+
+pushd uapi
+find . -type f -name '*.h' -exec cp -v "${kobj}/hdr/include/{}" {} \;
+
+go_on=true
+while $go_on; do
+ go_on=false
+ while read f; do
+ if [ "${f#asm/}" != "$f" ]; then
+ # skip architecture dependent asm/ headers
+ continue
+ fi
+ if [ -f "$f" ]; then
+ # already present
+ continue
+ fi
+ if [ ! -f "${kobj}/hdr/include/${f}" ]; then
+ # not a kernel header
+ continue
+ fi
+ echo "+ add $f"
+ go_on=true
+ mkdir -p "${f%/*}"
+ cp "${kobj}/hdr/include/${f}" "${f}"
+ done < <(
+ find . -type f -name '*.[ch]' -exec sed -nre '\_^[[:blank:]]*#include[[:blank:]]<.+>_ { s_^[[:blank:]]*#include[[:blank:]]<([^>]*)>.*$_\1_ ; p }' {} \; \
+ | LC_ALL=C sort -u
+ )
+done
+popd
+rm -rf "$kobj"
+
+git add uapi
+git commit -s -F - <<EOT
+update UAPI header copies
+
+Update to kernel ${desc}.
+
+EOT
diff --git a/sff-common.c b/sff-common.c
index e951cf1..a5c1510 100644
--- a/sff-common.c
+++ b/sff-common.c
@@ -53,6 +53,23 @@
printf("\n");
}
+void sff_show_lane_status(const char *name, unsigned int lane_cnt,
+ const char *yes, const char *no, unsigned int value)
+{
+ printf("\t%-41s : ", name);
+ if (!value) {
+ printf("None\n");
+ return;
+ }
+
+ printf("[");
+ while (lane_cnt--) {
+ printf(" %s%c", value & 1 ? yes : no, lane_cnt ? ',': ' ');
+ value >>= 1;
+ }
+ printf("]\n");
+}
+
void sff8024_show_oui(const __u8 *id, int id_offset)
{
printf("\t%-41s : %02x:%02x:%02x\n", "Vendor OUI",
diff --git a/sff-common.h b/sff-common.h
index dd12dda..57bcc4a 100644
--- a/sff-common.h
+++ b/sff-common.h
@@ -198,6 +198,8 @@
const char *unit);
void sff_show_ascii(const __u8 *id, unsigned int first_reg,
unsigned int last_reg, const char *name);
+void sff_show_lane_status(const char *name, unsigned int lane_cnt,
+ const char *yes, const char *no, unsigned int value);
void sff_show_thresholds(struct sff_diags sd);
void sff8024_show_oui(const __u8 *id, int id_offset);
diff --git a/shell-completion/bash/ethtool b/shell-completion/bash/ethtool
index 46334b5..99c5f6f 100644
--- a/shell-completion/bash/ethtool
+++ b/shell-completion/bash/ethtool
@@ -254,6 +254,9 @@
[tx-usecs-high]=1
[tx-usecs-irq]=1
[tx-usecs-low]=1
+ [tx-aggr-max-bytes]=1
+ [tx-aggr-max-frames]=1
+ [tx-aggr-time-usecs]=1
)
case "$prev" in
diff --git a/uapi/linux/const.h b/uapi/linux/const.h
new file mode 100644
index 0000000..1eb84b5
--- /dev/null
+++ b/uapi/linux/const.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* const.h: Macros for dealing with constants. */
+
+#ifndef _LINUX_CONST_H
+#define _LINUX_CONST_H
+
+/* Some constant macros are used in both assembler and
+ * C code. Therefore we cannot annotate them always with
+ * 'UL' and other type specifiers unilaterally. We
+ * use the following macros to deal with this.
+ *
+ * Similarly, _AT() will cast an expression with a type in C, but
+ * leave it unchanged in asm.
+ */
+
+#ifdef __ASSEMBLY__
+#define _AC(X,Y) X
+#define _AT(T,X) X
+#else
+#define __AC(X,Y) (X##Y)
+#define _AC(X,Y) __AC(X,Y)
+#define _AT(T,X) ((T)(X))
+#endif
+
+#define _UL(x) (_AC(x, UL))
+#define _ULL(x) (_AC(x, ULL))
+
+#define _BITUL(x) (_UL(1) << (x))
+#define _BITULL(x) (_ULL(1) << (x))
+
+#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1)
+#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#endif /* _LINUX_CONST_H */
diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h
index f1f94f7..1d0731b 100644
--- a/uapi/linux/ethtool.h
+++ b/uapi/linux/ethtool.h
@@ -157,8 +157,10 @@
* in its bus driver structure (e.g. pci_driver::name). Must
* not be an empty string.
* @version: Driver version string; may be an empty string
- * @fw_version: Firmware version string; may be an empty string
- * @erom_version: Expansion ROM version string; may be an empty string
+ * @fw_version: Firmware version string; driver defined; may be an
+ * empty string
+ * @erom_version: Expansion ROM version string; driver defined; may be
+ * an empty string
* @bus_info: Device bus address. This should match the dev_name()
* string for the underlying bus device, if there is one. May be
* an empty string.
@@ -177,10 +179,6 @@
*
* Users can use the %ETHTOOL_GSSET_INFO command to get the number of
* strings in any string set (from Linux 2.6.34).
- *
- * Drivers should set at most @driver, @version, @fw_version and
- * @bus_info in their get_drvinfo() implementation. The ethtool
- * core fills in the other fields using other driver operations.
*/
struct ethtool_drvinfo {
__u32 cmd;
@@ -712,6 +710,24 @@
};
/**
+ * 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
@@ -780,6 +796,31 @@
};
/**
+ * 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
@@ -1183,7 +1224,7 @@
__u32 rule_cnt;
__u32 rss_context;
};
- __u32 rule_locs[0];
+ __u32 rule_locs[];
};
@@ -1735,6 +1776,16 @@
ETHTOOL_LINK_MODE_100baseFX_Half_BIT = 90,
ETHTOOL_LINK_MODE_100baseFX_Full_BIT = 91,
ETHTOOL_LINK_MODE_10baseT1L_Full_BIT = 92,
+ ETHTOOL_LINK_MODE_800000baseCR8_Full_BIT = 93,
+ ETHTOOL_LINK_MODE_800000baseKR8_Full_BIT = 94,
+ ETHTOOL_LINK_MODE_800000baseDR8_Full_BIT = 95,
+ 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
};
@@ -1846,6 +1897,7 @@
#define SPEED_100000 100000
#define SPEED_200000 200000
#define SPEED_400000 400000
+#define SPEED_800000 800000
#define SPEED_UNKNOWN -1
diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h
index ed46d35..a8b0d79 100644
--- a/uapi/linux/ethtool_netlink.h
+++ b/uapi/linux/ethtool_netlink.h
@@ -51,6 +51,12 @@
ETHTOOL_MSG_MODULE_SET,
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,
@@ -97,6 +103,12 @@
ETHTOOL_MSG_MODULE_GET_REPLY,
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,
@@ -262,6 +274,7 @@
ETHTOOL_A_LINKSTATE_SQI_MAX, /* u32 */
ETHTOOL_A_LINKSTATE_EXT_STATE, /* u8 */
ETHTOOL_A_LINKSTATE_EXT_SUBSTATE, /* u8 */
+ ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT, /* u32 */
/* add new constants above here */
__ETHTOOL_A_LINKSTATE_CNT,
@@ -343,6 +356,9 @@
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 */
+ ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN, /* u32 */
+ ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX, /* u32 */
/* add new constants above here */
__ETHTOOL_A_RINGS_CNT,
@@ -397,6 +413,9 @@
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,
@@ -412,6 +431,7 @@
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,
@@ -728,6 +748,8 @@
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)
@@ -761,7 +783,7 @@
/* add new constants above here */
__ETHTOOL_A_STATS_GRP_CNT,
- ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_CNT - 1)
+ ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_GRP_CNT - 1)
};
enum {
@@ -879,6 +901,80 @@
ETHTOOL_A_PSE_MAX = (__ETHTOOL_A_PSE_CNT - 1)
};
+enum {
+ ETHTOOL_A_RSS_UNSPEC,
+ ETHTOOL_A_RSS_HEADER,
+ ETHTOOL_A_RSS_CONTEXT, /* u32 */
+ ETHTOOL_A_RSS_HFUNC, /* u32 */
+ ETHTOOL_A_RSS_INDIR, /* binary */
+ ETHTOOL_A_RSS_HKEY, /* binary */
+
+ __ETHTOOL_A_RSS_CNT,
+ 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/hdlc/ioctl.h b/uapi/linux/hdlc/ioctl.h
new file mode 100644
index 0000000..b06341a
--- /dev/null
+++ b/uapi/linux/hdlc/ioctl.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __HDLC_IOCTL_H__
+#define __HDLC_IOCTL_H__
+
+
+#define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */
+
+#define CLOCK_DEFAULT 0 /* Default setting */
+#define CLOCK_EXT 1 /* External TX and RX clock - DTE */
+#define CLOCK_INT 2 /* Internal TX and RX clock - DCE */
+#define CLOCK_TXINT 3 /* Internal TX and external RX clock */
+#define CLOCK_TXFROMRX 4 /* TX clock derived from external RX clock */
+
+
+#define ENCODING_DEFAULT 0 /* Default setting */
+#define ENCODING_NRZ 1
+#define ENCODING_NRZI 2
+#define ENCODING_FM_MARK 3
+#define ENCODING_FM_SPACE 4
+#define ENCODING_MANCHESTER 5
+
+
+#define PARITY_DEFAULT 0 /* Default setting */
+#define PARITY_NONE 1 /* No parity */
+#define PARITY_CRC16_PR0 2 /* CRC16, initial value 0x0000 */
+#define PARITY_CRC16_PR1 3 /* CRC16, initial value 0xFFFF */
+#define PARITY_CRC16_PR0_CCITT 4 /* CRC16, initial 0x0000, ITU-T version */
+#define PARITY_CRC16_PR1_CCITT 5 /* CRC16, initial 0xFFFF, ITU-T version */
+#define PARITY_CRC32_PR0_CCITT 6 /* CRC32, initial value 0x00000000 */
+#define PARITY_CRC32_PR1_CCITT 7 /* CRC32, initial value 0xFFFFFFFF */
+
+#define LMI_DEFAULT 0 /* Default setting */
+#define LMI_NONE 1 /* No LMI, all PVCs are static */
+#define LMI_ANSI 2 /* ANSI Annex D */
+#define LMI_CCITT 3 /* ITU-T Annex A */
+#define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned int clock_rate; /* bits per second */
+ unsigned int clock_type; /* internal, external, TX-internal etc. */
+ unsigned short loopback;
+} sync_serial_settings; /* V.35, V.24, X.21 */
+
+typedef struct {
+ unsigned int clock_rate; /* bits per second */
+ unsigned int clock_type; /* internal, external, TX-internal etc. */
+ unsigned short loopback;
+ unsigned int slot_map;
+} te1_settings; /* T1, E1 */
+
+typedef struct {
+ unsigned short encoding;
+ unsigned short parity;
+} raw_hdlc_proto;
+
+typedef struct {
+ unsigned int t391;
+ unsigned int t392;
+ unsigned int n391;
+ unsigned int n392;
+ unsigned int n393;
+ unsigned short lmi;
+ unsigned short dce; /* 1 for DCE (network side) operation */
+} fr_proto;
+
+typedef struct {
+ unsigned int dlci;
+} fr_proto_pvc; /* for creating/deleting FR PVCs */
+
+typedef struct {
+ unsigned int dlci;
+ char master[IFNAMSIZ]; /* Name of master FRAD device */
+}fr_proto_pvc_info; /* for returning PVC information only */
+
+typedef struct {
+ unsigned int interval;
+ unsigned int timeout;
+} cisco_proto;
+
+typedef struct {
+ unsigned short dce; /* 1 for DCE (network side) operation */
+ unsigned int modulo; /* modulo (8 = basic / 128 = extended) */
+ unsigned int window; /* frame window size */
+ unsigned int t1; /* timeout t1 */
+ unsigned int t2; /* timeout t2 */
+ unsigned int n2; /* frame retry counter */
+} x25_hdlc_proto;
+
+/* PPP doesn't need any info now - supply length = 0 to ioctl */
+
+#endif /* __ASSEMBLY__ */
+#endif /* __HDLC_IOCTL_H__ */
diff --git a/uapi/linux/if.h b/uapi/linux/if.h
new file mode 100644
index 0000000..b287b2a
--- /dev/null
+++ b/uapi/linux/if.h
@@ -0,0 +1,296 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the INET interface module.
+ *
+ * Version: @(#)if.h 1.0.2 04/18/93
+ *
+ * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988
+ * Ross Biro
+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _LINUX_IF_H
+#define _LINUX_IF_H
+
+#include <linux/libc-compat.h> /* for compatibility with glibc */
+#include <linux/types.h> /* for "__kernel_caddr_t" et al */
+#include <linux/socket.h> /* for "struct sockaddr" et al */
+ /* for "__user" et al */
+
+#include <sys/socket.h> /* for struct sockaddr. */
+
+#if __UAPI_DEF_IF_IFNAMSIZ
+#define IFNAMSIZ 16
+#endif /* __UAPI_DEF_IF_IFNAMSIZ */
+#define IFALIASZ 256
+#define ALTIFNAMSIZ 128
+#include <linux/hdlc/ioctl.h>
+
+/* For glibc compatibility. An empty enum does not compile. */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || \
+ __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0
+/**
+ * enum net_device_flags - &struct net_device flags
+ *
+ * These are the &struct net_device flags, they can be set by drivers, the
+ * kernel and some can be triggered by userspace. Userspace can query and
+ * set these flags using userspace utilities but there is also a sysfs
+ * entry available for all dev flags which can be queried and set. These flags
+ * are shared for all types of net_devices. The sysfs entries are available
+ * via /sys/class/net/<dev>/flags. Flags which can be toggled through sysfs
+ * are annotated below, note that only a few flags can be toggled and some
+ * other flags are always preserved from the original net_device flags
+ * even if you try to set them via sysfs. Flags which are always preserved
+ * are kept under the flag grouping @IFF_VOLATILE. Flags which are __volatile__
+ * are annotated below as such.
+ *
+ * You should have a pretty good reason to be extending these flags.
+ *
+ * @IFF_UP: interface is up. Can be toggled through sysfs.
+ * @IFF_BROADCAST: broadcast address valid. Volatile.
+ * @IFF_DEBUG: turn on debugging. Can be toggled through sysfs.
+ * @IFF_LOOPBACK: is a loopback net. Volatile.
+ * @IFF_POINTOPOINT: interface is has p-p link. Volatile.
+ * @IFF_NOTRAILERS: avoid use of trailers. Can be toggled through sysfs.
+ * Volatile.
+ * @IFF_RUNNING: interface RFC2863 OPER_UP. Volatile.
+ * @IFF_NOARP: no ARP protocol. Can be toggled through sysfs. Volatile.
+ * @IFF_PROMISC: receive all packets. Can be toggled through sysfs.
+ * @IFF_ALLMULTI: receive all multicast packets. Can be toggled through
+ * sysfs.
+ * @IFF_MASTER: master of a load balancer. Volatile.
+ * @IFF_SLAVE: slave of a load balancer. Volatile.
+ * @IFF_MULTICAST: Supports multicast. Can be toggled through sysfs.
+ * @IFF_PORTSEL: can set media type. Can be toggled through sysfs.
+ * @IFF_AUTOMEDIA: auto media select active. Can be toggled through sysfs.
+ * @IFF_DYNAMIC: dialup device with changing addresses. Can be toggled
+ * through sysfs.
+ * @IFF_LOWER_UP: driver signals L1 up. Volatile.
+ * @IFF_DORMANT: driver signals dormant. Volatile.
+ * @IFF_ECHO: echo sent packets. Volatile.
+ */
+enum net_device_flags {
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
+ IFF_UP = 1<<0, /* sysfs */
+ IFF_BROADCAST = 1<<1, /* __volatile__ */
+ IFF_DEBUG = 1<<2, /* sysfs */
+ IFF_LOOPBACK = 1<<3, /* __volatile__ */
+ IFF_POINTOPOINT = 1<<4, /* __volatile__ */
+ IFF_NOTRAILERS = 1<<5, /* sysfs */
+ IFF_RUNNING = 1<<6, /* __volatile__ */
+ IFF_NOARP = 1<<7, /* sysfs */
+ IFF_PROMISC = 1<<8, /* sysfs */
+ IFF_ALLMULTI = 1<<9, /* sysfs */
+ IFF_MASTER = 1<<10, /* __volatile__ */
+ IFF_SLAVE = 1<<11, /* __volatile__ */
+ IFF_MULTICAST = 1<<12, /* sysfs */
+ IFF_PORTSEL = 1<<13, /* sysfs */
+ IFF_AUTOMEDIA = 1<<14, /* sysfs */
+ IFF_DYNAMIC = 1<<15, /* sysfs */
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
+ IFF_LOWER_UP = 1<<16, /* __volatile__ */
+ IFF_DORMANT = 1<<17, /* __volatile__ */
+ IFF_ECHO = 1<<18, /* __volatile__ */
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
+};
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
+
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
+#define IFF_UP IFF_UP
+#define IFF_BROADCAST IFF_BROADCAST
+#define IFF_DEBUG IFF_DEBUG
+#define IFF_LOOPBACK IFF_LOOPBACK
+#define IFF_POINTOPOINT IFF_POINTOPOINT
+#define IFF_NOTRAILERS IFF_NOTRAILERS
+#define IFF_RUNNING IFF_RUNNING
+#define IFF_NOARP IFF_NOARP
+#define IFF_PROMISC IFF_PROMISC
+#define IFF_ALLMULTI IFF_ALLMULTI
+#define IFF_MASTER IFF_MASTER
+#define IFF_SLAVE IFF_SLAVE
+#define IFF_MULTICAST IFF_MULTICAST
+#define IFF_PORTSEL IFF_PORTSEL
+#define IFF_AUTOMEDIA IFF_AUTOMEDIA
+#define IFF_DYNAMIC IFF_DYNAMIC
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
+
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
+#define IFF_LOWER_UP IFF_LOWER_UP
+#define IFF_DORMANT IFF_DORMANT
+#define IFF_ECHO IFF_ECHO
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
+
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\
+ IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
+
+#define IF_GET_IFACE 0x0001 /* for querying only */
+#define IF_GET_PROTO 0x0002
+
+/* For definitions see hdlc.h */
+#define IF_IFACE_V35 0x1000 /* V.35 serial interface */
+#define IF_IFACE_V24 0x1001 /* V.24 serial interface */
+#define IF_IFACE_X21 0x1002 /* X.21 serial interface */
+#define IF_IFACE_T1 0x1003 /* T1 telco serial interface */
+#define IF_IFACE_E1 0x1004 /* E1 telco serial interface */
+#define IF_IFACE_SYNC_SERIAL 0x1005 /* can't be set by software */
+#define IF_IFACE_X21D 0x1006 /* X.21 Dual Clocking (FarSite) */
+
+/* For definitions see hdlc.h */
+#define IF_PROTO_HDLC 0x2000 /* raw HDLC protocol */
+#define IF_PROTO_PPP 0x2001 /* PPP protocol */
+#define IF_PROTO_CISCO 0x2002 /* Cisco HDLC protocol */
+#define IF_PROTO_FR 0x2003 /* Frame Relay protocol */
+#define IF_PROTO_FR_ADD_PVC 0x2004 /* Create FR PVC */
+#define IF_PROTO_FR_DEL_PVC 0x2005 /* Delete FR PVC */
+#define IF_PROTO_X25 0x2006 /* X.25 */
+#define IF_PROTO_HDLC_ETH 0x2007 /* raw HDLC, Ethernet emulation */
+#define IF_PROTO_FR_ADD_ETH_PVC 0x2008 /* Create FR Ethernet-bridged PVC */
+#define IF_PROTO_FR_DEL_ETH_PVC 0x2009 /* Delete FR Ethernet-bridged PVC */
+#define IF_PROTO_FR_PVC 0x200A /* for reading PVC status */
+#define IF_PROTO_FR_ETH_PVC 0x200B
+#define IF_PROTO_RAW 0x200C /* RAW Socket */
+
+/* RFC 2863 operational status */
+enum {
+ IF_OPER_UNKNOWN,
+ IF_OPER_NOTPRESENT,
+ IF_OPER_DOWN,
+ IF_OPER_LOWERLAYERDOWN,
+ IF_OPER_TESTING,
+ IF_OPER_DORMANT,
+ IF_OPER_UP,
+};
+
+/* link modes */
+enum {
+ IF_LINK_MODE_DEFAULT,
+ IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */
+ IF_LINK_MODE_TESTING, /* limit upward transition to testing */
+};
+
+/*
+ * Device mapping structure. I'd just gone off and designed a
+ * beautiful scheme using only loadable modules with arguments
+ * for driver options and along come the PCMCIA people 8)
+ *
+ * Ah well. The get() side of this is good for WDSETUP, and it'll
+ * be handy for debugging things. The set side is fine for now and
+ * being very small might be worth keeping for clean configuration.
+ */
+
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_IFMAP
+struct ifmap {
+ unsigned long mem_start;
+ unsigned long mem_end;
+ unsigned short base_addr;
+ unsigned char irq;
+ unsigned char dma;
+ unsigned char port;
+ /* 3 bytes spare */
+};
+#endif /* __UAPI_DEF_IF_IFMAP */
+
+struct if_settings {
+ unsigned int type; /* Type of physical device or protocol */
+ unsigned int size; /* Size of the data allocated by the caller */
+ union {
+ /* {atm/eth/dsl}_settings anyone ? */
+ raw_hdlc_proto *raw_hdlc;
+ cisco_proto *cisco;
+ fr_proto *fr;
+ fr_proto_pvc *fr_pvc;
+ fr_proto_pvc_info *fr_pvc_info;
+ x25_hdlc_proto *x25;
+
+ /* interface settings */
+ sync_serial_settings *sync;
+ te1_settings *te1;
+ } ifs_ifsu;
+};
+
+/*
+ * Interface request structure used for socket
+ * ioctl's. All interface ioctl's must have parameter
+ * definitions which begin with ifr_name. The
+ * remainder may be interface specific.
+ */
+
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_IFREQ
+struct ifreq {
+#define IFHWADDRLEN 6
+ union
+ {
+ char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ } ifr_ifrn;
+
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_netmask;
+ struct sockaddr ifru_hwaddr;
+ short ifru_flags;
+ int ifru_ivalue;
+ int ifru_mtu;
+ struct ifmap ifru_map;
+ char ifru_slave[IFNAMSIZ]; /* Just fits the size */
+ char ifru_newname[IFNAMSIZ];
+ void * ifru_data;
+ struct if_settings ifru_settings;
+ } ifr_ifru;
+};
+#endif /* __UAPI_DEF_IF_IFREQ */
+
+#define ifr_name ifr_ifrn.ifrn_name /* interface name */
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
+#define ifr_flags ifr_ifru.ifru_flags /* flags */
+#define ifr_metric ifr_ifru.ifru_ivalue /* metric */
+#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+#define ifr_map ifr_ifru.ifru_map /* device map */
+#define ifr_slave ifr_ifru.ifru_slave /* slave device */
+#define ifr_data ifr_ifru.ifru_data /* for use by interface */
+#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
+#define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
+#define ifr_qlen ifr_ifru.ifru_ivalue /* Queue length */
+#define ifr_newname ifr_ifru.ifru_newname /* New name */
+#define ifr_settings ifr_ifru.ifru_settings /* Device/proto settings*/
+
+/*
+ * Structure used in SIOCGIFCONF request.
+ * Used to retrieve interface configuration
+ * for machine (useful for programs which
+ * must know all networks accessible).
+ */
+
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_IFCONF
+struct ifconf {
+ int ifc_len; /* size of buffer */
+ union {
+ char *ifcu_buf;
+ struct ifreq *ifcu_req;
+ } ifc_ifcu;
+};
+#endif /* __UAPI_DEF_IF_IFCONF */
+
+#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
+#define ifc_req ifc_ifcu.ifcu_req /* array of structures */
+
+#endif /* _LINUX_IF_H */
diff --git a/uapi/linux/if_addr.h b/uapi/linux/if_addr.h
new file mode 100644
index 0000000..d6db3ff
--- /dev/null
+++ b/uapi/linux/if_addr.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __LINUX_IF_ADDR_H
+#define __LINUX_IF_ADDR_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+struct ifaddrmsg {
+ __u8 ifa_family;
+ __u8 ifa_prefixlen; /* The prefix length */
+ __u8 ifa_flags; /* Flags */
+ __u8 ifa_scope; /* Address scope */
+ __u32 ifa_index; /* Link index */
+};
+
+/*
+ * Important comment:
+ * IFA_ADDRESS is prefix address, rather than local interface address.
+ * It makes no difference for normally configured broadcast interfaces,
+ * but for point-to-point IFA_ADDRESS is DESTINATION address,
+ * local address is supplied in IFA_LOCAL attribute.
+ *
+ * IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags.
+ * If present, the value from struct ifaddrmsg will be ignored.
+ */
+enum {
+ IFA_UNSPEC,
+ IFA_ADDRESS,
+ IFA_LOCAL,
+ IFA_LABEL,
+ IFA_BROADCAST,
+ IFA_ANYCAST,
+ IFA_CACHEINFO,
+ IFA_MULTICAST,
+ IFA_FLAGS,
+ IFA_RT_PRIORITY, /* u32, priority/metric for prefix route */
+ IFA_TARGET_NETNSID,
+ IFA_PROTO, /* u8, address protocol */
+ __IFA_MAX,
+};
+
+#define IFA_MAX (__IFA_MAX - 1)
+
+/* ifa_flags */
+#define IFA_F_SECONDARY 0x01
+#define IFA_F_TEMPORARY IFA_F_SECONDARY
+
+#define IFA_F_NODAD 0x02
+#define IFA_F_OPTIMISTIC 0x04
+#define IFA_F_DADFAILED 0x08
+#define IFA_F_HOMEADDRESS 0x10
+#define IFA_F_DEPRECATED 0x20
+#define IFA_F_TENTATIVE 0x40
+#define IFA_F_PERMANENT 0x80
+#define IFA_F_MANAGETEMPADDR 0x100
+#define IFA_F_NOPREFIXROUTE 0x200
+#define IFA_F_MCAUTOJOIN 0x400
+#define IFA_F_STABLE_PRIVACY 0x800
+
+struct ifa_cacheinfo {
+ __u32 ifa_prefered;
+ __u32 ifa_valid;
+ __u32 cstamp; /* created timestamp, hundredths of seconds */
+ __u32 tstamp; /* updated timestamp, hundredths of seconds */
+};
+
+/* backwards compatibility for userspace */
+#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
+#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
+
+/* ifa_proto */
+#define IFAPROT_UNSPEC 0
+#define IFAPROT_KERNEL_LO 1 /* loopback */
+#define IFAPROT_KERNEL_RA 2 /* set by kernel from router announcement */
+#define IFAPROT_KERNEL_LL 3 /* link-local set by kernel */
+
+#endif
diff --git a/uapi/linux/if_ether.h b/uapi/linux/if_ether.h
new file mode 100644
index 0000000..a1aff8e
--- /dev/null
+++ b/uapi/linux/if_ether.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the Ethernet IEEE 802.3 interface.
+ *
+ * Version: @(#)if_ether.h 1.0.1a 02/08/94
+ *
+ * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Donald Becker, <becker@super.org>
+ * Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_IF_ETHER_H
+#define _LINUX_IF_ETHER_H
+
+#include <linux/types.h>
+
+/*
+ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
+ * and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_TLEN 2 /* Octets in ethernet type field */
+#define ETH_HLEN 14 /* Total octets in header. */
+#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN 1500 /* Max. octets in payload */
+#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
+#define ETH_FCS_LEN 4 /* Octets in the FCS */
+
+#define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */
+#define ETH_MAX_MTU 0xFFFFU /* 65535, same as IP_MAX_MTU */
+
+/*
+ * These are the defined Ethernet Protocol ID's.
+ */
+
+#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
+#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
+#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
+#define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */
+#define ETH_P_ERSPAN2 0x22EB /* ERSPAN version 2 (type III) */
+#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+#define ETH_P_X25 0x0805 /* CCITT X.25 */
+#define ETH_P_ARP 0x0806 /* Address Resolution packet */
+#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
+#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
+#define ETH_P_BATMAN 0x4305 /* B.A.T.M.A.N.-Advanced packet [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
+#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
+#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
+#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
+#define ETH_P_LAT 0x6004 /* DEC LAT */
+#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
+#define ETH_P_CUST 0x6006 /* DEC Customer use */
+#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
+#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */
+#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
+#define ETH_P_ATALK 0x809B /* Appletalk DDP */
+#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
+#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
+#define ETH_P_ERSPAN 0x88BE /* ERSPAN type II */
+#define ETH_P_IPX 0x8137 /* IPX over DIX */
+#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
+#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */
+#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */
+#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
+ * defined in draft-wilson-wrec-wccp-v2-00.txt */
+#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
+#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
+#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
+#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
+#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
+#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */
+#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
+ * over Ethernet
+ */
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#define ETH_P_PROFINET 0x8892 /* PROFINET */
+#define ETH_P_REALTEK 0x8899 /* Multiple proprietary protocols */
+#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
+#define ETH_P_ETHERCAT 0x88A4 /* EtherCAT */
+#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
+#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
+#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */
+#define ETH_P_TIPC 0x88CA /* TIPC */
+#define ETH_P_LLDP 0x88CC /* Link Layer Discovery Protocol */
+#define ETH_P_MRP 0x88E3 /* Media Redundancy Protocol */
+#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
+#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
+#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
+#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
+#define ETH_P_NCSI 0x88F8 /* NCSI protocol */
+#define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */
+#define ETH_P_CFM 0x8902 /* Connectivity Fault Management */
+#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
+#define ETH_P_IBOE 0x8915 /* Infiniband over Ethernet */
+#define ETH_P_TDLS 0x890D /* TDLS */
+#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
+#define ETH_P_80221 0x8917 /* IEEE 802.21 Media Independent Handover Protocol */
+#define ETH_P_HSR 0x892F /* IEC 62439-3 HSRv1 */
+#define ETH_P_NSH 0x894F /* Network Service Header */
+#define ETH_P_LOOPBACK 0x9000 /* Ethernet loopback packet, per IEEE 802.3 */
+#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DSA_8021Q 0xDADB /* Fake VLAN Header for DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DSA_A5PSW 0xE001 /* A5PSW Tag Value [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */
+#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
+
+#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is more than this value
+ * then the frame is Ethernet II. Else it is 802.3 */
+
+/*
+ * Non DIX types. Won't clash for 1500 types.
+ */
+
+#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
+#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
+#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
+#define ETH_P_802_2 0x0004 /* 802.2 frames */
+#define ETH_P_SNAP 0x0005 /* Internal only */
+#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
+#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
+#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
+#define ETH_P_CAN 0x000C /* CAN: Controller Area Network */
+#define ETH_P_CANFD 0x000D /* CANFD: CAN flexible data rate*/
+#define ETH_P_CANXL 0x000E /* CANXL: eXtended frame Length */
+#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
+#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
+#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
+#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
+#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
+#define ETH_P_ECONET 0x0018 /* Acorn Econet */
+#define ETH_P_HDLC 0x0019 /* HDLC frames */
+#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */
+#define ETH_P_DSA 0x001B /* Distributed Switch Arch. */
+#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
+#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
+#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
+#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
+#define ETH_P_XDSA 0x00F8 /* Multiplexed DSA protocol */
+#define ETH_P_MAP 0x00F9 /* Qualcomm multiplexing and
+ * aggregation protocol
+ */
+#define ETH_P_MCTP 0x00FA /* Management component transport
+ * protocol packets
+ */
+
+/*
+ * This is an Ethernet frame header.
+ */
+
+/* allow libcs like musl to deactivate this, glibc does not implement this. */
+#ifndef __UAPI_DEF_ETHHDR
+#define __UAPI_DEF_ETHHDR 1
+#endif
+
+#if __UAPI_DEF_ETHHDR
+struct ethhdr {
+ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
+ unsigned char h_source[ETH_ALEN]; /* source ether addr */
+ __be16 h_proto; /* packet type ID field */
+} __attribute__((packed));
+#endif
+
+
+#endif /* _LINUX_IF_ETHER_H */
diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h
index 153fcb9..02af33c 100644
--- a/uapi/linux/if_link.h
+++ b/uapi/linux/if_link.h
@@ -372,6 +372,11 @@
IFLA_TSO_MAX_SEGS,
IFLA_ALLMULTI, /* Allmulti count: > 0 means acts ALLMULTI */
+ IFLA_DEVLINK_PORT,
+
+ IFLA_GSO_IPV4_MAX_SIZE,
+ IFLA_GRO_IPV4_MAX_SIZE,
+
__IFLA_MAX
};
@@ -559,6 +564,10 @@
IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
IFLA_BRPORT_LOCKED,
+ IFLA_BRPORT_MAB,
+ IFLA_BRPORT_MCAST_N_GROUPS,
+ IFLA_BRPORT_MCAST_MAX_GROUPS,
+ IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -625,6 +634,7 @@
IFLA_MACVLAN_MACADDR_COUNT,
IFLA_MACVLAN_BC_QUEUE_LEN,
IFLA_MACVLAN_BC_QUEUE_LEN_USED,
+ IFLA_MACVLAN_BC_CUTOFF,
__IFLA_MACVLAN_MAX,
};
@@ -816,6 +826,7 @@
IFLA_VXLAN_TTL_INHERIT,
IFLA_VXLAN_DF,
IFLA_VXLAN_VNIFILTER, /* only applicable with COLLECT_METADATA mode */
+ IFLA_VXLAN_LOCALBYPASS,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
diff --git a/uapi/linux/libc-compat.h b/uapi/linux/libc-compat.h
new file mode 100644
index 0000000..a159991
--- /dev/null
+++ b/uapi/linux/libc-compat.h
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Compatibility interface for userspace libc header coordination:
+ *
+ * Define compatibility macros that are used to control the inclusion or
+ * exclusion of UAPI structures and definitions in coordination with another
+ * userspace C library.
+ *
+ * This header is intended to solve the problem of UAPI definitions that
+ * conflict with userspace definitions. If a UAPI header has such conflicting
+ * definitions then the solution is as follows:
+ *
+ * * Synchronize the UAPI header and the libc headers so either one can be
+ * used and such that the ABI is preserved. If this is not possible then
+ * no simple compatibility interface exists (you need to write translating
+ * wrappers and rename things) and you can't use this interface.
+ *
+ * Then follow this process:
+ *
+ * (a) Include libc-compat.h in the UAPI header.
+ * e.g. #include <linux/libc-compat.h>
+ * This include must be as early as possible.
+ *
+ * (b) In libc-compat.h add enough code to detect that the comflicting
+ * userspace libc header has been included first.
+ *
+ * (c) If the userspace libc header has been included first define a set of
+ * guard macros of the form __UAPI_DEF_FOO and set their values to 1, else
+ * set their values to 0.
+ *
+ * (d) Back in the UAPI header with the conflicting definitions, guard the
+ * definitions with:
+ * #if __UAPI_DEF_FOO
+ * ...
+ * #endif
+ *
+ * This fixes the situation where the linux headers are included *after* the
+ * libc headers. To fix the problem with the inclusion in the other order the
+ * userspace libc headers must be fixed like this:
+ *
+ * * For all definitions that conflict with kernel definitions wrap those
+ * defines in the following:
+ * #if !__UAPI_DEF_FOO
+ * ...
+ * #endif
+ *
+ * This prevents the redefinition of a construct already defined by the kernel.
+ */
+#ifndef _LIBC_COMPAT_H
+#define _LIBC_COMPAT_H
+
+/* We have included glibc headers... */
+#if defined(__GLIBC__)
+
+/* Coordinate with glibc net/if.h header. */
+#if defined(_NET_IF_H) && defined(__USE_MISC)
+
+/* GLIBC headers included first so don't define anything
+ * that would already be defined. */
+
+#define __UAPI_DEF_IF_IFCONF 0
+#define __UAPI_DEF_IF_IFMAP 0
+#define __UAPI_DEF_IF_IFNAMSIZ 0
+#define __UAPI_DEF_IF_IFREQ 0
+/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0
+/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
+
+#else /* _NET_IF_H */
+
+/* Linux headers included first, and we must define everything
+ * we need. The expectation is that glibc will check the
+ * __UAPI_DEF_* defines and adjust appropriately. */
+
+#define __UAPI_DEF_IF_IFCONF 1
+#define __UAPI_DEF_IF_IFMAP 1
+#define __UAPI_DEF_IF_IFNAMSIZ 1
+#define __UAPI_DEF_IF_IFREQ 1
+/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
+/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+
+#endif /* _NET_IF_H */
+
+/* Coordinate with glibc netinet/in.h header. */
+#if defined(_NETINET_IN_H)
+
+/* GLIBC headers included first so don't define anything
+ * that would already be defined. */
+#define __UAPI_DEF_IN_ADDR 0
+#define __UAPI_DEF_IN_IPPROTO 0
+#define __UAPI_DEF_IN_PKTINFO 0
+#define __UAPI_DEF_IP_MREQ 0
+#define __UAPI_DEF_SOCKADDR_IN 0
+#define __UAPI_DEF_IN_CLASS 0
+
+#define __UAPI_DEF_IN6_ADDR 0
+/* The exception is the in6_addr macros which must be defined
+ * if the glibc code didn't define them. This guard matches
+ * the guard in glibc/inet/netinet/in.h which defines the
+ * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */
+#if defined(__USE_MISC) || defined (__USE_GNU)
+#define __UAPI_DEF_IN6_ADDR_ALT 0
+#else
+#define __UAPI_DEF_IN6_ADDR_ALT 1
+#endif
+#define __UAPI_DEF_SOCKADDR_IN6 0
+#define __UAPI_DEF_IPV6_MREQ 0
+#define __UAPI_DEF_IPPROTO_V6 0
+#define __UAPI_DEF_IPV6_OPTIONS 0
+#define __UAPI_DEF_IN6_PKTINFO 0
+#define __UAPI_DEF_IP6_MTUINFO 0
+
+#else
+
+/* Linux headers included first, and we must define everything
+ * we need. The expectation is that glibc will check the
+ * __UAPI_DEF_* defines and adjust appropriately. */
+#define __UAPI_DEF_IN_ADDR 1
+#define __UAPI_DEF_IN_IPPROTO 1
+#define __UAPI_DEF_IN_PKTINFO 1
+#define __UAPI_DEF_IP_MREQ 1
+#define __UAPI_DEF_SOCKADDR_IN 1
+#define __UAPI_DEF_IN_CLASS 1
+
+#define __UAPI_DEF_IN6_ADDR 1
+/* We unconditionally define the in6_addr macros and glibc must
+ * coordinate. */
+#define __UAPI_DEF_IN6_ADDR_ALT 1
+#define __UAPI_DEF_SOCKADDR_IN6 1
+#define __UAPI_DEF_IPV6_MREQ 1
+#define __UAPI_DEF_IPPROTO_V6 1
+#define __UAPI_DEF_IPV6_OPTIONS 1
+#define __UAPI_DEF_IN6_PKTINFO 1
+#define __UAPI_DEF_IP6_MTUINFO 1
+
+#endif /* _NETINET_IN_H */
+
+/* Coordinate with glibc netipx/ipx.h header. */
+#if defined(__NETIPX_IPX_H)
+
+#define __UAPI_DEF_SOCKADDR_IPX 0
+#define __UAPI_DEF_IPX_ROUTE_DEFINITION 0
+#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0
+#define __UAPI_DEF_IPX_CONFIG_DATA 0
+#define __UAPI_DEF_IPX_ROUTE_DEF 0
+
+#else /* defined(__NETIPX_IPX_H) */
+
+#define __UAPI_DEF_SOCKADDR_IPX 1
+#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
+#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
+#define __UAPI_DEF_IPX_CONFIG_DATA 1
+#define __UAPI_DEF_IPX_ROUTE_DEF 1
+
+#endif /* defined(__NETIPX_IPX_H) */
+
+/* Definitions for xattr.h */
+#if defined(_SYS_XATTR_H)
+#define __UAPI_DEF_XATTR 0
+#else
+#define __UAPI_DEF_XATTR 1
+#endif
+
+/* If we did not see any headers from any supported C libraries,
+ * or we are being included in the kernel, then define everything
+ * that we need. Check for previous __UAPI_* definitions to give
+ * unsupported C libraries a way to opt out of any kernel definition. */
+#else /* !defined(__GLIBC__) */
+
+/* Definitions for if.h */
+#ifndef __UAPI_DEF_IF_IFCONF
+#define __UAPI_DEF_IF_IFCONF 1
+#endif
+#ifndef __UAPI_DEF_IF_IFMAP
+#define __UAPI_DEF_IF_IFMAP 1
+#endif
+#ifndef __UAPI_DEF_IF_IFNAMSIZ
+#define __UAPI_DEF_IF_IFNAMSIZ 1
+#endif
+#ifndef __UAPI_DEF_IF_IFREQ
+#define __UAPI_DEF_IF_IFREQ 1
+#endif
+/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
+#endif
+/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+#endif
+
+/* Definitions for in.h */
+#ifndef __UAPI_DEF_IN_ADDR
+#define __UAPI_DEF_IN_ADDR 1
+#endif
+#ifndef __UAPI_DEF_IN_IPPROTO
+#define __UAPI_DEF_IN_IPPROTO 1
+#endif
+#ifndef __UAPI_DEF_IN_PKTINFO
+#define __UAPI_DEF_IN_PKTINFO 1
+#endif
+#ifndef __UAPI_DEF_IP_MREQ
+#define __UAPI_DEF_IP_MREQ 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IN
+#define __UAPI_DEF_SOCKADDR_IN 1
+#endif
+#ifndef __UAPI_DEF_IN_CLASS
+#define __UAPI_DEF_IN_CLASS 1
+#endif
+
+/* Definitions for in6.h */
+#ifndef __UAPI_DEF_IN6_ADDR
+#define __UAPI_DEF_IN6_ADDR 1
+#endif
+#ifndef __UAPI_DEF_IN6_ADDR_ALT
+#define __UAPI_DEF_IN6_ADDR_ALT 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IN6
+#define __UAPI_DEF_SOCKADDR_IN6 1
+#endif
+#ifndef __UAPI_DEF_IPV6_MREQ
+#define __UAPI_DEF_IPV6_MREQ 1
+#endif
+#ifndef __UAPI_DEF_IPPROTO_V6
+#define __UAPI_DEF_IPPROTO_V6 1
+#endif
+#ifndef __UAPI_DEF_IPV6_OPTIONS
+#define __UAPI_DEF_IPV6_OPTIONS 1
+#endif
+#ifndef __UAPI_DEF_IN6_PKTINFO
+#define __UAPI_DEF_IN6_PKTINFO 1
+#endif
+#ifndef __UAPI_DEF_IP6_MTUINFO
+#define __UAPI_DEF_IP6_MTUINFO 1
+#endif
+
+/* Definitions for ipx.h */
+#ifndef __UAPI_DEF_SOCKADDR_IPX
+#define __UAPI_DEF_SOCKADDR_IPX 1
+#endif
+#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION
+#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
+#endif
+#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION
+#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
+#endif
+#ifndef __UAPI_DEF_IPX_CONFIG_DATA
+#define __UAPI_DEF_IPX_CONFIG_DATA 1
+#endif
+#ifndef __UAPI_DEF_IPX_ROUTE_DEF
+#define __UAPI_DEF_IPX_ROUTE_DEF 1
+#endif
+
+/* Definitions for xattr.h */
+#ifndef __UAPI_DEF_XATTR
+#define __UAPI_DEF_XATTR 1
+#endif
+
+#endif /* __GLIBC__ */
+
+#endif /* _LIBC_COMPAT_H */
diff --git a/uapi/linux/neighbour.h b/uapi/linux/neighbour.h
new file mode 100644
index 0000000..5e67a7e
--- /dev/null
+++ b/uapi/linux/neighbour.h
@@ -0,0 +1,224 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __LINUX_NEIGHBOUR_H
+#define __LINUX_NEIGHBOUR_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+struct ndmsg {
+ __u8 ndm_family;
+ __u8 ndm_pad1;
+ __u16 ndm_pad2;
+ __s32 ndm_ifindex;
+ __u16 ndm_state;
+ __u8 ndm_flags;
+ __u8 ndm_type;
+};
+
+enum {
+ NDA_UNSPEC,
+ NDA_DST,
+ NDA_LLADDR,
+ NDA_CACHEINFO,
+ NDA_PROBES,
+ NDA_VLAN,
+ NDA_PORT,
+ NDA_VNI,
+ NDA_IFINDEX,
+ NDA_MASTER,
+ NDA_LINK_NETNSID,
+ NDA_SRC_VNI,
+ NDA_PROTOCOL, /* Originator of entry */
+ NDA_NH_ID,
+ NDA_FDB_EXT_ATTRS,
+ NDA_FLAGS_EXT,
+ NDA_NDM_STATE_MASK,
+ NDA_NDM_FLAGS_MASK,
+ __NDA_MAX
+};
+
+#define NDA_MAX (__NDA_MAX - 1)
+
+/*
+ * Neighbor Cache Entry Flags
+ */
+
+#define NTF_USE (1 << 0)
+#define NTF_SELF (1 << 1)
+#define NTF_MASTER (1 << 2)
+#define NTF_PROXY (1 << 3) /* == ATF_PUBL */
+#define NTF_EXT_LEARNED (1 << 4)
+#define NTF_OFFLOADED (1 << 5)
+#define NTF_STICKY (1 << 6)
+#define NTF_ROUTER (1 << 7)
+/* Extended flags under NDA_FLAGS_EXT: */
+#define NTF_EXT_MANAGED (1 << 0)
+#define NTF_EXT_LOCKED (1 << 1)
+
+/*
+ * Neighbor Cache Entry States.
+ */
+
+#define NUD_INCOMPLETE 0x01
+#define NUD_REACHABLE 0x02
+#define NUD_STALE 0x04
+#define NUD_DELAY 0x08
+#define NUD_PROBE 0x10
+#define NUD_FAILED 0x20
+
+/* Dummy states */
+#define NUD_NOARP 0x40
+#define NUD_PERMANENT 0x80
+#define NUD_NONE 0x00
+
+/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change and make no
+ * address resolution or NUD.
+ *
+ * NUD_PERMANENT also cannot be deleted by garbage collectors. This holds true
+ * for dynamic entries with NTF_EXT_LEARNED flag as well. However, upon carrier
+ * down event, NUD_PERMANENT entries are not flushed whereas NTF_EXT_LEARNED
+ * flagged entries explicitly are (which is also consistent with the routing
+ * subsystem).
+ *
+ * When NTF_EXT_LEARNED is set for a bridge fdb entry the different cache entry
+ * states don't make sense and thus are ignored. Such entries don't age and
+ * can roam.
+ *
+ * NTF_EXT_MANAGED flagged neigbor entries are managed by the kernel on behalf
+ * of a user space control plane, and automatically refreshed so that (if
+ * possible) they remain in NUD_REACHABLE state.
+ *
+ * NTF_EXT_LOCKED flagged bridge FDB entries are entries generated by the
+ * bridge in response to a host trying to communicate via a locked bridge port
+ * with MAB enabled. Their purpose is to notify user space that a host requires
+ * authentication.
+ */
+
+struct nda_cacheinfo {
+ __u32 ndm_confirmed;
+ __u32 ndm_used;
+ __u32 ndm_updated;
+ __u32 ndm_refcnt;
+};
+
+/*****************************************************************
+ * Neighbour tables specific messages.
+ *
+ * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the
+ * NLM_F_DUMP flag set. Every neighbour table configuration is
+ * spread over multiple messages to avoid running into message
+ * size limits on systems with many interfaces. The first message
+ * in the sequence transports all not device specific data such as
+ * statistics, configuration, and the default parameter set.
+ * This message is followed by 0..n messages carrying device
+ * specific parameter sets.
+ * Although the ordering should be sufficient, NDTA_NAME can be
+ * used to identify sequences. The initial message can be identified
+ * by checking for NDTA_CONFIG. The device specific messages do
+ * not contain this TLV but have NDTPA_IFINDEX set to the
+ * corresponding interface index.
+ *
+ * To change neighbour table attributes, send RTM_SETNEIGHTBL
+ * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3],
+ * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked
+ * otherwise. Device specific parameter sets can be changed by
+ * setting NDTPA_IFINDEX to the interface index of the corresponding
+ * device.
+ ****/
+
+struct ndt_stats {
+ __u64 ndts_allocs;
+ __u64 ndts_destroys;
+ __u64 ndts_hash_grows;
+ __u64 ndts_res_failed;
+ __u64 ndts_lookups;
+ __u64 ndts_hits;
+ __u64 ndts_rcv_probes_mcast;
+ __u64 ndts_rcv_probes_ucast;
+ __u64 ndts_periodic_gc_runs;
+ __u64 ndts_forced_gc_runs;
+ __u64 ndts_table_fulls;
+};
+
+enum {
+ NDTPA_UNSPEC,
+ NDTPA_IFINDEX, /* u32, unchangeable */
+ NDTPA_REFCNT, /* u32, read-only */
+ NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */
+ NDTPA_BASE_REACHABLE_TIME, /* u64, msecs */
+ NDTPA_RETRANS_TIME, /* u64, msecs */
+ NDTPA_GC_STALETIME, /* u64, msecs */
+ NDTPA_DELAY_PROBE_TIME, /* u64, msecs */
+ NDTPA_QUEUE_LEN, /* u32 */
+ NDTPA_APP_PROBES, /* u32 */
+ NDTPA_UCAST_PROBES, /* u32 */
+ NDTPA_MCAST_PROBES, /* u32 */
+ NDTPA_ANYCAST_DELAY, /* u64, msecs */
+ NDTPA_PROXY_DELAY, /* u64, msecs */
+ NDTPA_PROXY_QLEN, /* u32 */
+ NDTPA_LOCKTIME, /* u64, msecs */
+ NDTPA_QUEUE_LENBYTES, /* u32 */
+ NDTPA_MCAST_REPROBES, /* u32 */
+ NDTPA_PAD,
+ NDTPA_INTERVAL_PROBE_TIME_MS, /* u64, msecs */
+ __NDTPA_MAX
+};
+#define NDTPA_MAX (__NDTPA_MAX - 1)
+
+struct ndtmsg {
+ __u8 ndtm_family;
+ __u8 ndtm_pad1;
+ __u16 ndtm_pad2;
+};
+
+struct ndt_config {
+ __u16 ndtc_key_len;
+ __u16 ndtc_entry_size;
+ __u32 ndtc_entries;
+ __u32 ndtc_last_flush; /* delta to now in msecs */
+ __u32 ndtc_last_rand; /* delta to now in msecs */
+ __u32 ndtc_hash_rnd;
+ __u32 ndtc_hash_mask;
+ __u32 ndtc_hash_chain_gc;
+ __u32 ndtc_proxy_qlen;
+};
+
+enum {
+ NDTA_UNSPEC,
+ NDTA_NAME, /* char *, unchangeable */
+ NDTA_THRESH1, /* u32 */
+ NDTA_THRESH2, /* u32 */
+ NDTA_THRESH3, /* u32 */
+ NDTA_CONFIG, /* struct ndt_config, read-only */
+ NDTA_PARMS, /* nested TLV NDTPA_* */
+ NDTA_STATS, /* struct ndt_stats, read-only */
+ NDTA_GC_INTERVAL, /* u64, msecs */
+ NDTA_PAD,
+ __NDTA_MAX
+};
+#define NDTA_MAX (__NDTA_MAX - 1)
+
+ /* FDB activity notification bits used in NFEA_ACTIVITY_NOTIFY:
+ * - FDB_NOTIFY_BIT - notify on activity/expire for any entry
+ * - FDB_NOTIFY_INACTIVE_BIT - mark as inactive to avoid multiple notifications
+ */
+enum {
+ FDB_NOTIFY_BIT = (1 << 0),
+ FDB_NOTIFY_INACTIVE_BIT = (1 << 1)
+};
+
+/* embedded into NDA_FDB_EXT_ATTRS:
+ * [NDA_FDB_EXT_ATTRS] = {
+ * [NFEA_ACTIVITY_NOTIFY]
+ * ...
+ * }
+ */
+enum {
+ NFEA_UNSPEC,
+ NFEA_ACTIVITY_NOTIFY,
+ NFEA_DONT_REFRESH,
+ __NFEA_MAX
+};
+#define NFEA_MAX (__NFEA_MAX - 1)
+
+#endif
diff --git a/uapi/linux/net_tstamp.h b/uapi/linux/net_tstamp.h
index 55501e5..a2c66b3 100644
--- a/uapi/linux/net_tstamp.h
+++ b/uapi/linux/net_tstamp.h
@@ -31,8 +31,9 @@
SOF_TIMESTAMPING_OPT_PKTINFO = (1<<13),
SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14),
SOF_TIMESTAMPING_BIND_PHC = (1 << 15),
+ SOF_TIMESTAMPING_OPT_ID_TCP = (1 << 16),
- SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_BIND_PHC,
+ SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_ID_TCP,
SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
SOF_TIMESTAMPING_LAST
};
diff --git a/uapi/linux/posix_types.h b/uapi/linux/posix_types.h
new file mode 100644
index 0000000..9a7a740
--- /dev/null
+++ b/uapi/linux/posix_types.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_POSIX_TYPES_H
+#define _LINUX_POSIX_TYPES_H
+
+#include <linux/stddef.h>
+
+/*
+ * This allows for 1024 file descriptors: if NR_OPEN is ever grown
+ * beyond that you'll have to change this too. But 1024 fd's seem to be
+ * enough even for such "real" unices like OSF/1, so hopefully this is
+ * one limit that doesn't have to be changed [again].
+ *
+ * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in
+ * <sys/time.h> (and thus <linux/time.h>) - but this is a more logical
+ * place for them. Solved by having dummy defines in <sys/time.h>.
+ */
+
+/*
+ * This macro may have been defined in <gnu/types.h>. But we always
+ * use the one here.
+ */
+#undef __FD_SETSIZE
+#define __FD_SETSIZE 1024
+
+typedef struct {
+ unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(long))];
+} __kernel_fd_set;
+
+/* Type of a signal handler. */
+typedef void (*__kernel_sighandler_t)(int);
+
+/* Type of a SYSV IPC key. */
+typedef int __kernel_key_t;
+typedef int __kernel_mqd_t;
+
+#include <asm/posix_types.h>
+
+#endif /* _LINUX_POSIX_TYPES_H */
diff --git a/uapi/linux/rtnetlink.h b/uapi/linux/rtnetlink.h
index f4a540c..2132e94 100644
--- a/uapi/linux/rtnetlink.h
+++ b/uapi/linux/rtnetlink.h
@@ -635,6 +635,7 @@
TCA_INGRESS_BLOCK,
TCA_EGRESS_BLOCK,
TCA_DUMP_FLAGS,
+ TCA_EXT_WARN_MSG,
__TCA_MAX
};
@@ -786,6 +787,7 @@
TCA_ROOT_FLAGS,
TCA_ROOT_COUNT,
TCA_ROOT_TIME_DELTA, /* in msecs */
+ TCA_ROOT_EXT_WARN_MSG,
__TCA_ROOT_MAX,
#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
};
diff --git a/uapi/linux/socket.h b/uapi/linux/socket.h
new file mode 100644
index 0000000..89c227f
--- /dev/null
+++ b/uapi/linux/socket.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_SOCKET_H
+#define _LINUX_SOCKET_H
+
+/*
+ * Desired design of maximum size and alignment (see RFC2553)
+ */
+#define _K_SS_MAXSIZE 128 /* Implementation specific max size */
+
+typedef unsigned short __kernel_sa_family_t;
+
+/*
+ * The definition uses anonymous union and struct in order to control the
+ * default alignment.
+ */
+struct __kernel_sockaddr_storage {
+ union {
+ struct {
+ __kernel_sa_family_t ss_family; /* address family */
+ /* Following field(s) are implementation specific */
+ char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+ /* space to achieve desired size, */
+ /* _SS_MAXSIZE value minus size of ss_family */
+ };
+ void *__align; /* implementation specific desired alignment */
+ };
+};
+
+#define SOCK_SNDBUF_LOCK 1
+#define SOCK_RCVBUF_LOCK 2
+
+#define SOCK_BUF_LOCK_MASK (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK)
+
+#define SOCK_TXREHASH_DEFAULT 255
+#define SOCK_TXREHASH_DISABLED 0
+#define SOCK_TXREHASH_ENABLED 1
+
+#endif /* _LINUX_SOCKET_H */
diff --git a/uapi/linux/stddef.h b/uapi/linux/stddef.h
new file mode 100644
index 0000000..bb6ea51
--- /dev/null
+++ b/uapi/linux/stddef.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_STDDEF_H
+#define _LINUX_STDDEF_H
+
+
+
+#ifndef __always_inline
+#define __always_inline __inline__
+#endif
+
+/**
+ * __struct_group() - Create a mirrored named and anonyomous struct
+ *
+ * @TAG: The tag name for the named sub-struct (usually empty)
+ * @NAME: The identifier name of the mirrored sub-struct
+ * @ATTRS: Any struct attributes (usually empty)
+ * @MEMBERS: The member declarations for the mirrored structs
+ *
+ * Used to create an anonymous union of two structs with identical layout
+ * and size: one anonymous and one named. The former's members can be used
+ * normally without sub-struct naming, and the latter can be used to
+ * reason about the start, end, and size of the group of struct members.
+ * The named struct can also be explicitly tagged for layer reuse, as well
+ * as both having struct attributes appended.
+ */
+#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
+ union { \
+ struct { MEMBERS } ATTRS; \
+ struct TAG { MEMBERS } ATTRS NAME; \
+ }
+
+/**
+ * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
+ *
+ * @TYPE: The type of each flexible array element
+ * @NAME: The name of the flexible array member
+ *
+ * In order to have a flexible array member in a union or alone in a
+ * struct, it needs to be wrapped in an anonymous struct with at least 1
+ * named member, but that member can be empty.
+ */
+#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
+ struct { \
+ struct { } __empty_ ## NAME; \
+ TYPE NAME[]; \
+ }
+#endif
diff --git a/uapi/linux/types.h b/uapi/linux/types.h
new file mode 100644
index 0000000..e670013
--- /dev/null
+++ b/uapi/linux/types.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_TYPES_H
+#define _LINUX_TYPES_H
+
+#include <asm/types.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/posix_types.h>
+
+#ifdef __SIZEOF_INT128__
+typedef __signed__ __int128 __s128 __attribute__((aligned(16)));
+typedef unsigned __int128 __u128 __attribute__((aligned(16)));
+#endif
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
+
+/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
+#ifdef __CHECKER__
+#define __bitwise __attribute__((bitwise))
+#else
+#define __bitwise
+#endif
+
+/* The kernel doesn't use this legacy form, but user space does */
+#define __bitwise__ __bitwise
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+
+typedef __u16 __bitwise __sum16;
+typedef __u32 __bitwise __wsum;
+
+/*
+ * aligned_u64 should be used in defining kernel<->userspace ABIs to avoid
+ * common 32/64-bit compat problems.
+ * 64-bit values align to 4-byte boundaries on x86_32 (and possibly other
+ * architectures) and to 8-byte boundaries on 64-bit architectures. The new
+ * aligned_64 type enforces 8-byte alignment so that structs containing
+ * aligned_64 values have the same alignment on 32-bit and 64-bit architectures.
+ * No conversions are necessary between 32-bit user-space and a 64-bit kernel.
+ */
+#define __aligned_u64 __u64 __attribute__((aligned(8)))
+#define __aligned_be64 __be64 __attribute__((aligned(8)))
+#define __aligned_le64 __le64 __attribute__((aligned(8)))
+
+typedef unsigned __bitwise __poll_t;
+
+#endif /* __ASSEMBLY__ */
+#endif /* _LINUX_TYPES_H */