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