1# SPDX-License-Identifier: GPL-2.0
2
3humanize()
4{
5	local speed=$1; shift
6
7	for unit in bps Kbps Mbps Gbps; do
8		if (($(echo "$speed < 1024" | bc))); then
9			break
10		fi
11
12		speed=$(echo "scale=1; $speed / 1024" | bc)
13	done
14
15	echo "$speed${unit}"
16}
17
18rate()
19{
20	local t0=$1; shift
21	local t1=$1; shift
22	local interval=$1; shift
23
24	echo $((8 * (t1 - t0) / interval))
25}
26
27start_traffic()
28{
29	local h_in=$1; shift    # Where the traffic egresses the host
30	local sip=$1; shift
31	local dip=$1; shift
32	local dmac=$1; shift
33
34	$MZ $h_in -p 8000 -A $sip -B $dip -c 0 \
35		-a own -b $dmac -t udp -q &
36	sleep 1
37}
38
39stop_traffic()
40{
41	# Suppress noise from killing mausezahn.
42	{ kill %% && wait %%; } 2>/dev/null
43}
44
45check_rate()
46{
47	local rate=$1; shift
48	local min=$1; shift
49	local what=$1; shift
50
51	if ((rate > min)); then
52		return 0
53	fi
54
55	echo "$what $(humanize $ir) < $(humanize $min)" > /dev/stderr
56	return 1
57}
58
59measure_rate()
60{
61	local sw_in=$1; shift   # Where the traffic ingresses the switch
62	local host_in=$1; shift # Where it ingresses another host
63	local counter=$1; shift # Counter to use for measurement
64	local what=$1; shift
65
66	local interval=10
67	local i
68	local ret=0
69
70	# Dips in performance might cause momentary ingress rate to drop below
71	# 1Gbps. That wouldn't saturate egress and MC would thus get through,
72	# seemingly winning bandwidth on account of UC. Demand at least 2Gbps
73	# average ingress rate to somewhat mitigate this.
74	local min_ingress=2147483648
75
76	for i in {5..0}; do
77		local t0=$(ethtool_stats_get $host_in $counter)
78		local u0=$(ethtool_stats_get $sw_in $counter)
79		sleep $interval
80		local t1=$(ethtool_stats_get $host_in $counter)
81		local u1=$(ethtool_stats_get $sw_in $counter)
82
83		local ir=$(rate $u0 $u1 $interval)
84		local er=$(rate $t0 $t1 $interval)
85
86		if check_rate $ir $min_ingress "$what ingress rate"; then
87			break
88		fi
89
90		# Fail the test if we can't get the throughput.
91		if ((i == 0)); then
92			ret=1
93		fi
94	done
95
96	echo $ir $er
97	return $ret
98}
99