File Index
Files and directories
Sign in
FILE

tsn_lib.sh

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/forwarding/tsn_lib.sh BASH
  1#!/bin/bash
  2# SPDX-License-Identifier: GPL-2.0
  3# Copyright 2021-2022 NXP
  4
  5tc_testing_scripts_dir=$(dirname $0)/../../tc-testing/scripts
  6
  7REQUIRE_ISOCHRON=${REQUIRE_ISOCHRON:=yes}
  8REQUIRE_LINUXPTP=${REQUIRE_LINUXPTP:=yes}
  9
 10# Tunables
 11UTC_TAI_OFFSET=37
 12ISOCHRON_CPU=1
 13
 14if [[ "$REQUIRE_ISOCHRON" = "yes" ]]; then
 15	# https://github.com/vladimiroltean/tsn-scripts
 16	# WARNING: isochron versions pre-1.0 are unstable,
 17	# always use the latest version
 18	require_command isochron
 19fi
 20if [[ "$REQUIRE_LINUXPTP" = "yes" ]]; then
 21	require_command phc2sys
 22	require_command ptp4l
 23	require_command phc_ctl
 24fi
 25
 26phc2sys_start()
 27{
 28	local uds_address=$1
 29	local extra_args=""
 30
 31	if ! [ -z "${uds_address}" ]; then
 32		extra_args="${extra_args} -z ${uds_address}"
 33	fi
 34
 35	phc2sys_log="$(mktemp)"
 36
 37	chrt -f 10 phc2sys -m \
 38		-a -rr \
 39		--step_threshold 0.00002 \
 40		--first_step_threshold 0.00002 \
 41		${extra_args} \
 42		> "${phc2sys_log}" 2>&1 &
 43	phc2sys_pid=$!
 44
 45	echo "phc2sys logs to ${phc2sys_log} and has pid ${phc2sys_pid}"
 46
 47	sleep 1
 48}
 49
 50phc2sys_stop()
 51{
 52	{ kill ${phc2sys_pid} && wait ${phc2sys_pid}; } 2> /dev/null
 53	rm "${phc2sys_log}" 2> /dev/null
 54}
 55
 56# Replace space separators from interface list with underscores
 57if_names_to_label()
 58{
 59	local if_name_list="$1"
 60
 61	echo "${if_name_list/ /_}"
 62}
 63
 64ptp4l_start()
 65{
 66	local if_names="$1"
 67	local slave_only=$2
 68	local uds_address=$3
 69	local log="ptp4l_log_$(if_names_to_label ${if_names})"
 70	local pid="ptp4l_pid_$(if_names_to_label ${if_names})"
 71	local extra_args=""
 72
 73	for if_name in ${if_names}; do
 74		extra_args="${extra_args} -i ${if_name}"
 75	done
 76
 77	if [ "${slave_only}" = true ]; then
 78		extra_args="${extra_args} -s"
 79	fi
 80
 81	# declare dynamic variables ptp4l_log_${if_name} and ptp4l_pid_${if_name}
 82	# as global, so that they can be referenced later
 83	declare -g "${log}=$(mktemp)"
 84
 85	chrt -f 10 ptp4l -m -2 -P \
 86		--step_threshold 0.00002 \
 87		--first_step_threshold 0.00002 \
 88		--tx_timestamp_timeout 100 \
 89		--uds_address="${uds_address}" \
 90		${extra_args} \
 91		> "${!log}" 2>&1 &
 92	declare -g "${pid}=$!"
 93
 94	echo "ptp4l for interfaces ${if_names} logs to ${!log} and has pid ${!pid}"
 95
 96	sleep 1
 97}
 98
 99ptp4l_stop()
