From 206d41ad5ce69d224e311f4f12cc7f963f8eedc4 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Mon, 8 Dec 2025 11:38:05 +0530 Subject: [PATCH 1/2] WiFi_Firmware_Driver: add ath10k support and clean logging Extend firmware scan and driver checks to handle ath10k in addition to ath11k. Detect SoC from DT model and choose appropriate firmware path dynamically. Verify active ath10k/ath11k kernel modules via lsmod for stronger validation. Switch to log_info/log_fail/log_pass flow for consistent functestlib usage. Signed-off-by: Srikanth Muppandam --- .../WiFi/WiFi_Firmware_Driver/run.sh | 170 ++++++++++++++---- 1 file changed, 139 insertions(+), 31 deletions(-) diff --git a/Runner/suites/Connectivity/WiFi/WiFi_Firmware_Driver/run.sh b/Runner/suites/Connectivity/WiFi/WiFi_Firmware_Driver/run.sh index d4a92a02..06c69a0c 100755 --- a/Runner/suites/Connectivity/WiFi/WiFi_Firmware_Driver/run.sh +++ b/Runner/suites/Connectivity/WiFi/WiFi_Firmware_Driver/run.sh @@ -25,6 +25,7 @@ if [ -z "$__INIT_ENV_LOADED" ]; then # shellcheck disable=SC1090 . "$INIT_ENV" fi + # Always source functestlib.sh, using $TOOLS exported by init_env # shellcheck disable=SC1090,SC1091 . "$TOOLS/functestlib.sh" @@ -33,11 +34,18 @@ TESTNAME="WiFi_Firmware_Driver" test_path=$(find_test_case_by_name "$TESTNAME") cd "$test_path" || exit 1 +RES_FILE="./${TESTNAME}.res" +: >"$RES_FILE" + log_info "--------------------------------------------------------------------------" log_info "-------------------Starting $TESTNAME Testcase----------------------------" log_info "=== Test Initialization ===" -check_dependencies find grep modprobe lsmod cat +if ! check_dependencies find grep modprobe lsmod cat stat; then + log_skip "$TESTNAME SKIP - required tools (find/grep/modprobe/lsmod/cat/stat) missing" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi # Detect SoC from /proc/device-tree/model if [ -f /proc/device-tree/model ]; then @@ -47,51 +55,151 @@ else fi log_info "Detected SoC model: $soc_model" -# Scan firmware -log_info "Scanning for WiFi firmware under /lib/firmware/ath11k/..." +# --------------------------------------------------------------------------- +# Firmware detection: support ath11k (amss.bin / wpss.mbn) and ath10k (WCN3990) +# --------------------------------------------------------------------------- +log_info "Scanning for WiFi firmware (ath11k / ath10k)..." + fwfile="" -if find /lib/firmware/ath11k/ -type f -name "amss.bin" -print -quit 2>/dev/null | grep -q .; then - fwfile=$(find /lib/firmware/ath11k/ -type f -name "amss.bin" -print -quit 2>/dev/null) -elif find /lib/firmware/ath11k/ -type f -name "wpss.mbn" -print -quit 2>/dev/null | grep -q .; then - fwfile=$(find /lib/firmware/ath11k/ -type f -name "wpss.mbn" -print -quit 2>/dev/null) +wifi_family="" + +# Prefer ath11k if present (Lemans/Monaco/Kodiak type platforms) +if [ -d /lib/firmware/ath11k ]; then + if find /lib/firmware/ath11k/ -type f -name "amss.bin" -print -quit 2>/dev/null | grep -q .; then + fwfile=$(find /lib/firmware/ath11k/ -type f -name "amss.bin" -print -quit 2>/dev/null) + wifi_family="ath11k" + elif find /lib/firmware/ath11k/ -type f -name "wpss.mbn" -print -quit 2>/dev/null | grep -q .; then + fwfile=$(find /lib/firmware/ath11k/ -type f -name "wpss.mbn" -print -quit 2>/dev/null) + wifi_family="ath11k" + fi fi -if [ -z "$fwfile" ]; then - log_skip_exit "$TESTNAME" "No WiFi firmware (amss.bin or wpss.mbn) found under /lib/firmware/ath11k/" +# If no ath11k firmware found, try ath10k (e.g. WCN3990 on RB1/QCM2290) +if [ -z "$fwfile" ] && [ -d /lib/firmware/ath10k ]; then + # Look for wlan firmware or generic firmware-*.bin + if find /lib/firmware/ath10k/ -type f -name "wlanmdsp.mbn" -print -quit 2>/dev/null | grep -q .; then + fwfile=$(find /lib/firmware/ath10k/ -type f -name "wlanmdsp.mbn" -print -quit 2>/dev/null) + wifi_family="ath10k" + elif find /lib/firmware/ath10k/ -type f -name "firmware-*.bin" -print -quit 2>/dev/null | grep -q .; then + fwfile=$(find /lib/firmware/ath10k/ -type f -name "firmware-*.bin" -print -quit 2>/dev/null) + wifi_family="ath10k" + fi +fi + +if [ -z "$fwfile" ] || [ -z "$wifi_family" ]; then + log_skip "$TESTNAME SKIP - No ath11k/ath10k WiFi firmware found under /lib/firmware (ath11k or ath10k)" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 fi size=$(stat -c%s "$fwfile" 2>/dev/null) basename=$(basename "$fwfile") +log_info "Detected WiFi firmware family: $wifi_family" log_info "Detected firmware [$basename]: $fwfile (size: $size bytes)" -case "$basename" in - wpss.mbn) - log_info "Platform using wpss.mbn firmware (e.g., Kodiak)" - if validate_remoteproc_running "wpss"; then - log_info "Remoteproc 'wpss' is active and validated." - else - log_fail_exit "$TESTNAME" "Remoteproc 'wpss' validation failed." - fi - log_info "No module load needed for wpss-based platform (e.g., Kodiak)." +suite_rc=0 + +# --------------------------------------------------------------------------- +# Family-specific handling (load / validate) – use log_* only, decide at end +# --------------------------------------------------------------------------- +case "$wifi_family" in + ath11k) + case "$basename" in + wpss.mbn) + log_info "Platform using wpss.mbn firmware (e.g., Kodiak - WPSS via remoteproc)" + if validate_remoteproc_running "wpss"; then + log_info "Remoteproc 'wpss' is active and validated." + else + log_fail "Remoteproc 'wpss' validation failed." + suite_rc=1 + fi + log_info "No ath11k_pci module load needed for wpss-based platform." + ;; + amss.bin) + log_info "amss.bin firmware detected (e.g., WCN6855 - Lemans/Monaco via ath11k_pci)" + if ! modprobe ath11k_pci 2>/dev/null; then + log_fail "Failed to load ath11k_pci module." + suite_rc=1 + else + log_info "ath11k_pci module loaded successfully." + fi + ;; + *) + log_skip "$TESTNAME SKIP - Unsupported ath11k firmware type: $basename" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + ;; + esac ;; - amss.bin) - log_info "amss.bin firmware detected (e.g., WCN6855 - Lemans/Monaco)" - if ! modprobe ath11k_pci 2>/dev/null; then - log_fail_exit "$TESTNAME" "Failed to load ath11k_pci module." + ath10k) + log_info "ath10k firmware detected (e.g., WCN3990 on RB1/QCM2290)." + # Ensure ath10k_core + one of the bus drivers (snoc/pci/sdio) are loaded + if ! lsmod | grep -q '^ath10k_core\s'; then + log_info "ath10k_core not loaded yet; attempting to load ath10k bus drivers..." + bus_loaded=0 + for m in ath10k_snoc ath10k_pci ath10k_sdio; do + if modprobe "$m" 2>/dev/null; then + log_info "Loaded ath10k bus driver module: $m" + bus_loaded=1 + break + fi + done + if [ "$bus_loaded" -ne 1 ]; then + log_fail "Failed to load any ath10k bus driver (ath10k_snoc/ath10k_pci/ath10k_sdio)." + suite_rc=1 + fi + else + log_info "ath10k_core already loaded; skipping bus driver modprobe attempts." fi ;; *) - log_skip_exit "$TESTNAME" "Unsupported firmware type: $basename" + log_skip "$TESTNAME SKIP - Unsupported WiFi family detected: $wifi_family" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 ;; esac -log_info "Checking active ath11k-related kernel modules via lsmod..." -if lsmod | grep -Eq '^ath11k(_.*)?\s'; then - lsmod | grep -E '^ath11k(_.*)?\s' | while read -r mod_line; do - log_info " Module loaded: $mod_line" - done -else - log_fail_exit "$TESTNAME" "No ath11k-related kernel module detected via lsmod" +# --------------------------------------------------------------------------- +# Module visibility checks (family-specific) – explicitly verify ath10k modules +# --------------------------------------------------------------------------- +if [ "$wifi_family" = "ath11k" ]; then + log_info "Checking active ath11k-related kernel modules via lsmod..." + if lsmod | grep -Eq '^ath11k(_.*)?\s'; then + lsmod | grep -E '^ath11k(_.*)?\s' | while read -r mod_line; do + log_info " Module loaded: $mod_line" + done + else + log_fail "No ath11k-related kernel module detected via lsmod." + suite_rc=1 + fi +elif [ "$wifi_family" = "ath10k" ]; then + log_info "Checking active ath10k-related kernel modules via lsmod..." + if lsmod | grep -q '^ath10k_core\s'; then + log_info " Core module loaded: ath10k_core" + else + log_fail "ath10k_core module is not loaded." + suite_rc=1 + fi + + if lsmod | grep -Eq '^ath10k_(snoc|pci|sdio)\s'; then + lsmod | grep -E '^ath10k_(snoc|pci|sdio)\s' | while read -r mod_line; do + log_info " Bus driver loaded: $mod_line" + done + else + log_fail "No ath10k bus driver module (ath10k_snoc/ath10k_pci/ath10k_sdio) detected via lsmod." + suite_rc=1 + fi +fi + +# --------------------------------------------------------------------------- +# Final result +# --------------------------------------------------------------------------- +if [ "$suite_rc" -eq 0 ]; then + log_pass "$TESTNAME: PASS - WiFi firmware and driver validation successful." + echo "$TESTNAME PASS" >"$RES_FILE" + exit 0 fi -log_pass_exit "$TESTNAME" "WiFi firmware and driver validation successful." +log_fail "$TESTNAME: FAIL - WiFi firmware/driver validation encountered errors." +echo "$TESTNAME FAIL" >"$RES_FILE" +exit 1 From 3bfcc6a427de96a68cdc67cc4df6d3b37b085bd4 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Mon, 8 Dec 2025 18:00:29 +0530 Subject: [PATCH 2/2] functestlib: fix remoteproc firmware path lookup Rework get_remoteproc_path_by_firmware() to iterate firmware files directly and read them without using cat. This avoids the bogus idx arithmetic that caused "operand expected" errors while still allowing callers to derive the remoteproc index from the returned path. Signed-off-by: Srikanth Muppandam --- Runner/utils/functestlib.sh | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/Runner/utils/functestlib.sh b/Runner/utils/functestlib.sh index 8cac4874..f1af00d6 100755 --- a/Runner/utils/functestlib.sh +++ b/Runner/utils/functestlib.sh @@ -1900,15 +1900,35 @@ dt_has_remoteproc_fw() { } # Find the remoteproc path for a given firmware substring (e.g., "adsp", "cdsp", "gdsp"). +# Logic: +# - grep -n over /sys/class/remoteproc/remoteproc*/firmware (one line per remoteproc) +# - Take the first matching line number (1-based) +# - Subtract 1 → remoteproc index → /sys/class/remoteproc/remoteproc${idx} get_remoteproc_path_by_firmware() { - name="$1" - idx path - # List all remoteproc firmware nodes, match name, and return the remoteproc path - idx=$(cat /sys/class/remoteproc/remoteproc*/firmware 2>/dev/null | grep -n "$name" | cut -d: -f1 | head -n1) - [ -z "$idx" ] && return 1 - idx=$((idx - 1)) - path="/sys/class/remoteproc/remoteproc${idx}" - [ -d "$path" ] && echo "$path" && return 0 + name=$1 + + [ -n "$name" ] || return 1 + [ -d /sys/class/remoteproc ] || return 1 + + for fw in /sys/class/remoteproc/remoteproc*/firmware; do + # Skip if glob didn't match any file + [ -f "$fw" ] || continue + + # Read first line from firmware file without using cat + if IFS= read -r fwname <"$fw"; then + case "$fwname" in + *"$name"*) + # Map firmware file back to its remoteproc directory + dir=${fw%/firmware} + if [ -d "$dir" ]; then + printf '%s\n' "$dir" + return 0 + fi + ;; + esac + fi + done + return 1 }