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 239 max_speed=${speeds_arr[0]} 240 for current in ${speeds_arr[@]}; do 241 if [[ $current -gt $max_speed ]]; then 242 max_speed=$current 243 fi 244 done 245 246 setup_wait_dev_with_timeout $h1 247 setup_wait_dev_with_timeout $h2 248 chosen_speed=$(ethtool $h1 | grep 'Speed:') 249 chosen_speed=${chosen_speed%"Mb/s"*} 250 chosen_speed=${chosen_speed#*"Speed: "} 251 ((chosen_speed == max_speed)) 252 check_err $? "h1 advertise $speed_to_advertise, h2 sync to speed $chosen_speed" 253 254 log_test "check highest speed" 255 256 ethtool -s $h2 autoneg on 257 ethtool -s $h1 autoneg on 258} 259 260different_speeds_autoneg_on() 261{ 262 # Test that when we configure links to advertise different speeds, 263 # links are not up and ping fails. 264 RET=0 265 266 local -a speeds=($(different_speeds_get $h1 $h2 1 1)) 267 local speed1=${speeds[0]} 268 local speed2=${speeds[1]} 269 270 speed1=$(hex_speed_value_get $speed1) 271 speed2=$(hex_speed_value_get $speed2) 272 273 ethtool_set $h1 advertise $speed1 274 ethtool_set $h2 advertise $speed2 275 276 if (($RET)); then 277 setup_wait_dev_with_timeout $h1 278 setup_wait_dev_with_timeout $h2 279 ping_do $h1 192.0.2.2 280 check_fail $? "ping with different speeds autoneg on" 281 fi 282 283 log_test "advertise different speeds autoneg on" 284 285 ethtool -s $h2 autoneg on 286 ethtool -s $h1 autoneg on 287} 288 289skip_on_veth 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