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