298 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4ALL_TESTS="5 same_speeds_autoneg_off6 different_speeds_autoneg_off7 combination_of_neg_on_and_off8 advertise_subset_of_speeds9 check_highest_speed_is_chosen10 different_speeds_autoneg_on11"12NUM_NETIFS=213lib_dir=$(dirname "$0")14source "$lib_dir"/../../../net/forwarding/lib.sh15source ethtool_lib.sh16 17h1_create()18{19 simple_if_init $h1 192.0.2.1/2420}21 22h1_destroy()23{24 simple_if_fini $h1 192.0.2.1/2425}26 27h2_create()28{29 simple_if_init $h2 192.0.2.2/2430}31 32h2_destroy()33{34 simple_if_fini $h2 192.0.2.2/2435}36 37setup_prepare()38{39 h1=${NETIFS[p1]}40 h2=${NETIFS[p2]}41 42 h1_create43 h2_create44}45 46cleanup()47{48 pre_cleanup49 50 h2_destroy51 h1_destroy52}53 54same_speeds_autoneg_off()55{56 # Check that when each of the reported speeds is forced, the links come57 # up and are operational.58 local -a speeds_arr=($(common_speeds_get $h1 $h2 0 0))59 60 for speed in "${speeds_arr[@]}"; do61 RET=062 ethtool_set $h1 speed $speed autoneg off63 ethtool_set $h2 speed $speed autoneg off64 65 setup_wait_dev_with_timeout $h166 setup_wait_dev_with_timeout $h267 ping_do $h1 192.0.2.268 check_err $? "ping with speed $speed autoneg off"69 log_test "force speed $speed on both ends"70 done71 72 ethtool -s $h2 autoneg on73 ethtool -s $h1 autoneg on74}75 76different_speeds_autoneg_off()77{78 # Test that when we force different speeds, links are not up and ping79 # fails.80 RET=081 82 local -a speeds_arr=($(different_speeds_get $h1 $h2 0 0))83 local speed1=${speeds_arr[0]}84 local speed2=${speeds_arr[1]}85 86 ethtool_set $h1 speed $speed1 autoneg off87 ethtool_set $h2 speed $speed2 autoneg off88 89 setup_wait_dev_with_timeout $h190 setup_wait_dev_with_timeout $h291 ping_do $h1 192.0.2.292 check_fail $? "ping with different speeds"93 94 log_test "force of different speeds autoneg off"95 96 ethtool -s $h2 autoneg on97 ethtool -s $h1 autoneg on98}99 100combination_of_neg_on_and_off()101{102 # Test that when one device is forced to a speed supported by both103 # endpoints and the other device is configured to autoneg on, the links104 # are up and ping passes.105 local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1))106 107 for speed in "${speeds_arr[@]}"; do108 RET=0109 ethtool_set $h1 speed $speed autoneg off110 111 setup_wait_dev_with_timeout $h1112 setup_wait_dev_with_timeout $h2113 ping_do $h1 192.0.2.2114 check_err $? "ping with h1-speed=$speed autoneg off, h2 autoneg on"115 log_test "force speed $speed vs. autoneg"116 done117 118 ethtool -s $h1 autoneg on119}120 121hex_speed_value_get()122{123 local speed=$1; shift124 125 local shift_size=${speed_values[$speed]}126 speed=$((0x1 << $"shift_size"))127 printf "%#x" "$speed"128}129 130subset_of_common_speeds_get()131{132 local dev1=$1; shift133 local dev2=$1; shift134 local adver=$1; shift135 136 local -a speeds_arr=($(common_speeds_get $dev1 $dev2 0 $adver))137 local speed_to_advertise=0138 local speed_to_remove=${speeds_arr[0]}139 speed_to_remove+='base'140 141 local -a speeds_mode_arr=($(common_speeds_get $dev1 $dev2 1 $adver))142 143 for speed in ${speeds_mode_arr[@]}; do144 if [[ $speed != $speed_to_remove* ]]; then145 speed=$(hex_speed_value_get $speed)146 speed_to_advertise=$(($speed_to_advertise | \147 $speed))148 fi149 150 done151 152 # Convert to hex.153 printf "%#x" "$speed_to_advertise"154}155 156speed_to_advertise_get()157{158 # The function returns the hex number that is composed by OR-ing all159 # the modes corresponding to the provided speed.160 local speed_without_mode=$1; shift161 local supported_speeds=("$@"); shift162 local speed_to_advertise=0163 164 speed_without_mode+='base'165 166 for speed in ${supported_speeds[@]}; do167 if [[ $speed == $speed_without_mode* ]]; then168 speed=$(hex_speed_value_get $speed)169 speed_to_advertise=$(($speed_to_advertise | \170 $speed))171 fi172 173 done174 175 # Convert to hex.176 printf "%#x" "$speed_to_advertise"177}178 179advertise_subset_of_speeds()180{181 # Test that when one device advertises a subset of speeds and another182 # advertises a specific speed (but all modes of this speed), the links183 # are up and ping passes.184 RET=0185 186 local speed_1_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1)187 ethtool_set $h1 advertise $speed_1_to_advertise188 189 if [ $RET != 0 ]; then190 log_test "advertise subset of speeds"191 return192 fi193 194 local -a speeds_arr_without_mode=($(common_speeds_get $h1 $h2 0 1))195 # Check only speeds that h1 advertised. Remove the first speed.196 unset speeds_arr_without_mode[0]197 local -a speeds_arr_with_mode=($(common_speeds_get $h1 $h2 1 1))198 199 for speed_value in ${speeds_arr_without_mode[@]}; do200 RET=0201 local speed_2_to_advertise=$(speed_to_advertise_get $speed_value \202 "${speeds_arr_with_mode[@]}")203 ethtool_set $h2 advertise $speed_2_to_advertise204 205 setup_wait_dev_with_timeout $h1206 setup_wait_dev_with_timeout $h2207 ping_do $h1 192.0.2.2208 check_err $? "ping with h1=$speed_1_to_advertise, h2=$speed_2_to_advertise ($speed_value)"209 210 log_test "advertise $speed_1_to_advertise vs. $speed_2_to_advertise"211 done212 213 ethtool -s $h2 autoneg on214 ethtool -s $h1 autoneg on215}216 217check_highest_speed_is_chosen()218{219 # Test that when one device advertises a subset of speeds, the other220 # chooses the highest speed. This test checks configuration without221 # traffic.222 RET=0223 224 local max_speed225 local chosen_speed226 local speed_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1)227 228 ethtool_set $h1 advertise $speed_to_advertise229 230 if [ $RET != 0 ]; then231 log_test "check highest speed"232 return233 fi234 235 local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1))236 237 max_speed=${speeds_arr[0]}238 for current in ${speeds_arr[@]}; do239 if [[ $current -gt $max_speed ]]; then240 max_speed=$current241 fi242 done243 244 setup_wait_dev_with_timeout $h1245 setup_wait_dev_with_timeout $h2246 chosen_speed=$(ethtool $h1 | grep 'Speed:')247 chosen_speed=${chosen_speed%"Mb/s"*}248 chosen_speed=${chosen_speed#*"Speed: "}249 ((chosen_speed == max_speed))250 check_err $? "h1 advertise $speed_to_advertise, h2 sync to speed $chosen_speed"251 252 log_test "check highest speed"253 254 ethtool -s $h2 autoneg on255 ethtool -s $h1 autoneg on256}257 258different_speeds_autoneg_on()259{260 # Test that when we configure links to advertise different speeds,261 # links are not up and ping fails.262 RET=0263 264 local -a speeds=($(different_speeds_get $h1 $h2 1 1))265 local speed1=${speeds[0]}266 local speed2=${speeds[1]}267 268 speed1=$(hex_speed_value_get $speed1)269 speed2=$(hex_speed_value_get $speed2)270 271 ethtool_set $h1 advertise $speed1272 ethtool_set $h2 advertise $speed2273 274 if (($RET)); then275 setup_wait_dev_with_timeout $h1276 setup_wait_dev_with_timeout $h2277 ping_do $h1 192.0.2.2278 check_fail $? "ping with different speeds autoneg on"279 fi280 281 log_test "advertise different speeds autoneg on"282 283 ethtool -s $h2 autoneg on284 ethtool -s $h1 autoneg on285}286 287trap cleanup EXIT288 289setup_prepare290setup_wait291 292declare -gA speed_values293eval "speed_values=($(speeds_arr_get))"294 295tests_run296 297exit $EXIT_STATUS298