xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/firmware/fw_lib.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun# Library of helpers for test scripts.
5*4882a593Smuzhiyunset -e
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunDIR=/sys/devices/virtual/misc/test_firmware
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunPROC_CONFIG="/proc/config.gz"
10*4882a593SmuzhiyunTEST_DIR=$(dirname $0)
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun# We need to load a different file to test request_firmware_into_buf
13*4882a593Smuzhiyun# I believe the issue is firmware loaded cached vs. non-cached
14*4882a593Smuzhiyun# with same filename is bungled.
15*4882a593Smuzhiyun# To reproduce rename this to test-firmware.bin
16*4882a593SmuzhiyunTEST_FIRMWARE_INTO_BUF_FILENAME=test-firmware-into-buf.bin
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun# Kselftest framework requirement - SKIP code is 4.
19*4882a593Smuzhiyunksft_skip=4
20*4882a593Smuzhiyun
21*4882a593Smuzhiyunprint_reqs_exit()
22*4882a593Smuzhiyun{
23*4882a593Smuzhiyun	echo "You must have the following enabled in your kernel:" >&2
24*4882a593Smuzhiyun	cat $TEST_DIR/config >&2
25*4882a593Smuzhiyun	exit $ksft_skip
26*4882a593Smuzhiyun}
27*4882a593Smuzhiyun
28*4882a593Smuzhiyuntest_modprobe()
29*4882a593Smuzhiyun{
30*4882a593Smuzhiyun	if [ ! -d $DIR ]; then
31*4882a593Smuzhiyun		print_reqs_exit
32*4882a593Smuzhiyun	fi
33*4882a593Smuzhiyun}
34*4882a593Smuzhiyun
35*4882a593Smuzhiyuncheck_mods()
36*4882a593Smuzhiyun{
37*4882a593Smuzhiyun	local uid=$(id -u)
38*4882a593Smuzhiyun	if [ $uid -ne 0 ]; then
39*4882a593Smuzhiyun		echo "skip all tests: must be run as root" >&2
40*4882a593Smuzhiyun		exit $ksft_skip
41*4882a593Smuzhiyun	fi
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun	trap "test_modprobe" EXIT
44*4882a593Smuzhiyun	if [ ! -d $DIR ]; then
45*4882a593Smuzhiyun		modprobe test_firmware
46*4882a593Smuzhiyun	fi
47*4882a593Smuzhiyun	if [ ! -f $PROC_CONFIG ]; then
48*4882a593Smuzhiyun		if modprobe configs 2>/dev/null; then
49*4882a593Smuzhiyun			echo "Loaded configs module"
50*4882a593Smuzhiyun			if [ ! -f $PROC_CONFIG ]; then
51*4882a593Smuzhiyun				echo "You must have the following enabled in your kernel:" >&2
52*4882a593Smuzhiyun				cat $TEST_DIR/config >&2
53*4882a593Smuzhiyun				echo "Resorting to old heuristics" >&2
54*4882a593Smuzhiyun			fi
55*4882a593Smuzhiyun		else
56*4882a593Smuzhiyun			echo "Failed to load configs module, using old heuristics" >&2
57*4882a593Smuzhiyun		fi
58*4882a593Smuzhiyun	fi
59*4882a593Smuzhiyun}
60*4882a593Smuzhiyun
61*4882a593Smuzhiyuncheck_setup()
62*4882a593Smuzhiyun{
63*4882a593Smuzhiyun	HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)"
64*4882a593Smuzhiyun	HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)"
65*4882a593Smuzhiyun	HAS_FW_LOADER_COMPRESS="$(kconfig_has CONFIG_FW_LOADER_COMPRESS=y)"
66*4882a593Smuzhiyun	PROC_FW_IGNORE_SYSFS_FALLBACK="0"
67*4882a593Smuzhiyun	PROC_FW_FORCE_SYSFS_FALLBACK="0"
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun	if [ -z $PROC_SYS_DIR ]; then
70*4882a593Smuzhiyun		PROC_SYS_DIR="/proc/sys/kernel"
71*4882a593Smuzhiyun	fi
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun	FW_PROC="${PROC_SYS_DIR}/firmware_config"
74*4882a593Smuzhiyun	FW_FORCE_SYSFS_FALLBACK="$FW_PROC/force_sysfs_fallback"
75*4882a593Smuzhiyun	FW_IGNORE_SYSFS_FALLBACK="$FW_PROC/ignore_sysfs_fallback"
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun	if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
78*4882a593Smuzhiyun		PROC_FW_FORCE_SYSFS_FALLBACK="$(cat $FW_FORCE_SYSFS_FALLBACK)"
79*4882a593Smuzhiyun	fi
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun	if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then
82*4882a593Smuzhiyun		PROC_FW_IGNORE_SYSFS_FALLBACK="$(cat $FW_IGNORE_SYSFS_FALLBACK)"
83*4882a593Smuzhiyun	fi
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun	if [ "$PROC_FW_FORCE_SYSFS_FALLBACK" = "1" ]; then
86*4882a593Smuzhiyun		HAS_FW_LOADER_USER_HELPER="yes"
87*4882a593Smuzhiyun		HAS_FW_LOADER_USER_HELPER_FALLBACK="yes"
88*4882a593Smuzhiyun	fi
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun	if [ "$PROC_FW_IGNORE_SYSFS_FALLBACK" = "1" ]; then
91*4882a593Smuzhiyun		HAS_FW_LOADER_USER_HELPER_FALLBACK="no"
92*4882a593Smuzhiyun		HAS_FW_LOADER_USER_HELPER="no"
93*4882a593Smuzhiyun	fi
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
96*4882a593Smuzhiyun	       OLD_TIMEOUT="$(cat /sys/class/firmware/timeout)"
97*4882a593Smuzhiyun	fi
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun	OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)"
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun	if [ "$HAS_FW_LOADER_COMPRESS" = "yes" ]; then
102*4882a593Smuzhiyun		if ! which xz 2> /dev/null > /dev/null; then
103*4882a593Smuzhiyun			HAS_FW_LOADER_COMPRESS=""
104*4882a593Smuzhiyun		fi
105*4882a593Smuzhiyun	fi
106*4882a593Smuzhiyun}
107*4882a593Smuzhiyun
108*4882a593Smuzhiyunverify_reqs()
109*4882a593Smuzhiyun{
110*4882a593Smuzhiyun	if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then
111*4882a593Smuzhiyun		if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
112*4882a593Smuzhiyun			echo "usermode helper disabled so ignoring test"
113*4882a593Smuzhiyun			exit 0
114*4882a593Smuzhiyun		fi
115*4882a593Smuzhiyun	fi
116*4882a593Smuzhiyun}
117*4882a593Smuzhiyun
118*4882a593Smuzhiyunsetup_tmp_file()
119*4882a593Smuzhiyun{
120*4882a593Smuzhiyun	FWPATH=$(mktemp -d)
121*4882a593Smuzhiyun	FW="$FWPATH/test-firmware.bin"
122*4882a593Smuzhiyun	echo "ABCD0123" >"$FW"
123*4882a593Smuzhiyun	FW_INTO_BUF="$FWPATH/$TEST_FIRMWARE_INTO_BUF_FILENAME"
124*4882a593Smuzhiyun	echo "EFGH4567" >"$FW_INTO_BUF"
125*4882a593Smuzhiyun	NAME=$(basename "$FW")
126*4882a593Smuzhiyun	if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
127*4882a593Smuzhiyun		echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path
128*4882a593Smuzhiyun	fi
129*4882a593Smuzhiyun}
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun__setup_random_file()
132*4882a593Smuzhiyun{
133*4882a593Smuzhiyun	RANDOM_FILE_PATH="$(mktemp -p $FWPATH)"
134*4882a593Smuzhiyun	# mktemp says dry-run -n is unsafe, so...
135*4882a593Smuzhiyun	if [[ "$1" = "fake" ]]; then
136*4882a593Smuzhiyun		rm -rf $RANDOM_FILE_PATH
137*4882a593Smuzhiyun		sync
138*4882a593Smuzhiyun	else
139*4882a593Smuzhiyun		echo "ABCD0123" >"$RANDOM_FILE_PATH"
140*4882a593Smuzhiyun	fi
141*4882a593Smuzhiyun	echo $RANDOM_FILE_PATH
142*4882a593Smuzhiyun}
143*4882a593Smuzhiyun
144*4882a593Smuzhiyunsetup_random_file()
145*4882a593Smuzhiyun{
146*4882a593Smuzhiyun	echo $(__setup_random_file)
147*4882a593Smuzhiyun}
148*4882a593Smuzhiyun
149*4882a593Smuzhiyunsetup_random_file_fake()
150*4882a593Smuzhiyun{
151*4882a593Smuzhiyun	echo $(__setup_random_file fake)
152*4882a593Smuzhiyun}
153*4882a593Smuzhiyun
154*4882a593Smuzhiyunproc_set_force_sysfs_fallback()
155*4882a593Smuzhiyun{
156*4882a593Smuzhiyun	if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
157*4882a593Smuzhiyun		echo -n $1 > $FW_FORCE_SYSFS_FALLBACK
158*4882a593Smuzhiyun		check_setup
159*4882a593Smuzhiyun	fi
160*4882a593Smuzhiyun}
161*4882a593Smuzhiyun
162*4882a593Smuzhiyunproc_set_ignore_sysfs_fallback()
163*4882a593Smuzhiyun{
164*4882a593Smuzhiyun	if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then
165*4882a593Smuzhiyun		echo -n $1 > $FW_IGNORE_SYSFS_FALLBACK
166*4882a593Smuzhiyun		check_setup
167*4882a593Smuzhiyun	fi
168*4882a593Smuzhiyun}
169*4882a593Smuzhiyun
170*4882a593Smuzhiyunproc_restore_defaults()
171*4882a593Smuzhiyun{
172*4882a593Smuzhiyun	proc_set_force_sysfs_fallback 0
173*4882a593Smuzhiyun	proc_set_ignore_sysfs_fallback 0
174*4882a593Smuzhiyun}
175*4882a593Smuzhiyun
176*4882a593Smuzhiyuntest_finish()
177*4882a593Smuzhiyun{
178*4882a593Smuzhiyun	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
179*4882a593Smuzhiyun		echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
180*4882a593Smuzhiyun	fi
181*4882a593Smuzhiyun	if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
182*4882a593Smuzhiyun		if [ "$OLD_FWPATH" = "" ]; then
183*4882a593Smuzhiyun			# A zero-length write won't work; write a null byte
184*4882a593Smuzhiyun			printf '\000' >/sys/module/firmware_class/parameters/path
185*4882a593Smuzhiyun		else
186*4882a593Smuzhiyun			echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
187*4882a593Smuzhiyun		fi
188*4882a593Smuzhiyun	fi
189*4882a593Smuzhiyun	if [ -f $FW ]; then
190*4882a593Smuzhiyun		rm -f "$FW"
191*4882a593Smuzhiyun	fi
192*4882a593Smuzhiyun	if [ -f $FW_INTO_BUF ]; then
193*4882a593Smuzhiyun		rm -f "$FW_INTO_BUF"
194*4882a593Smuzhiyun	fi
195*4882a593Smuzhiyun	if [ -d $FWPATH ]; then
196*4882a593Smuzhiyun		rm -rf "$FWPATH"
197*4882a593Smuzhiyun	fi
198*4882a593Smuzhiyun	proc_restore_defaults
199*4882a593Smuzhiyun}
200*4882a593Smuzhiyun
201*4882a593Smuzhiyunkconfig_has()
202*4882a593Smuzhiyun{
203*4882a593Smuzhiyun	if [ -f $PROC_CONFIG ]; then
204*4882a593Smuzhiyun		if zgrep -q $1 $PROC_CONFIG 2>/dev/null; then
205*4882a593Smuzhiyun			echo "yes"
206*4882a593Smuzhiyun		else
207*4882a593Smuzhiyun			echo "no"
208*4882a593Smuzhiyun		fi
209*4882a593Smuzhiyun	else
210*4882a593Smuzhiyun		# We currently don't have easy heuristics to infer this
211*4882a593Smuzhiyun		# so best we can do is just try to use the kernel assuming
212*4882a593Smuzhiyun		# you had enabled it. This matches the old behaviour.
213*4882a593Smuzhiyun		if [ "$1" = "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" ]; then
214*4882a593Smuzhiyun			echo "yes"
215*4882a593Smuzhiyun		elif [ "$1" = "CONFIG_FW_LOADER_USER_HELPER=y" ]; then
216*4882a593Smuzhiyun			if [ -d /sys/class/firmware/ ]; then
217*4882a593Smuzhiyun				echo yes
218*4882a593Smuzhiyun			else
219*4882a593Smuzhiyun				echo no
220*4882a593Smuzhiyun			fi
221*4882a593Smuzhiyun		fi
222*4882a593Smuzhiyun	fi
223*4882a593Smuzhiyun}
224