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