xref: /linux/tools/testing/selftests/drivers/net/mlxsw/ethtool_lanes.sh (revision c771600c6af14749609b49565ffb4cac2959710d)
1f72e2f48SDanielle Ratson#!/bin/bash
2f72e2f48SDanielle Ratson# SPDX-License-Identifier: GPL-2.0
3f72e2f48SDanielle Ratson
4f72e2f48SDanielle Ratsonlib_dir=$(dirname $0)/../../../net/forwarding
5f8669d7bSIdo Schimmelethtool_lib_dir=$(dirname $0)/../hw
6f72e2f48SDanielle Ratson
7f72e2f48SDanielle RatsonALL_TESTS="
8f72e2f48SDanielle Ratson	autoneg
9f72e2f48SDanielle Ratson	autoneg_force_mode
10f72e2f48SDanielle Ratson"
11f72e2f48SDanielle Ratson
12f72e2f48SDanielle RatsonNUM_NETIFS=2
13f72e2f48SDanielle Ratson: ${TIMEOUT:=30000} # ms
14f72e2f48SDanielle Ratsonsource $lib_dir/lib.sh
15f8669d7bSIdo Schimmelsource $ethtool_lib_dir/ethtool_lib.sh
16f72e2f48SDanielle Ratson
17f72e2f48SDanielle Ratsonsetup_prepare()
18f72e2f48SDanielle Ratson{
19f72e2f48SDanielle Ratson	swp1=${NETIFS[p1]}
20f72e2f48SDanielle Ratson	swp2=${NETIFS[p2]}
21f72e2f48SDanielle Ratson
22f72e2f48SDanielle Ratson	ip link set dev $swp1 up
23f72e2f48SDanielle Ratson	ip link set dev $swp2 up
24f72e2f48SDanielle Ratson
25f72e2f48SDanielle Ratson	busywait "$TIMEOUT" wait_for_port_up ethtool $swp2
26f72e2f48SDanielle Ratson	check_err $? "ports did not come up"
27f72e2f48SDanielle Ratson
288d612ed4SDanielle Ratson	busywait $TIMEOUT sh -c "ethtool $swp1 | grep -q Lanes:"
298d612ed4SDanielle Ratson	if [[ $? -ne 0 ]]; then
30f72e2f48SDanielle Ratson		log_test "SKIP: driver does not support lanes setting"
31f72e2f48SDanielle Ratson		exit 1
32f72e2f48SDanielle Ratson	fi
33f72e2f48SDanielle Ratson
34f72e2f48SDanielle Ratson	ip link set dev $swp2 down
35f72e2f48SDanielle Ratson	ip link set dev $swp1 down
36f72e2f48SDanielle Ratson}
37f72e2f48SDanielle Ratson
38f72e2f48SDanielle Ratsoncheck_lanes()
39f72e2f48SDanielle Ratson{
40f72e2f48SDanielle Ratson	local dev=$1; shift
41f72e2f48SDanielle Ratson	local lanes=$1; shift
42f72e2f48SDanielle Ratson	local max_speed=$1; shift
43f72e2f48SDanielle Ratson	local chosen_lanes
44f72e2f48SDanielle Ratson
45f72e2f48SDanielle Ratson	chosen_lanes=$(ethtool $dev | grep 'Lanes:')
46f72e2f48SDanielle Ratson	chosen_lanes=${chosen_lanes#*"Lanes: "}
47f72e2f48SDanielle Ratson
48f72e2f48SDanielle Ratson	((chosen_lanes == lanes))
49f72e2f48SDanielle Ratson	check_err $? "swp1 advertise $max_speed and $lanes, devs sync to $chosen_lanes"
50f72e2f48SDanielle Ratson}
51f72e2f48SDanielle Ratson
52f72e2f48SDanielle Ratsoncheck_unsupported_lanes()
53f72e2f48SDanielle Ratson{
54f72e2f48SDanielle Ratson	local dev=$1; shift
55f72e2f48SDanielle Ratson	local max_speed=$1; shift
56f72e2f48SDanielle Ratson	local max_lanes=$1; shift
57f72e2f48SDanielle Ratson	local autoneg=$1; shift
58f72e2f48SDanielle Ratson	local autoneg_str=""
59f72e2f48SDanielle Ratson
60f72e2f48SDanielle Ratson	local unsupported_lanes=$((max_lanes *= 2))
61f72e2f48SDanielle Ratson
62f72e2f48SDanielle Ratson	if [[ $autoneg -eq 0 ]]; then
63f72e2f48SDanielle Ratson		autoneg_str="autoneg off"
64f72e2f48SDanielle Ratson	fi
65f72e2f48SDanielle Ratson
66f72e2f48SDanielle Ratson	ethtool -s $swp1 speed $max_speed lanes $unsupported_lanes $autoneg_str &> /dev/null
67f72e2f48SDanielle Ratson	check_fail $? "Unsuccessful $unsupported_lanes lanes setting was expected"
68f72e2f48SDanielle Ratson}
69f72e2f48SDanielle Ratson
70f72e2f48SDanielle Ratsonmax_speed_and_lanes_get()
71f72e2f48SDanielle Ratson{
72f72e2f48SDanielle Ratson	local dev=$1; shift
73f72e2f48SDanielle Ratson	local arr=("$@")
74f72e2f48SDanielle Ratson	local max_lanes
75f72e2f48SDanielle Ratson	local max_speed
76f72e2f48SDanielle Ratson	local -a lanes_arr
77f72e2f48SDanielle Ratson	local -a speeds_arr
78f72e2f48SDanielle Ratson	local -a max_values
79f72e2f48SDanielle Ratson
80f72e2f48SDanielle Ratson	for ((i=0; i<${#arr[@]}; i+=2)); do
81f72e2f48SDanielle Ratson		speeds_arr+=("${arr[$i]}")
82f72e2f48SDanielle Ratson		lanes_arr+=("${arr[i+1]}")
83f72e2f48SDanielle Ratson	done
84f72e2f48SDanielle Ratson
85f72e2f48SDanielle Ratson	max_values+=($(get_max "${speeds_arr[@]}"))
86f72e2f48SDanielle Ratson	max_values+=($(get_max "${lanes_arr[@]}"))
87f72e2f48SDanielle Ratson
88f72e2f48SDanielle Ratson	echo ${max_values[@]}
89f72e2f48SDanielle Ratson}
90f72e2f48SDanielle Ratson
91f72e2f48SDanielle Ratsonsearch_linkmode()
92f72e2f48SDanielle Ratson{
93f72e2f48SDanielle Ratson	local speed=$1; shift
94f72e2f48SDanielle Ratson	local lanes=$1; shift
95f72e2f48SDanielle Ratson	local arr=("$@")
96f72e2f48SDanielle Ratson
97f72e2f48SDanielle Ratson	for ((i=0; i<${#arr[@]}; i+=2)); do
98f72e2f48SDanielle Ratson		if [[ $speed -eq ${arr[$i]} && $lanes -eq ${arr[i+1]} ]]; then
99f72e2f48SDanielle Ratson			return 1
100f72e2f48SDanielle Ratson		fi
101f72e2f48SDanielle Ratson	done
102f72e2f48SDanielle Ratson	return 0
103f72e2f48SDanielle Ratson}
104f72e2f48SDanielle Ratson
105f72e2f48SDanielle Ratsonautoneg()
106f72e2f48SDanielle Ratson{
107f72e2f48SDanielle Ratson	RET=0
108f72e2f48SDanielle Ratson
109f72e2f48SDanielle Ratson	local lanes
110f72e2f48SDanielle Ratson	local max_speed
111f72e2f48SDanielle Ratson	local max_lanes
112f72e2f48SDanielle Ratson
113f72e2f48SDanielle Ratson	local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1))
114f72e2f48SDanielle Ratson	local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}"))
115f72e2f48SDanielle Ratson	max_speed=${max_values[0]}
116f72e2f48SDanielle Ratson	max_lanes=${max_values[1]}
117f72e2f48SDanielle Ratson
118f72e2f48SDanielle Ratson	lanes=$max_lanes
119f72e2f48SDanielle Ratson
120f72e2f48SDanielle Ratson	while [[ $lanes -ge 1 ]]; do
121f72e2f48SDanielle Ratson		search_linkmode $max_speed $lanes "${linkmodes_params[@]}"
122f72e2f48SDanielle Ratson		if [[ $? -eq 1 ]]; then
123f72e2f48SDanielle Ratson			ethtool_set $swp1 speed $max_speed lanes $lanes
124f72e2f48SDanielle Ratson			ip link set dev $swp1 up
125f72e2f48SDanielle Ratson			ip link set dev $swp2 up
1268d612ed4SDanielle Ratson
1278d612ed4SDanielle Ratson			busywait $TIMEOUT sh -c "ethtool $swp1 | grep -q Lanes:"
1288d612ed4SDanielle Ratson			check_err $? "Lanes parameter is not presented on time"
129f72e2f48SDanielle Ratson
130f72e2f48SDanielle Ratson			check_lanes $swp1 $lanes $max_speed
131f72e2f48SDanielle Ratson			log_test "$lanes lanes is autonegotiated"
132f72e2f48SDanielle Ratson		fi
133f72e2f48SDanielle Ratson		let $((lanes /= 2))
134f72e2f48SDanielle Ratson	done
135f72e2f48SDanielle Ratson
136f72e2f48SDanielle Ratson	check_unsupported_lanes $swp1 $max_speed $max_lanes 1
137f72e2f48SDanielle Ratson	log_test "Lanes number larger than max width is not set"
138f72e2f48SDanielle Ratson
139f72e2f48SDanielle Ratson	ip link set dev $swp2 down
140f72e2f48SDanielle Ratson	ip link set dev $swp1 down
141f72e2f48SDanielle Ratson}
142f72e2f48SDanielle Ratson
143f72e2f48SDanielle Ratsonautoneg_force_mode()
144f72e2f48SDanielle Ratson{
145f72e2f48SDanielle Ratson	RET=0
146f72e2f48SDanielle Ratson
147f72e2f48SDanielle Ratson	local lanes
148f72e2f48SDanielle Ratson	local max_speed
149f72e2f48SDanielle Ratson	local max_lanes
150f72e2f48SDanielle Ratson
151f72e2f48SDanielle Ratson	local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1))
152f72e2f48SDanielle Ratson	local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}"))
153f72e2f48SDanielle Ratson	max_speed=${max_values[0]}
154f72e2f48SDanielle Ratson	max_lanes=${max_values[1]}
155f72e2f48SDanielle Ratson
156f72e2f48SDanielle Ratson	lanes=$max_lanes
157f72e2f48SDanielle Ratson
158f72e2f48SDanielle Ratson	while [[ $lanes -ge 1 ]]; do
159f72e2f48SDanielle Ratson		search_linkmode $max_speed $lanes "${linkmodes_params[@]}"
160f72e2f48SDanielle Ratson		if [[ $? -eq 1 ]]; then
161f72e2f48SDanielle Ratson			ethtool_set $swp1 speed $max_speed lanes $lanes autoneg off
162f72e2f48SDanielle Ratson			ethtool_set $swp2 speed $max_speed lanes $lanes autoneg off
163f72e2f48SDanielle Ratson			ip link set dev $swp1 up
164f72e2f48SDanielle Ratson			ip link set dev $swp2 up
1658d612ed4SDanielle Ratson
1668d612ed4SDanielle Ratson			busywait $TIMEOUT sh -c "ethtool $swp1 | grep -q Lanes:"
1678d612ed4SDanielle Ratson			check_err $? "Lanes parameter is not presented on time"
168f72e2f48SDanielle Ratson
169f72e2f48SDanielle Ratson			check_lanes $swp1 $lanes $max_speed
170f72e2f48SDanielle Ratson			log_test "Autoneg off, $lanes lanes detected during force mode"
171f72e2f48SDanielle Ratson		fi
172f72e2f48SDanielle Ratson		let $((lanes /= 2))
173f72e2f48SDanielle Ratson	done
174f72e2f48SDanielle Ratson
175f72e2f48SDanielle Ratson	check_unsupported_lanes $swp1 $max_speed $max_lanes 0
176f72e2f48SDanielle Ratson	log_test "Lanes number larger than max width is not set"
177f72e2f48SDanielle Ratson
178f72e2f48SDanielle Ratson	ip link set dev $swp2 down
179f72e2f48SDanielle Ratson	ip link set dev $swp1 down
180f72e2f48SDanielle Ratson
181f72e2f48SDanielle Ratson	ethtool -s $swp2 autoneg on
182f72e2f48SDanielle Ratson	ethtool -s $swp1 autoneg on
183f72e2f48SDanielle Ratson}
184f72e2f48SDanielle Ratson
185f72e2f48SDanielle Ratsoncheck_ethtool_lanes_support
186f72e2f48SDanielle Ratsonsetup_prepare
187f72e2f48SDanielle Ratson
188f72e2f48SDanielle Ratsontests_run
189f72e2f48SDanielle Ratson
190f72e2f48SDanielle Ratsonexit $EXIT_STATUS
191