Script A: wait 45 s between starting and stopping mgmt_ping_monitor.
`start` returns after one second, but a round is roughly 30 s -- without
the pause the log held only the START banner and no RESULT line.
Docs brought up to date with the eight commits since 419b680:
- Tech Stack gains bgctl, systemd-run, iproute2 and hw-test-session;
the stress row moves off the hammer scripts
- Structure and Key Features cover mgmt_ping_monitor.sh, and mark
bmc_monitor{,_ddr}.sh as disabled -- their call sites in B and C are
commented out, though the files remain
- Data Flow rewritten for all three scripts
- Two constraints added: TTL's `timeout` is global and must be restored,
and two management NICs on one subnet cause ARP flux (hence
ARP_STRICT, and nic_tx/nic_rx as the evidence of which NIC sent)
- CLAUDE gotchas add the `ip -s link` column order, that a monitor's
`start` returns in one second rather than after a round, and that
show_dmesg now ends with `dmesg -C`
- Phase 3 ticks the move to bgctl; Phase 5 gains the mgmt-ping, NVMe and
EDAC parsing targets. Future Extensions notes that Script C never cats
mgmt_ping.log, so the soak's ping results stay on the DUT
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
New Blanton_Script/mgmt_ping_monitor.sh: brings both management NICs up
with iproute2 (`ip link set` / `address replace` / `route replace` with
per-NIC metric) and pings each one's own target -- eth0 -> .30, eth1 ->
.31 -- appending to a rotating log. Same sub-commands as the bmc
monitors, plus `summary` for just the per-leg RESULT lines.
Both NICs stay up, which on a shared subnet lets the target's ARP be
answered by either one, so a reply can land on the NIC that did not
send. ARP_STRICT applies arp_ignore/arp_announce to prevent that, and
each leg logs `ip -s link show` with the interface's own TX/RX packet
delta across the burst as direct evidence of which NIC carried the
traffic. Note `ip -s link` orders columns "bytes packets ...", so the
packet count is the second field.
Script A: hw-test-session start/log/status, a fuller DUT inventory
(version, fwutil, syseeprom, ssdhealth, TPM, nvme smart-log, smartctl),
bmc-first-enroll and bmc-manager version/status, ras-mc-ctl summary, and
both 100G uplinks now brought up rather than 513 being left down.
Script B: stress moves to bgctl (memtester, qfx5252-stress-ssd/-usb) and
the BMC DDR load runs through bmc-manager, replacing the hammer scripts
and the bmc_monitor pair. Adds a BMC USB net test that discovers the
cdc_ncm interface and runs a 4-hour ping under systemd-run.
Script C: stops the bgctl jobs, the BMC USB unit and the mgmt ping, then
collects journalctl, per-NIC counters, ras-mc-ctl and NVMe health, and
closes the session with hw-test-session finish.
utils/show_dmesg.ttl: one combined error regex with `dmesg -T`, an
i2c-filtered view, then `dmesg -C` so Script C's capture shows only what
the soak produced. utils/setup_pmon.ttl: add the TPM FRU/read checks.
Fix: Script B set `timeout = 15` for the cdc_ncm probe and never
restored it, leaving the cap in force for everything after -- including
the traffic init, which walks 108 VLANs per unit and takes far longer
than 15 s. A timed-out wait returns without the prompt, so the macro
would have run ahead of the DUT for the rest of the soak. Reset to 0 at
:skip_ping, where both branches meet.
Script A -> V1.0.6.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
`config save -y` was sent straight after the Ethernet514 startup with no
wait in between. The shell buffers the second line and still runs it, so
nothing visibly breaks, but every wait from there on matches the prompt
of the previous command -- leaving the macro permanently one step ahead
and issuing `show interfaces status` while `config save` is still
running. Every other sendln in the file waits first; this one now does
too.
Version left at V1.0.5.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
wait_init.ttl: the comparison was strictly greater than WT_MIN, so a unit
reporting exactly 216 never passed and Script A sat in the poll loop
forever. 216 is not an arbitrary number -- TL_PAIRS holds 108 loopback
pairs, so 108 x 2 = 216 is every cabled port being up, i.e. precisely the
state being waited for. Comparison is now `< WT_MIN`, making the
threshold "at least 216".
Script A: bring the 100G uplinks into a known state before reading their
status -- Ethernet513 on asic0, Ethernet514 on asic1 -- and persist it
with `config save -y`. The stray `wait` after show_dmesg is dropped; the
one opening the new block consumes that prompt instead.
Version left at V1.0.5.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Rework the traffic blocks in A, B and C as explicit if/elseif branches
holding literal commands, and drop the derived swb_any/swb_opt from
config.ttl -- the branches read straight off the page and there is no
indirection to follow.
All nine conditions compared SWB_UNIT0 against itself, though:
if SWB_UNIT0 = 1 && SWB_UNIT0 = 1 -> SWB_UNIT0 = 1
elseif SWB_UNIT0 = 1 && SWB_UNIT0 = 0 -> never
elseif SWB_UNIT0 = 0 && SWB_UNIT0 = 1 -> never
so the single-unit paths were unreachable. A DUT with only unit 0 would
have run the both-unit commands and hit bcmcmd on an absent unit 1,
while a DUT with only unit 1 fell through to the empty else and skipped
traffic entirely. Second operand is now SWB_UNIT1.
Verified per branch that the -u argument matches the condition guarding
it: both units carry no -u (tool default TL_UNITS="0 1"), unit-0-only
carries -u 0, unit-1-only carries -u 1, and the else stays empty.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
The bench is not always fully populated. config.ttl now declares which
switch units exist:
SWB_UNIT0 = 1 ; this DUT has switch unit 0
SWB_UNIT1 = 1 ; this DUT has switch unit 1
Two values are derived there rather than repeating the same test in
three scripts: swb_any (0 = no unit at all) and swb_opt, the suffix
appended to each blanton_traffic_linespeed call -- "" for both units so
the tool's own TL_UNITS="0 1" applies, " -u 0" or " -u 1" for a single
one.
Script A, B and C build their traffic commands with sprintf2 and the
suffix, wrapped in `if swb_any = 1`. A half-populated DUT no longer
issues bcmcmd against an absent unit, and a DUT with no switch board
skips the traffic stage outright instead of filling the log with
failures.
wait_init.ttl reads the same two flags instead of its own copies, so the
wait and the traffic blocks cannot disagree about what is installed.
Script A -> V1.0.5.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
wait_init.ttl V3.0.0 adds WT_UNIT0 and WT_UNIT1 at the top of the file.
Benches are not always fully populated, and V2.0.0 waited on both units
unconditionally, so a DUT with one switch board sat in the poll loop
forever -- silently, since the loop neither advances nor reports.
both units -> 1 , 1
unit 0 only -> 1 , 0
unit 1 only -> 0 , 1
no unit -> 0 , 0 (bypass, returns immediately)
A disabled unit is skipped rather than polled and ignored: its whole
block sits inside the if, so no bcmcmd is issued for it and no
misleading error reaches the log.
Two independent integer flags rather than a "0 1" string, because
parsing a string in TTL needs strscan and this is meant to be edited by
hand at the bench.
All three exit paths still leave exactly one prompt unconsumed, so
Script A's surrounding waits are unaffected.
Script A history: recorded under the existing V1.0.4 block rather than a
new version, matching the consolidation done there.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Script A: `hpe-eeprom-tlv show --bus 4 --addr 0x50` after `show boot`, so
the board identity is on record next to the image it booted. The empty
Check History placeholder is dropped.
Script A and B: disable the lldp feature and `config save -y` before the
traffic stage, so the switch stops sourcing its own frames and the
loopback pair counters reflect only the injected burst.
Script B: `sfputil lpmode off` on Ethernet513/514 before reading their
status -- a transceiver left in low-power mode will not link.
Script A -> V1.0.5, with the history covering the Script B changes too,
per this project's convention of keeping one consolidated log in A.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
wait_init.ttl V2.0.0 now polls
bcmcmd -n 0 -c ps | grep -w up | wc -l
bcmcmd -n 1 -c ps | grep -w up | wc -l
and proceeds only when BOTH exceed 216, so the baseline is taken with
the data plane actually up rather than merely with pmon answering.
V1.0.0 could use `wait "Thermal Not detected" prompt` because that was a
string-presence test. Comparing a count needs the value captured, so the
count is wrapped in an echo marker and read with waitregex +
groupmatchstr1 + str2int. The command echo cannot false-match: it reads
"PORTS0=$(bcmcmd ..." and the pattern requires a digit immediately after
the "=". The optional-space allowance covers a wc that pads its output.
The two thresholds are compared in nested ifs rather than with `and`,
which is bitwise in TTL.
WT_MIN and WT_INTERVAL are at the top of the file. The enter/exit prompt
contract is unchanged, so Script A's surrounding waits still line up.
Script A -> V1.0.4.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
publish/publish.sh packages src/Script_ABC_Blanton into
publish/Script_ABC_Blanton_<Ver>/, with -z for a zip, -f to overwrite,
-n for a dry run.
The version is read from Script A's "; Version :" header rather than
passed in, so the folder name cannot disagree with what the tester sees
on opening the macro. The header is CRLF, so the carriage return is
stripped -- left in, it becomes part of the directory name. Captured
logs are excluded (they carry DUT serials) but the empty logs/ is kept
because logopen writes there. .gitignore now admits the tool while
still ignoring its output.
config.ttl: testcase ENV, margin scan off for this run.
Docs brought up to date with the 14 commits since 8aa5c90 -- SWB
channel/address map, the traffic and BMC tooling, line-ending policy,
and the exec-bit and tail -f traps.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
New utils/wait_init.ttl polls `show platform temperature` every 10 s
until it stops reporting "Thermal Not detected", so Script A does not
record a baseline while pmon is still coming up. Script A calls it right
after `show boot` and bumps to V1.0.3.
The include pointed at utils/wait_thermal.ttl while the file is
wait_init.ttl -- as Script A's own V1.0.3 history line says. Corrected;
Tera Term aborts the macro when an include cannot be opened, so this
would have stopped Script A at line 59 on the first run.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Script A and B: `show interfaces status Ethernet513,Ethernet514` before
the traffic stage, so the uplink state is on record next to the counters
it explains. In B this takes the slot the empty "eye measurement"
placeholder held.
Script B: drop -u 0 from the traffic calls. A and C already defaulted to
TL_UNITS="0 1", so B was pinned to unit 0 while C stopped both -- the
soak only ever loaded one switch board, and C's stop hit a unit that was
never initialised. All three scripts now cover both units.
Script B: post-clear settle 10 s -> 15 s, matching A.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
`bmc_monitor.sh tail` runs `tail -n 50 -f`, which never returns, so
Script C stopped at the first call and never reached CHECK Stress
results, the traffic counters, or the closing messagebox. Stopping the
monitors first made it worse: with the file no longer growing, tail -f
just waits forever.
Read the two logs directly instead, so the whole BMC capture lands in
the master log and the macro carries on.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Script A: dump the BMC banner via `bmc-manager run 'cat /etc/issue'`,
and add the missing `wait` before `show boot`.
Script B: start bmc_monitor_ddr.sh and bmc_monitor.sh alongside the
host stress load.
Script C: stop both and dump their logs into the master log.
bmc_monitor.sh: INTERVAL_SEC 5 -> 10.
Known blockers, filed here so they are not lost -- this wiring does not
work yet as written:
1. `bmc_monitor.sh tail` runs `tail -n 50 -f`, which never returns.
Script C blocks on the first one and never reaches CHECK Stress
results, the traffic counters, or the final messagebox. It needs a
non-following dump (cat) instead.
2. Both scripts are mode 100644 and are the first .sh here meant to be
executed rather than sourced. do_start re-execs "$SCRIPT_PATH"
__daemon directly, so the execute bit is required even when invoked
through bash -- and a Windows -> USB -> DUT copy cannot carry it.
A chmod +x is needed before the start calls, as Script B already
does for mlucas-avx2.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Both scripts defaulted to LOG_NAME="bmc_poll.log", and PID_FILE is
derived from it, so the monitor and the DDR stress shared one log and
one pid file -- while the whole point of the split is to run them at
the same time.
The failure was quiet rather than loud: is_running greps the pid's
cmdline for its own SCRIPT_NAME, so the second script did not recognise
the first as running and started anyway. prepare_log_on_start then
truncated the log the first one was writing (START_LOG_MODE=new), both
raced on the pid file, and a later stop could only reap whichever wrote
it last, orphaning the other.
bmc_monitor_ddr.sh now uses bmc_ddr.log, which also moves its pid file
to bmc_ddr.pid. Both remain covered by the *.log ignore rule.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
bmc_monitor.sh was doing two unrelated jobs: sampling `free -m` every
few seconds, and running `memtester 500M 1` as a stress load. They want
different timeouts -- a monitor should give up in 30 s, a memtester
pass legitimately runs for minutes -- and mixing them meant either
cutting memtester short or letting a hung sample stall the loop.
bmc_monitor.sh now polls `free -m` only, keeping CMD_TIMEOUT_SEC=30.
bmc_monitor_ddr.sh is the stress half: memtester only, with
CMD_TIMEOUT_SEC raised to 3600. The two are otherwise identical.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
bmc_monitor.sh (V1.1.0): polls the BMC from the SONiC host via
`bmc-manager run`, appending to a rotating log. Runs detached, so no
interactive SSH session to the BMC is needed and the BMC's busybox
toolchain never comes into play. Subcommands start/stop/status/fg/tail/
clear; the polled command list, interval, per-command timeout and log
rotation are configured at the top of the file. START_LOG_MODE defaults
to "new", so one run means one log. Default COMMANDS are `free -m` and
`memtester 500M 1`, i.e. the BMC is memory-stressed alongside the host
soak.
Script A: `show boot` after the time sync to record the image the DUT
booted, and `show uptime` at the end of the traffic baseline.
Script C: `show reboot-cause` and `show uptime` after the traffic
report, so an unplanned reset during the soak is visible in the
closing snapshot rather than only in dmesg.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
The values were corrected in ababb2c but every comment describing the
pairing still said the old one, leaving four confs where the comment
contradicted the line it sat on:
CB_I2C_CH=8 # CB F3 Ch6 = SWB0 CONN13/CONN14 ...
That reads as a typo waiting to be "fixed" back to 6, which would undo
a bench-verified value. Comments now state the real pairing:
Ch6 = SWB0 CONN14/CONN16 Ch8 = SWB0 CONN13/CONN15
Ch7 = SWB1 CONN14/CONN16 Ch9 = SWB1 CONN13/CONN15
Same map corrected in margin.sh's header (two places).
Ref/margin_command_trace.md gets a staleness banner rather than an
edit. Its 1223 expanded cb_pmbus_* commands were generated from the old
values - 487 of them use addresses that no longer exist (0x5D, 0x5F,
0x63, 0x65) - so patching the headings would leave the bodies wrong and
look authoritative. The banner carries the correct table and says the
SWB chapters need regenerating; chapters 1-4 are transport-independent
and remain valid.
Comments only: no CB_I2C_CH value and no CHIPS address was touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Verified against the DUT. Two things were wrong in the SWB confs.
Channel assignment: CONN13/CONN15 and CONN14/CONN16 were paired the
wrong way round. The bench wiring is
SWB0 Ch6 = CONN14/CONN16 Ch8 = CONN13/CONN15
SWB1 Ch7 = CONN14/CONN16 Ch9 = CONN13/CONN15
LTC2977 addresses: the high half of each LTC2980 was recorded one step
above the low half (0x5C/0x5D, 0x62/0x63). These are 7-bit addresses
derived from 8-bit pairs, so they step by two: 0x5C/0x5E and 0x62/0x64.
This also clears the collision noted in v2.6.0, where SWB0_CONN13 chip2
and SWB0_CONN14 chip1 both landed on 0x5E on Ch6. Each channel now
carries two disjoint address pairs (0x5C/0x5E and 0x62/0x64), verified
collision-free across all eight SWB confs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Every value in the report printed as 2147483647 because grp() rendered
counters with sprintf("%d", v). The DUT's awk casts to a 32-bit int for
%d, so any counter above 2^31-1 saturates -- and a real line-speed run
is around 7e11, three orders of magnitude past that. Formatting with
%.0f keeps the value in awk's double domain, which is exact to 2^53.
The FAIL delta line had the same defect (%+d): a dead port makes the
delta as large as the counter itself, so the one number needed to
diagnose the failure would have been the one that saturated.
Verdicts were never affected. The cross-check compares the TX[]/RX[]
doubles directly and only the display path goes through grp(), so past
PASS results stand; only the printed numbers were wrong.
Verified against a captured run (secret/Counter.log, 108 pairs): values
now match the raw MIB_TPOK/MIB_RPOK lines exactly, and the loopback
identity holds (cd0.TX == cd32.RX, cd0.RX == cd32.TX).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
Script A: the TRAFFIC-SETUP-STAGE placeholder is now a full loopback
round (ps, init, clear, show, start, stop, report) with 15 s settles, so
the run has a traffic baseline before the soak starts.
Script B: widen the post-clear settle from 3 s to 10 s.
Script C: drop -u 0 from stop/report so both switch units are covered.
Note: Script B still pins -u 0 while A and C now default to both units.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
margin.sh and settings/*.conf carried CRLF into the repo, so sourcing
them on the SONiC DUT failed outright:
-bash: $'\r': command not found
margin.sh: line 126: syntax error near unexpected token `$'{\r''
settings/*.conf was the quieter half of the same bug: margin_init
sources them, and an unquoted assignment such as CB_I2C_CH=6 became
"6\r", so the SWB transport would have driven I2C with a malformed
channel number.
Content is unchanged - the diff is carriage returns only, and bash -n
passes on every converted file.
Add .gitattributes so this cannot come back: *.sh/*.conf/*.py/*.txt/*.md
are pinned to LF, *.ttl stays CRLF (Tera Term runs on Windows only) and
office formats are marked binary.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
margin.sh v2.6.0 resolves the SWB backend via _swb_find_backend, which
searches the parent Blanton_Script/ dir, so the copies bundled inside
LTC2980_Margin_Script/ are dead weight and would silently drift from
the shared originals.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
margin.sh (swb path only, CB/i2c path untouched):
- Search blanton_cb_i2c.sh / blanton_fpga_pcimem.sh in the parent
Blanton_Script/ dir as well; the old code only looked next to margin.sh
where those files do not exist, so TRANSPORT=swb always failed to load.
- _swb_setup: validate CB_I2C_CH, cb_i2c_init <ch> 0x88 0x00 once per
session, then CB_I2C_AUTO_INIT=0 to drop 4 pcimem writes per transfer.
- Probe every LTC2977 in CHIPS with cb_pmbus_read <ch> <addr> 0x00 1.
- Check cb_pmbus_read/write return codes; a NACK is now reported instead
of silently becoming Vout=0.0000.
- Fix DEBUG_MODE collision with blanton_fpga_pcimem.sh: pcimem tracing is
gated by MARGIN_SWB_PCIMEM_DEBUG via _swb_call.
- Add margin_swb_info / probe / scan / reset / sem wrappers.
settings: fix CB_I2C_CH per bench wiring (CONN14/CONN15 were swapped)
Ch6 = SWB0 CONN13/14, Ch8 = SWB0 CONN15/16,
Ch7 = SWB1 CONN13/14, Ch9 = SWB1 CONN15/16
Ref/margin_command_trace.md: new command trace reference - every i2c /
cb_pmbus command issued by margin_init, margin_status and
margin_apply_profile combo_high3, expanded per channel for the CB conf
and all 8 SWB confs, with LINEAR16 values and register meanings.
Known issue documented, not changed: SWB0_CONN13 chip2 (0x5E) collides
with SWB0_CONN14 chip1 (0x5E) now that both sit on Ch6; SWB1 pattern
suggests 0x5D, pending hardware confirmation.
Bring both docs in line with the five commits pulled from Gitea.
- BDF: pcimem V1.5.0 auto-detects the CB FPGA BDF, so the "edit the four
lines per DUT" guidance was inverted. Documented the detection order
and fpga_rescan, and flagged that utils/show_pcie_error_reg_*.ttl
still hard-codes its 7 BDFs -- the footgun is only half gone
- Traffic: documented blanton_traffic_linespeed.sh (bcmcmd SWB loopback,
per-pair TX/RX cross-check) and tools/bcm_mibpair_report + the three
loopback command tables; noted the route taken differs from the
SONiC-CLI approach Phase 4 originally planned
- Stress: stress_hhmd and stress_pcie were removed on 08-17, so the job
count is 8 not 10; soak loop now pulls full setup_pmon (9 items)
- Constraints: added the bcmcmd exit-0 and stdin-eating gotchas
- Phases: ticked 10 completed items, corrected Phase 3/4 acceptance
criteria, and moved BDF auto-detect out of Future Extensions
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
V0.4.0 -- report now lists ALL 108 pairs, PASS / FAIL / NA alike,
one line per port (two lines per pair). Missing counters render as
'-', so -a becomes the default (the flag is still accepted) and the
long "# NA (no counters): ..." summary line is dropped since every
NA pair is now a visible row. The table printer is generalised to a
column array with per-column alignment, keeping the pad-then-colour
order so ANSI codes do not break the column widths. This is the only
intentional difference from tools/bcm_mibpair_report_V1.1.0.py.
V0.3.3 -- accept -tx / -length as aliases for -c / -l so a tx burst
can be written the way the bcm command reads
("start -u 0 -tx 100 -length 512"); both are validated as positive
integers. Fix --dry-run printing nothing for init/start/stop/report
since V0.3.1, where the new bcm wrapper discarded the "[DRY ]" lines.
Offline report notes now go to stderr so the table on stdout stays
pipe/diff clean.
Co-Authored-By: Claude <noreply@anthropic.com>
Blanton_Script/blanton_traffic_linespeed.sh V0.3.2 drives the whole
loopback traffic run from the DUT shell via bcmcmd, for both switch
boards (unit 0 and 1):
- init : vlan remove 1 pbm=cd, then create/add the 108 loopback
pairs (VLAN 30..137, cdN <-> cdN+32)
- clear : clear c
- show : show c (raw)
- start : tx <count> length=<len> VLantag=<vid> per VLAN
- stop : remove the pairs, optional --destroy
- ps : port status of the cabled ports
- report: parse the show c MIB_TPOK/MIB_RPOK counters and lay them
out one pair per block with a cross-check verdict
(cdA.TX == cdB.RX and cdA.RX == cdB.TX), PASS green /
FAIL red / NA yellow, --tolerance for snapshot skew,
--tsv, --raw and -f <log> for offline analysis; the raw
capture is kept under /tmp
- run : ps -> init -> clear -> start -> report
Options -u/-c/-l/-p/-T/-d/-n and a sourceable function API, in the
style of the other blanton_*.sh tools. Command output matches the
former Tera Term macros byte for byte; report output matches
tools/bcm_mibpair_report_V1.1.0.py, added here as the off-box
equivalent, together with the raw bcmcmd command lists under tools/.
ScriptA sources the tool, ScriptB runs ps/init/clear/show/start and
drops stress_hhmd and stress_pcie, ScriptC stops the traffic and
prints the pair counter report.
blanton_fpga_pcimem.sh V1.5.0.
The four FUNCT0..3_RES sysfs paths were hard-coded and had to be
edited for every DUT, because the CB FPGA's BDF changes with the
PCIe enumeration (0000:03:00.x / 0000:05:00.x seen so far).
Detection order at source time: FPGA_BDF override -> sysfs scan for
vendor 0x1590 with all four functions exposing resource0 -> lspci
-Dnn name/id match -> FPGA_BDF_FALLBACK. Adds fpga_rescan for a
DUT swap, FPGA_BDF / FPGA_VENDOR_ID / FPGA_LSPCI_MATCH overrides,
FPGA_BDF_ACTIVE reporting and FPGA_QUIET. Detection runs once, so
cb_fpga / pmc / icb / swb keep zero per-command overhead.
- utils/setup_pmon.ttl: add 'show platform leak status' and 'leak channels'
- Script A: move setup_pmon include into the TAKE DATA block
- Script B: soak loop now reuses utils/setup_pmon.ttl instead of inline fan/temperature
- Script C: fix header title (was 'Script B')
Bring the Blanton Tera Term TTL test suite under version control and
document how the pieces fit together.
- ARCHITECTURE.md: A/B/C script roles, host-to-DUT-to-FPGA data path,
config/settings/profile data models, PCIe AER + EDAC topology table,
10 key constraints, and 6 development phases derived from the
Status_20260814 spreadsheet's On-Going items
- CLAUDE.md: stack, smoke-test commands, conventions, and the hardware
footguns (per-unit BDF, VSPI vs VI2C timing, repeated START,
STORE_USER_ALL, ARB_LOST false positives)
- secret/: gitignored credential store with README + .example template,
so the DUT login stops living in 1_Blanton_Script_A.ttl
- .gitignore: secret/*, For_AI/, *.log, publish/, *.DSN
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM