diff --git a/build.sh b/build.sh index 3565b821..7ccf3bdb 100755 --- a/build.sh +++ b/build.sh @@ -68,6 +68,7 @@ ports=( "lsb_vsx" "heatshrink" "smolrtsp" + "ethtool" ) diff --git a/ethtool/build.sh b/ethtool/build.sh new file mode 100755 index 00000000..b2e1ec49 --- /dev/null +++ b/ethtool/build.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +set -e + +version="${PORTS_ETHTOOL_VERSION:-6.14}" +archive_filename="ethtool-${version}.tar.gz" + +PREFIX_PORT_SRC="${PREFIX_PORT_BUILD}/${version}" +b_port_download "https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/snapshot/" "${archive_filename}" + +if [ ! -d "${PREFIX_PORT_SRC}" ]; then + echo "Extracting sources from ${archive_filename}" + mkdir -p "${PREFIX_PORT_SRC}" + tar -axf "${PREFIX_PORT}/${archive_filename}" --strip-components 1 -C "${PREFIX_PORT_SRC}" +fi + +b_port_apply_patches "${PREFIX_PORT_SRC}" "${version}" + +# +# Autogen +# +if [ ! -f "${PREFIX_PORT_SRC}/configure" ]; then + ( cd "${PREFIX_PORT_SRC}" && "${PREFIX_PORT_SRC}/autogen.sh" ) +fi + +# +# Configure +# +if [ ! -f "${PREFIX_PORT_SRC}/Makefile" ]; then + ( cd "${PREFIX_PORT_SRC}" && "${PREFIX_PORT_SRC}/configure" CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" \ + --host="${HOST}" --prefix="${PREFIX_PORTS_INSTALL}" --disable-netlink ) +fi + +# +# Make +# +make -C "$PREFIX_PORT_SRC" +make -C "$PREFIX_PORT_SRC" install + +cp -a "$PREFIX_PORT_SRC/ethtool" "$PREFIX_PROG/ethtool" +$STRIP -o "$PREFIX_PROG_STRIPPED/ethtool" "$PREFIX_PROG/ethtool" +b_install "$PREFIX_PORTS_INSTALL/ethtool" /usr/bin/ diff --git a/ethtool/patches/6.14/01-replace-symbols.patch b/ethtool/patches/6.14/01-replace-symbols.patch new file mode 100644 index 00000000..4c9fc08c --- /dev/null +++ b/ethtool/patches/6.14/01-replace-symbols.patch @@ -0,0 +1,132 @@ +diff --git a/ethtool.c b/ethtool.c +index 327a2da..f7639d4 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -47,9 +47,17 @@ + #include + #include + ++#ifdef __phoenix__ ++#include ++#include ++#include ++#include "uapi/linux/netlink.h" ++#define AF_NETLINK 16 ++#else + #include + #include + #include ++#endif + + #include "common.h" + #include "netlink/extapi.h" +diff --git a/internal.h b/internal.h +index 6947ec1..f10c426 100644 +--- a/internal.h ++++ b/internal.h +@@ -24,7 +24,6 @@ + #define __UAPI_DEF_IF_IFNAMSIZ 1 + #define __UAPI_DEF_IF_IFMAP 1 + #define __UAPI_DEF_IF_IFREQ 1 +-#include + + #include "json_writer.h" + #include "json_print.h" +@@ -42,8 +41,17 @@ typedef uint16_t u16; + typedef uint8_t u8; + typedef int32_t s32; + ++#ifdef __phoenix__ ++#include ++#include "uapi/linux/net_tstamp.h" ++#include ++#include ++#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) ++#else + #include + #include ++#include ++#endif + + #if __BYTE_ORDER == __BIG_ENDIAN + static inline u16 cpu_to_be16(u16 value) +diff --git a/rxclass.c b/rxclass.c +index 1e202cc..c1d1581 100644 +--- a/rxclass.c ++++ b/rxclass.c +@@ -8,7 +8,13 @@ + #include + #include + ++#ifdef __phoenix__ ++#include ++#include ++#else + #include ++#endif ++ + #include + #include "internal.h" + +diff --git a/uapi/linux/net_tstamp.h b/uapi/linux/net_tstamp.h +index 383213d..5dbbf0f 100644 +--- a/uapi/linux/net_tstamp.h ++++ b/uapi/linux/net_tstamp.h +@@ -10,8 +10,15 @@ + #ifndef _NET_TIMESTAMPING_H + #define _NET_TIMESTAMPING_H + ++#ifdef __phoenix__ ++#include "types.h" ++#include "socket.h" /* for SO_TIMESTAMPING */ ++ ++typedef int __kernel_clockid_t; ++#else + #include + #include /* for SO_TIMESTAMPING */ ++#endif + + /* + * Possible type of hwtstamp provider. Mainly "precise" the default one +diff --git a/uapi/linux/netlink.h b/uapi/linux/netlink.h +index ff64eb1..aca203c 100644 +--- a/uapi/linux/netlink.h ++++ b/uapi/linux/netlink.h +@@ -2,9 +2,15 @@ + #ifndef __LINUX_NETLINK_H + #define __LINUX_NETLINK_H + ++#ifdef __phoenix__ ++#include "const.h" ++#include "socket.h" ++#include "types.h" ++#else + #include + #include /* for __kernel_sa_family_t */ + #include ++#endif + + #define NETLINK_ROUTE 0 /* Routing/device hook */ + #define NETLINK_UNUSED 1 /* Unused number */ +diff --git a/uapi/linux/types.h b/uapi/linux/types.h +index 2518741..7600a6e 100644 +--- a/uapi/linux/types.h ++++ b/uapi/linux/types.h +@@ -2,11 +2,17 @@ + #ifndef _LINUX_TYPES_H + #define _LINUX_TYPES_H + ++#ifdef __phoenix__ ++#include ++#else + #include ++#endif + + #ifndef __ASSEMBLY__ + ++#ifndef __phoenix__ + #include ++#endif + + #ifdef __SIZEOF_INT128__ + typedef __signed__ __int128 __s128 __attribute__((aligned(16))); diff --git a/ethtool/patches/6.14/02-undef-symbols-from-libphoenix.patch b/ethtool/patches/6.14/02-undef-symbols-from-libphoenix.patch new file mode 100644 index 00000000..5fb27215 --- /dev/null +++ b/ethtool/patches/6.14/02-undef-symbols-from-libphoenix.patch @@ -0,0 +1,231 @@ +diff --git a/internal.h b/internal.h +index f10c426..0d82412 100644 +--- a/internal.h ++++ b/internal.h +@@ -43,10 +43,39 @@ typedef int32_t s32; + + #ifdef __phoenix__ + #include ++#include "uapi/linux/ethtool.h" + #include "uapi/linux/net_tstamp.h" + #include + #include + #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) ++ ++static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep, __u32 speed) ++{ ++ ep->speed = (__u16)(speed & 0xFFFF); ++ ep->speed_hi = (__u16)(speed >> 16); ++} ++ ++static __inline__ __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep) ++{ ++ return (ep->speed_hi << 16) | ep->speed; ++} ++ ++static __inline__ int ethtool_validate_speed(__u32 speed) ++{ ++ return speed <= INT_MAX || speed == (__u32)SPEED_UNKNOWN; ++} ++ ++static __inline__ int ethtool_validate_duplex(__u8 duplex) ++{ ++ switch (duplex) { ++ case DUPLEX_HALF: ++ case DUPLEX_FULL: ++ case DUPLEX_UNKNOWN: ++ return 1; ++ } ++ ++ return 0; ++} + #else + #include + #include +diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h +index 506e086..de358df 100644 +--- a/uapi/linux/ethtool.h ++++ b/uapi/linux/ethtool.h +@@ -32,6 +32,7 @@ + * initializer. + */ + ++#ifndef __phoenix__ + /** + * struct ethtool_cmd - DEPRECATED, link control and status + * This structure is DEPRECATED, please use struct ethtool_link_settings. +@@ -120,6 +121,7 @@ struct ethtool_cmd { + __u32 reserved[2]; + }; + ++ + static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) + { +@@ -131,6 +133,7 @@ static __inline__ __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep) + { + return (ep->speed_hi << 16) | ep->speed; + } ++#endif + + /* Device supports clause 22 register access to PHY or peripherals + * using the interface defined in . This should not be +@@ -652,6 +655,7 @@ enum ethtool_link_ext_substate_module { + ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY = 1, + }; + ++#ifndef __phoenix__ + #define ETH_GSTRING_LEN 32 + + /** +@@ -712,6 +716,7 @@ enum ethtool_stringset { + /* add new constants above here */ + ETH_SS_COUNT + }; ++#endif + + /** + * enum ethtool_mac_stats_src - source of ethtool MAC statistics +@@ -1088,6 +1093,7 @@ enum ethtool_module_fw_flash_status { + ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR, + }; + ++#ifndef __phoenix__ + /** + * struct ethtool_gstrings - string set for data tagging + * @cmd: Command number = %ETHTOOL_GSTRINGS +@@ -1171,6 +1177,7 @@ struct ethtool_test { + __u32 len; + __u64 data[]; + }; ++#endif + + /** + * struct ethtool_stats - device-specific statistics +@@ -1946,6 +1953,7 @@ enum ethtool_fec_config_bits { + + /* Link mode bit indices */ + enum ethtool_link_mode_bit_indices { ++#ifndef __phoenix__ + ETHTOOL_LINK_MODE_10baseT_Half_BIT = 0, + ETHTOOL_LINK_MODE_10baseT_Full_BIT = 1, + ETHTOOL_LINK_MODE_100baseT_Half_BIT = 2, +@@ -1978,7 +1986,7 @@ enum ethtool_link_mode_bit_indices { + ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT = 29, + ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT = 30, + ETHTOOL_LINK_MODE_25000baseCR_Full_BIT = 31, +- ++#endif + /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit + * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_* + * macro for bits > 31. The only way to use indices > 31 is to +@@ -2080,6 +2088,7 @@ enum ethtool_link_mode_bit_indices { + __ETHTOOL_LINK_MODE_MASK_NBITS + }; + ++#ifndef __phoenix__ + #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \ + (1UL << (ETHTOOL_LINK_MODE_ ## base_name ## _BIT)) + +@@ -2191,27 +2200,33 @@ enum ethtool_link_mode_bit_indices { + + #define SPEED_UNKNOWN -1 + +-static __inline__ int ethtool_validate_speed(__u32 speed) +-{ +- return speed <= INT_MAX || speed == (__u32)SPEED_UNKNOWN; +-} +- + /* Duplex, half or full. */ + #define DUPLEX_HALF 0x00 + #define DUPLEX_FULL 0x01 + #define DUPLEX_UNKNOWN 0xff + +-static __inline__ int ethtool_validate_duplex(__u8 duplex) +-{ +- switch (duplex) { +- case DUPLEX_HALF: +- case DUPLEX_FULL: +- case DUPLEX_UNKNOWN: +- return 1; +- } +- +- return 0; +-} ++/* Which connector port. */ ++#define PORT_TP 0x00 ++#define PORT_AUI 0x01 ++#define PORT_MII 0x02 ++#define PORT_FIBRE 0x03 ++#define PORT_BNC 0x04 ++#define PORT_DA 0x05 ++#define PORT_NONE 0xef ++#define PORT_OTHER 0xff ++ ++/* Enable or disable autonegotiation. */ ++#define AUTONEG_DISABLE 0x00 ++#define AUTONEG_ENABLE 0x01 ++ ++/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then ++ * the driver is required to renegotiate link ++ */ ++#define ETH_TP_MDI_INVALID 0x00 /* status: unknown; control: unsupported */ ++#define ETH_TP_MDI 0x01 /* status: MDI; control: force MDI */ ++#define ETH_TP_MDI_X 0x02 /* status: MDI-X; control: force MDI-X */ ++#define ETH_TP_MDI_AUTO 0x03 /* control: auto-select */ ++#endif + + #define MASTER_SLAVE_CFG_UNSUPPORTED 0 + #define MASTER_SLAVE_CFG_UNKNOWN 1 +@@ -2239,16 +2254,6 @@ static __inline__ int ethtool_validate_duplex(__u8 duplex) + /* The MAC is programmed with a sufficiently-large IPG. */ + #define RATE_MATCH_OPEN_LOOP 3 + +-/* Which connector port. */ +-#define PORT_TP 0x00 +-#define PORT_AUI 0x01 +-#define PORT_MII 0x02 +-#define PORT_FIBRE 0x03 +-#define PORT_BNC 0x04 +-#define PORT_DA 0x05 +-#define PORT_NONE 0xef +-#define PORT_OTHER 0xff +- + /* Which transceiver to use. */ + #define XCVR_INTERNAL 0x00 /* PHY and MAC are in the same package */ + #define XCVR_EXTERNAL 0x01 /* PHY and MAC are in different packages */ +@@ -2256,18 +2261,6 @@ static __inline__ int ethtool_validate_duplex(__u8 duplex) + #define XCVR_DUMMY2 0x03 + #define XCVR_DUMMY3 0x04 + +-/* Enable or disable autonegotiation. */ +-#define AUTONEG_DISABLE 0x00 +-#define AUTONEG_ENABLE 0x01 +- +-/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then +- * the driver is required to renegotiate link +- */ +-#define ETH_TP_MDI_INVALID 0x00 /* status: unknown; control: unsupported */ +-#define ETH_TP_MDI 0x01 /* status: MDI; control: force MDI */ +-#define ETH_TP_MDI_X 0x02 /* status: MDI-X; control: force MDI-X */ +-#define ETH_TP_MDI_AUTO 0x03 /* control: auto-select */ +- + /* Wake-On-Lan options. */ + #define WAKE_PHY (1 << 0) + #define WAKE_UCAST (1 << 1) +@@ -2430,6 +2423,7 @@ enum ethtool_reset_flags { + #define ETH_RESET_SHARED_SHIFT 16 + + ++#ifndef __phoenix__ + /** + * struct ethtool_link_settings - link control and status + * +@@ -2562,6 +2556,7 @@ struct ethtool_link_settings { + * __u32 map_lp_advertising[link_mode_masks_nwords]; + */ + }; ++#endif + + /** + * enum phy_upstream - Represents the upstream component a given PHY device diff --git a/ethtool/patches/6.14/03-add-ifloopback-manipulation.patch b/ethtool/patches/6.14/03-add-ifloopback-manipulation.patch new file mode 100644 index 00000000..17988cf1 --- /dev/null +++ b/ethtool/patches/6.14/03-add-ifloopback-manipulation.patch @@ -0,0 +1,142 @@ +diff --git a/ethtool.8.in b/ethtool.8.in +index 7e164a6..584b157 100644 +--- a/ethtool.8.in ++++ b/ethtool.8.in +@@ -247,6 +247,11 @@ ethtool \- query or control network driver and hardware settings + .A1 on off + .RB ... + .HP ++.B ethtool \-b|\-\-show\-loopback ++.I ethX ++.B ethtool \-B|\-\-config\-loopback ++.I ethX ++.B1 on off + .B ethtool \-p|\-\-identify + .I devname + .RI [ N ] +@@ -794,6 +799,20 @@ Specifies whether Rx ntuple filters and actions should be enabled + Specifies whether receive hashing offload should be enabled + .RE + .TP ++.B \-b \-\-show\-loopback ++Queries the specified ethernet device for loopback mode settings. ++.TP ++.B \-B \-\-config\-loopback ++Configures loopback mode on the specified ethernet device. Possible values ++are: ++.TP ++.A1 on off ++Switches loopback mode ++.B on ++or ++.B off ++for the specified ethernet device. ++.TP + .B \-p \-\-identify + Initiates adapter-specific action intended to enable an operator to + easily identify the adapter by sight. Typically this involves +diff --git a/ethtool.c b/ethtool.c +index f7639d4..c9d8ee2 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -29,6 +29,7 @@ + * * show settings for all devices + */ + ++#include "phoenix/ethtool.h" + #include "internal.h" + #include + #include +@@ -5754,6 +5755,56 @@ static int do_sfec(struct cmd_context *ctx) + + static int do_perqueue(struct cmd_context *ctx); + ++static int do_gloopback(struct cmd_context *ctx) ++{ ++ int err; ++ struct ethtool_value edata = { ++ .cmd = ETHTOOL_GLOOPBACK, ++ .data = 0, ++ }; ++ ++ err = send_ioctl(ctx, &edata); ++ if (err < 0) { ++ perror("Cannot get loopback status"); ++ return err; ++ } ++ printf("%.*s: Loopback is %s\n", IFNAMSIZ, ctx->ifr.ifr_name, edata.data ? "on" : "off"); ++ ++ return err; ++} ++ ++static int do_sloopback(struct cmd_context *ctx) ++{ ++ int err; ++ struct ethtool_value edata; ++ ++ edata.cmd = ETHTOOL_SLOOPBACK; ++ ++ if (ctx->argc != 1) { ++ exit_bad_args_info("{ on|off } should be provided"); ++ } ++ ++ if (strcmp(ctx->argp[0], "on") == 0) { ++ edata.data = 1; ++ } else if (strcmp(ctx->argp[0], "off") == 0) { ++ edata.data = 0; ++ } else { ++ exit_bad_args_info("{ on|off } are the only supported options"); ++ } ++ ++ err = send_ioctl(ctx, &edata); ++ if (err < 0) { ++ perror("Cannot set loopback"); ++ return err; ++ } ++ if (edata.data == ETH_PHY_LOOPBACK_SET_FAILED) { ++ fprintf(stderr, "Cannot set loopback: driver failed to set loopback"); ++ return 1; ++ } ++ ++ return 0; ++} ++ + #ifndef TEST_ETHTOOL + int send_ioctl(struct cmd_context *ctx, void *cmd) + { +@@ -5933,6 +5984,17 @@ static const struct option args[] = { + .func = do_nway_rst, + .help = "Restart N-WAY negotiation" + }, ++ { ++ .opts = "-b|--show-loopback", ++ .func = do_gloopback, ++ .help = "Show device loopback mode", ++ }, ++ { ++ .opts = "-B|--config-loopback", ++ .func = do_sloopback, ++ .help = "{EN|Dis}able device loopback", ++ .xhelp = " [ on|off ]\n", ++ }, + { + .opts = "-p|--identify", + .func = do_phys_id, +diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h +index de358df..5aad5dc 100644 +--- a/uapi/linux/ethtool.h ++++ b/uapi/linux/ethtool.h +@@ -216,11 +216,13 @@ struct ethtool_wolinfo { + __u8 sopass[SOPASS_MAX]; + }; + ++#ifndef __phoenix__ + /* for passing single values */ + struct ethtool_value { + __u32 cmd; + __u32 data; + }; ++#endif + + #define PFC_STORM_PREVENTION_AUTO 0xffff + #define PFC_STORM_PREVENTION_DISABLE 0