1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4ALL_TESTS=" 5 same_speeds_autoneg_off 6 different_speeds_autoneg_off 7 combination_of_neg_on_and_off 8 advertise_subset_of_speeds 9 check_highest_speed_is_chosen 10 different_speeds_autoneg_on 11" 12NUM_NETIFS=2 13source lib.sh 14source ethtool_lib.sh 15 16h1_create() 17{ 18 simple_if_init $h1 192.0.2.1/24 19} 20 21h1_destroy() 22{ 23 simple_if_fini $h1 192.0.2.1/24 24} 25 26h2_create() 27{ 28 simple_if_init $h2 192.0.2.2/24 29} 30 31h2_destroy() 32{ 33 simple_if_fini $h2 192.0.2.2/24 34} 35 36setup_prepare() 37{ 38 h1=${NETIFS[p1]} 39 h2=${NETIFS[p2]} 40 41 h1_create 42 h2_create 43} 44 45cleanup() 46{ 47 pre_cleanup 48 49 h2_destroy 50 h1_destroy 51} 52 53same_speeds_autoneg_off() 54{ 55 # Check that when each of the reported speeds is forced, the links come 56 # up and are operational. 57 local -a speeds_arr=($(common_speeds_get $h1 $h2 0 0)) 58 59 for speed in "${speeds_arr[@]}"; do 60 RET=0 61 ethtool_set $h1 speed $speed autoneg off 62 ethtool_set $h2 speed $speed autoneg off 63 64 setup_wait_dev_with_timeout $h1 65 setup_wait_dev_with_timeout $h2 66 ping_do $h1 192.0.2.2 67 check_err $? "speed $speed autoneg off" 68 log_test "force of same speed autoneg off" 69 log_info "speed = $speed" 70 done 71 72 ethtool -s $h2 autoneg on 73 ethtool -s $h1 autoneg on 74} 75 76different_speeds_autoneg_off() 77{ 78 # Test that when we force different speeds, links are not up and ping 79 # fails. 80 RET=0 81 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 off 87 ethtool_set $h2 speed $speed2 autoneg off 88 89 setup_wait_dev_with_timeout $h1 90 setup_wait_dev_with_timeout $h2 91 ping_do $h1 192.0.2.2 92 check_fail $? "ping with different speeds" 93 94 log_test "force of different speeds autoneg off" 95 96 ethtool -s $h2 autoneg on 97 ethtool -s $h1 autoneg on 98} 99 100combination_of_neg_on_and_off() 101{ 102 # Test that when one device is forced to a speed supported by both 103 # endpoints and the other device is configured to autoneg on, the links 104 # are up and ping passes. 105 local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1)) 106 107 for speed in "${speeds_arr[@]}"; do 108 RET=0 109 ethtool_set $h1 speed $speed autoneg off 110 111 setup_wait_dev_with_timeout $h1 112 setup_wait_dev_with_timeout $h2 113 ping_do $h1 192.0.2.2 114 check_err $? "h1-speed=$speed autoneg off, h2 autoneg on" 115 log_test "one side with autoneg off and another with autoneg on" 116 log_info "force speed = $speed" 117 done 118 119 ethtool -s $h1 autoneg on 120} 121 122hex_speed_value_get() 123{ 124 local speed=$1; shift 125 126 local shift_size=${speed_values[$speed]} 127 speed=$((0x1 << $"shift_size")) 128 printf "%#x" "$speed" 129} 130 131subset_of_common_speeds_get() 132{ 133 local dev1=$1; shift 134 local dev2=$1; shift 135 local adver=$1; shift 136 137 local -a speeds_arr=($(common_speeds_get $dev1 $dev2 0 $adver)) 138 local speed_to_advertise=0 139 local speed_to_remove=${speeds_arr[0]} 140 speed_to_remove+='base' 141 142 local -a speeds_mode_arr=($(common_speeds_get $dev1 $dev2 1 $adver)) 143 144 for speed in ${speeds_mode_arr[@]}; do 145 if [[ $speed != $speed_to_remove* ]]; then 146 speed=$(hex_speed_value_get $speed) 147 speed_to_advertise=$(($speed_to_advertise | \ 148 $speed)) 149 fi 150 151 done 152 153 # Convert to hex. 154 printf "%#x" "$speed_to_advertise" 155} 156 157speed_to_advertise_get() 158{ 159 # The function returns the hex number that is composed by OR-ing all 160 # the modes corresponding to the provided speed. 161 local speed_without_mode=$1; shift 162 local supported_speeds=("$@"); shift 163 local speed_to_advertise=0 164 165 speed_without_mode+='base' 166 167 for speed in ${supported_speeds[@]}; do 168 if [[ $speed == $speed_without_mode* ]]; then 169 speed=$(hex_speed_value_get $speed) 170 speed_to_advertise=$(($speed_to_advertise | \ 171 $speed)) 172 fi 173 174 done 175 176 # Convert to hex. 177 printf "%#x" "$speed_to_advertise" 178} 179 180advertise_subset_of_speeds() 181{ 182 # Test that when one device advertises a subset of speeds and another 183 # advertises a specific speed (but all modes of this speed), the links 184 # are up and ping passes. 185 RET=0 186 187 local speed_1_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1) 188 ethtool_set $h1 advertise $speed_1_to_advertise 189 190 if [ $RET != 0 ]; then 191 log_test "advertise subset of speeds" 192 return 193 fi 194 195 local -a speeds_arr_without_mode=($(common_speeds_get $h1 $h2 0 1)) 196 # Check only speeds that h1 advertised. Remove the first speed. 197 unset speeds_arr_without_mode[0] 198 local -a speeds_arr_with_mode=($(common_speeds_get $h1 $h2 1 1)) 199 200 for speed_value in ${speeds_arr_without_mode[@]}; do 201 RET=0 202 local speed_2_to_advertise=$(speed_to_advertise_get $speed_value \ 203 "${speeds_arr_with_mode[@]}") 204 ethtool_set $h2 advertise $speed_2_to_advertise 205 206 setup_wait_dev_with_timeout $h1 207 setup_wait_dev_with_timeout $h2 208 ping_do $h1 192.0.2.2 209 check_err $? "h1=$speed_1_to_advertise, h2=$speed_2_to_advertise ($speed_value)" 210 211 log_test "advertise subset of speeds" 212 log_info "h1=$speed_1_to_advertise, h2=$speed_2_to_advertise" 213 done 214 215 ethtool -s $h2 autoneg on 216 ethtool -s $h1 autoneg on 217} 218 219check_highest_speed_is_chosen() 220{ 221 # Test that when one device advertises a subset of speeds, the other 222 # chooses the highest speed. This test checks configuration without 223 # traffic. 224 RET=0 225 226 local max_speed 227 local chosen_speed 228 local speed_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1) 229 230 ethtool_set $h1 advertise $speed_to_advertise 231 232 if [ $RET != 0 ]; then 233 log_test "check highest speed" 234 return 235 fi 236 237 local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1)) 238 # Remove the first speed, h1 does not advertise this speed. 239 unset speeds_arr[0] 240 241 max_speed=${speeds_arr[0]} 242 for current in ${speeds_arr[@]}; do 243 if [[ $current -gt $max_speed ]]; then 244 max_speed=$current 245 fi 246 done 247 248 setup_wait_dev_with_timeout $h1 249 setup_wait_dev_with_timeout $h2 250 chosen_speed=$(ethtool $h1 | grep 'Speed:') 251 chosen_speed=${chosen_speed%"Mb/s"*} 252 chosen_speed=${chosen_speed#*"Speed: "} 253 ((chosen_speed == max_speed)) 254 check_err $? "h1 advertise $speed_to_advertise, h2 sync to speed $chosen_speed" 255 256 log_test "check highest speed" 257 258 ethtool -s $h2 autoneg on 259 ethtool -s $h1 autoneg on 260} 261 262different_speeds_autoneg_on() 263{ 264 # Test that when we configure links to advertise different speeds, 265 # links are not up and ping fails. 266 RET=0 267 268 local -a speeds=($(different_speeds_get $h1 $h2 1 1)) 269 local speed1=${speeds[0]} 270 local speed2=${speeds[1]} 271 272 speed1=$(hex_speed_value_get $speed1) 273 speed2=$(hex_speed_value_get $speed2) 274 275 ethtool_set $h1 advertise $speed1 276 ethtool_set $h2 advertise $speed2 277 278 if (($RET)); then 279 setup_wait_dev_with_timeout $h1 280 setup_wait_dev_with_timeout $h2 281 ping_do $h1 192.0.2.2 282 check_fail $? "ping with different speeds autoneg on" 283 fi 284 285 log_test "advertise different speeds autoneg on" 286 287 ethtool -s $h2 autoneg on 288 ethtool -s $h1 autoneg on 289} 290 291trap cleanup EXIT 292 293setup_prepare 294setup_wait 295 296declare -gA speed_values 297eval "speed_values=($(speeds_arr_get))" 298 299tests_run 300 301exit $EXIT_STATUS 302