1*a37dddddSRuss Weight#!/bin/bash 2*a37dddddSRuss Weight# SPDX-License-Identifier: GPL-2.0 3*a37dddddSRuss Weight# This validates the user-initiated fw upload mechanism of the firmware 4*a37dddddSRuss Weight# loader. It verifies that one or more firmware devices can be created 5*a37dddddSRuss Weight# for a device driver. It also verifies the data transfer, the 6*a37dddddSRuss Weight# cancellation support, and the error flows. 7*a37dddddSRuss Weightset -e 8*a37dddddSRuss Weight 9*a37dddddSRuss WeightTEST_REQS_FW_UPLOAD="yes" 10*a37dddddSRuss WeightTEST_DIR=$(dirname $0) 11*a37dddddSRuss Weight 12*a37dddddSRuss Weightprogress_states="preparing transferring programming" 13*a37dddddSRuss Weighterrors="hw-error 14*a37dddddSRuss Weight timeout 15*a37dddddSRuss Weight device-busy 16*a37dddddSRuss Weight invalid-file-size 17*a37dddddSRuss Weight read-write-error 18*a37dddddSRuss Weight flash-wearout" 19*a37dddddSRuss Weighterror_abort="user-abort" 20*a37dddddSRuss Weightfwname1=fw1 21*a37dddddSRuss Weightfwname2=fw2 22*a37dddddSRuss Weightfwname3=fw3 23*a37dddddSRuss Weight 24*a37dddddSRuss Weightsource $TEST_DIR/fw_lib.sh 25*a37dddddSRuss Weight 26*a37dddddSRuss Weightcheck_mods 27*a37dddddSRuss Weightcheck_setup 28*a37dddddSRuss Weightverify_reqs 29*a37dddddSRuss Weight 30*a37dddddSRuss Weighttrap "upload_finish" EXIT 31*a37dddddSRuss Weight 32*a37dddddSRuss Weightupload_finish() { 33*a37dddddSRuss Weight local fwdevs="$fwname1 $fwname2 $fwname3" 34*a37dddddSRuss Weight 35*a37dddddSRuss Weight for name in $fwdevs; do 36*a37dddddSRuss Weight if [ -e "$DIR/$name" ]; then 37*a37dddddSRuss Weight echo -n "$name" > "$DIR"/upload_unregister 38*a37dddddSRuss Weight fi 39*a37dddddSRuss Weight done 40*a37dddddSRuss Weight} 41*a37dddddSRuss Weight 42*a37dddddSRuss Weightupload_fw() { 43*a37dddddSRuss Weight local name="$1" 44*a37dddddSRuss Weight local file="$2" 45*a37dddddSRuss Weight 46*a37dddddSRuss Weight echo 1 > "$DIR"/"$name"/loading 47*a37dddddSRuss Weight cat "$file" > "$DIR"/"$name"/data 48*a37dddddSRuss Weight echo 0 > "$DIR"/"$name"/loading 49*a37dddddSRuss Weight} 50*a37dddddSRuss Weight 51*a37dddddSRuss Weightverify_fw() { 52*a37dddddSRuss Weight local name="$1" 53*a37dddddSRuss Weight local file="$2" 54*a37dddddSRuss Weight 55*a37dddddSRuss Weight echo -n "$name" > "$DIR"/config_upload_name 56*a37dddddSRuss Weight if ! cmp "$file" "$DIR"/upload_read > /dev/null 2>&1; then 57*a37dddddSRuss Weight echo "$0: firmware compare for $name did not match" >&2 58*a37dddddSRuss Weight exit 1 59*a37dddddSRuss Weight fi 60*a37dddddSRuss Weight 61*a37dddddSRuss Weight echo "$0: firmware upload for $name works" >&2 62*a37dddddSRuss Weight return 0 63*a37dddddSRuss Weight} 64*a37dddddSRuss Weight 65*a37dddddSRuss Weightinject_error() { 66*a37dddddSRuss Weight local name="$1" 67*a37dddddSRuss Weight local status="$2" 68*a37dddddSRuss Weight local error="$3" 69*a37dddddSRuss Weight 70*a37dddddSRuss Weight echo 1 > "$DIR"/"$name"/loading 71*a37dddddSRuss Weight echo -n "inject":"$status":"$error" > "$DIR"/"$name"/data 72*a37dddddSRuss Weight echo 0 > "$DIR"/"$name"/loading 73*a37dddddSRuss Weight} 74*a37dddddSRuss Weight 75*a37dddddSRuss Weightawait_status() { 76*a37dddddSRuss Weight local name="$1" 77*a37dddddSRuss Weight local expected="$2" 78*a37dddddSRuss Weight local status 79*a37dddddSRuss Weight local i 80*a37dddddSRuss Weight 81*a37dddddSRuss Weight let i=0 82*a37dddddSRuss Weight while [ $i -lt 50 ]; do 83*a37dddddSRuss Weight status=$(cat "$DIR"/"$name"/status) 84*a37dddddSRuss Weight if [ "$status" = "$expected" ]; then 85*a37dddddSRuss Weight return 0; 86*a37dddddSRuss Weight fi 87*a37dddddSRuss Weight sleep 1e-03 88*a37dddddSRuss Weight let i=$i+1 89*a37dddddSRuss Weight done 90*a37dddddSRuss Weight 91*a37dddddSRuss Weight echo "$0: Invalid status: Expected $expected, Actual $status" >&2 92*a37dddddSRuss Weight return 1; 93*a37dddddSRuss Weight} 94*a37dddddSRuss Weight 95*a37dddddSRuss Weightawait_idle() { 96*a37dddddSRuss Weight local name="$1" 97*a37dddddSRuss Weight 98*a37dddddSRuss Weight await_status "$name" "idle" 99*a37dddddSRuss Weight return $? 100*a37dddddSRuss Weight} 101*a37dddddSRuss Weight 102*a37dddddSRuss Weightexpect_error() { 103*a37dddddSRuss Weight local name="$1" 104*a37dddddSRuss Weight local expected="$2" 105*a37dddddSRuss Weight local error=$(cat "$DIR"/"$name"/error) 106*a37dddddSRuss Weight 107*a37dddddSRuss Weight if [ "$error" != "$expected" ]; then 108*a37dddddSRuss Weight echo "Invalid error: Expected $expected, Actual $error" >&2 109*a37dddddSRuss Weight return 1 110*a37dddddSRuss Weight fi 111*a37dddddSRuss Weight 112*a37dddddSRuss Weight return 0 113*a37dddddSRuss Weight} 114*a37dddddSRuss Weight 115*a37dddddSRuss Weightrandom_firmware() { 116*a37dddddSRuss Weight local bs="$1" 117*a37dddddSRuss Weight local count="$2" 118*a37dddddSRuss Weight local file=$(mktemp -p /tmp uploadfwXXX.bin) 119*a37dddddSRuss Weight 120*a37dddddSRuss Weight dd if=/dev/urandom of="$file" bs="$bs" count="$count" > /dev/null 2>&1 121*a37dddddSRuss Weight echo "$file" 122*a37dddddSRuss Weight} 123*a37dddddSRuss Weight 124*a37dddddSRuss Weighttest_upload_cancel() { 125*a37dddddSRuss Weight local name="$1" 126*a37dddddSRuss Weight local status 127*a37dddddSRuss Weight 128*a37dddddSRuss Weight for status in $progress_states; do 129*a37dddddSRuss Weight inject_error $name $status $error_abort 130*a37dddddSRuss Weight if ! await_status $name $status; then 131*a37dddddSRuss Weight exit 1 132*a37dddddSRuss Weight fi 133*a37dddddSRuss Weight 134*a37dddddSRuss Weight echo 1 > "$DIR"/"$name"/cancel 135*a37dddddSRuss Weight 136*a37dddddSRuss Weight if ! await_idle $name; then 137*a37dddddSRuss Weight exit 1 138*a37dddddSRuss Weight fi 139*a37dddddSRuss Weight 140*a37dddddSRuss Weight if ! expect_error $name "$status":"$error_abort"; then 141*a37dddddSRuss Weight exit 1 142*a37dddddSRuss Weight fi 143*a37dddddSRuss Weight done 144*a37dddddSRuss Weight 145*a37dddddSRuss Weight echo "$0: firmware upload cancellation works" 146*a37dddddSRuss Weight return 0 147*a37dddddSRuss Weight} 148*a37dddddSRuss Weight 149*a37dddddSRuss Weighttest_error_handling() { 150*a37dddddSRuss Weight local name=$1 151*a37dddddSRuss Weight local status 152*a37dddddSRuss Weight local error 153*a37dddddSRuss Weight 154*a37dddddSRuss Weight for status in $progress_states; do 155*a37dddddSRuss Weight for error in $errors; do 156*a37dddddSRuss Weight inject_error $name $status $error 157*a37dddddSRuss Weight 158*a37dddddSRuss Weight if ! await_idle $name; then 159*a37dddddSRuss Weight exit 1 160*a37dddddSRuss Weight fi 161*a37dddddSRuss Weight 162*a37dddddSRuss Weight if ! expect_error $name "$status":"$error"; then 163*a37dddddSRuss Weight exit 1 164*a37dddddSRuss Weight fi 165*a37dddddSRuss Weight 166*a37dddddSRuss Weight done 167*a37dddddSRuss Weight done 168*a37dddddSRuss Weight echo "$0: firmware upload error handling works" 169*a37dddddSRuss Weight} 170*a37dddddSRuss Weight 171*a37dddddSRuss Weighttest_fw_too_big() { 172*a37dddddSRuss Weight local name=$1 173*a37dddddSRuss Weight local fw_too_big=`random_firmware 512 5` 174*a37dddddSRuss Weight local expected="preparing:invalid-file-size" 175*a37dddddSRuss Weight 176*a37dddddSRuss Weight upload_fw $name $fw_too_big 177*a37dddddSRuss Weight rm -f $fw_too_big 178*a37dddddSRuss Weight 179*a37dddddSRuss Weight if ! await_idle $name; then 180*a37dddddSRuss Weight exit 1 181*a37dddddSRuss Weight fi 182*a37dddddSRuss Weight 183*a37dddddSRuss Weight if ! expect_error $name $expected; then 184*a37dddddSRuss Weight exit 1 185*a37dddddSRuss Weight fi 186*a37dddddSRuss Weight 187*a37dddddSRuss Weight echo "$0: oversized firmware error handling works" 188*a37dddddSRuss Weight} 189*a37dddddSRuss Weight 190*a37dddddSRuss Weightecho -n "$fwname1" > "$DIR"/upload_register 191*a37dddddSRuss Weightecho -n "$fwname2" > "$DIR"/upload_register 192*a37dddddSRuss Weightecho -n "$fwname3" > "$DIR"/upload_register 193*a37dddddSRuss Weight 194*a37dddddSRuss Weighttest_upload_cancel $fwname1 195*a37dddddSRuss Weighttest_error_handling $fwname1 196*a37dddddSRuss Weighttest_fw_too_big $fwname1 197*a37dddddSRuss Weight 198*a37dddddSRuss Weightfw_file1=`random_firmware 512 4` 199*a37dddddSRuss Weightfw_file2=`random_firmware 512 3` 200*a37dddddSRuss Weightfw_file3=`random_firmware 512 2` 201*a37dddddSRuss Weight 202*a37dddddSRuss Weightupload_fw $fwname1 $fw_file1 203*a37dddddSRuss Weightupload_fw $fwname2 $fw_file2 204*a37dddddSRuss Weightupload_fw $fwname3 $fw_file3 205*a37dddddSRuss Weight 206*a37dddddSRuss Weightverify_fw ${fwname1} ${fw_file1} 207*a37dddddSRuss Weightverify_fw ${fwname2} ${fw_file2} 208*a37dddddSRuss Weightverify_fw ${fwname3} ${fw_file3} 209*a37dddddSRuss Weight 210*a37dddddSRuss Weightecho -n "$fwname1" > "$DIR"/upload_unregister 211*a37dddddSRuss Weightecho -n "$fwname2" > "$DIR"/upload_unregister 212*a37dddddSRuss Weightecho -n "$fwname3" > "$DIR"/upload_unregister 213*a37dddddSRuss Weight 214*a37dddddSRuss Weightexit 0 215