100{
101	local if_names="$1"
102	local log="ptp4l_log_$(if_names_to_label ${if_names})"
103	local pid="ptp4l_pid_$(if_names_to_label ${if_names})"
104
105	{ kill ${!pid} && wait ${!pid}; } 2> /dev/null
106	rm "${!log}" 2> /dev/null
107}
108
109cpufreq_max()
110{
111	local cpu=$1
112	local freq="cpu${cpu}_freq"
113	local governor="cpu${cpu}_governor"
114
115	# Kernel may be compiled with CONFIG_CPU_FREQ disabled
116	if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
117		return
118	fi
119
120	# declare dynamic variables cpu${cpu}_freq and cpu${cpu}_governor as
121	# global, so they can be referenced later
122	declare -g "${freq}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq)"
123	declare -g "${governor}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor)"
124
125	cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_max_freq > \
126		/sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
127	echo -n "performance" > \
128		/sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
129}
130
131cpufreq_restore()
132{
133	local cpu=$1
134	local freq="cpu${cpu}_freq"
135	local governor="cpu${cpu}_governor"
136
137	if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
138		return
139	fi
140
141	echo "${!freq}" > /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
142	echo -n "${!governor}" > \
143		/sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
144}
145
146isochron_recv_start()
147{
148	local if_name=$1
149	local uds=$2
150	local stats_port=$3
151	local extra_args=$4
152	local pid="isochron_pid_${stats_port}"
153
154	if ! [ -z "${uds}" ]; then
155		extra_args="${extra_args} --unix-domain-socket ${uds}"
156	fi
157
158	isochron rcv \
159		--interface ${if_name} \
160		--sched-priority 98 \
161		--sched-fifo \
162		--utc-tai-offset ${UTC_TAI_OFFSET} \
163		--stats-port ${stats_port} \
164		--quiet \
165		${extra_args} & \
166	declare -g "${pid}=$!"
167
168	sleep 1
169}
170
171isochron_recv_stop()
172{
173	local stats_port=$1
174	local pid="isochron_pid_${stats_port}"
175
176	{ kill ${!pid} && wait ${!pid}; } 2> /dev/null
177}
178
179isochron_do()
180{
181	local sender_if_name=$1; shift
182	local receiver_if_name=$1; shift
183	local sender_uds=$1; shift
184	local receiver_uds=$1; shift
185	local base_time=$1; shift
186	local cycle_time=$1; shift
187	local shift_time=$1; shift
188	local window_size=$1; shift
189	local num_pkts=$1; shift
190	local vid=$1; shift
191	local priority=$1; shift
192	local dst_ip=$1; shift
193	local isochron_dat=$1; shift
194	local extra_args=""
195	local receiver_extra_args=""
196	local vrf="$(master_name_get ${sender_if_name})"
197	local use_l2="true"
198
199	if ! [ -z "${dst_ip}" ]; then
200		use_l2="false"
201	fi
202
203	if ! [ -z "${vrf}" ]; then
204		dst_ip="${dst_ip}%${vrf}"
205	fi
206
207	if ! [ -z "${vid}" ]; then
208		vid="--vid=${vid}"
209	fi
210
211	if [ -z "${receiver_uds}" ]; then
212		extra_args="${extra_args} --omit-remote-sync"
213	fi
214
215	if ! [ -z "${shift_time}" ]; then
216		extra_args="${extra_args} --shift-time=${shift_time}"
217	fi
218
219	if ! [ -z "${window_size}" ]; then
220		extra_args="${extra_args} --window-size=${window_size}"
221	fi
222
223	if [ "${use_l2}" = "true" ]; then
224		extra_args="${extra_args} --l2 --etype=0xdead ${vid}"
225		receiver_extra_args="--l2 --etype=0xdead"
226	else
227		extra_args="${extra_args} --l4 --ip-destination=${dst_ip}"
228		receiver_extra_args="--l4"
229	fi
230
231	cpufreq_max ${ISOCHRON_CPU}
232
233	isochron_recv_start "${h2}" "${receiver_uds}" 5000 "${receiver_extra_args}"
234
235	isochron send \
236		--interface ${sender_if_name} \
237		--unix-domain-socket ${sender_uds} \
238		--priority ${priority} \
239		--base-time ${base_time} \
240		--cycle-time ${cycle_time} \
241		--num-frames ${num_pkts} \
242		--frame-size 64 \
243		--txtime \
244		--utc-tai-offset ${UTC_TAI_OFFSET} \
245		--cpu-mask $((1 << ${ISOCHRON_CPU})) \
246		--sched-fifo \
247		--sched-priority 98 \
248		--client 127.0.0.1 \
249		--sync-threshold 5000 \
250		--output-file ${isochron_dat} \
251		${extra_args} \
252		--quiet
253
254	isochron_recv_stop 5000
255
256	cpufreq_restore ${ISOCHRON_CPU}
257}
258
259isochron_report_num_received()
260{
261	local isochron_dat=$1; shift
262
263	# Count all received packets by looking at the non-zero RX timestamps
264	isochron report \
265		--input-file "${isochron_dat}" \
266		--printf-format "%u\n" --printf-args "R" | \
267		grep -w -v '0' | wc -l
268}
269
270taprio_wait_for_admin()
271{
272	local if_name="$1"; shift
273
274	"$tc_testing_scripts_dir/taprio_wait_for_admin.sh" "$(which tc)" "$if_name"
275}
~/ Read-only file preview.