xref: /linux/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh (revision cf85f810f911234a06a4ef2439e8694b93b717fc)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#shellcheck disable=SC2034 # SC does not see the global variables
4#shellcheck disable=SC2317,SC2329 # unused functions
5
6ALL_TESTS="
7	test_eth_ctrl_stats
8	test_eth_mac_stats
9	test_pause_stats
10"
11: "${DRIVER_TEST_CONFORMANT:=yes}"
12STABLE_MAC_ADDRS=yes
13NUM_NETIFS=2
14lib_dir=$(dirname "$0")
15# shellcheck source=./../../../net/forwarding/lib.sh
16source "$lib_dir"/../../../net/forwarding/lib.sh
17# shellcheck source=./../../../kselftest/ktap_helpers.sh
18source "$lib_dir"/../../../kselftest/ktap_helpers.sh
19
20UINT32_MAX=$((2**32 - 1))
21SUBTESTS=0
22TEST_NAME=$(basename "$0" .sh)
23
24traffic_test()
25{
26	local iface=$1; shift
27	local neigh=$1; shift
28	local num_tx=$1; shift
29	local pkt_format="$1"; shift
30	local -a counters=("$@")
31	local int grp cnt target exact_check
32	local before after delta
33	local num_rx=$((num_tx * 2))
34	local xfail_message
35	local src="aggregate"
36	local i
37
38	for i in "${!counters[@]}"; do
39		read -r int grp cnt target exact_check xfail_message \
40			<<< "${counters[$i]}"
41
42		before[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src")
43	done
44
45	# shellcheck disable=SC2086 # needs split options
46	run_on "$iface" "$MZ" "$iface" -q -d 10usec -c "$num_tx" $pkt_format
47
48	# shellcheck disable=SC2086 # needs split options
49	run_on "$neigh" "$MZ" "$neigh" -q -d 10usec -c "$num_rx" $pkt_format
50
51	hw_stats_settle "$int"
52
53	for i in "${!counters[@]}"; do
54		read -r int grp cnt target exact_check xfail_message \
55			<<< "${counters[$i]}"
56
57		after[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src")
58		if [[ "${after[$i]}" == "null" ]]; then
59			ktap_test_skip "$TEST_NAME.$grp-$cnt"
60			continue;
61		fi
62
63		delta=$((after[i] - before[i]))
64
65		if [ "$exact_check" -ne 0 ]; then
66			[ "$delta" -eq "$target" ]
67		else
68			[ "$delta" -ge "$target" ] && \
69			[ "$delta" -le "$UINT32_MAX" ]
70		fi
71		err="$?"
72
73		if [[ $err != 0  ]] && [[ -n $xfail_message ]]; then
74			ktap_print_msg "$xfail_message"
75			ktap_test_xfail "$TEST_NAME.$grp-$cnt"
76			continue;
77		fi
78
79		if [[ $err != 0 ]]; then
80			ktap_print_msg "$grp-$cnt is not valid on $int (expected $target, got $delta)"
81			ktap_test_fail "$TEST_NAME.$grp-$cnt"
82		else
83			ktap_test_pass "$TEST_NAME.$grp-$cnt"
84		fi
85	done
86}
87
88test_eth_ctrl_stats()
89{
90	local pkt_format="-a own -b bcast 88:08 -p 64"
91	local num_pkts=1000
92	local -a counters
93
94	counters=("$h1 eth-ctrl MACControlFramesTransmitted $num_pkts 0")
95	traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \
96		"${counters[@]}"
97
98	counters=("$h1 eth-ctrl MACControlFramesReceived $num_pkts 0")
99	traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \
100		"${counters[@]}"
101}
102SUBTESTS=$((SUBTESTS + 2))
103
104test_eth_mac_stats()
105{
106	local pkt_size=100
107	local pkt_size_fcs=$((pkt_size + 4))
108	local bcast_pkt_format="-a own -b bcast -p $pkt_size"
109	local mcast_pkt_format="-a own -b 01:00:5E:00:00:01 -p $pkt_size"
110	local num_pkts=2000
111	local octets=$((pkt_size_fcs * num_pkts))
112	local -a counters error_cnt collision_cnt
113
114	# Error counters should be exactly zero
115	counters=("$h1 eth-mac FrameCheckSequenceErrors 0 1"
116		  "$h1 eth-mac AlignmentErrors 0 1"
117		  "$h1 eth-mac FramesLostDueToIntMACXmitError 0 1"
118		  "$h1 eth-mac CarrierSenseErrors 0 1"
119		  "$h1 eth-mac FramesLostDueToIntMACRcvError 0 1"
120		  "$h1 eth-mac InRangeLengthErrors 0 1"
121		  "$h1 eth-mac OutOfRangeLengthField 0 1"
122		  "$h1 eth-mac FrameTooLongErrors 0 1"
123		  "$h1 eth-mac FramesAbortedDueToXSColls 0 1")
124	traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
125		"${counters[@]}"
126
127	# Collision related counters should also be zero
128	counters=("$h1 eth-mac SingleCollisionFrames 0 1"
129		  "$h1 eth-mac MultipleCollisionFrames 0 1"
130		  "$h1 eth-mac FramesWithDeferredXmissions 0 1"
131		  "$h1 eth-mac LateCollisions 0 1"
132		  "$h1 eth-mac FramesWithExcessiveDeferral 0 1")
133	traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
134		"${counters[@]}"
135
136	counters=("$h1 eth-mac BroadcastFramesXmittedOK $num_pkts 0"
137		  "$h1 eth-mac OctetsTransmittedOK $octets 0")
138	traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
139		"${counters[@]}"
140
141	counters=("$h1 eth-mac BroadcastFramesReceivedOK $num_pkts 0"
142		  "$h1 eth-mac OctetsReceivedOK $octets 0")
143	traffic_test "$h2" "$h1" "$num_pkts" "$bcast_pkt_format" \
144		"${counters[@]}"
145
146	counters=("$h1 eth-mac FramesTransmittedOK $num_pkts 0"
147		  "$h1 eth-mac MulticastFramesXmittedOK $num_pkts 0")
148	traffic_test "$h1" "$h2" "$num_pkts" "$mcast_pkt_format" \
149		"${counters[@]}"
150
151	counters=("$h1 eth-mac FramesReceivedOK $num_pkts 0"
152		  "$h1 eth-mac MulticastFramesReceivedOK $num_pkts 0")
153	traffic_test "$h2" "$h1" "$num_pkts" "$mcast_pkt_format" \
154		"${counters[@]}"
155}
156SUBTESTS=$((SUBTESTS + 22))
157
158test_pause_stats()
159{
160	local pkt_format="-a own -b 01:80:c2:00:00:01 88:08:00:01:00:01"
161	local xfail_message="software sent pause frames not detected"
162	local num_pkts=2000
163	local -a counters
164	local int
165	local i
166
167	# Check that there is pause frame support
168	for ((i = 1; i <= NUM_NETIFS; ++i)); do
169		int="${NETIFS[p$i]}"
170		if ! run_on "$int" ethtool -I --json -a "$int" > /dev/null 2>&1; then
171			ktap_test_skip "$TEST_NAME.tx_pause_frames"
172			ktap_test_skip "$TEST_NAME.rx_pause_frames"
173			return
174		fi
175	done
176
177	counters=("$h1 pause tx_pause_frames $num_pkts 0 $xfail_message")
178	traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \
179		"${counters[@]}"
180
181	counters=("$h1 pause rx_pause_frames $num_pkts 0")
182	traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \
183		"${counters[@]}"
184}
185SUBTESTS=$((SUBTESTS + 2))
186
187setup_prepare()
188{
189	local iface
190
191	h1=${NETIFS[p1]}
192	h2=${NETIFS[p2]}
193
194	h2_mac=$(mac_get "$h2")
195}
196
197ktap_print_header
198ktap_set_plan $SUBTESTS
199
200check_ethtool_counter_group_support
201trap cleanup EXIT
202
203setup_prepare
204setup_wait
205
206tests_run
207
208ktap_finished
209