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