129a1c00cSLuis R. Rodriguez#!/bin/bash
229a1c00cSLuis R. Rodriguez# SPDX-License-Identifier: GPL-2.0
329a1c00cSLuis R. Rodriguez
429a1c00cSLuis R. Rodriguez# Library of helpers for test scripts.
529a1c00cSLuis R. Rodriguezset -e
629a1c00cSLuis R. Rodriguez
729a1c00cSLuis R. RodriguezDIR=/sys/devices/virtual/misc/test_firmware
829a1c00cSLuis R. Rodriguez
929a1c00cSLuis R. RodriguezPROC_CONFIG="/proc/config.gz"
1029a1c00cSLuis R. RodriguezTEST_DIR=$(dirname $0)
1129a1c00cSLuis R. Rodriguez
1229a1c00cSLuis R. Rodriguezprint_reqs_exit()
1329a1c00cSLuis R. Rodriguez{
1429a1c00cSLuis R. Rodriguez	echo "You must have the following enabled in your kernel:" >&2
1529a1c00cSLuis R. Rodriguez	cat $TEST_DIR/config >&2
1629a1c00cSLuis R. Rodriguez	exit 1
1729a1c00cSLuis R. Rodriguez}
1829a1c00cSLuis R. Rodriguez
1929a1c00cSLuis R. Rodrigueztest_modprobe()
2029a1c00cSLuis R. Rodriguez{
2129a1c00cSLuis R. Rodriguez	if [ ! -d $DIR ]; then
2229a1c00cSLuis R. Rodriguez		print_reqs_exit
2329a1c00cSLuis R. Rodriguez	fi
2429a1c00cSLuis R. Rodriguez}
2529a1c00cSLuis R. Rodriguez
2629a1c00cSLuis R. Rodriguezcheck_mods()
2729a1c00cSLuis R. Rodriguez{
2829a1c00cSLuis R. Rodriguez	trap "test_modprobe" EXIT
2929a1c00cSLuis R. Rodriguez	if [ ! -d $DIR ]; then
3029a1c00cSLuis R. Rodriguez		modprobe test_firmware
3129a1c00cSLuis R. Rodriguez	fi
3229a1c00cSLuis R. Rodriguez	if [ ! -f $PROC_CONFIG ]; then
3329a1c00cSLuis R. Rodriguez		if modprobe configs 2>/dev/null; then
3429a1c00cSLuis R. Rodriguez			echo "Loaded configs module"
3529a1c00cSLuis R. Rodriguez			if [ ! -f $PROC_CONFIG ]; then
3629a1c00cSLuis R. Rodriguez				echo "You must have the following enabled in your kernel:" >&2
3729a1c00cSLuis R. Rodriguez				cat $TEST_DIR/config >&2
3829a1c00cSLuis R. Rodriguez				echo "Resorting to old heuristics" >&2
3929a1c00cSLuis R. Rodriguez			fi
4029a1c00cSLuis R. Rodriguez		else
4129a1c00cSLuis R. Rodriguez			echo "Failed to load configs module, using old heuristics" >&2
4229a1c00cSLuis R. Rodriguez		fi
4329a1c00cSLuis R. Rodriguez	fi
4429a1c00cSLuis R. Rodriguez}
45ef557787SLuis R. Rodriguez
46f5a61451SLuis R. Rodriguezcheck_setup()
47f5a61451SLuis R. Rodriguez{
48f5a61451SLuis R. Rodriguez	HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)"
49f5a61451SLuis R. Rodriguez	HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)"
50b3cf21faSLuis R. Rodriguez	PROC_FW_IGNORE_SYSFS_FALLBACK="0"
51b3cf21faSLuis R. Rodriguez	PROC_FW_FORCE_SYSFS_FALLBACK="0"
52b3cf21faSLuis R. Rodriguez
53b3cf21faSLuis R. Rodriguez	if [ -z $PROC_SYS_DIR ]; then
54b3cf21faSLuis R. Rodriguez		PROC_SYS_DIR="/proc/sys/kernel"
55b3cf21faSLuis R. Rodriguez	fi
56b3cf21faSLuis R. Rodriguez
57b3cf21faSLuis R. Rodriguez	FW_PROC="${PROC_SYS_DIR}/firmware_config"
58b3cf21faSLuis R. Rodriguez	FW_FORCE_SYSFS_FALLBACK="$FW_PROC/force_sysfs_fallback"
59b3cf21faSLuis R. Rodriguez	FW_IGNORE_SYSFS_FALLBACK="$FW_PROC/ignore_sysfs_fallback"
60b3cf21faSLuis R. Rodriguez
61b3cf21faSLuis R. Rodriguez	if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
62b3cf21faSLuis R. Rodriguez		PROC_FW_FORCE_SYSFS_FALLBACK="$(cat $FW_FORCE_SYSFS_FALLBACK)"
63b3cf21faSLuis R. Rodriguez	fi
64b3cf21faSLuis R. Rodriguez
65b3cf21faSLuis R. Rodriguez	if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then
66b3cf21faSLuis R. Rodriguez		PROC_FW_IGNORE_SYSFS_FALLBACK="$(cat $FW_IGNORE_SYSFS_FALLBACK)"
67b3cf21faSLuis R. Rodriguez	fi
68b3cf21faSLuis R. Rodriguez
69b3cf21faSLuis R. Rodriguez	if [ "$PROC_FW_FORCE_SYSFS_FALLBACK" = "1" ]; then
70b3cf21faSLuis R. Rodriguez		HAS_FW_LOADER_USER_HELPER="yes"
71b3cf21faSLuis R. Rodriguez		HAS_FW_LOADER_USER_HELPER_FALLBACK="yes"
72b3cf21faSLuis R. Rodriguez	fi
73b3cf21faSLuis R. Rodriguez
74b3cf21faSLuis R. Rodriguez	if [ "$PROC_FW_IGNORE_SYSFS_FALLBACK" = "1" ]; then
75b3cf21faSLuis R. Rodriguez		HAS_FW_LOADER_USER_HELPER_FALLBACK="no"
76b3cf21faSLuis R. Rodriguez		HAS_FW_LOADER_USER_HELPER="no"
77b3cf21faSLuis R. Rodriguez	fi
78f5a61451SLuis R. Rodriguez
79f5a61451SLuis R. Rodriguez	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
80f5a61451SLuis R. Rodriguez	       OLD_TIMEOUT="$(cat /sys/class/firmware/timeout)"
81f5a61451SLuis R. Rodriguez	fi
82f5a61451SLuis R. Rodriguez
83f5a61451SLuis R. Rodriguez	OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)"
84f5a61451SLuis R. Rodriguez}
85f5a61451SLuis R. Rodriguez
86f5a61451SLuis R. Rodriguezverify_reqs()
87f5a61451SLuis R. Rodriguez{
88f5a61451SLuis R. Rodriguez	if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then
89f5a61451SLuis R. Rodriguez		if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
90f5a61451SLuis R. Rodriguez			echo "usermode helper disabled so ignoring test"
91f5a61451SLuis R. Rodriguez			exit 0
92f5a61451SLuis R. Rodriguez		fi
93f5a61451SLuis R. Rodriguez	fi
94f5a61451SLuis R. Rodriguez}
95f5a61451SLuis R. Rodriguez
96f5a61451SLuis R. Rodriguezsetup_tmp_file()
97f5a61451SLuis R. Rodriguez{
98f5a61451SLuis R. Rodriguez	FWPATH=$(mktemp -d)
99f5a61451SLuis R. Rodriguez	FW="$FWPATH/test-firmware.bin"
100f5a61451SLuis R. Rodriguez	echo "ABCD0123" >"$FW"
101f5a61451SLuis R. Rodriguez	NAME=$(basename "$FW")
102f5a61451SLuis R. Rodriguez	if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
103f5a61451SLuis R. Rodriguez		echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path
104f5a61451SLuis R. Rodriguez	fi
105f5a61451SLuis R. Rodriguez}
106f5a61451SLuis R. Rodriguez
1079952db75SLuis R. Rodriguez__setup_random_file()
1089952db75SLuis R. Rodriguez{
1099952db75SLuis R. Rodriguez	RANDOM_FILE_PATH="$(mktemp -p $FWPATH)"
1109952db75SLuis R. Rodriguez	# mktemp says dry-run -n is unsafe, so...
1119952db75SLuis R. Rodriguez	if [[ "$1" = "fake" ]]; then
1129952db75SLuis R. Rodriguez		rm -rf $RANDOM_FILE_PATH
1139952db75SLuis R. Rodriguez		sync
1149952db75SLuis R. Rodriguez	else
1159952db75SLuis R. Rodriguez		echo "ABCD0123" >"$RANDOM_FILE_PATH"
1169952db75SLuis R. Rodriguez	fi
1179952db75SLuis R. Rodriguez	echo $RANDOM_FILE_PATH
1189952db75SLuis R. Rodriguez}
1199952db75SLuis R. Rodriguez
1209952db75SLuis R. Rodriguezsetup_random_file()
1219952db75SLuis R. Rodriguez{
1229952db75SLuis R. Rodriguez	echo $(__setup_random_file)
1239952db75SLuis R. Rodriguez}
1249952db75SLuis R. Rodriguez
1259952db75SLuis R. Rodriguezsetup_random_file_fake()
1269952db75SLuis R. Rodriguez{
1279952db75SLuis R. Rodriguez	echo $(__setup_random_file fake)
1289952db75SLuis R. Rodriguez}
1299952db75SLuis R. Rodriguez
130b3cf21faSLuis R. Rodriguezproc_set_force_sysfs_fallback()
131b3cf21faSLuis R. Rodriguez{
132b3cf21faSLuis R. Rodriguez	if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
133b3cf21faSLuis R. Rodriguez		echo -n $1 > $FW_FORCE_SYSFS_FALLBACK
134b3cf21faSLuis R. Rodriguez		check_setup
135b3cf21faSLuis R. Rodriguez	fi
136b3cf21faSLuis R. Rodriguez}
137b3cf21faSLuis R. Rodriguez
138b3cf21faSLuis R. Rodriguezproc_set_ignore_sysfs_fallback()
139b3cf21faSLuis R. Rodriguez{
140b3cf21faSLuis R. Rodriguez	if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then
141b3cf21faSLuis R. Rodriguez		echo -n $1 > $FW_IGNORE_SYSFS_FALLBACK
142b3cf21faSLuis R. Rodriguez		check_setup
143b3cf21faSLuis R. Rodriguez	fi
144b3cf21faSLuis R. Rodriguez}
145b3cf21faSLuis R. Rodriguez
146b3cf21faSLuis R. Rodriguezproc_restore_defaults()
147b3cf21faSLuis R. Rodriguez{
148b3cf21faSLuis R. Rodriguez	proc_set_force_sysfs_fallback 0
149b3cf21faSLuis R. Rodriguez	proc_set_ignore_sysfs_fallback 0
150b3cf21faSLuis R. Rodriguez}
151b3cf21faSLuis R. Rodriguez
152f5a61451SLuis R. Rodrigueztest_finish()
153f5a61451SLuis R. Rodriguez{
154f5a61451SLuis R. Rodriguez	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
155f5a61451SLuis R. Rodriguez		echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
156f5a61451SLuis R. Rodriguez	fi
157f5a61451SLuis R. Rodriguez	if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
158e5384092SBen Hutchings		if [ "$OLD_FWPATH" = "" ]; then
159e5384092SBen Hutchings			# A zero-length write won't work; write a null byte
160e5384092SBen Hutchings			printf '\000' >/sys/module/firmware_class/parameters/path
161e5384092SBen Hutchings		else
162f5a61451SLuis R. Rodriguez			echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
163f5a61451SLuis R. Rodriguez		fi
164e5384092SBen Hutchings	fi
165f5a61451SLuis R. Rodriguez	if [ -f $FW ]; then
166f5a61451SLuis R. Rodriguez		rm -f "$FW"
167f5a61451SLuis R. Rodriguez	fi
168f5a61451SLuis R. Rodriguez	if [ -d $FWPATH ]; then
169f5a61451SLuis R. Rodriguez		rm -rf "$FWPATH"
170f5a61451SLuis R. Rodriguez	fi
171b3cf21faSLuis R. Rodriguez	proc_restore_defaults
172f5a61451SLuis R. Rodriguez}
173f5a61451SLuis R. Rodriguez
174ef557787SLuis R. Rodriguezkconfig_has()
175ef557787SLuis R. Rodriguez{
176ef557787SLuis R. Rodriguez	if [ -f $PROC_CONFIG ]; then
177ef557787SLuis R. Rodriguez		if zgrep -q $1 $PROC_CONFIG 2>/dev/null; then
178ef557787SLuis R. Rodriguez			echo "yes"
179ef557787SLuis R. Rodriguez		else
180ef557787SLuis R. Rodriguez			echo "no"
181ef557787SLuis R. Rodriguez		fi
182ef557787SLuis R. Rodriguez	else
183ef557787SLuis R. Rodriguez		# We currently don't have easy heuristics to infer this
184ef557787SLuis R. Rodriguez		# so best we can do is just try to use the kernel assuming
185ef557787SLuis R. Rodriguez		# you had enabled it. This matches the old behaviour.
186ef557787SLuis R. Rodriguez		if [ "$1" = "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" ]; then
187ef557787SLuis R. Rodriguez			echo "yes"
188ef557787SLuis R. Rodriguez		elif [ "$1" = "CONFIG_FW_LOADER_USER_HELPER=y" ]; then
189ef557787SLuis R. Rodriguez			if [ -d /sys/class/firmware/ ]; then
190ef557787SLuis R. Rodriguez				echo yes
191ef557787SLuis R. Rodriguez			else
192ef557787SLuis R. Rodriguez				echo no
193ef557787SLuis R. Rodriguez			fi
194ef557787SLuis R. Rodriguez		fi
195ef557787SLuis R. Rodriguez	fi
196ef557787SLuis R. Rodriguez}
197