11#! /bin/sh
2-
3- # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4- # SPDX-License-Identifier: BSD-3-Clause-Clear
5-
2+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3+ # SPDX-License-Identifier: BSD-3-Clause-Clear
4+
65# Robustly find and source init_env
76SCRIPT_DIR=" $( cd " $( dirname " $0 " ) " && pwd) "
87INIT_ENV=" "
@@ -20,97 +19,213 @@ if [ -z "$INIT_ENV" ]; then
2019 exit 1
2120fi
2221
23- if [ -z " $__INIT_ENV_LOADED " ]; then
22+ if [ -z " ${ __INIT_ENV_LOADED:- } " ]; then
2423 # shellcheck disable=SC1090
2524 . " $INIT_ENV "
25+ __INIT_ENV_LOADED=1
2626fi
27+
2728# shellcheck disable=SC1090,SC1091
2829. " $TOOLS /functestlib.sh"
2930
3031TESTNAME=" Ethernet"
3132test_path=$( find_test_case_by_name " $TESTNAME " )
3233cd " $test_path " || exit 1
34+
3335res_file=" ./$TESTNAME .res"
3436summary_file=" ./$TESTNAME .summary"
3537rm -f " $res_file " " $summary_file "
36-
38+ : > " $summary_file "
39+
3740log_info " --------------------------------------------------------------------------"
3841log_info " -------------------Starting $TESTNAME Testcase----------------------------"
3942
43+ # Config knobs (safe defaults)
44+ LINK_TIMEOUT_S=" ${LINK_TIMEOUT_S:- 5} "
45+ IP_TIMEOUT_S=" ${IP_TIMEOUT_S:- 10} "
46+ PING_TARGET=" ${PING_TARGET:- 8.8.8.8} "
47+ PING_COUNT=" ${PING_COUNT:- 4} "
48+ PING_WAIT_S=" ${PING_WAIT_S:- 2} "
49+ PING_RETRIES=" ${PING_RETRIES:- 3} "
50+
51+ log_info " Config: LINK_TIMEOUT_S=${LINK_TIMEOUT_S} IP_TIMEOUT_S=${IP_TIMEOUT_S} PING_TARGET=${PING_TARGET} PING_RETRIES=${PING_RETRIES} PING_COUNT=${PING_COUNT} PING_WAIT_S=${PING_WAIT_S} "
52+
53+ # Gate on kernel config BEFORE dependency checks (as requested)
54+ if ! check_kernel_config " CONFIG_QCA808X_PHY" ; then
55+ log_warn " $TESTNAME : CONFIG_QCA808X_PHY not enabled; skipping Ethernet test"
56+ echo " $TESTNAME SKIP" > " $res_file "
57+ exit 0
58+ fi
59+
4060# Check for dependencies
4161check_dependencies ip ping
4262
43- # User-specified interface (argument) or all detected
44- user_iface=" $1 "
45- if [ -n " $user_iface " ]; then
46- ETH_IFACES=" $user_iface "
47- log_info " User specified interface: $user_iface "
48- else
49- ETH_IFACES=" $( get_ethernet_interfaces) "
50- log_info " Auto-detected Ethernet interfaces: $ETH_IFACES "
63+ # ethtool is required for robust fallback on 100M-locked ports
64+ if ! command -v ethtool > /dev/null 2>&1 ; then
65+ log_warn " ethtool not found; cannot apply robust link-speed fallback; skipping"
66+ echo " $TESTNAME SKIP" > " $res_file "
67+ exit 0
5168fi
5269
70+ ETH_IFACES=" $( get_ethernet_interfaces) "
71+ log_info " Auto-detected Ethernet interfaces: $ETH_IFACES "
72+
5373if [ -z " $ETH_IFACES " ]; then
5474 log_warn " No Ethernet interfaces detected."
55- echo " No Ethernet interfaces detected." >> " $summary_file "
56- echo " $TESTNAME SKIP" > " $res_file "
75+ echo " No Ethernet interfaces detected." >> " $summary_file "
76+ echo " $TESTNAME SKIP" > " $res_file "
5777 exit 0
5878fi
5979
80+ # Detect if a network manager is active once (avoid fighting it per interface)
81+ nm_active=0
82+ if command -v systemctl > /dev/null 2>&1 ; then
83+ if systemctl is-active --quiet NetworkManager 2> /dev/null \
84+ || systemctl is-active --quiet systemd-networkd 2> /dev/null; then
85+ nm_active=1
86+ fi
87+ fi
88+
89+ if [ " $nm_active " -eq 1 ]; then
90+ log_info " Network manager detected (NetworkManager/systemd-networkd active): will wait for IP, will NOT run udhcpc."
91+ else
92+ log_info " No network manager detected: will use try_dhcp_client_safe if IP is missing."
93+ fi
94+
6095any_passed=0
6196any_tested=0
97+ any_skipped=0
6298
6399for iface in $ETH_IFACES ; do
64100 log_info " ---- Testing interface: $iface ----"
65101
66- if ! is_interface_up " $iface " ; then
67- log_warn " $iface is DOWN, skipping"
68- echo " $iface : SKIP (down/no cable)" >> " $summary_file "
102+ # FAST PATH (no ethtool dependency here):
103+ # If link is already up AND a valid (non-link-local) IPv4 exists, skip bring-up/DHCP.
104+ ip_addr=" $( get_ip_address " $iface " 2> /dev/null || true) "
105+ if is_valid_ipv4 " $ip_addr " && iface_link_up " $iface " ; then
106+ log_info " $iface fast-path: link is up and valid IP already present ($ip_addr ). Skipping link bring-up/IP acquisition."
107+
108+ log_pass " $iface is UP"
109+ log_info " $iface got IP: $ip_addr "
110+ any_tested=1
111+
112+ if run_ping_check " $iface " ; then
113+ log_pass " Ethernet connectivity verified via ping"
114+ echo " $iface : PASS (IP: $ip_addr , ping OK)" >> " $summary_file "
115+ any_passed=1
116+ else
117+ log_fail " Ping test failed for $iface "
118+ echo " $iface : FAIL (IP: $ip_addr , ping failed)" >> " $summary_file "
119+ fi
120+
69121 continue
70122 fi
71123
72- ip_addr=$( get_ip_address " $iface " )
73- if [ -z " $ip_addr " ]; then
74- if try_dhcp_client_safe " $iface " 10; then
75- ip_addr=$( get_ip_address " $iface " )
76- log_info " $iface obtained IP after DHCP: $ip_addr "
77- fi
124+ # Debug snapshot (compact)
125+ carrier=" ?"
126+ if [ -r " /sys/class/net/$iface /carrier" ]; then
127+ carrier=$( cat " /sys/class/net/$iface /carrier" 2> /dev/null || echo " ?" )
78128 fi
129+ log_info " $iface : initial carrier=$carrier "
130+ ip link show " $iface " 2> /dev/null | while IFS= read -r l; do [ -n " $l " ] && log_info " [ip-link] $l " ; done
131+ ethtool " $iface " 2> /dev/null | awk -F' : ' ' /^[[:space:]]*(Speed:|Duplex:|Auto-negotiation:|Link detected:)/ {print}' \
132+ | while IFS= read -r l; do [ -n " $l " ] && log_info " [ethtool] $l " ; done
133+
134+ log_info " Bringing link up with fallback for $iface (timeout=${LINK_TIMEOUT_S} s)..."
135+ if ethEnsureLinkUpWithFallback " $iface " " $LINK_TIMEOUT_S " ; then
136+ sp=" -"
137+ if sp=$( ethGetLinkSpeedMbps " $iface " 2> /dev/null) ; then
138+ log_info " $iface link is UP (speed=${sp} Mb/s)"
139+ else
140+ log_info " $iface link is UP (speed=unknown)"
141+ fi
142+ ethtool " $iface " 2> /dev/null | awk -F' : ' ' /^[[:space:]]*(Speed:|Duplex:|Auto-negotiation:|Link detected:)/ {print}' \
143+ | while IFS= read -r l; do [ -n " $l " ] && log_info " [ethtool] $l " ; done
144+ else
145+ # Decide SKIP/FAIL post-failure
146+ carrier=" ?"
147+ if [ -r " /sys/class/net/$iface /carrier" ]; then
148+ carrier=$( cat " /sys/class/net/$iface /carrier" 2> /dev/null || echo " ?" )
149+ fi
79150
80- if [ -z " $ip_addr " ]; then
81- log_warn " $iface did not obtain an IP address after DHCP attempt, skipping"
82- echo " $iface : SKIP (no IP, DHCP failed)" >> " $summary_file "
151+ log_info " Link bring-up failed for $iface . Diagnostics:"
152+ ip link show " $iface " 2> /dev/null | while IFS= read -r l; do [ -n " $l " ] && log_info " [ip-link] $l " ; done
153+ ethtool " $iface " 2> /dev/null | sed -n ' 1,80p' | while IFS= read -r l; do [ -n " $l " ] && log_info " [ethtool] $l " ; done
154+
155+ if [ " $carrier " = " 0" ]; then
156+ log_warn " $iface : no link detected (carrier=0); treating as no-cable and skipping"
157+ echo " $iface : SKIP (no cable/link; carrier=0)" >> " $summary_file "
158+ any_skipped=1
159+ elif [ " $carrier " = " 1" ]; then
160+ log_fail " $iface : carrier=1 but link did not come up after fallback; failing"
161+ echo " $iface : FAIL (link bring-up failed; carrier=1)" >> " $summary_file "
162+ any_tested=1
163+ else
164+ link_detected=" unknown"
165+ link_detected=$( ethtool " $iface " 2> /dev/null | awk -F' : ' ' /^[[:space:]]*Link detected:/ {print $2; exit 0}' || true)
166+ [ -n " $link_detected " ] || link_detected=" unknown"
167+
168+ if [ " $link_detected " = " no" ]; then
169+ log_warn " $iface : Link detected: no; treating as no-cable and skipping"
170+ echo " $iface : SKIP (no cable/link; ethtool Link detected: no)" >> " $summary_file "
171+ any_skipped=1
172+ else
173+ log_fail " $iface : link did not come up after fallback (carrier unknown, Link detected=${link_detected} ); failing"
174+ echo " $iface : FAIL (link bring-up failed; carrier unknown, Link detected=${link_detected} )" >> " $summary_file "
175+ any_tested=1
176+ fi
177+ fi
83178 continue
84179 fi
85180
86- if echo " $ip_addr " | grep -q ' ^169\.254' ; then
87- log_warn " $iface got only link-local IP ($ip_addr ), skipping"
88- echo " $iface : SKIP (link-local only: $ip_addr )" >> " $summary_file "
181+ # IP acquisition only if needed
182+ ip_addr=" $( get_ip_address " $iface " 2> /dev/null || true) "
183+ if [ -n " $ip_addr " ]; then
184+ log_info " $iface pre-existing IP: $ip_addr "
185+ else
186+ log_info " $iface has no IPv4 address yet."
187+ fi
188+
189+ if ! is_valid_ipv4 " $ip_addr " ; then
190+ if [ " $nm_active " -eq 1 ]; then
191+ log_info " Waiting up to ${IP_TIMEOUT_S} s for IP on $iface (managed by network manager)..."
192+ ip_addr=" $( wait_for_ip_address " $iface " " $IP_TIMEOUT_S " 2> /dev/null || true) "
193+ else
194+ log_info " Attempting safe DHCP on $iface (timeout=${IP_TIMEOUT_S} s)..."
195+ if try_dhcp_client_safe " $iface " " $IP_TIMEOUT_S " ; then
196+ ip_addr=" $( get_ip_address " $iface " 2> /dev/null || true) "
197+ fi
198+ fi
199+ fi
200+
201+ ip -4 addr show " $iface " 2> /dev/null | while IFS= read -r l; do [ -n " $l " ] && log_info " [ip-addr] $l " ; done
202+ ip route show dev " $iface " 2> /dev/null | sed -n ' 1,40p' | while IFS= read -r l; do [ -n " $l " ] && log_info " [ip-route:$iface ] $l " ; done
203+
204+ if ! is_valid_ipv4 " $ip_addr " ; then
205+ if [ -z " $ip_addr " ]; then
206+ log_warn " $iface did not obtain an IP address, skipping"
207+ echo " $iface : SKIP (no IP)" >> " $summary_file "
208+ any_skipped=1
209+ else
210+ log_warn " $iface got only link-local IP ($ip_addr ), skipping"
211+ echo " $iface : SKIP (link-local only: $ip_addr )" >> " $summary_file "
212+ any_skipped=1
213+ fi
89214 continue
90215 fi
91216
92217 log_pass " $iface is UP"
93218 log_info " $iface got IP: $ip_addr "
94219
95220 any_tested=1
96- retries=3
97- pass=0
98- for i in $( seq 1 $retries ) ; do
99- if ping -I " $iface " -c 4 -W 2 8.8.8.8 > /dev/null 2>&1 ; then
100- log_pass " Ethernet connectivity verified via ping"
101- echo " $iface : PASS (IP: $ip_addr , ping OK)" >> " $summary_file "
102- pass=1
103- any_passed=1
104- break
105- else
106- log_warn " Ping failed for $iface (attempt $i /$retries )"
107- sleep 2
108- fi
109- done
110221
111- if [ " $pass " -eq 0 ]; then
222+ if run_ping_check " $iface " ; then
223+ log_pass " Ethernet connectivity verified via ping"
224+ echo " $iface : PASS (IP: $ip_addr , ping OK)" >> " $summary_file "
225+ any_passed=1
226+ else
112227 log_fail " Ping test failed for $iface "
113- echo " $iface : FAIL (IP: $ip_addr , ping failed)" >> " $summary_file "
228+ echo " $iface : FAIL (IP: $ip_addr , ping failed)" >> " $summary_file "
114229 fi
115230done
116231
@@ -121,15 +236,20 @@ else
121236 log_info " No summary information recorded."
122237fi
123238
239+ # Option B: use any_skipped so ShellCheck doesn't warn, and keep it visible in logs.
240+ log_info " Counters: any_tested=$any_tested any_passed=$any_passed any_skipped=$any_skipped "
241+
124242if [ " $any_passed " -gt 0 ]; then
125- echo " $TESTNAME PASS" > " $res_file "
243+ echo " $TESTNAME PASS" > " $res_file "
126244 exit 0
127- elif [ " $any_tested " -gt 0 ]; then
128- echo " $TESTNAME FAIL" > " $res_file "
129- exit 1
130- else
131- log_warn " No interfaces were tested (all were skipped)."
132- echo " No suitable Ethernet interfaces found. All were down, link-local, or failed to get IP." >> " $summary_file "
133- echo " $TESTNAME SKIP" > " $res_file "
245+ fi
246+
247+ if [ " $any_tested " -gt 0 ]; then
248+ echo " $TESTNAME FAIL" > " $res_file "
134249 exit 0
135250fi
251+
252+ log_warn " No interfaces were tested (all were skipped)."
253+ echo " No suitable Ethernet interfaces found. All were no-link, link-local, or no-IP." >> " $summary_file "
254+ echo " $TESTNAME SKIP" > " $res_file "
255+ exit 0
0 commit comments