Appliance image builds and boots for the locked-in hardware: kernel/ixgbe-sff.patch carries the product driver subset (raw I2C + sff_i2c, ETQF steering with rule round-trip, FCoE slot guard — bench-only reg_ops/ts_bench excluded), ported to v7.2 and compile-verified; mkimage applies it or dies, builds IXGBE=y (ICE/I40E out with the ice.pkg blob) and puts ixgbe.allow_unsupported_sfp=1 on the cmdline; load-ixgbe joins the repo anchored to its own path; module bringup ordered after the host checks because a down port's TX_DISABLE powers the PHY core down while the mailbox keeps answering (proven by flipping admin state: down reads 0xffff everywhere, core wakes 0.07-0.24s after the raise) with identify settling 3s bounded; cold-boot condition reproduced on the bench (ports downed first) and passing, confirmed on the appliance

This commit is contained in:
flamingcow
2026-08-18 09:41:38 -07:00
parent bb99695b47
commit d5ed4bfbd9
8 changed files with 626 additions and 17 deletions
+2
View File
@@ -40,6 +40,8 @@ cabletest drives this module through its own Go RollBall client (`phy.go`): modu
Not available in safe space: pre-FEC counter, cable length — those live in the µC vendor space that killed the modules.
**A down port hides the PHY: TX_DISABLE powers the core down, not the µC.** ixgbe qualifies this module as fiber (the fake-SR EEPROM) and asserts TX_DISABLE while the netdev is admin-down; the module then answers every PHY register read with 0xFFFF through a fully working, echo-matched mailbox — EEPROM reads are unaffected. Proven by flipping admin state on the bench: down = PHY ID 0xFFFFFFFF, and the core wakes within 0.25 s of the raise (measured 0.07–0.24 s across cycles; the BCM answers instantly). The dev host masks it (its unmanaged config leaves the ports up from boot); a fresh appliance boot hits it on a never-raised port. cabletest therefore raises the links before first touching a module, and settles identify through a short bounded wait while the core wakes.
**Mailbox latency is regime-dependent** — <25 ms per read linked (X520 host), ~220 ms steady with no link (bench-measured, `~/work/phydiag-work/rb_mbox_latency.py`), and beyond 3 s while 10GBASE-T training runs (observed live when a cable plug landed mid-read at bringup). cabletest's mailbox deadline (`rbCmdTimeout`) is sized past a full ~6 s training so a plug event reads busy, not dead.
**Mailbox trap: an orphaned command's completion answers as yours.** If a session dies mid-mailbox-op (killed process), the µC finishes the orphaned command on its own time, leaving CMD=DONE and that command's value in the block. A next session that issues a command and samples status immediately reads the orphan's DONE and value as its own — seen live: a PHY ID 1.2 read answered 0x0006, the orphaned EEE-advert (7.60) value of the killed session, while the very next read was correct. The client therefore never samples status before a full poll gap, reads the value from the same 6-byte block read as the status, and accepts a completion only when the block echoes the issued devad/reg (`phy.go` mbox). The split-transaction python clients always had the pre-sample gap, which is why the field campaign never hit this.