Per-module diagnostics: capabilities, register maps, hazards. Each device directory holds its doc plus its datasheets. NIC-side transports: [../nics/](../nics/README.md).
> ⚠ **Before touching any Wiitek/Marvell module, read the brick trap in [wiitek/](wiitek/README.md).** Two modules died permanently from register exploration.
## The modules
Counts and current placement: [../state.md](../state.md).
| 10Gtek | (claims SFP-10G-SR) | — | Copper RJ45 despite the SR part number; filler, not in the test set |
## The media lies (mostly)
**Every test module is a copper RJ45 10GBASE-T module** — none are fiber, whatever the EEPROM claims; the real media is a 10GBASE-T PHY inside each module. EEPROM honesty varies by vendor, with driver consequences:
- The X710 rejects the FS outright: i40e firmware disables Rx/Tx ("unsupported SFP module type", logged only at driver bind) and i40e has no override parameter — the FS can only live behind ixgbe. The rejection is silent at insertion time; a dead port with `ethtool` reporting no supported link modes is the symptom.
- Physical-layer reasoning must use 10GBASE-T: PAM16, LDPC FEC, self-synchronizing scrambler, 4 twisted pairs, distance/temperature sensitive — never an optical model.
- The module PHYs keep the copper link trained on their own: an admin `ip link set down` does NOT drop the wire unless the i40e `link-down-on-close` priv flag is set (peer sees the drop in ~200 ms, relinks in ~0.9 s).
## IEEE 802.3an standard registers (safe on all copper module PHYs)
Proven on the CUX3610 (before the originals died) and the Fibergaga; the BCM notably does **not** populate the SNR set ([fs/](fs/README.md)).
| Registers | What | Notes |
|---|---|---|
| PMA 1.133–1.136 / 1.137–1.140 | Per-pair SNR margin, current / minimum | CUX3610 value = `reg − 0x8000` in 0.1 dB. Retrain-dependent — only compare within one training session |
| AN 7.0 | Restart AN (`\|= 0x1200`, enable + restart) — forces retrain, refreshes SNR minimums | Proven safe everywhere. Always force the enable bit too: the BCM ECD can leave 7.0.12 cleared ([fs/](fs/README.md)), and a bare restart preserves it. An `ip link` bounce does not drop the copper line, so it won't retrain |
The full mailbox map (0x80 CMD, 0x81 devad, 0x82/0x83 reg, 0x84/0x85 value) is vendor-confirmed in [wiitek/10gbase-t-phy-register-operation.md](wiitek/10gbase-t-phy-register-operation.md). Split transactions (separate STOP per byte) are field-proven on both the Fibergaga and the original Wiiteks; the kernel `mdio-i2c` combined form is not required by the modules. cabletest carries a Go client (`phy.go`): split ≤4-byte offset writes, single-hold compound reads, whitelist-guarded against the Wiitek brick space — proven live over the patched-ixgbe `sff_i2c` on the X520.
- **TDR** (classic VCT/CDT/ECD): locates opens/shorts both-ended. The generic concern — *healthy-cable length* needs a far-end reflection, and a plugged-in terminated far end absorbs the pulse, so "OK" pairs report no distance (every kernel implementation only reports distance for *fault* results) — is disproven for the BCM: its ECD reports per-pair length for healthy pairs on a plugged, terminated, linked cable, meter-accurate ([fs/](fs/README.md)). **The BCM ECD is the product length path.**
- **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 question is only whether the estimate is exposed in a readable register (Aquantia: yes, `1E.C884`; BCM/Marvell: not in documented space).