1646cf7edSAmit Cohen#!/bin/bash
2646cf7edSAmit Cohen# SPDX-License-Identifier: GPL-2.0
3646cf7edSAmit Cohen
4646cf7edSAmit Cohenspeeds_arr_get()
5646cf7edSAmit Cohen{
6646cf7edSAmit Cohen	cmd='/ETHTOOL_LINK_MODE_[^[:space:]]*_BIT[[:space:]]+=[[:space:]]+/ \
7646cf7edSAmit Cohen		{sub(/,$/, "") \
8646cf7edSAmit Cohen		sub(/ETHTOOL_LINK_MODE_/,"") \
9646cf7edSAmit Cohen		sub(/_BIT/,"") \
10646cf7edSAmit Cohen		sub(/_Full/,"/Full") \
11646cf7edSAmit Cohen		sub(/_Half/,"/Half");\
12646cf7edSAmit Cohen		print "["$1"]="$3}'
13646cf7edSAmit Cohen
14646cf7edSAmit Cohen	awk "${cmd}" /usr/include/linux/ethtool.h
15646cf7edSAmit Cohen}
16646cf7edSAmit Cohen
17646cf7edSAmit Cohenethtool_set()
18646cf7edSAmit Cohen{
19646cf7edSAmit Cohen	local cmd="$@"
20646cf7edSAmit Cohen	local out=$(ethtool -s $cmd 2>&1 | wc -l)
21646cf7edSAmit Cohen
22646cf7edSAmit Cohen	check_err $out "error in configuration. $cmd"
23646cf7edSAmit Cohen}
24646cf7edSAmit Cohen
25*f72e2f48SDanielle Ratsondev_linkmodes_params_get()
26*f72e2f48SDanielle Ratson{
27*f72e2f48SDanielle Ratson	local dev=$1; shift
28*f72e2f48SDanielle Ratson	local adver=$1; shift
29*f72e2f48SDanielle Ratson	local -a linkmodes_params
30*f72e2f48SDanielle Ratson	local param_count
31*f72e2f48SDanielle Ratson	local arr
32*f72e2f48SDanielle Ratson
33*f72e2f48SDanielle Ratson	if (($adver)); then
34*f72e2f48SDanielle Ratson		mode="Advertised link modes"
35*f72e2f48SDanielle Ratson	else
36*f72e2f48SDanielle Ratson		mode="Supported link modes"
37*f72e2f48SDanielle Ratson	fi
38*f72e2f48SDanielle Ratson
39*f72e2f48SDanielle Ratson	local -a dev_linkmodes=($(dev_speeds_get $dev 1 $adver))
40*f72e2f48SDanielle Ratson	for ((i=0; i<${#dev_linkmodes[@]}; i++)); do
41*f72e2f48SDanielle Ratson		linkmodes_params[$i]=$(echo -e "${dev_linkmodes[$i]}" | \
42*f72e2f48SDanielle Ratson			# Replaces all non numbers with spaces
43*f72e2f48SDanielle Ratson			sed -e 's/[^0-9]/ /g' | \
44*f72e2f48SDanielle Ratson			# Squeeze spaces in sequence to 1 space
45*f72e2f48SDanielle Ratson			tr -s ' ')
46*f72e2f48SDanielle Ratson		# Count how many numbers were found in the linkmode
47*f72e2f48SDanielle Ratson		param_count=$(echo "${linkmodes_params[$i]}" | wc -w)
48*f72e2f48SDanielle Ratson		if [[ $param_count -eq 1 ]]; then
49*f72e2f48SDanielle Ratson			linkmodes_params[$i]="${linkmodes_params[$i]} 1"
50*f72e2f48SDanielle Ratson		elif [[ $param_count -ge 3 ]]; then
51*f72e2f48SDanielle Ratson			arr=(${linkmodes_params[$i]})
52*f72e2f48SDanielle Ratson			# Take only first two params
53*f72e2f48SDanielle Ratson			linkmodes_params[$i]=$(echo "${arr[@]:0:2}")
54*f72e2f48SDanielle Ratson		fi
55*f72e2f48SDanielle Ratson	done
56*f72e2f48SDanielle Ratson	echo ${linkmodes_params[@]}
57*f72e2f48SDanielle Ratson}
58*f72e2f48SDanielle Ratson
59646cf7edSAmit Cohendev_speeds_get()
60646cf7edSAmit Cohen{
61646cf7edSAmit Cohen	local dev=$1; shift
62646cf7edSAmit Cohen	local with_mode=$1; shift
63646cf7edSAmit Cohen	local adver=$1; shift
64646cf7edSAmit Cohen	local speeds_str
65646cf7edSAmit Cohen
66646cf7edSAmit Cohen	if (($adver)); then
67646cf7edSAmit Cohen		mode="Advertised link modes"
68646cf7edSAmit Cohen	else
69646cf7edSAmit Cohen		mode="Supported link modes"
70646cf7edSAmit Cohen	fi
71646cf7edSAmit Cohen
72646cf7edSAmit Cohen	speeds_str=$(ethtool "$dev" | \
73646cf7edSAmit Cohen		# Snip everything before the link modes section.
74646cf7edSAmit Cohen		sed -n '/'"$mode"':/,$p' | \
75646cf7edSAmit Cohen		# Quit processing the rest at the start of the next section.
76646cf7edSAmit Cohen		# When checking, skip the header of this section (hence the 2,).
77646cf7edSAmit Cohen		sed -n '2,${/^[\t][^ \t]/q};p' | \
78646cf7edSAmit Cohen		# Drop the section header of the current section.
79646cf7edSAmit Cohen		cut -d':' -f2)
80646cf7edSAmit Cohen
81646cf7edSAmit Cohen	local -a speeds_arr=($speeds_str)
82646cf7edSAmit Cohen	if [[ $with_mode -eq 0 ]]; then
83646cf7edSAmit Cohen		for ((i=0; i<${#speeds_arr[@]}; i++)); do
84646cf7edSAmit Cohen			speeds_arr[$i]=${speeds_arr[$i]%base*}
85646cf7edSAmit Cohen		done
86646cf7edSAmit Cohen	fi
87646cf7edSAmit Cohen	echo ${speeds_arr[@]}
88646cf7edSAmit Cohen}
89646cf7edSAmit Cohen
90646cf7edSAmit Cohencommon_speeds_get()
91646cf7edSAmit Cohen{
92646cf7edSAmit Cohen	dev1=$1; shift
93646cf7edSAmit Cohen	dev2=$1; shift
94646cf7edSAmit Cohen	with_mode=$1; shift
95646cf7edSAmit Cohen	adver=$1; shift
96646cf7edSAmit Cohen
97646cf7edSAmit Cohen	local -a dev1_speeds=($(dev_speeds_get $dev1 $with_mode $adver))
98646cf7edSAmit Cohen	local -a dev2_speeds=($(dev_speeds_get $dev2 $with_mode $adver))
99646cf7edSAmit Cohen
100646cf7edSAmit Cohen	comm -12 \
101646cf7edSAmit Cohen		<(printf '%s\n' "${dev1_speeds[@]}" | sort -u) \
102646cf7edSAmit Cohen		<(printf '%s\n' "${dev2_speeds[@]}" | sort -u)
103646cf7edSAmit Cohen}
104dd9e67ffSAmit Cohen
105dd9e67ffSAmit Cohendifferent_speeds_get()
106dd9e67ffSAmit Cohen{
107dd9e67ffSAmit Cohen	local dev1=$1; shift
108dd9e67ffSAmit Cohen	local dev2=$1; shift
109dd9e67ffSAmit Cohen	local with_mode=$1; shift
110dd9e67ffSAmit Cohen	local adver=$1; shift
111dd9e67ffSAmit Cohen
112dd9e67ffSAmit Cohen	local -a speeds_arr
113dd9e67ffSAmit Cohen
114dd9e67ffSAmit Cohen	speeds_arr=($(common_speeds_get $dev1 $dev2 $with_mode $adver))
115dd9e67ffSAmit Cohen	if [[ ${#speeds_arr[@]} < 2 ]]; then
116dd9e67ffSAmit Cohen		check_err 1 "cannot check different speeds. There are not enough speeds"
117dd9e67ffSAmit Cohen	fi
118dd9e67ffSAmit Cohen
119dd9e67ffSAmit Cohen	echo ${speeds_arr[0]} ${speeds_arr[1]}
120dd9e67ffSAmit Cohen}
121