Files
cabletest/docs/modules/fs/README.md
T

80 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FS SFP-10G-T-100 (Broadcom BCM84891L)
Documented, robust — survived the whole poking campaign un-bricked. Honest EEPROM (RJ45/10GBASE-T codes), which is what trips stock ixgbe qualification ([../README.md](../README.md)).
References in this directory: [bcm84891l-mdio-commands.md](bcm84891l-mdio-commands.md) (command handler, transcribed), [bcm84891l-sfp-registers.md](bcm84891l-sfp-registers.md) (transport reference, transcribed), and their source PDFs.
## SMI transport (I2C→MDIO bridge)
PHY at I2C 8-bit **0xAC write / 0xAD read**.
| Op | Frames |
|---|---|
| Clause-45 write | one I2C write to 0xAC: `[000+DevAD, RegH, RegL, DataH, DataL]` |
| Clause-45 read | I2C write to 0xAC: `[001+DevAD, RegH, RegL]`**delay >1 ms** (3 ms proven) → I2C read 2 B from 0xAD |
- Single-byte reads see the bridge as inert (returns 0) — the DevAD-prefixed frame + delay is mandatory. This is why early probing wrongly declared 0x56 dead. Treat 0x0000 reads as retry-with-longer-delay: 0 is also the bridge's not-ready signature.
- **The fetch is asynchronous and a late one serves the wrong register silently**: the read frame arms a fetch, and if it outruns the delay, reading 0xAD returns the *previous* transaction's response with no error — observed under load even at 3 ms (STATUS 0x0004 served as an SNR DATA read → 0.4 dB). Since the buffer only changes when a fetch lands, a result differing from the previous buffer value is provably fresh; an unchanged (or zero) result must be re-read **bare, without re-arming** — preserving clear-on-read registers — until it stabilizes. cabletest implements this freshness check on every bridged read (`phy.go`).
- Recorded for a future multi-byte firmware transport (mlx5 MCIA shape): read = write `[001+devad,RegH,RegL]` offset_size=1, STOP, >1 ms, read 2 B offset_size=0; write = offset_size=2, addr = devad<<8|RegH, data = `[RegL,DataH,DataL]`.
## MDIO command handler
Protocol and full verified catalog: [bcm84891l-mdio-commands.md](bcm84891l-mdio-commands.md). Traps:
- **SET commands execute stale DATA1** — the handler never clears DATA registers; write every parameter register explicitly before any SET.
- Poll STATUS ~100 ms; frozen up to 2 s during 10GBASE-T training — only run after link-up.
## Proven diagnostics
| Capability | How | Observed |
|---|---|---|
| Per-pair SNR | `CMD_GET_SNR` 0x8030, **invoked bare** (writing the documented DATA1 display flag returns zeros; IEEE 1.1331.140 never populate — constant 0x8080) | DATA25 = SNR AD ×0.1 dB; ≈ 2732 dB absolute on bench, 0.10.4 dB jitter. 10GBASE-T operating point ≈ 26.5 dB, so margin ≈ value 26.5. cabletest shows the margin classified green ≥ 3 dB / amber ≥ 1 dB / red below — provisional thresholds until the graded-noise correlation run |
| Die temperature | `CMD_GET_CURRENT_TEMP` 0x8031 | ~6870 °C on bench |
| Supply rails | `GET_CURRENT_VOLTAGE` 0x802F | 0.8 V and 1.88 V rails, tenths of mV |
| Error counters | IEEE PCS 3.32/3.33 — block lock, latched errored-block/BER, clear-on-read | The noise-stress error proxy |
| Retrain on demand | IEEE AN restart `7.0 \|= bit9` | Relinks in ~56 s |
## Probed configuration states
| Item | Command | State |
|---|---|---|
| EEE / AutogrEEEn | 0x8008/0x8009 | Once read 0x0047 (10G AutogrEEEn variable latency + 5G/1G native — local-only, invisible in IEEE 7.60/7.61, which read 0); later reads 0, treated as the truth. **Forced all-off** via SET with explicit params `(0, 0, 0x7A12, 0x480, 0)` + AN restart, verified. cabletest checks 0x8008 and forces only on mismatch, verifying 7.60 reads 0 either way (`phy.go`) |
| EEE wire-truth | arm 0x801A after link-up, read 0x801B | Zero LPI events/duration on idle link; repeat under traffic |
| Fast retrain | 0x800A (datasheet titles it EMI_MODE; description is fast retrain) | Enabled 10G/5G/2.5G; IEEE 1.147 = 0x0019, count bits zero. Keep enabled; read the 1.147 count per run — a marginal cable that fast-retrains still gets counted |
| Pair map | 0x8000 | DATA2 = 0x00E4 = identity (A/B/C/D straight through) — MDI wiring verification works |
| Fault pass-through | 0x800D | 0 = LF/RF pass to the line (0x8011/0x8010 could mask them as IDLE — leave off) |
| Host interface | 0x802B/0x802D/0x8027 | XFI polarity normal; TX FIR = main tap 0x3C only; MAC/PHY frequency locked; KR/SyncE/USXGMII/WOL disabled; temp warnings off |
| Jumbo | 0x801C/0x801D | cabletest checks 0x801D and forces enable on mismatch (`phy.go`). The ODM firmware reads back the 9K size option regardless of the requested 10K — and 9018-byte wire frames pass at line rate with zero loss/corrupt, so its "9K" covers ≥ 9018 in practice |
| 1588 | 0x8004 | Disabled (engine registers undocumented — see asks below) |
| Limited reach | 0x8006 | Disabled — its DATA3 "linked in LR mode" bit, the only handler-visible trace of the DSP length estimate, is unavailable without a config change |
## Firmware-reliability notes
GET returns are trusted: early exploration saw one anomalous DATA1 (0x0047 from the EEE GET, never reproduced) and die-temperature-like values in other commands' DATA1, treated as one-off noise. cabletest reads config before forcing it and corroborates EEE through 7.60 after any relink. The hard rule that stands: write every DATA register explicitly before any SET — the handler executes stale DATA.
## ECD — recovered from the OpenBCM SDK, proven on hardware
The ECD register mechanism is absent from the handler catalog and the datasheet excerpts here, but the OpenBCM SDK's copper-XGPHY driver (`sdk-6.5.27/src/soc/phy/phy8481.c` `phy_8481_cable_diag` + `phy8481.h`) carries it for the 8483x/8485x/8488x family — and the same SDK drives the identical command-handler registers (1E.0x4005/0x4037/0x40383C) as the BCM84891L datasheet, confirming the shared map. Validated on the FS:
| Register | Role |
|---|---|
| `1E.0x4006` | Control/status. Write under mask {15,14,13,12,10}: bit 15 = run now, bit 14 = run at AN, bit 12 = break link, bit 10 = length in meters (SDK writes value 0x8400 = run now + meters). Bit 11 = busy — poll until clear (SDK allows up to 50 s; observed < 0.5 s) |
| `1.0xA896` | Verdicts, 4 bits per pair: 1 = OK, 2 = open, 3 = short, 4 = inter-pair short |
| `1.0xA8970xA89A` | Per-pair lengths (pairs 1/2, 3/4, 5/6, 7/8), meters |
Observed on a plugged, linked, healthy cable: verdicts OK×4 and per-pair lengths of [45, 45, 41, 46] on a ~45 m cable — **meter-accurate with no calibration**, and this ECD reports length for healthy pairs, not just faults, resolving the terminated-far-end concern in [../README.md](../README.md). Caveats:
- The run blips the link (PMA 1.1 latch-low catches a drop even with the break-link bit clear) — do not run mid-measurement until the disturbance is characterized.
- Fault verdicts (open/short/inter-pair) are unexercised — deliberately: the product is a closed-loop tester, both ends always plugged.
- Family constraints from the SDK: port must be enabled; unsupported at forced 100M.
- `bcm_ecd_probe.py` in phydiag-work implements the recipe.
## Missing datasheet chapters
Chapters the datasheet TOC lists but the excerpts here omit — to source elsewhere:
1. The **ECD chapter** — now for confirming bit meanings rather than unblocking.
2. The **1588 operation chapter**.
3. Datasheet **§1.20 loopback** (copper line loopback) and **§1.17 EEE/fast-retrain monitoring**.
4. **Chapter 2 register summary.** The excerpt's TOC names them all.