Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Runner/suites/Connectivity/WiFi/WiFi_OnOff/WiFi_OnOff.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ metadata:
scope:
- functional

params:
WIFI_WAIT_SECS: "60"
WIFI_WAIT_STEP_SECS: "2"
WIFI_RECOVERY_RELOAD: "1"
WIFI_RECOVERY_RELOAD_AFTER_S: ""

run:
steps:
- REPO_PATH=$PWD
- cd Runner/suites/Connectivity/WiFi/WiFi_OnOff
- ./run.sh || true
- WIFI_WAIT_SECS="${WIFI_WAIT_SECS}" WIFI_WAIT_STEP_SECS="${WIFI_WAIT_STEP_SECS}" WIFI_RECOVERY_RELOAD="${WIFI_RECOVERY_RELOAD}" WIFI_RECOVERY_RELOAD_AFTER_S="${WIFI_RECOVERY_RELOAD_AFTER_S}" ./run.sh || true
- $REPO_PATH/Runner/utils/send-to-lava.sh WiFi_OnOff.res

26 changes: 17 additions & 9 deletions Runner/suites/Connectivity/WiFi/WiFi_OnOff/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ qcom,wcn6750
qcom,wcn3950
ath12k
ath11k
ath10k
wifi
wlan
qca
Expand All @@ -67,6 +68,8 @@ EOF

WIFI_WAIT_SECS="${WIFI_WAIT_SECS:-60}"
WIFI_WAIT_STEP_SECS="${WIFI_WAIT_STEP_SECS:-2}"
WIFI_RECOVERY_RELOAD="${WIFI_RECOVERY_RELOAD:-1}"
WIFI_RECOVERY_RELOAD_AFTER_S="${WIFI_RECOVERY_RELOAD_AFTER_S:-}"
WIFI_PROBE_LOG_DIR="${WIFI_PROBE_LOG_DIR:-./wifi_onoff_dmesg}"
WIFI_PROBE_LOG_TAG="${WIFI_PROBE_LOG_TAG:-${TESTNAME}/probe}"
WIFI_DT_PATTERNS="${WIFI_DT_PATTERNS:-$WIFI_DT_PATTERNS_DEFAULT}"
Expand Down Expand Up @@ -96,6 +99,7 @@ log_info "----------------------------------------------------------------------
log_info "-------------------Starting $TESTNAME Testcase----------------------------"
log_info "=== Test Initialization ==="
log_info "Config: WIFI_WAIT_SECS=${WIFI_WAIT_SECS} WIFI_WAIT_STEP_SECS=${WIFI_WAIT_STEP_SECS}"
log_info "Config: WIFI_RECOVERY_RELOAD=${WIFI_RECOVERY_RELOAD} WIFI_RECOVERY_RELOAD_AFTER_S=${WIFI_RECOVERY_RELOAD_AFTER_S:-auto}"
log_info "Config: WIFI_PROBE_LOG_TAG=${WIFI_PROBE_LOG_TAG}"

if [ -n "${WIFI_IFACE:-}" ]; then
Expand Down Expand Up @@ -128,9 +132,9 @@ fi

log_info "=== WiFi DT Validation ==="
if run_with_line_args wifi_dt_present "$WIFI_DT_PATTERNS"; then
log_pass "WiFi DT entry/compatible matched."
log_pass "WiFi/combined WCN DT entry/compatible matched."
else
log_warn "No WiFi DT entry/compatible matched from configured patterns."
log_warn "No WiFi/combined WCN DT entry/compatible matched from configured patterns."
fi

log_info "=== WiFi Module Visibility ==="
Expand Down Expand Up @@ -159,17 +163,21 @@ log_info "=== Waiting for WiFi Interface ==="
wifi_iface="$(wait_for_wifi_interface "$WIFI_WAIT_SECS" "$WIFI_WAIT_STEP_SECS" || true)"

if [ -z "$wifi_iface" ]; then
log_info "No WiFi interface detected after wait. Collecting diagnostics..."

log_info "No WiFi interface detected after wait/recovery. Collecting diagnostics..."
run_with_line_args wifi_dump_debug_info "$WIFI_DT_PATTERNS"
run_with_line_args wifi_log_module_info "$WIFI_DRIVER_MODULES"
wifi_has_probe_failures "$WIFI_PROBE_LOG_DIR" "$WIFI_PROBE_LOG_TAG" || true


