162306a36Sopenharmony_ci#!/bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci# Library of helpers for test scripts. 562306a36Sopenharmony_ciset -e 662306a36Sopenharmony_ci 762306a36Sopenharmony_ciDIR=/sys/devices/virtual/misc/test_firmware 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciPROC_CONFIG="/proc/config.gz" 1062306a36Sopenharmony_ciTEST_DIR=$(dirname $0) 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci# We need to load a different file to test request_firmware_into_buf 1362306a36Sopenharmony_ci# I believe the issue is firmware loaded cached vs. non-cached 1462306a36Sopenharmony_ci# with same filename is bungled. 1562306a36Sopenharmony_ci# To reproduce rename this to test-firmware.bin 1662306a36Sopenharmony_ciTEST_FIRMWARE_INTO_BUF_FILENAME=test-firmware-into-buf.bin 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci# Kselftest framework requirement - SKIP code is 4. 1962306a36Sopenharmony_ciksft_skip=4 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciprint_reqs_exit() 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci echo "You must have the following enabled in your kernel:" >&2 2462306a36Sopenharmony_ci cat $TEST_DIR/config >&2 2562306a36Sopenharmony_ci exit $ksft_skip 2662306a36Sopenharmony_ci} 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_citest_modprobe() 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci if [ ! -d $DIR ]; then 3162306a36Sopenharmony_ci print_reqs_exit 3262306a36Sopenharmony_ci fi 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cicheck_mods() 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci local uid=$(id -u) 3862306a36Sopenharmony_ci if [ $uid -ne 0 ]; then 3962306a36Sopenharmony_ci echo "skip all tests: must be run as root" >&2 4062306a36Sopenharmony_ci exit $ksft_skip 4162306a36Sopenharmony_ci fi 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci trap "test_modprobe" EXIT 4462306a36Sopenharmony_ci if [ ! -d $DIR ]; then 4562306a36Sopenharmony_ci modprobe test_firmware 4662306a36Sopenharmony_ci fi 4762306a36Sopenharmony_ci if [ ! -f $PROC_CONFIG ]; then 4862306a36Sopenharmony_ci if modprobe configs 2>/dev/null; then 4962306a36Sopenharmony_ci echo "Loaded configs module" 5062306a36Sopenharmony_ci if [ ! -f $PROC_CONFIG ]; then 5162306a36Sopenharmony_ci echo "You must have the following enabled in your kernel:" >&2 5262306a36Sopenharmony_ci cat $TEST_DIR/config >&2 5362306a36Sopenharmony_ci echo "Resorting to old heuristics" >&2 5462306a36Sopenharmony_ci fi 5562306a36Sopenharmony_ci else 5662306a36Sopenharmony_ci echo "Failed to load configs module, using old heuristics" >&2 5762306a36Sopenharmony_ci fi 5862306a36Sopenharmony_ci fi 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cicheck_setup() 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)" 6462306a36Sopenharmony_ci HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)" 6562306a36Sopenharmony_ci HAS_FW_LOADER_COMPRESS_XZ="$(kconfig_has CONFIG_FW_LOADER_COMPRESS_XZ=y)" 6662306a36Sopenharmony_ci HAS_FW_LOADER_COMPRESS_ZSTD="$(kconfig_has CONFIG_FW_LOADER_COMPRESS_ZSTD=y)" 6762306a36Sopenharmony_ci HAS_FW_UPLOAD="$(kconfig_has CONFIG_FW_UPLOAD=y)" 6862306a36Sopenharmony_ci PROC_FW_IGNORE_SYSFS_FALLBACK="0" 6962306a36Sopenharmony_ci PROC_FW_FORCE_SYSFS_FALLBACK="0" 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci if [ -z $PROC_SYS_DIR ]; then 7262306a36Sopenharmony_ci PROC_SYS_DIR="/proc/sys/kernel" 7362306a36Sopenharmony_ci fi 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci FW_PROC="${PROC_SYS_DIR}/firmware_config" 7662306a36Sopenharmony_ci FW_FORCE_SYSFS_FALLBACK="$FW_PROC/force_sysfs_fallback" 7762306a36Sopenharmony_ci FW_IGNORE_SYSFS_FALLBACK="$FW_PROC/ignore_sysfs_fallback" 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 8062306a36Sopenharmony_ci PROC_FW_FORCE_SYSFS_FALLBACK="$(cat $FW_FORCE_SYSFS_FALLBACK)" 8162306a36Sopenharmony_ci fi 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 8462306a36Sopenharmony_ci PROC_FW_IGNORE_SYSFS_FALLBACK="$(cat $FW_IGNORE_SYSFS_FALLBACK)" 8562306a36Sopenharmony_ci fi 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci if [ "$PROC_FW_FORCE_SYSFS_FALLBACK" = "1" ]; then 8862306a36Sopenharmony_ci HAS_FW_LOADER_USER_HELPER="yes" 8962306a36Sopenharmony_ci HAS_FW_LOADER_USER_HELPER_FALLBACK="yes" 9062306a36Sopenharmony_ci fi 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci if [ "$PROC_FW_IGNORE_SYSFS_FALLBACK" = "1" ]; then 9362306a36Sopenharmony_ci HAS_FW_LOADER_USER_HELPER_FALLBACK="no" 9462306a36Sopenharmony_ci HAS_FW_LOADER_USER_HELPER="no" 9562306a36Sopenharmony_ci fi 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 9862306a36Sopenharmony_ci OLD_TIMEOUT="$(cat /sys/class/firmware/timeout)" 9962306a36Sopenharmony_ci fi 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)" 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci if [ "$HAS_FW_LOADER_COMPRESS_XZ" = "yes" ]; then 10462306a36Sopenharmony_ci if ! which xz 2> /dev/null > /dev/null; then 10562306a36Sopenharmony_ci HAS_FW_LOADER_COMPRESS_XZ="" 10662306a36Sopenharmony_ci fi 10762306a36Sopenharmony_ci fi 10862306a36Sopenharmony_ci if [ "$HAS_FW_LOADER_COMPRESS_ZSTD" = "yes" ]; then 10962306a36Sopenharmony_ci if ! which zstd 2> /dev/null > /dev/null; then 11062306a36Sopenharmony_ci HAS_FW_LOADER_COMPRESS_ZSTD="" 11162306a36Sopenharmony_ci fi 11262306a36Sopenharmony_ci fi 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_civerify_reqs() 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then 11862306a36Sopenharmony_ci if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 11962306a36Sopenharmony_ci echo "usermode helper disabled so ignoring test" 12062306a36Sopenharmony_ci exit 0 12162306a36Sopenharmony_ci fi 12262306a36Sopenharmony_ci fi 12362306a36Sopenharmony_ci if [ "$TEST_REQS_FW_UPLOAD" = "yes" ]; then 12462306a36Sopenharmony_ci if [ ! "$HAS_FW_UPLOAD" = "yes" ]; then 12562306a36Sopenharmony_ci echo "firmware upload disabled so ignoring test" 12662306a36Sopenharmony_ci exit 0 12762306a36Sopenharmony_ci fi 12862306a36Sopenharmony_ci fi 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cisetup_tmp_file() 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci FWPATH=$(mktemp -d) 13462306a36Sopenharmony_ci FW="$FWPATH/test-firmware.bin" 13562306a36Sopenharmony_ci echo "ABCD0123" >"$FW" 13662306a36Sopenharmony_ci FW_INTO_BUF="$FWPATH/$TEST_FIRMWARE_INTO_BUF_FILENAME" 13762306a36Sopenharmony_ci echo "EFGH4567" >"$FW_INTO_BUF" 13862306a36Sopenharmony_ci NAME=$(basename "$FW") 13962306a36Sopenharmony_ci if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 14062306a36Sopenharmony_ci echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path 14162306a36Sopenharmony_ci fi 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci__setup_random_file() 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci RANDOM_FILE_PATH="$(mktemp -p $FWPATH)" 14762306a36Sopenharmony_ci # mktemp says dry-run -n is unsafe, so... 14862306a36Sopenharmony_ci if [[ "$1" = "fake" ]]; then 14962306a36Sopenharmony_ci rm -rf $RANDOM_FILE_PATH 15062306a36Sopenharmony_ci sync 15162306a36Sopenharmony_ci else 15262306a36Sopenharmony_ci echo "ABCD0123" >"$RANDOM_FILE_PATH" 15362306a36Sopenharmony_ci fi 15462306a36Sopenharmony_ci echo $RANDOM_FILE_PATH 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_cisetup_random_file() 15862306a36Sopenharmony_ci{ 15962306a36Sopenharmony_ci echo $(__setup_random_file) 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cisetup_random_file_fake() 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci echo $(__setup_random_file fake) 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ciproc_set_force_sysfs_fallback() 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 17062306a36Sopenharmony_ci echo -n $1 > $FW_FORCE_SYSFS_FALLBACK 17162306a36Sopenharmony_ci check_setup 17262306a36Sopenharmony_ci fi 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ciproc_set_ignore_sysfs_fallback() 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 17862306a36Sopenharmony_ci echo -n $1 > $FW_IGNORE_SYSFS_FALLBACK 17962306a36Sopenharmony_ci check_setup 18062306a36Sopenharmony_ci fi 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ciproc_restore_defaults() 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci proc_set_force_sysfs_fallback 0 18662306a36Sopenharmony_ci proc_set_ignore_sysfs_fallback 0 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_citest_finish() 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 19262306a36Sopenharmony_ci echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout 19362306a36Sopenharmony_ci fi 19462306a36Sopenharmony_ci if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 19562306a36Sopenharmony_ci if [ "$OLD_FWPATH" = "" ]; then 19662306a36Sopenharmony_ci # A zero-length write won't work; write a null byte 19762306a36Sopenharmony_ci printf '\000' >/sys/module/firmware_class/parameters/path 19862306a36Sopenharmony_ci else 19962306a36Sopenharmony_ci echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path 20062306a36Sopenharmony_ci fi 20162306a36Sopenharmony_ci fi 20262306a36Sopenharmony_ci if [ -f $FW ]; then 20362306a36Sopenharmony_ci rm -f "$FW" 20462306a36Sopenharmony_ci fi 20562306a36Sopenharmony_ci if [ -f $FW_INTO_BUF ]; then 20662306a36Sopenharmony_ci rm -f "$FW_INTO_BUF" 20762306a36Sopenharmony_ci fi 20862306a36Sopenharmony_ci if [ -d $FWPATH ]; then 20962306a36Sopenharmony_ci rm -rf "$FWPATH" 21062306a36Sopenharmony_ci fi 21162306a36Sopenharmony_ci proc_restore_defaults 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_cikconfig_has() 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci if [ -f $PROC_CONFIG ]; then 21762306a36Sopenharmony_ci if zgrep -q $1 $PROC_CONFIG 2>/dev/null; then 21862306a36Sopenharmony_ci echo "yes" 21962306a36Sopenharmony_ci else 22062306a36Sopenharmony_ci echo "no" 22162306a36Sopenharmony_ci fi 22262306a36Sopenharmony_ci else 22362306a36Sopenharmony_ci # We currently don't have easy heuristics to infer this 22462306a36Sopenharmony_ci # so best we can do is just try to use the kernel assuming 22562306a36Sopenharmony_ci # you had enabled it. This matches the old behaviour. 22662306a36Sopenharmony_ci if [ "$1" = "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" ]; then 22762306a36Sopenharmony_ci echo "yes" 22862306a36Sopenharmony_ci elif [ "$1" = "CONFIG_FW_LOADER_USER_HELPER=y" ]; then 22962306a36Sopenharmony_ci if [ -d /sys/class/firmware/ ]; then 23062306a36Sopenharmony_ci echo yes 23162306a36Sopenharmony_ci else 23262306a36Sopenharmony_ci echo no 23362306a36Sopenharmony_ci fi 23462306a36Sopenharmony_ci fi 23562306a36Sopenharmony_ci fi 23662306a36Sopenharmony_ci} 237