brintos

brintos / linux-shallow public Read only

0
0
Text · 6.9 KiB · bed748d Raw
328 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03# Copyright 2021-2022 NXP4 5# Note: On LS1028A, in lack of enough user ports, this setup requires patching6# the device tree to use the second CPU port as a user port7 8WAIT_TIME=19NUM_NETIFS=410STABLE_MAC_ADDRS=yes11NETIF_CREATE=no12lib_dir=$(dirname $0)/../../../net/forwarding13source $lib_dir/tc_common.sh14source $lib_dir/lib.sh15source $lib_dir/tsn_lib.sh16 17UDS_ADDRESS_H1="/var/run/ptp4l_h1"18UDS_ADDRESS_SWP1="/var/run/ptp4l_swp1"19 20# Tunables21NUM_PKTS=100022STREAM_VID=10023STREAM_PRIO=624# Use a conservative cycle of 10 ms to allow the test to still pass when the25# kernel has some extra overhead like lockdep etc26CYCLE_TIME_NS=1000000027# Create two Gate Control List entries, one OPEN and one CLOSE, of equal28# durations29GATE_DURATION_NS=$((${CYCLE_TIME_NS} / 2))30# Give 2/3 of the cycle time to user space and 1/3 to the kernel31FUDGE_FACTOR=$((${CYCLE_TIME_NS} / 3))32# Shift the isochron base time by half the gate time, so that packets are33# always received by swp1 close to the middle of the time slot, to minimize34# inaccuracies due to network sync35SHIFT_TIME_NS=$((${GATE_DURATION_NS} / 2))36 37h1=${NETIFS[p1]}38swp1=${NETIFS[p2]}39swp2=${NETIFS[p3]}40h2=${NETIFS[p4]}41 42H1_IPV4="192.0.2.1"43H2_IPV4="192.0.2.2"44H1_IPV6="2001:db8:1::1"45H2_IPV6="2001:db8:1::2"46 47# Chain number exported by the ocelot driver for48# Per-Stream Filtering and Policing filters49PSFP()50{51	echo 3000052}53 54psfp_chain_create()55{56	local if_name=$157 58	tc qdisc add dev $if_name clsact59 60	tc filter add dev $if_name ingress chain 0 pref 49152 flower \61		skip_sw action goto chain $(PSFP)62}63 64psfp_chain_destroy()65{66	local if_name=$167 68	tc qdisc del dev $if_name clsact69}70 71psfp_filter_check()72{73	local expected=$174	local packets=""75	local drops=""76	local stats=""77 78	stats=$(tc -j -s filter show dev ${swp1} ingress chain $(PSFP) pref 1)79	packets=$(echo ${stats} | jq ".[1].options.actions[].stats.packets")80	drops=$(echo ${stats} | jq ".[1].options.actions[].stats.drops")81 82	if ! [ "${packets}" = "${expected}" ]; then83		printf "Expected filter to match on %d packets but matched on %d instead\n" \84			"${expected}" "${packets}"85	fi86 87	echo "Hardware filter reports ${drops} drops"88}89 90h1_create()91{92	simple_if_init $h1 $H1_IPV4/24 $H1_IPV6/6493}94 95h1_destroy()96{97	simple_if_fini $h1 $H1_IPV4/24 $H1_IPV6/6498}99 100h2_create()101{102	simple_if_init $h2 $H2_IPV4/24 $H2_IPV6/64103}104 105h2_destroy()106{107	simple_if_fini $h2 $H2_IPV4/24 $H2_IPV6/64108}109 110switch_create()111{112	local h2_mac_addr=$(mac_get $h2)113 114	ip link set ${swp1} up115	ip link set ${swp2} up116 117	ip link add br0 type bridge vlan_filtering 1118	ip link set ${swp1} master br0119	ip link set ${swp2} master br0120	ip link set br0 up121 122	bridge vlan add dev ${swp2} vid ${STREAM_VID}123	bridge vlan add dev ${swp1} vid ${STREAM_VID}124	# PSFP on Ocelot requires the filter to also be added to the bridge125	# FDB, and not be removed126	bridge fdb add dev ${swp2} \127		${h2_mac_addr} vlan ${STREAM_VID} static master128 129	psfp_chain_create ${swp1}130 131	tc filter add dev ${swp1} ingress chain $(PSFP) pref 1 \132		protocol 802.1Q flower skip_sw \133		dst_mac ${h2_mac_addr} vlan_id ${STREAM_VID} \134		action gate base-time 0.000000000 \135		sched-entry OPEN  ${GATE_DURATION_NS} -1 -1 \136		sched-entry CLOSE ${GATE_DURATION_NS} -1 -1137}138 139switch_destroy()140{141	psfp_chain_destroy ${swp1}142	ip link del br0143}144 145txtime_setup()146{147	local if_name=$1148 149	tc qdisc add dev ${if_name} clsact150	# Classify PTP on TC 7 and isochron on TC 6151	tc filter add dev ${if_name} egress protocol 0x88f7 \152		flower action skbedit priority 7153	tc filter add dev ${if_name} egress protocol 802.1Q \154		flower vlan_ethtype 0xdead action skbedit priority 6155	tc qdisc add dev ${if_name} handle 100: parent root mqprio num_tc 8 \156		queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \157		map 0 1 2 3 4 5 6 7 \158		hw 1159	# Set up TC 6 for SO_TXTIME. tc-mqprio queues count from 1.160	tc qdisc replace dev ${if_name} parent 100:$((${STREAM_PRIO} + 1)) etf \161		clockid CLOCK_TAI offload delta ${FUDGE_FACTOR}162}163 164txtime_cleanup()165{166	local if_name=$1167 168	tc qdisc del dev ${if_name} root169	tc qdisc del dev ${if_name} clsact170}171 172setup_prepare()173{174	vrf_prepare175 176	h1_create177	h2_create178	switch_create179 180	txtime_setup ${h1}181 182	# Set up swp1 as a master PHC for h1, synchronized to the local183	# CLOCK_REALTIME.184	phc2sys_start ${UDS_ADDRESS_SWP1}185 186	# Assumption true for LS1028A: h1 and h2 use the same PHC. So by187	# synchronizing h1 to swp1 via PTP, h2 is also implicitly synchronized188	# to swp1 (and both to CLOCK_REALTIME).189	ptp4l_start ${h1} true ${UDS_ADDRESS_H1}190	ptp4l_start ${swp1} false ${UDS_ADDRESS_SWP1}191 192	# Make sure there are no filter matches at the beginning of the test193	psfp_filter_check 0194}195 196cleanup()197{198	pre_cleanup199 200	ptp4l_stop ${swp1}201	ptp4l_stop ${h1}202	phc2sys_stop203	isochron_recv_stop204 205	txtime_cleanup ${h1}206 207	h2_destroy208	h1_destroy209	switch_destroy210 211	vrf_cleanup212}213 214debug_incorrectly_dropped_packets()215{216	local isochron_dat=$1217	local dropped_seqids218	local seqid219 220	echo "Packets incorrectly dropped:"221 222	dropped_seqids=$(isochron report \223		--input-file "${isochron_dat}" \224		--printf-format "%u RX hw %T\n" \225		--printf-args "qR" | \226		grep 'RX hw 0.000000000' | \227		awk '{print $1}')228 229	for seqid in ${dropped_seqids}; do230		isochron report \231			--input-file "${isochron_dat}" \232			--start ${seqid} --stop ${seqid} \233			--printf-format "seqid %u scheduled for %T, HW TX timestamp %T\n" \234			--printf-args "qST"235	done236}237 238debug_incorrectly_received_packets()239{240	local isochron_dat=$1241 242	echo "Packets incorrectly received:"243 244	isochron report \245		--input-file "${isochron_dat}" \246		--printf-format "seqid %u scheduled for %T, HW TX timestamp %T, HW RX timestamp %T\n" \247		--printf-args "qSTR" |248		grep -v 'HW RX timestamp 0.000000000'249}250 251run_test()252{253	local base_time=$1254	local expected=$2255	local test_name=$3256	local debug=$4257	local isochron_dat="$(mktemp)"258	local extra_args=""259	local received260 261	isochron_do \262		"${h1}" \263		"${h2}" \264		"${UDS_ADDRESS_H1}" \265		"" \266		"${base_time}" \267		"${CYCLE_TIME_NS}" \268		"${SHIFT_TIME_NS}" \269		"${NUM_PKTS}" \270		"${STREAM_VID}" \271		"${STREAM_PRIO}" \272		"" \273		"${isochron_dat}"274 275	# Count all received packets by looking at the non-zero RX timestamps276	received=$(isochron report \277		--input-file "${isochron_dat}" \278		--printf-format "%u\n" --printf-args "R" | \279		grep -w -v '0' | wc -l)280 281	if [ "${received}" = "${expected}" ]; then282		RET=0283	else284		RET=1285		echo "Expected isochron to receive ${expected} packets but received ${received}"286	fi287 288	log_test "${test_name}"289 290	if [ "$RET" = "1" ]; then291		${debug} "${isochron_dat}"292	fi293 294	rm ${isochron_dat} 2> /dev/null295}296 297test_gate_in_band()298{299	# Send packets in-band with the OPEN gate entry300	run_test 0.000000000 ${NUM_PKTS} "In band" \301		debug_incorrectly_dropped_packets302 303	psfp_filter_check ${NUM_PKTS}304}305 306test_gate_out_of_band()307{308	# Send packets in-band with the CLOSE gate entry309	run_test 0.005000000 0 "Out of band" \310		debug_incorrectly_received_packets311 312	psfp_filter_check $((2 * ${NUM_PKTS}))313}314 315trap cleanup EXIT316 317ALL_TESTS="318	test_gate_in_band319	test_gate_out_of_band320"321 322setup_prepare323setup_wait324 325tests_run326 327exit $EXIT_STATUS328