if wifi_has_probe_failures "$WIFI_PROBE_LOG_DIR" "$WIFI_PROBE_LOG_TAG"; then
log_fail_exit "$TESTNAME" "WiFi driver probe/runtime failures detected and no usable WiFi interface was found." ""
fi

if wifi_stack_present; then
log_fail_exit "$TESTNAME" "WiFi stack present, but no usable WiFi interface was found after retries." ""
log_fail_exit "$TESTNAME" "WiFi runtime stack is present, but no usable WiFi interface was found after retries." ""
fi

log_skip_exit "$TESTNAME" "No WiFi interface found and no WiFi stack was detected. Skipping." ""

log_warn "WiFi modules may be loaded, but no WiFi phy/netdev/runtime object is exposed."
log_skip_exit "$TESTNAME" "No usable WiFi interface or runtime WiFi phy/netdev was found. Skipping." ""
fi

log_pass "Detected WiFi interface: $wifi_iface"
Expand Down
139 changes: 116 additions & 23 deletions Runner/utils/lib_connectivity.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,74 +14,149 @@ wifi_unblock_rfkill() {

# Retry WiFi interface discovery for a bounded time while unblocking rfkill.
# Prints interface name on success and returns non-zero on timeout.
#
# Optional recovery knobs:
# WIFI_RECOVERY_RELOAD=1|0
# Enable one controlled WiFi driver reload if no interface appears.
#
# WIFI_RECOVERY_RELOAD_AFTER_S=N
# Try reload after N seconds of waiting. Default: half of max_wait.
#
# WIFI_RECOVERY_MODULES="mod1 mod2 ..."
# Leaf WiFi driver modules eligible for reload.
#
# Notes:
# - stdout is reserved only for the detected interface name.
# - diagnostics go to stderr because callers use command substitution.
# - shared modules such as cfg80211/mac80211/mhi must not be reloaded here.
wait_for_wifi_interface() {
max_wait="${1:-60}"
sleep_step="${2:-2}"
waited=0
iface=""
settle_done=0

reload_done=0
reload_after=""
mod=""
recovery_modules="${WIFI_RECOVERY_MODULES:-ath12k_wifi7 ath12k_pci ath12k_ahb ath11k_pci ath11k_ahb ath11k_snoc ath10k_snoc ath10k_pci ath10k_sdio}"

case "$max_wait" in
''|*[!0-9]*)
max_wait=60
;;
esac

case "$sleep_step" in
''|*[!0-9]*)
sleep_step=2
;;
esac

if [ "$max_wait" -le 0 ] 2>/dev/null; then
max_wait=60
fi

if [ "$sleep_step" -le 0 ] 2>/dev/null; then
sleep_step=2
fi


reload_after="${WIFI_RECOVERY_RELOAD_AFTER_S:-}"
case "$reload_after" in
''|*[!0-9]*)
reload_after=$((max_wait / 2))
;;
esac

if [ "$reload_after" -le 0 ] 2>/dev/null; then
reload_after="$sleep_step"
fi

# Keep stdout reserved only for the detected interface name because callers
# commonly use command substitution:
# wifi_iface="$(wait_for_wifi_interface ...)"
# wifi_iface="$(wait_for_wifi_interface ...)"
#
# All diagnostics must go to stderr to avoid contaminating the returned
# interface name.
log_info "Waiting up to ${max_wait}s for WiFi interface creation" >&2

while [ "$waited" -lt "$max_wait" ]; do
wifi_unblock_rfkill

iface="$(get_wifi_interface 2>/dev/null || true)"
if [ -n "$iface" ]; then
printf '%s\n' "$iface"
return 0
fi

if [ "$settle_done" -eq 0 ]; then
settle_done=1

if command -v udevadm >/dev/null 2>&1; then
log_info "No WiFi interface yet; triggering net add uevents and waiting for udev settle" >&2
udevadm trigger --action=add --subsystem-match=net >/dev/null 2>&1 || true
udevadm settle --timeout=5 >/dev/null 2>&1 || true

