From 5b1fd814603fd77e352e4f106a2203d587a84fbd Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 21 Sep 2018 00:18:45 +0100 Subject: [PATCH] port: ethernet: Use combined setting for advertised link speeds This patch removes the speed and duplex settings and replaces them with a configuration option that allows to change advertised link speeds to a certain speed. Signed-off-by: Michael Tremer --- src/functions/functions.device | 78 ++++++++++++++++++++-------------- src/hooks/ports/ethernet | 54 ++++++++--------------- 2 files changed, 63 insertions(+), 69 deletions(-) diff --git a/src/functions/functions.device b/src/functions/functions.device index 412099cd..8384273d 100644 --- a/src/functions/functions.device +++ b/src/functions/functions.device @@ -19,6 +19,16 @@ # # ############################################################################### +declare -A DEVICE_LINK_SPEEDS=( + [10BaseT-Half]=0x1 + [10BaseT-Full]=0x2 + [100BaseT-Half]=0x4 + [100BaseT-Full]=0x8 + [1000BaseT-Half]=0x10 + [1000BaseT-Full]=0x20 + [10000BaseT-Full]=0x1000 +) + device_list() { local devices @@ -881,6 +891,41 @@ device_get_tx_errors() { __device_get_file ${device} statistics/tx_errors } +device_advertise_link_speeds() { + local device="${1}" + shift + + assert isset device + + # Advertised modes in hex + local advertise=0 + + local mode + for mode in $@; do + local m="${DEVICE_LINK_SPEEDS[${mode}]}" + if isset m; then + advertise="$(( advertise | m ))" + fi + done + + # If nothing was selected, we reset and enable everything + if [ ${advertise} -eq 0 ]; then + advertise=0xffffff + fi + + # Enable auto-negotiation + cmd_quiet ethtool --change "${device}" autoneg on + + # Set advertised link speeds + if ! cmd_quiet ethtool --change "${device}" advertise "0x$(hex "${advertise}")"; then + log ERROR "Could not set link modes of ${device}: $@" + return ${EXIT_ERROR} + fi + + log DEBUG "Set device link modes of ${device} to $@" + return ${EXIT_ERROR} +} + device_get_speed() { local device=${1} @@ -895,23 +940,6 @@ device_get_speed() { print "${speed}" } -device_set_speed() { - local device="${1}" - assert isset device - - local speed="${2}" - assert isinteger speed - - if ! cmd_quiet ethtool --change "${device}" speed "${speed}"; then - log ERROR "Could not set speed of ${device} to ${speed} MBit/s" - return ${EXIT_ERROR} - fi - - log DEBUG "Set speed of ${device} to ${speed} MBit/s" - - return ${EXIT_OK} -} - device_get_duplex() { local device=${1} @@ -927,22 +955,6 @@ device_get_duplex() { esac } -device_set_duplex() { - local device="${1}" - assert isset device - - local duplex="${2}" - assert isset duplex - - if ! cmd_quiet ethtool --change "${device}" duplex "${duplex}"; then - log ERROR "Could not set ${device} to ${duplex}-duplex mode" - return ${EXIT_ERROR} - fi - - log DEBUG "Set ${device} to ${duplex}-duplex mode" - return ${EXIT_OK} -} - device_get_link_string() { local device="${1}" assert isset device diff --git a/src/hooks/ports/ethernet b/src/hooks/ports/ethernet index 2db7f488..a52afe09 100644 --- a/src/hooks/ports/ethernet +++ b/src/hooks/ports/ethernet @@ -24,16 +24,10 @@ # Default MTU DEFAULT_MTU=1500 -# Selectable speeds in MBit/s -VALID_SPEEDS="10000 1000 100 10" - -# We can run in full or half duplex -VALID_DUPLEXES="full half" - # DEVICE equals the actual MAC address of the device. # If ADDRESS is set, the device will get ADDRESS set for its MAC address. -HOOK_SETTINGS="HOOK ADDRESS DEVICE DUPLEX MTU SPEED" +HOOK_SETTINGS="HOOK ADDRESS ADVERTISED_LINK_SPEEDS DEVICE MTU" hook_check_settings() { assert ismac DEVICE @@ -46,12 +40,11 @@ hook_check_settings() { assert mtu_is_valid "ethernet" "${MTU}" fi - if isset DUPLEX; then - assert isoneof DUPLEX ${VALID_DUPLEXES} - fi - - if isset SPEED; then - assert isoneof SPEED ${VALID_SPEEDS} + if isset MODES; then + local mode + for mode in ${MODES}; do + assert [ -n "${DEVICE_LINK_SPEEDS[${mode}]}" ] + done fi } @@ -67,13 +60,16 @@ hook_parse_cmdline() { fi ;; - --duplex=*) - DUPLEX="$(cli_get_val "${1}")" + --advertised-link-speeds=*) + ADVERTISED_LINK_SPEEDS="$(cli_get_val "${1}")" - if ! isoneof DUPLEX ${VALID_DUPLEXES}; then - error "Invalid duplex mode: ${DUPLEX}" - return ${EXIT_ERROR} - fi + local speed + for speed in ${ADVERTISED_LINK_SPEEDS}; do + if [ -z "${DEVICE_LINK_SPEEDS[${speed}]}" ]; then + error "Unsupported link speed: ${speed}" + return ${EXIT_ERROR} + fi + done ;; --mtu=*) @@ -85,15 +81,6 @@ hook_parse_cmdline() { fi ;; - --speed=*) - SPEED="$(cli_get_val "${1}")" - - if ! isoneof SPEED ${VALID_SPEEDS}; then - error "Invalid speed: ${SPEED}" - return ${EXIT_ERROR} - fi - ;; - *) error "Unknown argument: ${1}" return ${EXIT_ERROR} @@ -128,14 +115,9 @@ hook_up() { device_set_mtu "${port}" "${DEFAULT_MTU}" fi - # Set duplex mode - if isset DUPLEX; then - device_set_duplex "${port}" "${DUPLEX}" - fi - - # Set speed - if isset SPEED; then - device_set_speed "${port}" "${SPEED}" + # Set link speeds + if isset ADVERTISED_LINK_SPEEDS; then + device_advertise_link_speeds "${port}" ${ADVERTISED_LINK_SPEEDS} fi # Bring up the device -- 2.47.2