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