xref: /openbmc/linux/tools/testing/selftests/net/forwarding/tsn_lib.sh (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1954f46d2SVladimir Oltean#!/bin/bash
2954f46d2SVladimir Oltean# SPDX-License-Identifier: GPL-2.0
3954f46d2SVladimir Oltean# Copyright 2021-2022 NXP
4954f46d2SVladimir Oltean
5954f46d2SVladimir OlteanREQUIRE_ISOCHRON=${REQUIRE_ISOCHRON:=yes}
6954f46d2SVladimir OlteanREQUIRE_LINUXPTP=${REQUIRE_LINUXPTP:=yes}
7954f46d2SVladimir Oltean
8954f46d2SVladimir Oltean# Tunables
9954f46d2SVladimir OlteanUTC_TAI_OFFSET=37
10954f46d2SVladimir OlteanISOCHRON_CPU=1
11954f46d2SVladimir Oltean
12954f46d2SVladimir Olteanif [[ "$REQUIRE_ISOCHRON" = "yes" ]]; then
13954f46d2SVladimir Oltean	# https://github.com/vladimiroltean/tsn-scripts
14954f46d2SVladimir Oltean	# WARNING: isochron versions pre-1.0 are unstable,
15954f46d2SVladimir Oltean	# always use the latest version
16954f46d2SVladimir Oltean	require_command isochron
17954f46d2SVladimir Olteanfi
18954f46d2SVladimir Olteanif [[ "$REQUIRE_LINUXPTP" = "yes" ]]; then
19954f46d2SVladimir Oltean	require_command phc2sys
20954f46d2SVladimir Oltean	require_command ptp4l
21954f46d2SVladimir Olteanfi
22954f46d2SVladimir Oltean
23954f46d2SVladimir Olteanphc2sys_start()
24954f46d2SVladimir Oltean{
25*162d52dfSVladimir Oltean	local uds_address=$1
26954f46d2SVladimir Oltean	local extra_args=""
27954f46d2SVladimir Oltean
28954f46d2SVladimir Oltean	if ! [ -z "${uds_address}" ]; then
29954f46d2SVladimir Oltean		extra_args="${extra_args} -z ${uds_address}"
30954f46d2SVladimir Oltean	fi
31954f46d2SVladimir Oltean
32954f46d2SVladimir Oltean	phc2sys_log="$(mktemp)"
33954f46d2SVladimir Oltean
34954f46d2SVladimir Oltean	chrt -f 10 phc2sys -m \
35*162d52dfSVladimir Oltean		-a -rr \
36954f46d2SVladimir Oltean		--step_threshold 0.00002 \
37954f46d2SVladimir Oltean		--first_step_threshold 0.00002 \
38954f46d2SVladimir Oltean		${extra_args} \
39954f46d2SVladimir Oltean		> "${phc2sys_log}" 2>&1 &
40954f46d2SVladimir Oltean	phc2sys_pid=$!
41954f46d2SVladimir Oltean
42954f46d2SVladimir Oltean	echo "phc2sys logs to ${phc2sys_log} and has pid ${phc2sys_pid}"
43954f46d2SVladimir Oltean
44954f46d2SVladimir Oltean	sleep 1
45954f46d2SVladimir Oltean}
46954f46d2SVladimir Oltean
47954f46d2SVladimir Olteanphc2sys_stop()
48954f46d2SVladimir Oltean{
49954f46d2SVladimir Oltean	{ kill ${phc2sys_pid} && wait ${phc2sys_pid}; } 2> /dev/null
50954f46d2SVladimir Oltean	rm "${phc2sys_log}" 2> /dev/null
51954f46d2SVladimir Oltean}
52954f46d2SVladimir Oltean
537ff9396eSVladimir Oltean# Replace space separators from interface list with underscores
547ff9396eSVladimir Olteanif_names_to_label()
557ff9396eSVladimir Oltean{
567ff9396eSVladimir Oltean	local if_name_list="$1"
577ff9396eSVladimir Oltean
587ff9396eSVladimir Oltean	echo "${if_name_list/ /_}"
597ff9396eSVladimir Oltean}
607ff9396eSVladimir Oltean
61954f46d2SVladimir Olteanptp4l_start()
62954f46d2SVladimir Oltean{
637ff9396eSVladimir Oltean	local if_names="$1"
64954f46d2SVladimir Oltean	local slave_only=$2
65954f46d2SVladimir Oltean	local uds_address=$3
667ff9396eSVladimir Oltean	local log="ptp4l_log_$(if_names_to_label ${if_names})"
677ff9396eSVladimir Oltean	local pid="ptp4l_pid_$(if_names_to_label ${if_names})"
68954f46d2SVladimir Oltean	local extra_args=""
69954f46d2SVladimir Oltean
707ff9396eSVladimir Oltean	for if_name in ${if_names}; do
717ff9396eSVladimir Oltean		extra_args="${extra_args} -i ${if_name}"
727ff9396eSVladimir Oltean	done
737ff9396eSVladimir Oltean
74954f46d2SVladimir Oltean	if [ "${slave_only}" = true ]; then
75954f46d2SVladimir Oltean		extra_args="${extra_args} -s"
76954f46d2SVladimir Oltean	fi
77954f46d2SVladimir Oltean
78954f46d2SVladimir Oltean	# declare dynamic variables ptp4l_log_${if_name} and ptp4l_pid_${if_name}
79954f46d2SVladimir Oltean	# as global, so that they can be referenced later
80954f46d2SVladimir Oltean	declare -g "${log}=$(mktemp)"
81954f46d2SVladimir Oltean
82954f46d2SVladimir Oltean	chrt -f 10 ptp4l -m -2 -P \
83954f46d2SVladimir Oltean		--step_threshold 0.00002 \
84954f46d2SVladimir Oltean		--first_step_threshold 0.00002 \
85954f46d2SVladimir Oltean		--tx_timestamp_timeout 100 \
86954f46d2SVladimir Oltean		--uds_address="${uds_address}" \
87954f46d2SVladimir Oltean		${extra_args} \
88954f46d2SVladimir Oltean		> "${!log}" 2>&1 &
89954f46d2SVladimir Oltean	declare -g "${pid}=$!"
90954f46d2SVladimir Oltean
917ff9396eSVladimir Oltean	echo "ptp4l for interfaces ${if_names} logs to ${!log} and has pid ${!pid}"
92954f46d2SVladimir Oltean
93954f46d2SVladimir Oltean	sleep 1
94954f46d2SVladimir Oltean}
95954f46d2SVladimir Oltean
96954f46d2SVladimir Olteanptp4l_stop()
97954f46d2SVladimir Oltean{
987ff9396eSVladimir Oltean	local if_names="$1"
997ff9396eSVladimir Oltean	local log="ptp4l_log_$(if_names_to_label ${if_names})"
1007ff9396eSVladimir Oltean	local pid="ptp4l_pid_$(if_names_to_label ${if_names})"
101954f46d2SVladimir Oltean
102954f46d2SVladimir Oltean	{ kill ${!pid} && wait ${!pid}; } 2> /dev/null
103954f46d2SVladimir Oltean	rm "${!log}" 2> /dev/null
104954f46d2SVladimir Oltean}
105954f46d2SVladimir Oltean
106954f46d2SVladimir Olteancpufreq_max()
107954f46d2SVladimir Oltean{
108954f46d2SVladimir Oltean	local cpu=$1
109954f46d2SVladimir Oltean	local freq="cpu${cpu}_freq"
110954f46d2SVladimir Oltean	local governor="cpu${cpu}_governor"
111954f46d2SVladimir Oltean
112954f46d2SVladimir Oltean	# Kernel may be compiled with CONFIG_CPU_FREQ disabled
113954f46d2SVladimir Oltean	if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
114954f46d2SVladimir Oltean		return
115954f46d2SVladimir Oltean	fi
116954f46d2SVladimir Oltean
117954f46d2SVladimir Oltean	# declare dynamic variables cpu${cpu}_freq and cpu${cpu}_governor as
118954f46d2SVladimir Oltean	# global, so they can be referenced later
119954f46d2SVladimir Oltean	declare -g "${freq}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq)"
120954f46d2SVladimir Oltean	declare -g "${governor}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor)"
121954f46d2SVladimir Oltean
122954f46d2SVladimir Oltean	cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_max_freq > \
123954f46d2SVladimir Oltean		/sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
124954f46d2SVladimir Oltean	echo -n "performance" > \
125954f46d2SVladimir Oltean		/sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
126954f46d2SVladimir Oltean}
127954f46d2SVladimir Oltean
128954f46d2SVladimir Olteancpufreq_restore()
129954f46d2SVladimir Oltean{
130954f46d2SVladimir Oltean	local cpu=$1
131954f46d2SVladimir Oltean	local freq="cpu${cpu}_freq"
132954f46d2SVladimir Oltean	local governor="cpu${cpu}_governor"
133954f46d2SVladimir Oltean
134954f46d2SVladimir Oltean	if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
135954f46d2SVladimir Oltean		return
136954f46d2SVladimir Oltean	fi
137954f46d2SVladimir Oltean
138954f46d2SVladimir Oltean	echo "${!freq}" > /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
139954f46d2SVladimir Oltean	echo -n "${!governor}" > \
140954f46d2SVladimir Oltean		/sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
141954f46d2SVladimir Oltean}
142954f46d2SVladimir Oltean
143954f46d2SVladimir Olteanisochron_recv_start()
144954f46d2SVladimir Oltean{
145954f46d2SVladimir Oltean	local if_name=$1
146954f46d2SVladimir Oltean	local uds=$2
147a7ce95acSVladimir Oltean	local stats_port=$3
148a7ce95acSVladimir Oltean	local extra_args=$4
149a7ce95acSVladimir Oltean	local pid="isochron_pid_${stats_port}"
150954f46d2SVladimir Oltean
151954f46d2SVladimir Oltean	if ! [ -z "${uds}" ]; then
1527d45b5fdSVladimir Oltean		extra_args="${extra_args} --unix-domain-socket ${uds}"
153954f46d2SVladimir Oltean	fi
154954f46d2SVladimir Oltean
155954f46d2SVladimir Oltean	isochron rcv \
156954f46d2SVladimir Oltean		--interface ${if_name} \
157954f46d2SVladimir Oltean		--sched-priority 98 \
158954f46d2SVladimir Oltean		--sched-fifo \
159954f46d2SVladimir Oltean		--utc-tai-offset ${UTC_TAI_OFFSET} \
160a7ce95acSVladimir Oltean		--stats-port ${stats_port} \
161954f46d2SVladimir Oltean		--quiet \
162954f46d2SVladimir Oltean		${extra_args} & \
163a7ce95acSVladimir Oltean	declare -g "${pid}=$!"
164954f46d2SVladimir Oltean
165954f46d2SVladimir Oltean	sleep 1
166954f46d2SVladimir Oltean}
167954f46d2SVladimir Oltean
168954f46d2SVladimir Olteanisochron_recv_stop()
169954f46d2SVladimir Oltean{
170a7ce95acSVladimir Oltean	local stats_port=$1
171a7ce95acSVladimir Oltean	local pid="isochron_pid_${stats_port}"
172a7ce95acSVladimir Oltean
173a7ce95acSVladimir Oltean	{ kill ${!pid} && wait ${!pid}; } 2> /dev/null
174954f46d2SVladimir Oltean}
175954f46d2SVladimir Oltean
176954f46d2SVladimir Olteanisochron_do()
177954f46d2SVladimir Oltean{
178954f46d2SVladimir Oltean	local sender_if_name=$1; shift
179954f46d2SVladimir Oltean	local receiver_if_name=$1; shift
180954f46d2SVladimir Oltean	local sender_uds=$1; shift
181954f46d2SVladimir Oltean	local receiver_uds=$1; shift
182954f46d2SVladimir Oltean	local base_time=$1; shift
183954f46d2SVladimir Oltean	local cycle_time=$1; shift
184954f46d2SVladimir Oltean	local shift_time=$1; shift
185954f46d2SVladimir Oltean	local num_pkts=$1; shift
186954f46d2SVladimir Oltean	local vid=$1; shift
187954f46d2SVladimir Oltean	local priority=$1; shift
188954f46d2SVladimir Oltean	local dst_ip=$1; shift
189954f46d2SVladimir Oltean	local isochron_dat=$1; shift
190954f46d2SVladimir Oltean	local extra_args=""
191954f46d2SVladimir Oltean	local receiver_extra_args=""
192954f46d2SVladimir Oltean	local vrf="$(master_name_get ${sender_if_name})"
193954f46d2SVladimir Oltean	local use_l2="true"
194954f46d2SVladimir Oltean
195954f46d2SVladimir Oltean	if ! [ -z "${dst_ip}" ]; then
196954f46d2SVladimir Oltean		use_l2="false"
197954f46d2SVladimir Oltean	fi
198954f46d2SVladimir Oltean
199954f46d2SVladimir Oltean	if ! [ -z "${vrf}" ]; then
200954f46d2SVladimir Oltean		dst_ip="${dst_ip}%${vrf}"
201954f46d2SVladimir Oltean	fi
202954f46d2SVladimir Oltean
203954f46d2SVladimir Oltean	if ! [ -z "${vid}" ]; then
204954f46d2SVladimir Oltean		vid="--vid=${vid}"
205954f46d2SVladimir Oltean	fi
206954f46d2SVladimir Oltean
207954f46d2SVladimir Oltean	if [ -z "${receiver_uds}" ]; then
208954f46d2SVladimir Oltean		extra_args="${extra_args} --omit-remote-sync"
209954f46d2SVladimir Oltean	fi
210954f46d2SVladimir Oltean
211954f46d2SVladimir Oltean	if ! [ -z "${shift_time}" ]; then
212954f46d2SVladimir Oltean		extra_args="${extra_args} --shift-time=${shift_time}"
213954f46d2SVladimir Oltean	fi
214954f46d2SVladimir Oltean
215954f46d2SVladimir Oltean	if [ "${use_l2}" = "true" ]; then
216954f46d2SVladimir Oltean		extra_args="${extra_args} --l2 --etype=0xdead ${vid}"
217954f46d2SVladimir Oltean		receiver_extra_args="--l2 --etype=0xdead"
218954f46d2SVladimir Oltean	else
219954f46d2SVladimir Oltean		extra_args="${extra_args} --l4 --ip-destination=${dst_ip}"
220954f46d2SVladimir Oltean		receiver_extra_args="--l4"
221954f46d2SVladimir Oltean	fi
222954f46d2SVladimir Oltean
223954f46d2SVladimir Oltean	cpufreq_max ${ISOCHRON_CPU}
224954f46d2SVladimir Oltean
225a7ce95acSVladimir Oltean	isochron_recv_start "${h2}" "${receiver_uds}" 5000 "${receiver_extra_args}"
226954f46d2SVladimir Oltean
227954f46d2SVladimir Oltean	isochron send \
228954f46d2SVladimir Oltean		--interface ${sender_if_name} \
229954f46d2SVladimir Oltean		--unix-domain-socket ${sender_uds} \
230954f46d2SVladimir Oltean		--priority ${priority} \
231954f46d2SVladimir Oltean		--base-time ${base_time} \
232954f46d2SVladimir Oltean		--cycle-time ${cycle_time} \
233954f46d2SVladimir Oltean		--num-frames ${num_pkts} \
234954f46d2SVladimir Oltean		--frame-size 64 \
235954f46d2SVladimir Oltean		--txtime \
236954f46d2SVladimir Oltean		--utc-tai-offset ${UTC_TAI_OFFSET} \
237954f46d2SVladimir Oltean		--cpu-mask $((1 << ${ISOCHRON_CPU})) \
238954f46d2SVladimir Oltean		--sched-fifo \
239954f46d2SVladimir Oltean		--sched-priority 98 \
240954f46d2SVladimir Oltean		--client 127.0.0.1 \
241954f46d2SVladimir Oltean		--sync-threshold 5000 \
242954f46d2SVladimir Oltean		--output-file ${isochron_dat} \
243954f46d2SVladimir Oltean		${extra_args} \
244954f46d2SVladimir Oltean		--quiet
245954f46d2SVladimir Oltean
246a7ce95acSVladimir Oltean	isochron_recv_stop 5000
247954f46d2SVladimir Oltean
248954f46d2SVladimir Oltean	cpufreq_restore ${ISOCHRON_CPU}
249954f46d2SVladimir Oltean}
250