xref: /linux/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
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	rmon_rx_histogram
8	rmon_tx_histogram
9"
10
11: "${DRIVER_TEST_CONFORMANT:=yes}"
12NUM_NETIFS=2
13lib_dir=$(dirname "$0")
14source "$lib_dir"/../../../net/forwarding/lib.sh
15source "$lib_dir"/../../../kselftest/ktap_helpers.sh
16
17UINT32_MAX=$((2**32 - 1))
18ETH_FCS_LEN=4
19ETH_HLEN=$((6+6+2))
20TEST_NAME=$(basename "$0" .sh)
21
22declare -A netif_mtu
23
24ensure_mtu()
25{
26	local iface=$1; shift
27	local len=$1; shift
28	local required=$((len - ETH_HLEN - ETH_FCS_LEN))
29	local current
30
31	current=$(run_on "$iface" \
32		ip -j link show dev "$iface" | jq -r '.[0].mtu')
33	if [ "$current" -lt "$required" ]; then
34		run_on "$iface" ip link set dev "$iface" mtu "$required" \
35			|| return 1
36	fi
37}
38
39bucket_test()
40{
41	local iface=$1; shift
42	local neigh=$1; shift
43	local set=$1; shift
44	local bucket=$1; shift
45	local len=$1; shift
46	local num_rx=10000
47	local num_tx=20000
48	local expected=
49	local before=
50	local after=
51	local delta=
52
53	# Mausezahn does not include FCS bytes in its length - but the
54	# histogram counters do
55	len=$((len - ETH_FCS_LEN))
56	len=$((len > 0 ? len : 0))
57
58	before=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
59		jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val")
60
61	# Send 10k one way and 20k in the other, to detect counters
62	# mapped to the wrong direction
63	run_on "$neigh" \
64		"$MZ" "$neigh" -q -c "$num_rx" -p "$len" -a own -b bcast -d 10us
65	run_on "$iface" \
66		"$MZ" "$iface" -q -c "$num_tx" -p "$len" -a own -b bcast -d 10us
67
68	hw_stats_settle "$iface"
69
70	after=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
71		jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val")
72
73	delta=$((after - before))
74
75	expected=$([ "$set" = rx ] && echo "$num_rx" || echo "$num_tx")
76
77	[ "$delta" -ge "$expected" ] && [ "$delta" -le "$UINT32_MAX" ]
78}
79
80rmon_histogram()
81{
82	local iface=$1; shift
83	local neigh=$1; shift
84	local set=$1; shift
85	local nbuckets=0
86	local step=
87
88	while read -r -a bucket; do
89		step="$set-pkts${bucket[0]}to${bucket[1]}"
90
91		for if in "$iface" "$neigh"; do
92			if ! ensure_mtu "$if" "${bucket[0]}"; then
93				ktap_print_msg "$if does not support the required MTU for $step"
94				ktap_test_xfail "$TEST_NAME.$step"
95				return
96			fi
97		done
98
99		if ! bucket_test "$iface" "$neigh" "$set" "$nbuckets" "${bucket[0]}"; then
100			ktap_test_fail "$TEST_NAME.$step"
101			return 1
102		fi
103		ktap_test_pass "$TEST_NAME.$step"
104		nbuckets=$((nbuckets + 1))
105	done < <(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
106		jq -r ".[0].rmon[\"${set}-pktsNtoM\"][]|[.low, .high]|@tsv" 2>/dev/null)
107
108	if [ "$nbuckets" -eq 0 ]; then
109		ktap_print_msg "$iface does not support $set histogram counters"
110		return
111	fi
112}
113
114rmon_rx_histogram()
115{
116	rmon_histogram "$h1" "$h2" rx
117}
118
119rmon_tx_histogram()
120{
121	rmon_histogram "$h1" "$h2" tx
122}
123
124setup_prepare()
125{
126	h1=${NETIFS[p1]}
127	h2=${NETIFS[p2]}
128
129	for iface in "$h1" "$h2"; do
130		netif_mtu["$iface"]=$(run_on "$iface" \
131			ip -j link show dev "$iface" | jq -r '.[0].mtu')
132	done
133}
134
135cleanup()
136{
137	pre_cleanup
138
139	# Do not bring down the interfaces, just configure the initial MTU
140	for iface in "$h2" "$h1"; do
141		run_on "$iface" ip link set dev "$iface" \
142			mtu "${netif_mtu[$iface]}"
143	done
144}
145
146check_ethtool_counter_group_support
147trap cleanup EXIT
148
149bucket_count=$(ethtool --json -S "${NETIFS[p1]}" --groups rmon | \
150	jq -r '.[0].rmon |
151		"\((."rx-pktsNtoM" | length) +
152		   (."tx-pktsNtoM" | length))"')
153ktap_print_header
154ktap_set_plan "$bucket_count"
155
156setup_prepare
157setup_wait
158
159tests_run
160
161ktap_finished
162