25 KiB
RTL8812EU enumerating at 12 Mbit/s on Sstar-ehci-1 — investigation record
Device: ssc338q_fpv_openipc-urllc-aio (HiLink URLLC, SSC338Q / infinity6e).
Radio: Realtek RTL8812EU, USB ID 0bda:a81a, directly attached to the SSC338Q
USB 2.0 EHCI port (Sstar-ehci-1).
Fixed observations (treated as inputs, not re-derived here)
- The radio repeatedly enumerates at 12 Mbit/s (full speed) after USB unbind/rebind cycles.
- The active device tree reports
dpdm_swap = <0>andpower-enable-pad = <PAD_UNKNOWN>(0xffff). - Verified on hardware (2026-10, Piotr): the full
soc:Sstar-ehci-1platform-driver unbind/bind cycle (step 5 below) was performed over Ethernet, waited out, and/sys/bus/usb/devices/1-1/speedstill returned12. A complete HCD/UTMI re-initialization therefore does not restore high-speed negotiation on this board. - Verified on hardware (2026-10, Piotr): changing the input supply capacity did not improve negotiation. Supply-headroom tuning is ruled out.
- Verified on hardware (2026-10, Piotr): the radio is a custom carrier/module assembly, not a drop-in USB dongle: a four-wire host harness/pad connection, two RF pigtails, and visible local regulation on the carrier.
- Verified on hardware (2026-10, Piotr): 5.13 V measured directly at the module input, inside the common 4.75–5.25 V input range. The earlier "3.3 V fed into the 5 V input" hypothesis is therefore ruled out at module ingress (upstream of the carrier's local regulation).
- Verified on hardware (2026-10, Piotr): each USB data net was physically
traced as
SSC338Q-side -> approximately 100 ohm series resistor -> RTL8812EU-module D+ or D-; each component measured about 100 ohm across its own endpoints with all power removed. These are two separate per-line series resistors, not one 100-ohm differential termination. - RF/FEC configuration is not a USB fix and is out of scope for this issue.
- This document contains no credentials, pairing or RF-access material.
Conclusion (current fault-domain classification)
Combined with the exact vendor EHCI/UTMI source audit below (which found no HiLink-specific software discrepancy in anything this overlay or the shipped kernel build controls), the verified on-hardware results above eliminate the remaining software-adjacent candidates that are cheap to test:
- Ruled out: wifibroadcast/OpenIPC configuration, RF/FEC settings, ordinary userspace timing, a simple USB-device rebind, a full HCD/UTMI re-initialization (done on hardware, no change), input-supply-capacity tuning (done on hardware, no change), and wrong-voltage-at-module-ingress (measured 5.13 V at the input, within the 4.75–5.25 V range).
- Remaining fault domain: the USB high-speed physical path / signal integrity / rework — D+/D− routing and symmetry across the carrier, harness/pads and intervening components, controlled impedance and stubs, series/ESD/common-mode components on the pair, connector and solder integrity, or PHY-side / device-side silicon-level hardware — exactly the boundary detailed in the hardware section below. The supply findings above rule out only those two specific points: power quality downstream of the measured input — supply noise/ripple and the carrier's local regulator output — remains untested and stays inside this open fault domain.
Two caveats stay attached to this classification: it does not prove that every conceivable undocumented analog register in the vendor PHY block is irrelevant (the audited paths cover what the shipped source programs, not the full register space), and it does not claim any high-speed success — the fault is unresolved; only its domain is now sharply bounded.
First concrete physical candidate: the traced per-line ~100 ohm series resistors (see the hardware section below). FS signaling at 12 Mbit/s is edge-slow and tolerant, while HS chirp/negotiation is amplitude- and timing-critical, so excessive series damping on both lines is consistent with exactly this failure signature — FS survives, HS chirp is missed. This is a hypothesis with a matching signature, not a proven root cause, and the commonly seen external USB 2.0 series damping practice (roughly 15-33 ohm) is not a substitute for the exact SSC338Q PHY/reference-design requirement, which is not documented in this repository.
Operating posture while the fault stands: keep the existing 4096 kbit/s limit appropriate to full-speed operation; do not raise it on the assumption of high-speed throughput until HS is actually demonstrated.
Audited sources
Audited 2026-10-02. Everything the firmware ships is stock upstream of this builder overlay — the per-device delta in this repository carries no USB configuration at all. Exact provenance used for the audit:
| Artifact | Source | Ref |
|---|---|---|
| Kernel | github.com/openipc/linux, branch sigmastar-infinity6e |
branch tip 97b7fc4e at audit time, Linux 4.9.84 (the defconfig pins the branch, not the SHA, so later builds may move) |
| Kernel ref resolution | OpenIPC/firmware general/external.mk |
OPENIPC_KERNEL := $(OPENIPC_SOC_VENDOR)-$(OPENIPC_SOC_FAMILY) |
| Kernel config | OpenIPC/firmware br-ext-chip-sigmastar/board/infinity6e/infinity6e-ssc012b.config |
selected by this device's defconfig (BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE); moving master, HEAD 1b0d5e2 at audit time |
| DTB | arch/arm/boot/dts/infinity6e-ssc012b-s01a.dtb, built from the in-tree DTS and compiled into the kernel Image (CONFIG_SS_BUILTIN_DTB=y, CONFIG_SS_DTB_NAME="infinity6e-ssc012b-s01a") |
same kernel ref |
| WiFi driver | OpenIPC package rtl88x2eu-openipc → github.com/libc0607/rtl88x2eu-20230815 (HEAD) + one cflags patch |
general/package/rtl88x2eu-openipc/rtl88x2eu-openipc.mk |
| Builder overlay | this repository, devices/ssc338q_fpv_openipc-urllc-aio/ |
working tree |
The bootloader does not hand the kernel an FDT on this platform: with
CONFIG_SS_BUILTIN_DTB=y, arch/arm/kernel/devtree.c:281-299 falls back to
the DTB embedded in the Image and merges the bootloader's ATAGs (memory,
cmdline) into it. The audited DTS is what the running kernel sees.
Active DT node (matches the reported runtime state)
arch/arm/boot/dts/infinity6e.dtsi:818-828:
Sstar-ehci-1 {
compatible = "Sstar-ehci-1";
clocks = <&CLK_utmi>;
camclk = <CAMCLK_utmi>; /* compiled out: CONFIG_CAM_CLK is not set */
interrupts = <GIC_SPI INT_IRQ_UHC IRQ_TYPE_LEVEL_HIGH>;
dpdm_swap=<0>;
power-enable-pad = <PAD_UNKNOWN>;
status = "ok";
};
PAD_UNKNOWN = 0xFFFF (drivers/sstar/include/infinity6e/gpio.h:150).
The board DTS infinity6e-ssc012b-s01a.dts applies no USB override, and
CONFIG_SS_BUILTIN_UNFDT is not set, so the kernel Image's builtin DTB is the
only device tree in play (see the boot path above). This matches the runtime
facts exactly.
Kernel config (USB-relevant, infinity6e-ssc012b.config)
CONFIG_USB_EHCI_HCD=ybuilt-in; xHCI/OHCI/DWC2/DWC3 disabled; USB 3.0 node unused for this radio.CONFIG_MP_USB_MSTAR=y— enables the Sstar patch set indrivers/usb/host/ehci-hcd.canddrivers/usb/core/hub.c.# CONFIG_SS_USB_LOWPWR_SUSPEND is not set; no USB PHY framework drivers (all UTMI handling is inside the Sstar EHCI driver).CONFIG_USB_ANNOUNCE_NEW_DEVICES=y— dmesg reports the enumerated speed.
HS chirp / squelch / reset / PHY-tuning paths (as built)
All tuning is compile-time; there are no runtime knobs in this repo.
- Probe-time UTMI init —
drivers/sstar/usb/host/ehci-mstar.c,Titania3_series_start_ehc()(lines 232-579), called fromehci_hcd_mstar_drv_probe()forsoc:Sstar-ehci-1(call at line 681):- USBC
0x0a/0x28handshake resets the UHC MAC (lines 297-298). - CA (RX calibration) start/poll at UTMI
0x3cwith a "CA Fail" warning if the result reads all-ones or all-zeros (lines 330-339). - Squelch/disconnect level:
UTMI_DISCON_LEVEL_2A = 0x62(ehci-mstar.h:310) written to UTMI0x2a(lines 323-328, 396-397). - Chirp source select UTMI
0x15bit5 (line 387); new-HW chirp overwrite cleared at UTMI0x40bit4 (line 394).ENABLE_NEW_HW_CHRIP_PATCHis not defined, so the chirp-detect-level register UTMI0x42keeps its hardware default. - Eye/ TX tuning:
UTMI_EYE_SETTING_2C..2F = 0x10,0x02,0x00,0x81(ehci-mstar.h:355-361) at UTMI0x2c..0x2f(lines 406-410). ENABLE_HS_CONNECTION_FAIL_INTO_VFALL_ECOis on (ehci-mstar.h:152), USBC0x11bit1 (line 453) — the known "HS connection fails into VFALL" mitigation is active.- DP/DM swap:
_USB_UTMI_DPDM_SWAP_P0 = 0(ehci-mstar.h:294) anddpdm_swap=<0>in DT (probe lines 674-678 OR the DT value intoflag) both agree: no swap. UTMI0x0bbit5 stays clear. _USB_ANALOG_RX_SQUELCH_PATCH = 0(ehci-mstar.h:254-258): the CA-calibration-based squelch adjustment is compiled out.
- USBC
- Per-port-reset chirp window —
drivers/usb/core/hub.chub_port_reset()(lines 3124-3216), the_USB_HS_CHIRP_PATCHblock, runs on every root-hub port reset for USB 2.0:- Before asserting reset: eye parameters zeroed (UTMI
0x2c..0x2f) and squelch switched to0x80at UTMI0x2a(line 3168) — the value the Sstar chirp patch uses inside the reset window to catch a weak device chirp. - After the reset: eye parameters and squelch
0x62restored, then a UTMI TX/RX software-reset pulse (UTMI0x06bits1:0, lines 3207-3212). - The FS/HS verdict comes from the EHCI port status alone. The
speed-report cross-check against the UHC
0x84/0x85registers is guarded by_USB_SPEED_REPORT_RESET_PATCH, which is referenced athub.c:3007but never defined anywhere — that block is compiled out in this build.
- Before asserting reset: eye parameters zeroed (UTMI
- Full-speed fallback latch —
hub.c"bad dev" retry (lines 6113-6165): after repeated failed enumerations the driver sets UHC0x40bit7 ("force full speed", line 6138, viahcd->ehc_base); it is cleared on root-hub reinit when the device disconnects (lines 2353, 5557-5559). A device that enumerates successfully at FS from insertion did not need this latch — the port verdict itself was FS. - VBUS gating —
drivers/sstar/usb/host/infinity6e/usb_pad.cEnable_USB_VBUS()(lines 49-106): the DT property is present (0xffff), so the fallback default (PAD_PM_GPIO2) is not used; the value is truncated to(unsigned char)0xffff = 255(line 80). 255 is out of range on this SoC —GPIO_NR = 127(drivers/sstar/include/infinity6e/gpio.h:149, range-checked inmhal_pinmux.c:2054) — sogpio_request(255)fails and the function returns early. The probe ignores the return value (ehci-mstar.c:680). Net effect: no kernel-side VBUS gate; VBUS to the module is board-hardwired. Consistent with the device enumerating at all. - Clocks — nothing in Linux consumes
CLK_utmi/CAMCLK_utmifor this controller: the EHCI driver contains no clock/camclk code at all, so the UTMI reference clock state is inherited from the bootloader. There is no in-Linux analog power-cycle; the closest in-kernel equivalent is a full HCD unbind/rebind (below), which re-runs the wholeTitania3_series_start_ehc()block including CA calibration. - WiFi driver —
rtl88x2eu-20230815os_dep/linux/usb_intf.c(lines 637-661) passively recordspusbd->speed(USB_SPEED_FULL→RTW_USB_SPEED_1_1). There is no module parameter, retry or force-HS logic in the Realtek driver; at most it adapts to the reported speed (e.g.USB_FULL_SPEED_BULK_SIZEininclude/usb_ops.h:128-145). The speed is decided entirely by the host controller/PHY.
Why no device-specific software discrepancy was found (in this repository)
- This repository's per-device delta for
ssc338q_fpv_openipc-urllc-aiocontains no USB-host configuration anywhere: the defconfig selects packages/flash size only,load_sigmastardrives the camera pipeline only, the overlay seeds WiFi/wifibroadcast config, and the exclude list only trims rootfs files. - The defconfig is byte-identical to the closest sibling device
(
ssc338q_fpv_openipc-mario-aio), so there is no per-device divergence to correct. - Kernel, builtin DTB and kernel config are stock
openipc/linuxsigmastar-infinity6e/OpenIPC/firmwareartifacts; the DT state (dpdm_swap=0,power-enable-pad=0xffff) matches the reported runtime state, i.e. the firmware built is the firmware audited. - The FS fallback mitigations that exist in the kernel (chirp-window squelch
0x80, VFALL ECO) are compiled in and active for this build; the speed-report cross-check is compiled out (undefined macro), which weakens detection of a mis-reported speed but cannot by itself cause one. - Therefore a device-specific software correction within this repository is not justified by the evidence. A real fix would be a kernel-side change (openipc/linux driver/DT) or hardware — both outside this overlay's scope.
Candidate corrections considered and rejected
dpdm_swap=<1>: a swapped D+/D- pair would break full-speed enumeration too (same pair, same polarity); the device enumerates at FS, so polarity is correct. Flipping it would kill enumeration entirely. Rejected.- Enable
_USB_ANALOG_RX_SQUELCH_PATCHor changeUTMI_DISCON_LEVEL_2A/ eye settings: driver-source macro changes inopenipc/linux, with no in-repo evidence to pick values; the chirp window already uses the most sensitive squelch (0x80). Rejected without on-hardware UTMI measurements. power-enable-pad→ a real pad: VBUS is evidently board-hardwired (device enumerates with the property atPAD_UNKNOWN); pointing the gate at a wrong pad risks switching VBUS off. Rejected.- WiFi driver module options: none exist that influence enumeration speed (driver is passive). Rejected.
HiLink D+/D- hardware / rework investigation boundary
Assembly as observed (2026-10, Piotr): the radio is a custom carrier/module — not a drop-in dongle — connected to the host by a four-wire harness/pad connection, with two RF pigtails and visible local regulation on the carrier. The pad assignments have not been documented yet; nothing below assumes one.
With the software and software-adjacent candidates ruled out (see the conclusion above), the remaining fault domain is the USB high-speed physical path / signal integrity / rework, explicitly outside software scope:
- D+/D- pair routing on the HiLink carrier and through the four-wire harness: continuity and symmetry from the SSC338Q pads to the module pads; controlled impedance along the pair; stubs or test points hanging off it; series resistors / ESD protection / common-mode chokes or other intervening components; via, connector/harness and solder joint integrity.
- HS chirp failure with FS working is the classic marginal-analog signature: the same pair carries FS traffic fine while the HS chirp (a short, amplitude-critical burst at reset) is missed by the host squelch detector.
Next physical gate (before any rework):
- Macro photographs of both sides of the carrier/module — not yet reported.
- Identify all four host pads — determine which are VBUS, GND, D+, D- (the four-wire harness implies the classic set, but the actual assignment must come from tracing, not assumption) — not yet reported in full; the two data nets and their series resistors have been traced (see the fixed observations above).
- Trace D+/D- end to end, identifying every intervening component —
series resistors, ESD arrays, common-mode chokes, vias, connectors,
harness wires — and where the pair leaves the board. Status: performed
for both data nets — each net is
SSC338Q-side -> ~100 ohm series resistor -> module D+/D-, each resistor measuring ~100 ohm across its own endpoints, de-energized. No other intervening component was reported on the data nets.
Safety rule for all continuity/ohmmeter work: only with all power removed and rails discharged (unplug, then verify the rails are at 0 V before touching meter probes to pads). No powered measurements are proposed at this stage.
Gated, reversible experiment: reduce per-line series damping
Rationale: if the ~100 ohm per-line series resistors over-damp the pair, reducing the effective per-line series resistance by roughly four times (100 ohm -> ~25 ohm) into the range of common external USB 2.0 practice may let the HS chirp/eye reach the host squelch/timing margins again. This is a bounded, fully reversible test, not a repair commitment: the target value below is an example chosen from common practice, not the documented SSC338Q PHY/reference-design requirement, which must be confirmed from vendor material if the test succeeds.
Pre-flight gate (no soldering before this is done):
- Confirm the two resistors' package size and mark their exact locations (photograph before touching anything).
- Confirm the workmanship/ESD plan for soldering on the carrier.
Experiment (reversible — nothing is removed, parts are added in parallel):
- With all power removed and rails discharged and verified at 0 V (same rule as above). The work setup itself must not be able to feed voltage onto the unpowered board — including through the soldering iron's supply path — so use an isolated or battery-powered iron or equivalent isolation. Solder one matched resistor in parallel across each existing 100 ohm part — D+ and D- must be treated identically.
- Example value: 33 ohm in parallel with 100 ohm gives an effective (33 x 100) / (33 + 100) = 3300 / 133 = 24.8 ohm per line (~25 ohm). Any parallel pair follows R_eff = (R1 x R2) / (R1 + R2); keep the same value on both lines.
- Inspect under magnification for bridges, solder balls or damage to the parts and neighbours; the two lines must look identical.
- Before restoring power, measure each modified net again (de-energized) and confirm both read the same effective value, within part tolerance.
- Restore power only after inspection and run a fresh USB enumeration
check (
cat /sys/bus/usb/devices/1-1/speed).
Acceptance criterion: actual 480 Mbit/s negotiation. The enumeration result is the only judge of this test: no final line impedance or eye-quality outcome is assumed without signal-integrity measurement (a later diagnostic above). If behaviour regresses in any way or HS is not achieved, revert immediately: remove the parallel parts to restore the original ~100 ohm per line, and record what was observed. Until HS is actually demonstrated, keep the 4096 kbit/s operating limit (see the conclusion) regardless of this experiment.
Further isolation diagnostics, only after the gate above (all of them need rework access — the radio is pad-connected, not socketed, so this may mean a temporary rework socket or piggyback harness):
- Try a known-good HS USB device (any USB 2.0 flash disk) on the same host pads. HS on the disk but not on the radio points at the carrier/module side; FS on both points at the board-side pair.
- Try the RTL8812EU carrier on a different known-good HS host (a PC). HS there isolates the fault to this board's physical path.
- With suitable equipment, capture the HS chirp amplitude/eye at the host pads against the USB 2.0 electrical limits.
Any board rework (series resistor changes, pair shortening, shielding) invalidates prior software observations; re-verify from the on-device commands below after any hardware change.
Evidence status: the platform-driver re-probe (step 5 below), the input-supply-capacity change, the module-input voltage measurement, and the per-line series-resistor tracing (de-energized resistance checks) were performed on hardware (2026-10, Piotr) — none of the software-adjacent steps improved negotiation, the ingress voltage is in range, and the traced topology is as recorded above. The parallel-resistor experiment has not been performed yet; the register-read diagnostics (steps 1-4 below) have not been reported yet. No HS negotiation has been observed at any point, and this document does not claim any.
On-device verification (read-only diagnostics; step 5 re-probe already completed on hardware)
Run from a root shell on the device over a link that is not the USB radio
(Ethernet or serial console — see the wlan0 warning in step 5). All register
reads are read-only devmem accesses; do not write UTMI/USBC/UHC
registers from userspace (a write can wedge the bus until reboot).
Steps 1-4 have not been run/reported on the affected board yet and remain
the cheapest way to capture register-level evidence (CA calibration result,
squelch value, line state, force-FS latch) alongside the hardware work.
Register addresses (physical; the RIU window maps virtual 0xFD200000 to
physical 0x1F200000 — MS_IO_OFFSET 0xDE000000,
drivers/sstar/include/ms_platform.h:24, plus registers.h:37-38). Register
number n sits at byte offset 2*n, except odd n which sits at 2*n - 1
(exactly what hcd_readb does, hub.c:116-129). All reads are byte or
16-bit reads at these byte addresses.
| Block | Base (physical) | Derived from |
|---|---|---|
| UTMI0 | 0x1F284200 |
_MSTAR_UTMI0_BASE = 0xFD200000 + 0x42100*2 (ehci-mstar-chip.h:37) |
| USBC0 | 0x1F284600 |
+ 0x42300*2 (ehci-mstar-chip.h:39) |
| UHC0 (EHCI) | 0x1F284800 |
+ 0x42400*2 (ehci-mstar-chip.h:40) |
- Current enumerated speed
cat /sys/bus/usb/devices/*/speed # expect 12 (FS symptom) or 480 (HS fixed) dmesg | grep -E 'new (full|high)-speed USB device' - Force-full-speed latch check (stuck FS from a past failed HS enum)
Expected if healthy: bit7 clear. If bit7 is set, a previous enumeration failure latched FS; disconnect/reconnect the module's power (the root-hub reinit on disconnect clears it) and repeat.
devmem 0x1F284880 8 # UHC+0x40 bit7: 0x00/0x80 - Port / line state (all UHC0 = EHCI bank,
hcd->ehc_base; bit semantics as used by the driver:hub.c:4998enable=bit2,urb.c:532connect=bit0,message.c:88csc=bit1,hub.c:5801-5802line state)Speed-report composition (devmem 0x1F284860 8 # UHC+0x30: bit0 connect, bit1 csc, bit2 enable devmem 0x1F284881 8 # UHC+0x41: bits2:1 line state (odd reg -> 2n-1) devmem 0x1F284908 8 # UHC+0x84: bit7 of the speed report devmem 0x1F28490A 8 # UHC+0x85: bits3:0 of the speed reporthub.c:3007-3030; the kernel-side cross-check is compiled out — these are raw hardware registers):spd = (bit7 of UHC+0x84) | ((UHC+0x85 & 0xf) << 1);0x0c= high speed,0x06= full speed. - UTMI tuning as left by the driver
devmem 0x1F284254 8 # UTMI+0x2a squelch: expect 0x62 idle devmem 0x1F284278 16 # UTMI+0x3c CA calibration (16-bit)CA_FAILsignature (as the driver checks it,ehci-mstar.c:337-339): the 16-bit value at UTMI+0x78 masked with0xFFF0reading0x0000or0xFFF0— a failed RX calibration suppresses chirp detection and points at power/analog, not software.dmesgalso printsWARNING: CA Fail !!. - Full PHY re-init (in-kernel equivalent of a power cycle) — COMPLETED,
no improvement (2026-10, Piotr: performed over Ethernet, device still
enumerated at 12 Mbit/s). Kept here for reproducibility:
Safety:
ls /sys/bus/platform/drivers/Sstar-ehci-1/ # note the device name echo <device> > /sys/bus/platform/drivers/Sstar-ehci-1/unbind echo <device> > /sys/bus/platform/drivers/Sstar-ehci-1/bindwlan0on this device is the USB radio itself (8812eu,S40network:6), so unbinding the EHCI takes wlan0 down — run this from Ethernet or a serial console, never over the USB radio's link. The radio disappears and re-enumerates afterbind; ifwlan0does not come back on its own, re-run the network init (/etc/init.d/S40networkrestart) rather than poking WiFi config. Rebind re-runsTitania3_series_start_ehc()(USBC reset handshake, CA calibration, squelch/eye init) and then re-enumerates the radio. Expected dmesg on HS success:Sstar-ehci-1 H.W init,[USB] init squelch level 0x..and anew high-speed USB device number Nline. Re-running steps 1-4 afterwards gives the post-init register state. Observed on hardware: the device re-enumerated at full speed again. - True analog power cycle — only a full board re-power removes power
from the UTMI PHY and the module (VBUS is hardwired;
power-enable-padis not driven by Linux). Note this is distinct from the already-tested input-supply-capacity change, which alters headroom but was recorded as not improving negotiation. Power-cycle, then repeat steps 1-5 and compare: identical FS results across cold boot, re-probe and replug indicate the condition is stable (analog/hardware), while an occasional HS success would point at marginal timing.