# #
###############################################################################
+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
__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}
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}
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
# 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
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
}
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=*)
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}
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