]>
Commit | Line | Data |
---|---|---|
64916b57 AC |
1 | #!/bin/bash |
2 | # SPDX-License-Identifier: GPL-2.0 | |
3 | ||
4 | ALL_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 | " | |
12 | NUM_NETIFS=2 | |
13 | source lib.sh | |
14 | source ethtool_lib.sh | |
15 | ||
16 | h1_create() | |
17 | { | |
18 | simple_if_init $h1 192.0.2.1/24 | |
19 | } | |
20 | ||
21 | h1_destroy() | |
22 | { | |
23 | simple_if_fini $h1 192.0.2.1/24 | |
24 | } | |
25 | ||
26 | h2_create() | |
27 | { | |
28 | simple_if_init $h2 192.0.2.2/24 | |
29 | } | |
30 | ||
31 | h2_destroy() | |
32 | { | |
33 | simple_if_fini $h2 192.0.2.2/24 | |
34 | } | |
35 | ||
36 | setup_prepare() | |
37 | { | |
38 | h1=${NETIFS[p1]} | |
39 | h2=${NETIFS[p2]} | |
40 | ||
41 | h1_create | |
42 | h2_create | |
43 | } | |
44 | ||
45 | cleanup() | |
46 | { | |
47 | pre_cleanup | |
48 | ||
49 | h2_destroy | |
50 | h1_destroy | |
51 | } | |
52 | ||
64916b57 AC |
53 | same_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 | ||
76 | different_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 | ||
100 | combination_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 | ||
122 | hex_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 | ||
131 | subset_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 | ||
157 | speed_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 | ||
180 | advertise_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 | ||
219 | check_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 | ||
262 | different_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 | ||
291 | trap cleanup EXIT | |
292 | ||
293 | setup_prepare | |
294 | setup_wait | |
295 | ||
296 | declare -gA speed_values | |
297 | eval "speed_values=($(speeds_arr_get))" | |
298 | ||
299 | tests_run | |
300 | ||
301 | exit $EXIT_STATUS |