iface="$(get_wifi_interface 2>/dev/null || true)"
if [ -n "$iface" ]; then
printf '%s\n' "$iface"
return 0
fi
fi
fi


if [ "${WIFI_RECOVERY_RELOAD:-1}" = "1" ] &&
[ "$reload_done" -eq 0 ] &&
[ "$waited" -ge "$reload_after" ] &&
command -v modprobe >/dev/null 2>&1; then
reload_done=1

for mod in $recovery_modules; do
[ -n "$mod" ] || continue

if ! is_module_loaded "$mod"; then
continue
fi

log_warn "No WiFi interface after ${waited}s; attempting one controlled reload of $mod" >&2

if modprobe -r "$mod" >/dev/null 2>&1; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do test script reload the module here? Isnt it needs to be taken care by Kernel to safely loada modules on bootup? or by udev?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do test script reload the module here? Isnt it needs to be taken care by Kernel to safely loada modules on bootup? or by udev?

we do not reload modules during the normal path.

  1. Wait for WiFi interface normally

    • rfkill unblock
    • get_wifi_interface retry
    • udev trigger/settle
  2. If interface appears

    • no module reload
    • continue toggle test
  3. Only if interface does not appear after part of the wait

    • attempt one controlled reload
    • only for an already-loaded WiFi leaf driver module

sleep 2

if modprobe "$mod" >/dev/null 2>&1; then
log_info "Reloaded WiFi module: $mod" >&2

wifi_unblock_rfkill

if command -v udevadm >/dev/null 2>&1; then
udevadm trigger --action=add --subsystem-match=net >/dev/null 2>&1 || true
udevadm settle --timeout=5 >/dev/null 2>&1 || true
fi

iface="$(get_wifi_interface 2>/dev/null || true)"
if [ -n "$iface" ]; then
printf '%s\n' "$iface"
return 0
fi
else
log_warn "Reload failed for WiFi module $mod after unload" >&2
fi
else
log_warn "Could not unload WiFi module $mod; it may be busy" >&2
fi

# Attempt only one loaded leaf driver module.
break
done
fi

sleep "$sleep_step"
waited=$((waited + sleep_step))

if [ "$waited" -gt 0 ] && [ $((waited % 10)) -eq 0 ]; then
log_info "Still waiting for WiFi interface... waited=${waited}s/${max_wait}s" >&2
fi
done

return 1
}

Expand Down Expand Up @@ -115,19 +190,25 @@ wifi_log_module_info() {
done
}

# Return success when there is evidence that a WiFi software stack is present,
# even if no netdev has been created yet. Used to separate FAIL from SKIP.
# Return success when there is runtime evidence that WiFi registered a real
# device/phy/netdev.
#
# This intentionally does not treat generic module-only state as success.
# Modules such as cfg80211, mac80211, and mhi may be loaded even when no WiFi
# hardware has registered a phy or netdev.
#
# Used by tests to decide whether missing interface is a real runtime failure
# or a platform/no-device skip.
wifi_stack_present() {
mod=""
iface=""

for mod in ath12k_wifi7 ath12k ath11k ath11k_pci ath10k_pci ath10k_snoc cfg80211 mac80211 mhi; do
if is_module_loaded "$mod"; then
return 0
fi
done
iface="$(get_wifi_interface 2>/dev/null || true)"
if [ -n "$iface" ]; then
return 0
fi

if [ -d /sys/class/ieee80211 ]; then
if ls /sys/class/ieee80211/* >/dev/null 2>&1; then
if find /sys/class/ieee80211 -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null | grep . >/dev/null 2>&1; then
return 0
fi
fi
Expand All @@ -136,8 +217,20 @@ wifi_stack_present() {
if iw phy 2>/dev/null | grep . >/dev/null 2>&1; then
return 0
fi

if iw dev 2>/dev/null | grep -E '^[[:space:]]*Interface[[:space:]]+' >/dev/null 2>&1; then
return 0
fi
fi

for n in /sys/class/net/*; do
[ -e "$n" ] || continue

if [ -d "$n/wireless" ] || [ -e "$n/phy80211" ]; then
return 0
fi
done

return 1
}

Expand Down
Loading