Files
cabletest/docs/modules.md
T

4.9 KiB
Raw Blame History

Module-PHY diagnostics and the register maps

DANGER: Marvell CUX3610 (Wiitek UF-RJ45-10G-100) modules brick on certain reads

Both original Wiiteks were bricked permanently by register exploration — the death survives cold power cycles and reseats. Read this before touching any replacement.

The CUX3610 has an integrated microcontroller (Marvell Alaska-M, PHY ID 0x002B0BF4, firmware 12.1.5.0) that boots from onboard non-volatile storage. The high vendor register windows (3.0x8000+, 31.0xF000+) reached over RollBall are µC-mapped peripheral space, not PHY-core MDIO. A read of a trapped peripheral crashes the µC mid-operation and corrupts its persistent boot state, so it comes up FATAL forever after.

The trap: any register whose low byte is 0x64 in a high window (register high-byte ≥ 0x80), on any devad. Module 1 died reading 3.0x8064, module 2 reading 31.0xF064. The mailbox writes the address bytes, then the µC dies executing the access — the command never even needs to complete. 3.0x8064 is a known QCA808x CDT (cable-diagnostic) status register; the ODM firmware appears to emulate/intercept a CDT block there and crash on a cold read. A sloppy (reg & 0xFF) == 0x64 decode explains both deaths with one bug.

Rules for any Marvell/RollBall module:

  • Never sweep vendor register windows. Never read *.0x??64 (high-byte ≥ 0x80).
  • Single targeted reads only, on registers with a documented reason.
  • Recovery after a brick needs a vendor firmware image + the boot-download protocol (registers 1.0xC050 boot status, 1.0xD0F0D0F3 download) — we have no CUX3610 image, so bricks are effectively dead. A ghost i2c device at 7-bit 0x57 (returns zeros) is the ROM bootloader waiting for a download.

What the Marvell modules give (safely)

Proven on the CUX3610 before they died, and on the Fibergaga oracle — all IEEE 802.3an standard registers, safe on any Marvell module:

  • Per-pair SNR margin — PMA 1.1331.136 current, 1.1371.140 minimum.
    • On the CUX3610 the value is reg 0x8000 in 0.1 dB (saw A 9.1 / B 7.1 / C 7.7 / D 8.9 dB).
    • Retrain-dependent — only compare within one training session.
  • Latched error/retrain detection — PCS 3.32/3.33.
    • Block-lock loss, BER saturate, errored blocks; clear-on-read.
  • Link-partner / master-slave — 7.33.
  • FW version 1.0xC011/12; boot status 1.0xC050.
  • Forcing a retrain (to refresh SNR minimums):
    • RollBall write 7.0 |= bit9 (restart AN) — proven safe.
    • An ip link bounce does not drop the copper line, so it won't retrain.

Not available in safe space: pre-FEC counter, cable length. Those live in the µC vendor space that killed the modules.

Marvell cable-length register candidates (unverified, single-shot only)

From kernel drivers for sibling parts — templates for a future single targeted probe on a sacrificial module, never a sweep, never near *.0x??64:

  • TDR from the 88Q2220 (marvell-88q2xxx.c, same 0x002b0bXX family, recipe cited from "the Marvell API"), all in MMD 3:
    • TDR_RESET 0xFECA — init 0x0D90, clear 0x1D90.
    • Calibration: 0xFED9 = 0x010E, 0xFEDA = 0x00EB, 0xFEDE = 0x0058.
    • TDR_STATUS 0xFEDD — write 0x0002 to start; ~500 ms test.
    • Read TDR_STATUS: bits[1:0] = 01 done; [7:4] verdict (0x7 OK / 0xE open / 0x3 short / 0x5 noise); [15:8] distance in meters.
    • Single-pair on the Q2220; the 4-pair CUX3610 likely has per-pair variants nearby. Low bytes are nowhere near the 0x64 trap.
  • QCA-style CDT (qcom/qcom.h):
    • 3.0x8064 CDT_STATUS, 3.0x80650x8068 per-pair results, 3.0x80740x807E thresholds.
    • This IS the trap address — only ever entered via the full start sequence, never a cold status read; treat as off-limits absent strong evidence.
  • Next doc-mining lead for the 4-pair pattern: gtAdvVct.c in the Marvell qd-dsdt GPL dumps (e.g. github.com/andy928/xpenology arch/arm/plat-feroceon/mv_hal/qd-dsdt/).

Cable-length physics (applies to both vendors)

  • TDR (classic VCT/CDT/ECD):
    • Locates opens/shorts both-ended.
    • But healthy-cable length needs a far-end reflection, and a plugged-in terminated far end absorbs the pulse — so "OK" pairs report no distance. Effectively single-ended for length.
    • Every kernel implementation only reports distance for fault results.
  • DSP estimate:
    • Both vendors' PHYs compute linked-cable length continuously from insertion loss during training (Marvell "proactively determines cable length"; the BCM's limited-reach power mode switches "based on cable length" while linked).
    • Works in the product's both-ends-plugged topology — the open question is only whether the estimate is exposed in a readable register.
  • NIC timestamp path-delay — the module-independent fallback if the DSP length isn't reachable:
    • Works linked.
    • Needs per-packet or PTP-latch hardware timestamps.
    • Needs a short-cable calibration to cancel fixed PHY latency (~4.8 ns/m one way; 50 m ≈ 240 ns).