summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/drivers/net/mlxsw/ethtool_lanes.sh
blob: 91891b9418d7664a27832274b76845aa95d3f4d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

lib_dir=$(dirname $0)/../../../net/forwarding

ALL_TESTS="
	autoneg
	autoneg_force_mode
"

NUM_NETIFS=2
: ${TIMEOUT:=30000} # ms
source $lib_dir/lib.sh
source $lib_dir/ethtool_lib.sh

setup_prepare()
{
	swp1=${NETIFS[p1]}
	swp2=${NETIFS[p2]}

	ip link set dev $swp1 up
	ip link set dev $swp2 up

	busywait "$TIMEOUT" wait_for_port_up ethtool $swp2
	check_err $? "ports did not come up"

	local lanes_exist=$(ethtool $swp1 | grep 'Lanes:')
	if [[ -z $lanes_exist ]]; then
		log_test "SKIP: driver does not support lanes setting"
		exit 1
	fi

	ip link set dev $swp2 down
	ip link set dev $swp1 down
}

check_lanes()
{
	local dev=$1; shift
	local lanes=$1; shift
	local max_speed=$1; shift
	local chosen_lanes

	chosen_lanes=$(ethtool $dev | grep 'Lanes:')
	chosen_lanes=${chosen_lanes#*"Lanes: "}

	((chosen_lanes == lanes))
	check_err $? "swp1 advertise $max_speed and $lanes, devs sync to $chosen_lanes"
}

check_unsupported_lanes()
{
	local dev=$1; shift
	local max_speed=$1; shift
	local max_lanes=$1; shift
	local autoneg=$1; shift
	local autoneg_str=""

	local unsupported_lanes=$((max_lanes *= 2))

	if [[ $autoneg -eq 0 ]]; then
		autoneg_str="autoneg off"
	fi

	ethtool -s $swp1 speed $max_speed lanes $unsupported_lanes $autoneg_str &> /dev/null
	check_fail $? "Unsuccessful $unsupported_lanes lanes setting was expected"
}

max_speed_and_lanes_get()
{
	local dev=$1; shift
	local arr=("$@")
	local max_lanes
	local max_speed
	local -a lanes_arr
	local -a speeds_arr
	local -a max_values

	for ((i=0; i<${#arr[@]}; i+=2)); do
		speeds_arr+=("${arr[$i]}")
		lanes_arr+=("${arr[i+1]}")
	done

	max_values+=($(get_max "${speeds_arr[@]}"))
	max_values+=($(get_max "${lanes_arr[@]}"))

	echo ${max_values[@]}
}

search_linkmode()
{
	local speed=$1; shift
	local lanes=$1; shift
	local arr=("$@")

	for ((i=0; i<${#arr[@]}; i+=2)); do
		if [[ $speed -eq ${arr[$i]} && $lanes -eq ${arr[i+1]} ]]; then
			return 1
		fi
	done
	return 0
}

autoneg()
{
	RET=0

	local lanes
	local max_speed
	local max_lanes

	local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1))
	local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}"))
	max_speed=${max_values[0]}
	max_lanes=${max_values[1]}

	lanes=$max_lanes

	while [[ $lanes -ge 1 ]]; do
		search_linkmode $max_speed $lanes "${linkmodes_params[@]}"
		if [[ $? -eq 1 ]]; then
			ethtool_set $swp1 speed $max_speed lanes $lanes
			ip link set dev $swp1 up
			ip link set dev $swp2 up
			busywait "$TIMEOUT" wait_for_port_up ethtool $swp2
			check_err $? "ports did not come up"

			check_lanes $swp1 $lanes $max_speed
			log_test "$lanes lanes is autonegotiated"
		fi
		let $((lanes /= 2))
	done

	check_unsupported_lanes $swp1 $max_speed $max_lanes 1
	log_test "Lanes number larger than max width is not set"

	ip link set dev $swp2 down
	ip link set dev $swp1 down
}

autoneg_force_mode()
{
	RET=0

	local lanes
	local max_speed
	local max_lanes

	local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1))
	local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}"))
	max_speed=${max_values[0]}
	max_lanes=${max_values[1]}

	lanes=$max_lanes

	while [[ $lanes -ge 1 ]]; do
		search_linkmode $max_speed $lanes "${linkmodes_params[@]}"
		if [[ $? -eq 1 ]]; then
			ethtool_set $swp1 speed $max_speed lanes $lanes autoneg off
			ethtool_set $swp2 speed $max_speed lanes $lanes autoneg off
			ip link set dev $swp1 up
			ip link set dev $swp2 up
			busywait "$TIMEOUT" wait_for_port_up ethtool $swp2
			check_err $? "ports did not come up"

			check_lanes $swp1 $lanes $max_speed
			log_test "Autoneg off, $lanes lanes detected during force mode"
		fi
		let $((lanes /= 2))
	done

	check_unsupported_lanes $swp1 $max_speed $max_lanes 0
	log_test "Lanes number larger than max width is not set"

	ip link set dev $swp2 down
	ip link set dev $swp1 down

	ethtool -s $swp2 autoneg on
	ethtool -s $swp1 autoneg on
}

check_ethtool_lanes_support
setup_prepare

tests_run

exit $EXIT_STATUS