summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh
blob: c085d2a4c9894cdde74e0241fbcda9abc22efec5 (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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#shellcheck disable=SC2034 # SC does not see the global variables
#shellcheck disable=SC2317,SC2329 # unused functions

ALL_TESTS="
	test_eth_ctrl_stats
	test_eth_mac_stats
	test_pause_stats
"
: "${DRIVER_TEST_CONFORMANT:=yes}"
STABLE_MAC_ADDRS=yes
NUM_NETIFS=2
lib_dir=$(dirname "$0")
# shellcheck source=./../../../net/forwarding/lib.sh
source "$lib_dir"/../../../net/forwarding/lib.sh
# shellcheck source=./../../../kselftest/ktap_helpers.sh
source "$lib_dir"/../../../kselftest/ktap_helpers.sh

UINT32_MAX=$((2**32 - 1))
SUBTESTS=0
TEST_NAME=$(basename "$0" .sh)

traffic_test()
{
	local iface=$1; shift
	local neigh=$1; shift
	local num_tx=$1; shift
	local pkt_format="$1"; shift
	local -a counters=("$@")
	local int grp cnt target exact_check
	local before after delta
	local num_rx=$((num_tx * 2))
	local xfail_message
	local src="aggregate"
	local i

	for i in "${!counters[@]}"; do
		read -r int grp cnt target exact_check xfail_message \
			<<< "${counters[$i]}"

		before[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src")
	done

	# shellcheck disable=SC2086 # needs split options
	run_on "$iface" "$MZ" "$iface" -q -c "$num_tx" $pkt_format

	# shellcheck disable=SC2086 # needs split options
	run_on "$neigh" "$MZ" "$neigh" -q -c "$num_rx" $pkt_format

	for i in "${!counters[@]}"; do
		read -r int grp cnt target exact_check xfail_message \
			<<< "${counters[$i]}"

		after[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src")
		if [[ "${after[$i]}" == "null" ]]; then
			ktap_test_skip "$TEST_NAME.$grp-$cnt"
			continue;
		fi

		delta=$((after[i] - before[i]))

		if [ "$exact_check" -ne 0 ]; then
			[ "$delta" -eq "$target" ]
		else
			[ "$delta" -ge "$target" ] && \
			[ "$delta" -le "$UINT32_MAX" ]
		fi
		err="$?"

		if [[ $err != 0  ]] && [[ -n $xfail_message ]]; then
			ktap_print_msg "$xfail_message"
			ktap_test_xfail "$TEST_NAME.$grp-$cnt"
			continue;
		fi

		if [[ $err != 0 ]]; then
			ktap_print_msg "$grp-$cnt is not valid on $int (expected $target, got $delta)"
			ktap_test_fail "$TEST_NAME.$grp-$cnt"
		else
			ktap_test_pass "$TEST_NAME.$grp-$cnt"
		fi
	done
}

test_eth_ctrl_stats()
{
	local pkt_format="-a own -b bcast 88:08 -p 64"
	local num_pkts=1000
	local -a counters

	counters=("$h1 eth-ctrl MACControlFramesTransmitted $num_pkts 0")
	traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \
		"${counters[@]}"

	counters=("$h1 eth-ctrl MACControlFramesReceived $num_pkts 0")
	traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \
		"${counters[@]}"
}
SUBTESTS=$((SUBTESTS + 2))

test_eth_mac_stats()
{
	local pkt_size=100
	local pkt_size_fcs=$((pkt_size + 4))
	local bcast_pkt_format="-a own -b bcast -p $pkt_size"
	local mcast_pkt_format="-a own -b 01:00:5E:00:00:01 -p $pkt_size"
	local num_pkts=2000
	local octets=$((pkt_size_fcs * num_pkts))
	local -a counters error_cnt collision_cnt

	# Error counters should be exactly zero
	counters=("$h1 eth-mac FrameCheckSequenceErrors 0 1"
		  "$h1 eth-mac AlignmentErrors 0 1"
		  "$h1 eth-mac FramesLostDueToIntMACXmitError 0 1"
		  "$h1 eth-mac CarrierSenseErrors 0 1"
		  "$h1 eth-mac FramesLostDueToIntMACRcvError 0 1"
		  "$h1 eth-mac InRangeLengthErrors 0 1"
		  "$h1 eth-mac OutOfRangeLengthField 0 1"
		  "$h1 eth-mac FrameTooLongErrors 0 1"
		  "$h1 eth-mac FramesAbortedDueToXSColls 0 1")
	traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
		"${counters[@]}"

	# Collision related counters should also be zero
	counters=("$h1 eth-mac SingleCollisionFrames 0 1"
		  "$h1 eth-mac MultipleCollisionFrames 0 1"
		  "$h1 eth-mac FramesWithDeferredXmissions 0 1"
		  "$h1 eth-mac LateCollisions 0 1"
		  "$h1 eth-mac FramesWithExcessiveDeferral 0 1")
	traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
		"${counters[@]}"

	counters=("$h1 eth-mac BroadcastFramesXmittedOK $num_pkts 0"
		  "$h1 eth-mac OctetsTransmittedOK $octets 0")
	traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
		"${counters[@]}"

	counters=("$h1 eth-mac BroadcastFramesReceivedOK $num_pkts 0"
		  "$h1 eth-mac OctetsReceivedOK $octets 0")
	traffic_test "$h2" "$h1" "$num_pkts" "$bcast_pkt_format" \
		"${counters[@]}"

	counters=("$h1 eth-mac FramesTransmittedOK $num_pkts 0"
		  "$h1 eth-mac MulticastFramesXmittedOK $num_pkts 0")
	traffic_test "$h1" "$h2" "$num_pkts" "$mcast_pkt_format" \
		"${counters[@]}"

	counters=("$h1 eth-mac FramesReceivedOK $num_pkts 0"
		  "$h1 eth-mac MulticastFramesReceivedOK $num_pkts 0")
	traffic_test "$h2" "$h1" "$num_pkts" "$mcast_pkt_format" \
		"${counters[@]}"
}
SUBTESTS=$((SUBTESTS + 22))

test_pause_stats()
{
	local pkt_format="-a own -b 01:80:c2:00:00:01 88:08:00:01:00:01"
	local xfail_message="software sent pause frames not detected"
	local num_pkts=2000
	local -a counters
	local int
	local i

	# Check that there is pause frame support
	for ((i = 1; i <= NUM_NETIFS; ++i)); do
		int="${NETIFS[p$i]}"
		if ! run_on "$int" ethtool -I --json -a "$int" > /dev/null 2>&1; then
			ktap_test_skip "$TEST_NAME.tx_pause_frames"
			ktap_test_skip "$TEST_NAME.rx_pause_frames"
			return
		fi
	done

	counters=("$h1 pause tx_pause_frames $num_pkts 0 $xfail_message")
	traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \
		"${counters[@]}"

	counters=("$h1 pause rx_pause_frames $num_pkts 0")
	traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \
		"${counters[@]}"
}
SUBTESTS=$((SUBTESTS + 2))

setup_prepare()
{
	local iface

	h1=${NETIFS[p1]}
	h2=${NETIFS[p2]}

	h2_mac=$(mac_get "$h2")
}

ktap_print_header
ktap_set_plan $SUBTESTS

check_ethtool_counter_group_support
trap cleanup EXIT

setup_prepare
setup_wait

tests_run

ktap_finished