Compare commits

..
25 Commits
Author SHA1 Message Date
etwenandClaude Opus 5.5 be329a0fc3 docs: Add version and platform badges to the user guide
Same shields.io badge row as the STPViewer README: version 1.2.7,
host Windows, Tera Term 5.x, DUT SONiC, shell bash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-11-12 20:50:47 +08:00
etwenandClaude Opus 5.5 5b2777d547 docs: Record the V1.2.7 additions in Script A's history and release note
Script 4_1, blanton_tr518_thermal.sh, blanton_multiphase_read.sh and
Script_User_Guide.md are added to the V1.2.7 block of Script A's history
and to docs/release-notes/v1.2.7.md, which V1.2.7 is re-released with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-11-12 20:44:32 +08:00
etwenandClaude Opus 5.5 62ce31a4e5 feat(ttl): Add Script 4_1, the thermal run with an idle phase
Script 4 with 300 idle rounds first (PMON snapshot, SWB0/SWB1 rail power,
AVT CPU power, sleep 1), then blanton_tr518_thermal.sh start and the
full-load loop, which also logs nvme smart-log / smartctl -x and waits
with a DUT-side sleep 1 instead of pause 60. No teardown, like Script 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-11-12 20:44:32 +08:00
etwenandClaude Opus 5.5 755c37c57e docs: Fold the LTC2980 margin README into the user guide
Section 2.4 now carries the full LTC2980_Margin_Script usage: the nine
boards, every margin_* function, the OPERATION codes, all profiles
including the comboA/comboB checkerboards, the script/ batch runners, and
the NVM save commands with the 18-line margin_save blanton table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-11-12 20:42:49 +08:00
etwenandClaude Opus 5.5 37b7b88822 docs: Add the tester user guide to the delivered package
Script_User_Guide.md sits in src/Script_ABC_Blanton/ so publish.sh ships
it. Part 1 covers deploying Blanton_Script/ from USB to the DUT, config.ttl,
and what Scripts A, B and C run; part 2 covers every tool in
Blanton_Script/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-11-12 20:35:58 +08:00
etwenandClaude Opus 5.5 be24eebff2 feat(pwr): Add blanton_multiphase_read.sh to read back the SWB VRMs
Reads the controllers blanton_multiphase_margin.sh writes (native i2c,
SWB0 = i2c-13/15, SWB1 = i2c-14/16) and prints one row per chip in the
pu_show.sh layout - VOUT/VOUT2, IOUT/IOUT2, POUT (V x I), TEMP - with the
raw PMBus word in hex after every voltage and current, plus the total
power per board. PAGE is read back after each page and the page is re-read
if something else moved it. Not run on the bench yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-11-12 20:35:58 +08:00
etwenandClaude Opus 5.5 957eda3ab4 feat(pwr): Add blanton_tr518_thermal.sh for the thermal tr 518 load
A copy of blanton_tr518.sh V1.0.1 with the thermal tr 518 arguments
(Scenario=6 Profile=2 portstopktszstride=1 Count=260 PktSize=603,218
CheckLinkTime=20 CheckDataTime=200 TestPhase=1, no PortList / rm=ext).
The argument string is read from TR_THERMAL_ARGS so an override meant for
blanton_tr518.sh does not leak in. Not run on the bench yet; no TTL calls it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-11-12 20:35:58 +08:00
etwenandClaude Opus 5.5 9c9ec5f4f5 docs: Record V1.2.7 in Script A's history and add the release note
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-22 14:26:14 +08:00
etwenandClaude Opus 5.5 3395ba5873 build: Update the vendor NFC tool to v2.5
Replace blantons_nfc_validate.py (v2.3) with the customer's
qfx5252-nfc-validate v2.5, renamed so nfc_polling.sh keeps working
unchanged. The default 'test --debug' output is the same; bad
arguments now print [FAIL] and exit 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-22 14:26:14 +08:00
etwenandClaude Opus 5.5 3264052949 fix(fdr): Limit blanton_fdr.sh to the cabled ports
The default '1-259,270-565' also covered the uncabled ports
(cd15..19, cd47..51, cd111..115, ...). Use the TL_PS_PORTS list of
blanton_traffic_linespeed.sh instead, the same one blanton_ber_debug.sh
uses. Port 268 (ce0) stays out; FDR_PORTS can add it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-22 14:26:14 +08:00
etwenandClaude Opus 5.5 f02ba22924 feat(ttl): Read the FDR counters in every Script B soak round
Script B runs blanton_fdr.sh rdcnt after the Tray ID stress in each
round, so the FDR counters started before the loop are logged through
the soak, not only at Script C. The call is not gated by SWB_UNIT0 /
SWB_UNIT1. Recorded under V1.2.6 in Script A's history and the release
note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 22:55:09 +08:00
etwenandClaude Opus 5.5 738f1dd1c6 docs: Record V1.2.6 in Script A's history and add the release note
Script A: header to V1.2.6; entries for blanton_fdr.sh, the unused
lanes off in Script A, and the FDR hooks in Script A, B and C, with
notes on the unverified STOp keyword, the lanes never being turned
back on, the both-units-only gating and the exec bits.

CLAUDE.md / ARCHITECTURE.md: status and release to V1.2.6, FDR and the
unused lanes in the overview, the Script A flow, the tree and the
commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 22:50:25 +08:00
etwenandClaude Opus 5.5 0407bbe04f feat(ttl): Run FDR around the traffic test and turn off unused lanes
When both switch units are enabled, Script A wraps its traffic baseline
in blanton_fdr.sh start / clear / rdcnt / stop and runs the traffic for
40 s instead of 15 s, so the counters are read after the first 30 s
interval is published. Script B starts and clears FDR with the traffic
setup before the soak loop, and Script C reads and stops it around the
traffic stop, so the counters cover the whole soak. The single-unit
branches are unchanged.

Script A runs unused_lanes.sh off before the BER baseline. Nothing turns
the lanes back on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 22:50:25 +08:00
etwenandClaude Opus 5.5 319ee07de3 feat(fdr): Add blanton_fdr.sh for phydiag fdrstat
start / clear / rdcnt / stop send fdrstat STArt bin_group=both
Interval=30 / clear / Counters / STOp through bcmcmd on ports
'1-259,270-565', unit 0 then unit 1, and print the output as is. -u
picks one unit, -i sets the interval, -n is a dry run, FDR_PORTS
overrides the port list.

The STOp keyword is inferred from prbsstat STOp and has not been
checked on the bench.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 22:50:25 +08:00
etwenandClaude Opus 5.5 16da1c68f2 docs: Record V1.2.5 in Script A's history and add the release note
Script A: header to V1.2.5 / 2026-10-21; entries for
blanton_ber_debug.sh, retimer_lanes.sh, unused_lanes.sh, the PMON power
readback, the --force on the USB stress, the boot cycle title and the
fast boot cycle, with notes on p=p31 vs blanton_ber.sh's p=3, the
missing port 268, the double read in Script 4, the exec bits and the
EN_Cold_Warm_boot = 0 hang.

CLAUDE.md / ARCHITECTURE.md: status and release to V1.2.5, the new
scripts in the overview, the tree and the commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 09:01:55 +08:00
etwenandClaude Opus 5.5 f378340f41 feat(boot): Add a fast boot cycle and show the count in the title
5_1_Blanton_Script_Boot_Cycle_Fast.ttl is Script 5 with the traffic run
removed from Check Pt8; only 'blanton_traffic_linespeed ps' is left,
for a shorter cycle when the boot count is what matters.

Script 5 sets the window title to 'Reboot Cycle Test : n' or 'Power
Cycle Test : n' every round. Script B and Script 5 pass --force to
qfx5252-stress-usb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 09:01:55 +08:00
etwenandClaude Opus 5.5 fd2282d34b feat(pwr): Read switch-board rail power in every PMON snapshot
setup_pmon.ttl now calls TH6_SWB0/1_power_readback.sh after show
platform current, so Script A, B, C, 4 and 5 all log the 19 rails of
each switch board. Script 4 still calls both readbacks in its own loop
as well, so it reads them twice per round.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 09:01:55 +08:00
etwenandClaude Opus 5.5 aed2be66b2 feat(retimer): Add tools to turn off TX on unused lanes
retimer_lanes.sh turns TX off / on, or shows the state, for a lane map
of one Agera3 retimer on both the sys and the line side, by TX squelch
(default) or lane power-down. It refuses 'off' on lanes with RX PMD
lock unless --force is given, and reads the state back to print PASS
or FAIL.

unused_lanes.sh applies that to a built-in table of 14 retimer rows and
one direct-TH6 row (TSC31) on each switch board; TH6 rows go through
'port ... enable=' in the syncd container. --asic, --th6, --only and
--force select what it touches; it ends with ok / refused / failed
counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 09:01:55 +08:00
etwenandClaude Opus 5.5 b652ec8072 feat(ber): Add a raw BER run with p=p31 and sleep 40
blanton_ber_debug.sh runs the hand-pasted flow from tools/BER_Test.txt
as one command: prbs set p=p31, prbs get twice, prbsstat STArt
Interval=30, sleep 40, Ber, STOp, prbs clear. Every bcmcmd output is
printed as is under a timestamped header; there is no parsing, no
PASS/FAIL and no summary. -u 0 / -u 1 picks one switch unit, both by
default. The port list is the 200G ports without 268, as in
BER_Test.txt; BER_PORTS, BER_POLY, BER_INTERVAL and BER_WAIT can be
overridden. blanton_ber.sh is left unchanged.

BER_Test.txt: p=3 -> p=p31 (verified on the bench), plus a unit 1
block, a both-units block and port en=0/1 for every cabled port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131orciRKrejchsuDk6UpXk
2026-10-21 09:01:55 +08:00
etwenandClaude Opus 5.5 4db9b45ce7 docs: Record V1.2.4 in Script A's history and add the release note
Script A: header to V1.2.4 / 2026-10-01; entries for tray_id_stress.sh,
the Script A and Script B hooks, and 6_Blanton_Script_BER_Cycle.ttl,
with notes on the exec bit, the sleep-vs-Interval rule, the hard-coded
BDF, the hostname, the SONiC-only fan setting and the placeholder
password.

CLAUDE.md: status and last release to V1.2.4; the Tray ID stress and the
BER cycle in the overview; a commands block for tray_id_stress.sh; a
gotcha that prbsstat Ber must be read after the first interval is
published, and that Script A / C's own BER (Interval=30, sleep 30) sits
on that edge and has not been verified.

ARCHITECTURE.md: Script A ref and the tag checkbox to V1.2.4; Script 5's
current file name and the new macro 6 in the tree; tray_id_stress.sh in
the tree.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd
2026-10-01 13:32:14 +08:00
etwenandClaude Opus 5.5 7937ade30e feat(ttl): Add the Diag / SONiC BER cycle macro
6_Blanton_Script_BER_Cycle.ttl is a standalone macro, not part of A/B/C.
Each cycle measures PRBS BER on unit 0 in the Diag OS, cold-boots into
SONiC by writing the CB FPGA, measures again, and cold-boots back; while
1, no end. The boot target is chosen in the BIOS Boot Manager ("USB
Device" = Diag, "Hard Drive" = SONiC) and confirmed by the boot
signature. The log goes to Logs\Blanton_BER_Cycle_<ts>.log.

prbsstat runs with Interval=30 and the BER is read after sleep 40. The
sleep has to be longer than the interval: checked against the error
counts 'prbs get' reports in the same cycle, sleep 10 read Diag ~60x and
SONiC ~40x low, and sleep 30 still read Diag ~60x low because its Ber is
sent 30.15 s after STArt, before the first interval is published.
Interval=30 + sleep 40 matched on both sides over 73 cycles.

Known limits: the SONiC -> Diag boot writes a hard-coded BDF
(0000:05:00.0); the prompts assume the hostname 'sonic'; the fan is set
to 30 % on the SONiC side only; the password is the placeholder.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd
2026-10-01 13:32:14 +08:00
etwenandClaude Opus 5.5 ebb2260798 feat(i2c): Add a Tray ID I2C stress and run it in Script A and B
tray_id_stress.sh writes 0xA5 and 0x5A to register 0x02 of device 0x70
on buses 34, 35, 38 and 39, reading each back and comparing. The two
patterns put every bit in both states. It prints one PASS / FAIL / ERROR
line per step and a per-bus Summary with a single RESULT line; exit 0 is
all PASS, 1 is any FAIL or I2C error, 2 is bad arguments. FAIL (wrong
value read) and ERROR (i2cset / i2cget failed) are counted apart.

The original value is read first and written back at the end, verified
by a read; -R skips that, -n N repeats the sequence. Buses, address,
register and patterns are editable at the top of the file.

Script A runs one pass after show_dmesg as the baseline. Script B runs
one pass in every soak round, before the sleep 60.

The script is called by path and needs the exec bit on the DUT.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd
2026-10-01 13:32:14 +08:00
etwenandClaude Opus 5.5 1d3fb4f929 docs: Record V1.2.3 in Script A's history and add the release note
Script A: header to V1.2.3 / 2026-09-23; five entries under V1.2.3 for
setup_pmon.ttl, ddr5_temp.sh, hsc_temp_readback.sh, avt_pmpower.sh and
Script 4, with notes on the ~4 s per snapshot, the exec bit, the CRLF in
hsc_temp_readback.sh v1.0.0 and AVT not being shipped.

CLAUDE.md: status to V1.2.3; the PMON temperatures and Script 4's CPU
power in the overview; a commands block for the three new scripts; fix
the stale Script 5 file name and the "last release V1.1.5" line.

ARCHITECTURE.md: Script A ref to V1.2.3; the three scripts in the tree
and in setup_pmon's comment; avt_pmpower.sh in Script 4's row; the git
tag checkbox to V1.2.3.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd
2026-09-23 14:44:07 +08:00
etwenandClaude Opus 5.5 0ad76ea8b0 feat(pwr): Log AMD CPU package power in the Script 4 loop
avt_pmpower.sh runs AVTCMD -module pmm "get_pmdata()" and summarizes
SktPwr, PPT Fast / Slow against their limits, and MemPwr. -p takes the
AVTCMD path, -q drops the raw PM table. Exit 2 = AVTCMD missing,
3 = AVTCMD failed, 4 = nothing parsed. The values are SMU telemetry, not
a measurement.

Script 4 calls it every round after the two TH6_SWB power readbacks, so
switch rails and CPU package power sit side by side in each sample.

AVT is under NDA and not shipped in Blanton_Script. It has to be
unpacked on the DUT at ~/AVT_Linux_NDA_2.8.37/ beforehand; otherwise the
call exits 2 each round and the loop continues without the reading.
Without -q the full PM table is logged once a minute.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd
2026-09-23 14:43:28 +08:00
etwenandClaude Opus 5.5 4ce4d6c62e feat(temp): Add DDR5 DIMM and hot-swap controller temperatures to PMON
ddr5_temp.sh reads the SPD5118 hub on each DDR5 DIMM (i2c bus 5,
0x50/0x51, register 0x31: bit[12:2], sign bit 12, 0.25 C/LSB). A failed
read prints 'read fail' instead of a number. Bus and addresses can be
passed as arguments.

hsc_temp_readback.sh reads the LTC4287 hot-swap controllers on i2c bus
28: HSC_MAIN @ 0x40 and HSC_STBY @ 0x45, internal and external sensor
each, selected through 0xF3 and read from 0x8D (Kelvin). v1.0.1 adds the
header, corrects the delay comments (DELAY is 0.5 s, not 100 ms) and
converts the file from CRLF to LF - CRLF fails outright under bash on
SONiC.

utils/setup_pmon.ttl calls both right after 'show platform temperature'.
It is shared, so every PMON snapshot gets them: Script A's baseline,
each Script B soak round, Script C, the Script 4 loop and every Script 5
check point. hsc_temp_readback.sh adds ~4 s to each snapshot.

Both are called by path and need the exec bit on the DUT.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd
2026-09-23 14:43:28 +08:00
29 changed files with 4777 additions and 30 deletions
+17 -6
View File
@@ -161,7 +161,9 @@ Blanton_TTL_Script/
└── Script_ABC_Blanton/ # ← Tera Term 的工作目錄(整包給測試員) └── Script_ABC_Blanton/ # ← Tera Term 的工作目錄(整包給測試員)
│ │
├── 4_Blanton_Script_thermal_safety.ttl # 熱 / 安規:獨立跑,不接 A→B→C ├── 4_Blanton_Script_thermal_safety.ttl # 熱 / 安規:獨立跑,不接 A→B→C
├── 5_Blanton_Script_Reboot_Cycle.ttl # 重開機循環:獨立跑,while 1 無止境(未上機驗證) ├── 5_Blanton_Script_Boot_Cycle.ttl # 開機循環(warm / cold,EN_Cold_Warm_boot):獨立跑,while 1 無止境
├── 5_1_Blanton_Script_Boot_Cycle_Fast.ttl # 同 Script 5,但 Check Pt8 只跑 traffic ps(不打流量),循環較短
├── 6_Blanton_Script_BER_Cycle.ttl # Diag ↔ SONiC 冷開機循環,兩邊各量一次 unit 0 BER:獨立跑,while 1
├── config.ttl # 全域設定:testcase 名、EN_Margin / EN_TX_FIR / EN_log / EN_timestamp、 ├── config.ttl # 全域設定:testcase 名、EN_Margin / EN_TX_FIR / EN_log / EN_timestamp、
│ # 風扇與 SWB 宣告、SSD/USB/BMC_USB 壓力秒數、三個 prompt 字串 │ # 風扇與 SWB 宣告、SSD/USB/BMC_USB 壓力秒數、三個 prompt 字串
├── hammer/ # 🚫 gitignored — mlucas ELF binary(~99 MB),DUT image 自帶, ├── hammer/ # 🚫 gitignored — mlucas ELF binary(~99 MB),DUT image 自帶,
@@ -174,6 +176,7 @@ Blanton_TTL_Script/
│ ├── pcie_bus.ttl # lspci -tvvv / -vv │ ├── pcie_bus.ttl # lspci -tvvv / -vv
│ ├── setup_pmon.ttl # show platform summary/fan/temperature/psustatus/voltage/ │ ├── setup_pmon.ttl # show platform summary/fan/temperature/psustatus/voltage/
│ │ # current/ssdhealth/leak status/leak channels + TPM(11 項) │ │ # current/ssdhealth/leak status/leak channels + TPM(11 項)
│ │ # V1.2.3 起 + ddr5_temp.sh + hsc_temp_readback.sh
│ ├── show_dmesg.ttl # dmesg -T 合併 error 正則 + i2c 過濾 + dmesg -C 清空 │ ├── show_dmesg.ttl # dmesg -T 合併 error 正則 + i2c 過濾 + dmesg -C 清空
│ ├── show_margin_status.ttl # source margin_status_all.sh(掃 9 顆 LTC2980) │ ├── show_margin_status.ttl # source margin_status_all.sh(掃 9 顆 LTC2980)
│ ├── kill_all_process.ttl # kill $(jobs -p) │ ├── kill_all_process.ttl # kill $(jobs -p)
@@ -203,6 +206,8 @@ Blanton_TTL_Script/
│ # ⚠️ V1.1.9 起 A/B/C 內註解掉的呼叫已整段刪除,只剩手動執行 │ # ⚠️ V1.1.9 起 A/B/C 內註解掉的呼叫已整段刪除,只剩手動執行
├── blanton_ber.sh # 全機 SerDes BER 掃描(phydiag prbs / prbsstat) ├── blanton_ber.sh # 全機 SerDes BER 掃描(phydiag prbs / prbsstat)
│ # V1.2.2 起含 port 268(100G ce0),summary 每 unit 分 200G/100G/TOTAL │ # V1.2.2 起含 port 268(100G ce0),summary 每 unit 分 200G/100G/TOTAL
├── blanton_ber_debug.sh # BER 原始輸出(p=p31、sleep 40、-u 0|1),不判定
├── blanton_fdr.sh # FDR 統計(phydiag fdrstat start/clear/Counters/STOp),A/B/C 夾住流量
├── bcm_100g_dsc_cycle.sh # 100G link down/up 循環 + 每輪 DSC 與 retimer TX/RX 讀回(未驗證) ├── bcm_100g_dsc_cycle.sh # 100G link down/up 循環 + 每輪 DSC 與 retimer TX/RX 讀回(未驗證)
├── bcm_dsc_scan.sh # 全機 SerDes DSC dump(phydiag <port> dsc,~445 port × 2 unit) ├── bcm_dsc_scan.sh # 全機 SerDes DSC dump(phydiag <port> dsc,~445 port × 2 unit)
│ # 由 EN_TX_FIR 控制,A 與 C 各掃一次;單次約 10 分鐘 │ # 由 EN_TX_FIR 控制,A 與 C 各掃一次;單次約 10 分鐘
@@ -210,11 +215,17 @@ Blanton_TTL_Script/
├── blanton_multiphase_margin.sh # 多相 VRM margin(原生 i2c,38 條軌) ├── blanton_multiphase_margin.sh # 多相 VRM margin(原生 i2c,38 條軌)
├── pwr_brick.sh # PDB / CPB power brick 讀值(VI2C ch4) ├── pwr_brick.sh # PDB / CPB power brick 讀值(VI2C ch4)
├── nfc_polling.sh # NFC tag 背景輪詢 + PASS/FAIL 統計 ├── nfc_polling.sh # NFC tag 背景輪詢 + PASS/FAIL 統計
├── blantons_nfc_validate.py # NFC/NCI 驗證工具(廠商提供,未修改) ├── blantons_nfc_validate.py # NFC/NCI 驗證工具(廠商提供,未修改;V1.2.7 起為 v2.5)
├── blanton_tr518.sh # TR518 封包測試,量功耗前的負載來源 ├── blanton_tr518.sh # TR518 封包測試,量功耗前的負載來源
├── TH6_SWB0_power_readback.sh # SWB0 19 條軌 V×I + 總功耗 ├── TH6_SWB0_power_readback.sh # SWB0 19 條軌 V×I + 總功耗
├── TH6_SWB1_power_readback.sh # SWB1 同上 ├── TH6_SWB1_power_readback.sh # SWB1 同上
│ # ⚠️ 已納入交付,但 A/B/C 的呼叫仍註解掉(bring-up 中) │ # V1.2.5 起由 utils/setup_pmon.ttl 呼叫,每個 PMON 快照都有
├── ddr5_temp.sh # DDR5 DIMM 溫度(SPD5118 @ i2c-5 0x50/0x51,reg 0x31)
├── hsc_temp_readback.sh # LTC4287 HSC 溫度(i2c-28 0x40/0x45,內/外部感溫)
├── avt_pmpower.sh # AMD CPU 封裝功耗(AVTCMD pmm get_pmdata;AVT 是 NDA,不隨包)
├── tray_id_stress.sh # Tray ID I2C stress(bus 34/35/38/39 0x70 reg 0x02,寫 0xA5/0x5A 讀回)
├── retimer_lanes.sh # 單顆 Agera3 retimer 的 lane TX off/on/status(sys + line side)
├── unused_lanes.sh # 依內建表把沒接線的 retimer lane / TH6 port 關掉(呼叫 retimer_lanes.sh)
├── usb_target.sh # 偵測 USB 裝置節點/掛載點(排除系統碟) ├── usb_target.sh # 偵測 USB 裝置節點/掛載點(排除系統碟)
├── bmc_monitor.sh # BMC 監控:free -m + I2C 寫入/讀回圖樣測試 ├── bmc_monitor.sh # BMC 監控:free -m + I2C 寫入/讀回圖樣測試
├── bmc_monitor_ddr.sh # ⚠️ 已停用:V1.1.9 起 B/C 內的註解區塊已刪除,DDR 壓力走 bgctl + bmc-manager ├── bmc_monitor_ddr.sh # ⚠️ 已停用:V1.1.9 起 B/C 內的註解區塊已刪除,DDR 壓力走 bgctl + bmc-manager
@@ -377,10 +388,10 @@ PROFILE_CHANNELS=( "0:high:8" "1:low:8" ... ) # "channel:operation:change_perc
| 模組 | 進入點 | 功能 | | 模組 | 進入點 | 功能 |
|------|--------|------| |------|--------|------|
| **Script A(Pre-test)** | `1_Blanton_Script_A.ttl` V1.2.2 | root 登入 → `date -s` 對時 → 清 job log → **收掉前一輪殘留**(`hw-test-session finish` → `bgctl reset --yes` → `bgctl stop --all` → `bgctl list` 確認清空)→ `hw-test-session start` → **設定風扇轉速** → **等資料面就緒**(`wait_init.ttl`)→ DUT 清單(boot/version/fwutil/syseeprom/ssdhealth/TPM/NVMe)→ BMC enroll + version/status → source bash 工具 → 清/讀 7 組 PCIe AER + `ras-mc-ctl --summary` → `lspci` → margin → PMON → dmesg → **10G/1G 管理網路 ping** → **NFC 基線**(start → 30s → stop → report)→ 100G uplink 設定與狀態 → **BER 基線掃描**(依 `SWB_UNIT`,V1.2.1 新增)→ **一輪流量基線** → **SerDes DSC 基線**(`EN_TX_FIR`)→ `show uptime` | | **Script A(Pre-test)** | `1_Blanton_Script_A.ttl` V1.2.7 | root 登入 → `date -s` 對時 → 清 job log → **收掉前一輪殘留**(`hw-test-session finish` → `bgctl reset --yes` → `bgctl stop --all` → `bgctl list` 確認清空)→ `hw-test-session start` → **設定風扇轉速** → **等資料面就緒**(`wait_init.ttl`)→ DUT 清單(boot/version/fwutil/syseeprom/ssdhealth/TPM/NVMe)→ BMC enroll + version/status → source bash 工具 → 清/讀 7 組 PCIe AER + `ras-mc-ctl --summary` → `lspci` → margin → PMON → dmesg → **10G/1G 管理網路 ping** → **NFC 基線**(start → 30s → stop → report)→ 100G uplink 設定與狀態 → **`unused_lanes.sh off`**(V1.2.6)→ **BER 基線掃描**(依 `SWB_UNIT`,V1.2.1 新增)→ **一輪流量基線**(V1.2.6 起兩 unit 時夾 FDR,sleep 40) → **SerDes DSC 基線**(`EN_TX_FIR`)→ `show uptime` |
| **Script B(Stress)** | `2_Blanton_Script_B.ttl` | **V1.1.8 起 `mlucas-avx2 -cpu 0:15` 由 `systemd-run --unit=mlucas-amm`(`Type=exec`、`Restart=always`)啟動,不再是 shell 的 `&` 背景 job** + `bgctl run` 的 `memtester` / SSD / USB 壓力(v1.1.7 起 SSD/USB 的 `--runtime`/`--passes` 讀 `config.ttl` 的 `SSD_RUNTIME`/`SSD_COUNT`、`USB_RUNTIME`/`USB_COUNT`;BMC memtester 不帶次數 = 跑到被停) + BMC DDR(`bmc-manager run memtester`)→ BMC USB net test(探測 cdc_ncm 介面,`systemd-run` 掛 `BMC_USB_RUNTIME` 秒的 ping,V1.1.8 前寫死 4 小時)→ 啟動 mgmt ping 監控 → **啟動 NFC 輪詢** → `jobs` / `systemctl is-active mlucas-amm` / `bgctl list` → traffic(依 `SWB_UNIT`)→ `while 1` 每輪 PMON + `bgctl list`/`jobs`/`systemctl is-active mlucas-amm` + `sleep 60`(**V1.1.4 起 margin 不在迴圈內**;V1.2.0 起等待走 DUT 端 `sleep` 而非 macro 端 `pause`)| | **Script B(Stress)** | `2_Blanton_Script_B.ttl` | **V1.1.8 起 `mlucas-avx2 -cpu 0:15` 由 `systemd-run --unit=mlucas-amm`(`Type=exec`、`Restart=always`)啟動,不再是 shell 的 `&` 背景 job** + `bgctl run` 的 `memtester` / SSD / USB 壓力(v1.1.7 起 SSD/USB 的 `--runtime`/`--passes` 讀 `config.ttl` 的 `SSD_RUNTIME`/`SSD_COUNT`、`USB_RUNTIME`/`USB_COUNT`;BMC memtester 不帶次數 = 跑到被停) + BMC DDR(`bmc-manager run memtester`)→ BMC USB net test(探測 cdc_ncm 介面,`systemd-run` 掛 `BMC_USB_RUNTIME` 秒的 ping,V1.1.8 前寫死 4 小時)→ 啟動 mgmt ping 監控 → **啟動 NFC 輪詢** → `jobs` / `systemctl is-active mlucas-amm` / `bgctl list` → traffic(依 `SWB_UNIT`)→ `while 1` 每輪 PMON + `bgctl list`/`jobs`/`systemctl is-active mlucas-amm` + `sleep 60`(**V1.1.4 起 margin 不在迴圈內**;V1.2.0 起等待走 DUT 端 `sleep` 而非 macro 端 `pause`)|
| **Script C(Post-test)** | `3_Blanton_Script_C.ttl` | `kill $(jobs -p)` + **`systemctl stop mlucas-amm`**(systemd unit 不是 shell job,`jobs -p` 抓不到)+ `bgctl stop --all` / `reset` + 停 BMC USB unit、mgmt ping 與 **NFC 輪詢** → PMON + dmesg → 7 組 AER + `ras-mc-ctl` → BMC USB `journalctl` **寫進 `log/bmc_usb_net.log`**(不再印在 console) → `ip -s link show eth0/eth1` → `cat` mlucas log(並 `cp` 進 job 目錄一起帶走)→ **NFC `report`** → traffic `stop` + `report` → **SerDes DSC 收尾**(`EN_TX_FIR`)→ **BER 掃描**(依 `SWB_UNIT`)→ NVMe 健康 → `show reboot-cause` → **margin 掃描**(`EN_Margin`,V1.1.4 由 Script B 移來)→ `uptime` → **job log 複製到 USB(帶時戳)** → `exit` + wait『Script done』→ `hw-test-session finish` | | **Script C(Post-test)** | `3_Blanton_Script_C.ttl` | `kill $(jobs -p)` + **`systemctl stop mlucas-amm`**(systemd unit 不是 shell job,`jobs -p` 抓不到)+ `bgctl stop --all` / `reset` + 停 BMC USB unit、mgmt ping 與 **NFC 輪詢** → PMON + dmesg → 7 組 AER + `ras-mc-ctl` → BMC USB `journalctl` **寫進 `log/bmc_usb_net.log`**(不再印在 console) → `ip -s link show eth0/eth1` → `cat` mlucas log(並 `cp` 進 job 目錄一起帶走)→ **NFC `report`** → traffic `stop` + `report` → **SerDes DSC 收尾**(`EN_TX_FIR`)→ **BER 掃描**(依 `SWB_UNIT`)→ NVMe 健康 → `show reboot-cause` → **margin 掃描**(`EN_Margin`,V1.1.4 由 Script B 移來)→ `uptime` → **job log 複製到 USB(帶時戳)** → `exit` + wait『Script done』→ `hw-test-session finish` |
| **Script 4(Thermal / Safety)** | `4_Blanton_Script_thermal_safety.ttl` | **獨立腳本,不接 A→B→C。** Script A 式的環境建立(登入 / session / 風扇 / `wait_init` / DUT 清單 / BMC / PCIe 清除 / `pcie_bus` / PMON / dmesg)→ **滿載**(`mlucas-avx2 -cpu 0:15`,V1.1.8 起與 Script B 同樣掛成 `mlucas-amm` systemd unit + `blanton_tr518.sh start`)→ `while 1`:PMON + `TH6_SWB0/1_power_readback.sh` + `bgctl list` / `jobs` / `systemctl is-active mlucas-amm`,`pause 60`。**沒有收尾段** —— 中斷後 DUT 仍在 `port cd lb=mac` / `l2 learn off` / `test mode nr=yes`,且 CPU 仍滿載,要手動 `blanton_tr518.sh stop` + `systemctl stop mlucas-amm` | | **Script 4(Thermal / Safety)** | `4_Blanton_Script_thermal_safety.ttl` | **獨立腳本,不接 A→B→C。** Script A 式的環境建立(登入 / session / 風扇 / `wait_init` / DUT 清單 / BMC / PCIe 清除 / `pcie_bus` / PMON / dmesg)→ **滿載**(`mlucas-avx2 -cpu 0:15`,V1.1.8 起與 Script B 同樣掛成 `mlucas-amm` systemd unit + `blanton_tr518.sh start`)→ `while 1`:PMON + `TH6_SWB0/1_power_readback.sh` + `avt_pmpower.sh`(CPU 封裝功耗,V1.2.3)+ `bgctl list` / `jobs` / `systemctl is-active mlucas-amm`,`pause 60`。**沒有收尾段** —— 中斷後 DUT 仍在 `port cd lb=mac` / `l2 learn off` / `test mode nr=yes`,且 CPU 仍滿載,要手動 `blanton_tr518.sh stop` + `systemctl stop mlucas-amm` |
| **Script 5(Reboot Cycle)** | `5_Blanton_Script_Reboot_Cycle.ttl` | **獨立腳本,不接 A→B→C。** `while 1`:登入 → `sudo -i` → 對時 → 風扇 → **Check Pt1~Pt13**(DUT/BMC info、mgmt ping、NFC、SSD、USB、BMC USB、port status + 15s traffic、BER、NVMe、platform data、dmesg i2c、PCIe error counters)→ `show uptime` → `reboot` → `wait "Booting in blind mode"`。`cnt_cycle` 每輪 +1 印在標頭。**沒有結束條件** —— 要停就關掉 Tera Term 的 macro。**尚未上機驗證** | | **Script 5(Reboot Cycle)** | `5_Blanton_Script_Reboot_Cycle.ttl` | **獨立腳本,不接 A→B→C。** `while 1`:登入 → `sudo -i` → 對時 → 風扇 → **Check Pt1~Pt13**(DUT/BMC info、mgmt ping、NFC、SSD、USB、BMC USB、port status + 15s traffic、BER、NVMe、platform data、dmesg i2c、PCIe error counters)→ `show uptime` → `reboot` → `wait "Booting in blind mode"`。`cnt_cycle` 每輪 +1 印在標頭。**沒有結束條件** —— 要停就關掉 Tera Term 的 macro。**尚未上機驗證** |
| **SWB loopback 流量** | `blanton_traffic_linespeed <sub> [-u 0\|1\|all]` | `init`(VLAN 30..137,成對 `cdN`/`cdN+32`)→ `clear` → `start`(`tx 200 length=324 PatternRandom=yes`,v0.7.0 起)→ `stop` → `report`(per-pair TX/RX 交叉比對 PASS/FAIL);另有 `ps`(link/speed)與 `run`(一條龍)。**V0.6.0 起含 100G uplink `ce0`**(VLAN 138):它沒有 loopback 對象,靠 **ingress mirror 打回自己**維持循環,`report` 最後一列就是它,底下再接一份跨 unit summary | | **SWB loopback 流量** | `blanton_traffic_linespeed <sub> [-u 0\|1\|all]` | `init`(VLAN 30..137,成對 `cdN`/`cdN+32`)→ `clear` → `start`(`tx 200 length=324 PatternRandom=yes`,v0.7.0 起)→ `stop` → `report`(per-pair TX/RX 交叉比對 PASS/FAIL);另有 `ps`(link/speed)與 `run`(一條龍)。**V0.6.0 起含 100G uplink `ce0`**(VLAN 138):它沒有 loopback 對象,靠 **ingress mirror 打回自己**維持循環,`report` 最後一列就是它,底下再接一份跨 unit summary |
| **FPGA 暫存器存取** | `cb_fpga <fn> <addr> [data]`、`fpga_rescan` | pcimem 打 `resource0` + BAR 相對 offset,32-bit word;BDF 於 source 時自動偵測;`pmc/icb/swb0/swb1_fpga` 走 VSPI 窗口 | | **FPGA 暫存器存取** | `cb_fpga <fn> <addr> [data]`、`fpga_rescan` | pcimem 打 `resource0` + BAR 相對 offset,32-bit word;BDF 於 source 時自動偵測;`pmc/icb/swb0/swb1_fpga` 走 VSPI 窗口 |
@@ -808,7 +819,7 @@ margin status、全部 VRM 軌的 Vin/Vout/Iout/Temp、CB + ICB 溫感讀值,
- [ ] `CHANGELOG.md`:延續三支腳本頂端的 Version History,集中成一份 - [ ] `CHANGELOG.md`:延續三支腳本頂端的 Version History,集中成一份
- [ ] 三支腳本的 header 版號與 `CHANGELOG.md` 對齊,`config.ttl` 加 `script_version` 並寫進 log 開頭 - [ ] 三支腳本的 header 版號與 `CHANGELOG.md` 對齊,`config.ttl` 加 `script_version` 並寫進 log 開頭
- [ ] `docs/TTL_Script_Blanton_Status_*.xlsx` 更新為全 OK,或把剩餘項目移進 Future Extensions - [ ] `docs/TTL_Script_Blanton_Status_*.xlsx` 更新為全 OK,或把剩餘項目移進 Future Extensions
- [x] 打 git tag,push `nas` + `gitea`(已至 `V1.2.2`;`publish/` 依 Script A 檔頭版號打包) - [x] 打 git tag,push `nas` + `gitea`(已至 `V1.2.7`;`publish/` 依 Script A 檔頭版號打包)
**驗收條件:** 從 zip 解壓到一台乾淨的測試 NB,照 README 操作,不看原始碼就能完成一輪 A→B→C **驗收條件:** 從 zip 解壓到一台乾淨的測試 NB,照 README 操作,不看原始碼就能完成一輪 A→B→C
並產出 summary;`publish/` 內容與 git tag 一致。 並產出 summary;`publish/` 內容與 git tag 一致。
+58 -4
View File
@@ -9,7 +9,7 @@ DUT 端的取數能力由一組 **bash 工具庫** 提供(CB FPGA `pcimem` →
完整架構見 [ARCHITECTURE.md](ARCHITECTURE.md)。 完整架構見 [ARCHITECTURE.md](ARCHITECTURE.md)。
**目前狀態(2026-09-15)**:Script A 為 **V1.2.2**(A 集中記錄所有 TTL 的變更)。涵蓋 **目前狀態(2026-10-22)**:Script A 為 **V1.2.7**(A 集中記錄所有 TTL 的變更)。涵蓋
PCIe AER / DDR EDAC / PMON+TPM / 電壓 margin(9 顆 LTC2980)/ SWB loopback 線速流量 / PCIe AER / DDR EDAC / PMON+TPM / 電壓 margin(9 顆 LTC2980)/ SWB loopback 線速流量 /
10G+1G 管理網路 ping / BMC DDR 與 USB / NVMe 健康,壓力層走平台的 `bgctl`。 10G+1G 管理網路 ping / BMC DDR 與 USB / NVMe 健康,壓力層走平台的 `bgctl`。
switch unit 數量由 `config.ttl` 的 `SWB_UNIT0` / `SWB_UNIT1` 宣告,風扇轉速由 `FAN_SPEED` 指定 switch unit 數量由 `config.ttl` 的 `SWB_UNIT0` / `SWB_UNIT1` 宣告,風扇轉速由 `FAN_SPEED` 指定
@@ -33,12 +33,25 @@ Script A 開頭會先收掉前一輪殘留(`hw-test-session finish` + `bgctl r
再 `bgctl list` 確認沒有 job 留著佔資源。 再 `bgctl list` 確認沒有 job 留著佔資源。
NFC tag 讀取由 `nfc_polling.sh` 背景輪詢(A 做基線、B 起、C 停並 report)。 NFC tag 讀取由 `nfc_polling.sh` 背景輪詢(A 做基線、B 起、C 停並 report)。
另有 **`4_Blanton_Script_thermal_safety.ttl`**(熱 / 安規,**獨立跑不接 A→B→C**,滿載後每分鐘 另有 **`4_Blanton_Script_thermal_safety.ttl`**(熱 / 安規,**獨立跑不接 A→B→C**,滿載後每分鐘
取 PMON + 兩片 SWB 的軌功耗;**沒有收尾段**,中斷後要手動 `blanton_tr518.sh stop`)。 取 PMON + 兩片 SWB 的軌功耗 + **AMD CPU 封裝功耗**(`avt_pmpower.sh`,V1.2.3);**沒有收尾段**,中斷後要手動 `blanton_tr518.sh stop`)。
以及 **`5_Blanton_Script_Reboot_Cycle.ttl`**(重開機循環,**獨立跑不接 A→B→C**:登入 → 風扇 → **V1.2.3 起 PMON 快照(`utils/setup_pmon.ttl`)多了 DDR5 DIMM 溫度(`ddr5_temp.sh`)與 LTC4287 HSC 溫度
(`hsc_temp_readback.sh`)**,A/B/C/4/5 全部吃到;HSC 那支每次約 +4 秒。
**V1.2.4 新增 Tray ID I2C stress(`tray_id_stress.sh`)**:Script A 跑一次當基線、Script B 每輪 soak 跑一次。
另新增 **`6_Blanton_Script_BER_Cycle.ttl`**(Diag ↔ SONiC 冷開機循環量 BER,**獨立跑不接 A→B→C**),
操作與分析見 `tmp/BER_Test_Cycle/runbook.md`(tmp 不進 git)。
**V1.2.5 起 PMON 快照也帶兩片 SWB 的軌功耗**(`TH6_SWB{0,1}_power_readback.sh` 搬進 `setup_pmon.ttl`),
⚠️ Script 4 迴圈原本就自己讀一次,現在**每輪讀兩次**。V1.2.5 另有 `blanton_ber_debug.sh`(BER 原始輸出、`p=p31`、`sleep 40`)、
`retimer_lanes.sh` / `unused_lanes.sh`(把沒接線的 retimer lane / TH6 port 關 TX),以及
`5_1_Blanton_Script_Boot_Cycle_Fast.ttl`(Script 5 拿掉流量那段,只留 `ps`)。
**V1.2.6 起 FDR 統計(`blanton_fdr.sh`,`phydiag fdrstat`)接進流量**:A 包住流量基線(sleep 15→40)、
B 在 soak 前 start、每輪 rdcnt、C 收尾 rdcnt + stop,**只在兩個 unit 都開時才跑**。Script A 另在 BER 前先 `unused_lanes.sh off`,
⚠️ **沒有任何地方再 `on` 回來**。
**V1.2.7**:`blanton_fdr.sh` 預設 port 改成只含有接線的 port(同 traffic 的 `TL_PS_PORTS`,不含 268);`blantons_nfc_validate.py` 換成客戶 v2.5(`qfx5252-nfc-validate` 改名,`nfc_polling.sh` 不用改);另新增 `4_1_Blanton_Script_thermal.ttl`(Script 4 + 300 輪 idle + `blanton_tr518_thermal.sh`)、`blanton_multiphase_read.sh`(多相 VRM 讀值含 hex)、交付包內的 `Script_User_Guide.md`(測試員手冊)——**三支 script 皆未上機驗證**。
以及 **`5_Blanton_Script_Boot_Cycle.ttl`**(重開機循環,**獨立跑不接 A→B→C**:登入 → 風扇 →
Check Pt1~Pt13 → `reboot` → `wait "Booting in blind mode"`,`cnt_cycle` 每輪遞增,`while 1` 無止境, Check Pt1~Pt13 → `reboot` → `wait "Booting in blind mode"`,`cnt_cycle` 每輪遞增,`while 1` 無止境,
要停就關 Tera Term 的 macro)。**尚未上機驗證**。 要停就關 Tera Term 的 macro)。**尚未上機驗證**。
流程圖:`docs/Blanton_Test_Flow.drawio`。 流程圖:`docs/Blanton_Test_Flow.drawio`。
最後一次發布是 **V1.1.5**;SWB 的 I2C 通道與位址已於 2026-08-19 上機驗證。 最後一次發布是 **V1.2.7**;SWB 的 I2C 通道與位址已於 2026-08-19 上機驗證。
margin 的 `VNOM` 已於 2026-08-30 改為 Blanton 實測中位數(144 條軌中 86 條上調 0.8~2.5%)。 margin 的 `VNOM` 已於 2026-08-30 改為 Blanton 實測中位數(144 條軌中 86 條上調 0.8~2.5%)。
交付用 `./publish/publish.sh` 打包。 交付用 `./publish/publish.sh` 打包。
@@ -129,6 +142,21 @@ bash ~/Blanton_Script/port_prbs_monitor.sh report # PASS/FAIL 統計(沒
bash ~/Blanton_Script/port_prbs_monitor.sh stop # 收尾會跑 prbsstat STOp + prbs clear bash ~/Blanton_Script/port_prbs_monitor.sh stop # 收尾會跑 prbsstat STOp + prbs clear
# ⚠️ PRBS 打起來時 link 會顯示 down,這是正常的 —— 所以 start 刻意不印 port status # ⚠️ PRBS 打起來時 link 會顯示 down,這是正常的 —— 所以 start 刻意不印 port status
# ── 溫度 / CPU 功耗(V1.2.3,已接進 PMON / Script 4)──
~/Blanton_Script/ddr5_temp.sh # DDR5 DIMM 溫度(SPD5118,預設 bus 5, 0x50 0x51)
~/Blanton_Script/ddr5_temp.sh 5 0x50 # 指定 bus / 位址
~/Blanton_Script/hsc_temp_readback.sh # LTC4287 HSC_MAIN(0x40)/HSC_STBY(0x45) 內外部溫度,bus 28,約 4 秒
~/Blanton_Script/avt_pmpower.sh -p ~/AVT_Linux_NDA_2.8.37/AVTCMD # CPU SktPwr / PPT / MemPwr
~/Blanton_Script/avt_pmpower.sh -q -p ... # 只印摘要,不倒整張 PM table
# ⚠️ AVT 是 NDA,不在交付包裡:DUT 上要先解壓到 ~/AVT_Linux_NDA_2.8.37/,沒有就每輪 exit 2
# ⚠️ 數值是 SMU telemetry 不是量測,要準就對照 VR 的 PMBus READ_POUT
# ── Tray ID I2C stress(V1.2.4,Script A / B 已接)────
~/Blanton_Script/tray_id_stress.sh # bus 34/35/38/39,0x70 reg 0x02:寫 0xA5/0x5A 讀回比對 → Summary
~/Blanton_Script/tray_id_stress.sh -n 100 # 重複 100 輪
~/Blanton_Script/tray_id_stress.sh -R # 跑完不還原(預設會寫回原值並讀回確認)
# exit 0 = 全 PASS、1 = 有 FAIL(讀回不符)或 ERROR(i2cset/i2cget 本身失敗)、2 = 參數錯
# ── PDB / CPB power brick 讀值 ────────────────────── # ── PDB / CPB power brick 讀值 ──────────────────────
./Blanton_Script/pwr_brick.sh show # Vin/Iin/Vout/Iout/Temp × 5 顆 ./Blanton_Script/pwr_brick.sh show # Vin/Iin/Vout/Iout/Temp × 5 顆
./Blanton_Script/pwr_brick.sh show -r # 多印 raw word ./Blanton_Script/pwr_brick.sh show -r # 多印 raw word
@@ -158,6 +186,27 @@ sleep 30 # 至少等一個 interval 再 rep
# -u 0 / -u 1 單邊;-c 1e-9 換門檻;-F 只列失敗;-f <log> 離線重解 # -u 0 / -u 1 單邊;-c 1e-9 換門檻;-F 只列失敗;-f <log> 離線重解
# ⚠️ 不能跟 blanton_traffic_linespeed / blanton_tr518 同時跑(都會接管同一批 port) # ⚠️ 不能跟 blanton_traffic_linespeed / blanton_tr518 同時跑(都會接管同一批 port)
# ── BER 原始輸出(V1.2.5,不判定、不 summary,TTL 未接)──
./Blanton_Script/blanton_ber_debug.sh # unit 0+1:set p=p31 → get×2 → STArt 30 → sleep 40 → Ber → STOp → clear
./Blanton_Script/blanton_ber_debug.sh -u 0 # 單一 unit
# 清單同 tools/BER_Test.txt,不含 268;BER_PORTS="...,268" 可加
# ⚠️ 這支是 p=p31(已上機驗證),blanton_ber.sh 仍是 p=3 —— 兩者量的碼型可能不同
# ── FDR 統計(V1.2.6,A/B/C 已接,只在 SWB_UNIT0=SWB_UNIT1=1)──
~/Blanton_Script/blanton_fdr.sh start # fdrstat STArt bin_group=both Interval=30,unit 0 → 1
~/Blanton_Script/blanton_fdr.sh clear # fdrstat clear
~/Blanton_Script/blanton_fdr.sh rdcnt # fdrstat Counters(Interval 結算後才讀,A 用 sleep 40)
~/Blanton_Script/blanton_fdr.sh stop # fdrstat STOp ⚠️ 關鍵字是類推的,未上機驗證
# -u 0|1 單邊;-i <sec> 改 Interval;-n dry-run。ports 預設同 traffic 的 TL_PS_PORTS(只含有接線的 port,不含 268;FDR_PORTS 可改)
# ── 沒接線的 retimer lane / TH6 port 關 TX(V1.2.5;V1.2.6 起 Script A 會 off,沒人 on 回來)──
./Blanton_Script/unused_lanes.sh status # 兩 unit 全部列出 rx_lock / tx_off
./Blanton_Script/unused_lanes.sh off [--asic 0] [--th6] # 預設 TX squelch;--th6 連 retimer 後面的 TH6 port 一起關
./Blanton_Script/unused_lanes.sh on
./Blanton_Script/retimer_lanes.sh 0 0x102 0xff status # 單顆 retimer:<asic> <addr> <lane_map> <off|on|status>
# ⚠️ lane 有 RX lock(有訊號進來)時 off 會被拒絕(exit 2),--force 才會硬關
# ⚠️ unused_lanes.sh 會檢查同目錄的 retimer_lanes.sh 有沒有 exec bit —— 兩支都要 chmod +x
# ── SerDes DSC 擷取(TX_FIR / RXFFE / DFE / EYE / SNR)── # ── SerDes DSC 擷取(TX_FIR / RXFFE / DFE / EYE / SNR)──
./Blanton_Script/bcm_dsc_scan.sh # unit 0+1 全掃,約 10 分鐘 ./Blanton_Script/bcm_dsc_scan.sh # unit 0+1 全掃,約 10 分鐘
./Blanton_Script/bcm_dsc_scan.sh -u 0 # 只掃一個 unit(時間減半) ./Blanton_Script/bcm_dsc_scan.sh -u 0 # 只掃一個 unit(時間減半)
@@ -346,6 +395,11 @@ Tera Term 連 COM port (115200-8-N-1)
- ⚠️ **`stress_hhmd.py` / `stress_pcie.py` 已於 2026-08-17 由 KC 移除**(Status 表 ScriptB #5/#7)。 - ⚠️ **`stress_hhmd.py` / `stress_pcie.py` 已於 2026-08-17 由 KC 移除**(Status 表 ScriptB #5/#7)。
Script B 現在是 **8 個背景 job**(1 mlucas + 5 mem + ssd + usb),不是 10 個。 Script B 現在是 **8 個背景 job**(1 mlucas + 5 mem + ssd + usb),不是 10 個。
I2C/PCIe 的持續讀取壓力目前沒有替代品。 I2C/PCIe 的持續讀取壓力目前沒有替代品。
- ⚠️ **`prbsstat Ber` 要等第一個 interval 結算之後才讀:sleep 必須「大於」Interval**(2026-09-30 驗證)。
`6_Blanton_Script_BER_Cycle.ttl` 用 `Interval=30` + `sleep 40`。拿同一輪 `prbs get` 的錯誤數交叉比對:sleep 10 時 Diag 低 ~60×、
SONiC 低 ~40×;sleep 30(= Interval)時 Diag 仍低 ~60×(Ber 在 STArt 後 30.15 s 送出,剛好在結算前)。
⚠️ **Script A / C 的 BER 也是 `blanton_ber.sh start`(Interval=30)→ TTL `sleep 30` → `report`**,跑在 SONiC 上 —— 正是「sleep = Interval」的邊界情況,
能不能趕上第一個 interval 結算**未驗證**。建議改成 `sleep 40`(或 `BER_INTERVAL` 調小),並用 `validate_prbsget.py` 的方法驗證一次
- ⚠️ **`pause` 是停 macro,`sleep` 是停 DUT**(V1.2.0 起 A/B/C 一律用後者):`pause N` 期間 macro 不理會 - ⚠️ **`pause` 是停 macro,`sleep` 是停 DUT**(V1.2.0 起 A/B/C 一律用後者):`pause N` 期間 macro 不理會
DUT,shell 是閒著的,等於用猜的估上一個指令跑多久;`sendln "sleep N"` + `wait prompt_sonic_root` DUT,shell 是閒著的,等於用猜的估上一個指令跑多久;`sendln "sleep N"` + `wait prompt_sonic_root`
把等待放到 DUT 上,prompt 回來才繼續,兩邊不會走散,而且這一段會帶時戳進 log。 把等待放到 DUT 上,prompt 回來才繼續,兩邊不會走散,而且這一段會帶時戳進 log。
+53
View File
@@ -0,0 +1,53 @@
# v1.2.3 — DIMM and hot-swap temperatures in every snapshot, and CPU power next to the switch rails
## ✨ New features
**Every PMON snapshot now reads DDR5 DIMM and hot-swap controller temperatures**
* `utils/setup_pmon.ttl` runs `ddr5_temp.sh` and `hsc_temp_readback.sh` right after `show platform temperature`. Because `setup_pmon` is shared, this lands everywhere a snapshot is taken: Script A's baseline, each Script B soak round, Script C, the Script 4 loop and every Script 5 check point.
* `ddr5_temp.sh` reads the SPD5118 hub on each DIMM: i2c bus 5, `0x50` / `0x51`, register `0x31` (`bit[12:2]`, sign bit 12, 0.25 °C/LSB). A read that fails prints `read fail` — never a number it did not read. Bus and addresses can be passed: `ddr5_temp.sh [bus] [addr ...]`.
* `hsc_temp_readback.sh` reads both LTC4287 hot-swap controllers on i2c bus 28 — `HSC_MAIN @ 0x40` (PU11 internal / PQ1 external) and `HSC_STBY @ 0x45` (PU46 internal / PQ53 external). The source is selected through `0xF3`, then `READ_TEMPERATURE` `0x8D` is read in Kelvin and converted.
**Script 4 logs AMD CPU package power every round**
* `avt_pmpower.sh` runs `AVTCMD -module pmm "get_pmdata()"` and summarizes `SktPwr`, `PPT Fast` / `PPT Slow` against their limits, and `MemPwr`.
* It runs after the two `TH6_SWB` power readbacks, so each sample now puts the switch rails and the CPU package side by side.
* `-q` prints the summary only. Exit `2` = AVTCMD not found, `3` = AVTCMD failed, `4` = the PM table parsed to nothing (format changed).
## 🐛 Bug fixes
**`hsc_temp_readback.sh` was saved with CRLF line endings**
* Copied to the DUT as-is, bash on SONiC fails on the first line (`$'\r': command not found`). The shipped file is LF.
* Its comments said the delay between I2C transactions was 100 ms; `DELAY=0.5` is what actually runs. Comments corrected and a Version History header added.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.2.3.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
```bash
chmod +x ~/Blanton_Script/*.sh
grep -rlU $'\r' ~/Blanton_Script # expect no output
ls ~/AVT_Linux_NDA_2.8.37/AVTCMD # Script 4 only - must already be there
```
## ⚠️ Before you run
* **Redeploy `Blanton_Script/`.** If an earlier copy of `hsc_temp_readback.sh` reached the DUT, it is CRLF and will not run.
* **`chmod +x` after deploying.** `setup_pmon` calls both new scripts by path. Without the exec bit each call is `Permission denied` and the snapshot carries on without those rows — nothing stops, nothing warns.
* **Each PMON snapshot is ~4 s longer.** `hsc_temp_readback.sh` sleeps 0.5 s twice for each of its four readings. It adds up in Script 5, which snapshots at every check point.
* **AVT is not in this package (NDA).** Unpack it on the DUT at exactly `~/AVT_Linux_NDA_2.8.37/` before Script 4. Missing, the call exits `2` every round and the loop runs on without a CPU power reading.
* **Script 4 logs the full PM table once a minute**, because the call is made without `-q`.
* **CPU power is SMU telemetry, not a measurement.** Its absolute accuracy is whatever the BIOS SVI calibration gives — cross-check against the VR's PMBus `READ_POUT` when the number matters.
* **None of the three new scripts has been checked against the Script A/B/C flow on hardware yet.**
* **Do not run the boot cycle with `EN_Cold_Warm_boot = 0`**, and check the hard-coded BDF on every board before the cold path (see v1.2.2).
* **BER, the DSC cycle, `blanton_traffic_linespeed` and `blanton_tr518.sh` cannot overlap.** They all take the same ports.
* **Script 4 has no teardown**: finish it with `blanton_tr518.sh stop` **and** `systemctl stop mlucas-amm`.
* **`blanton_multiphase_margin.sh save` is permanent**, and must not be mixed with `margin.sh`.
* **`FAN_SPEED` is 100.**
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.2.2...V1.2.3](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.2.2...V1.2.3)
+54
View File
@@ -0,0 +1,54 @@
# v1.2.4 — Tray ID I2C stress in Script A and B, and a Diag / SONiC BER cycle that reads the BER correctly
## ✨ New features
**`tray_id_stress.sh` — Tray ID I2C write / read-back stress**
* Buses `34` / `35` / `38` / `39`, device `0x70`, register `0x02`. Each bus gets `0xA5` written and read back, then `0x5A` written and read back — the two patterns put every bit in both states.
* One line per step (`PASS` / `FAIL` / `ERROR`), then a per-bus **Summary** table and a single `Tray ID stress RESULT: PASS|FAIL` line. Exit `0` = all PASS, `1` = any FAIL or I2C error, `2` = bad arguments.
* `FAIL` (the read worked but returned the wrong value) and `ERROR` (`i2cset` / `i2cget` itself failed) are counted separately, because they point at different faults.
* The original register value is read first and **written back at the end**, verified by a read. `-R` skips that; `-n N` repeats the whole sequence N times. Buses, address, register and patterns are editable at the top of the file.
**Script A and Script B run it**
* **Script A** runs one pass after `show_dmesg` as the baseline.
* **Script B** runs one pass in every soak round, before `sleep 60` — 12 writes per round, registers restored each time.
**`6_Blanton_Script_BER_Cycle.ttl` — Diag ↔ SONiC BER cycle (standalone)**
* Each cycle measures PRBS BER on unit 0 in the Diag OS, cold-boots into SONiC, measures again, and cold-boots back to Diag. `while 1`, no end. The boot target is picked in the BIOS Boot Manager (`USB Device` = Diag, `Hard Drive` = SONiC).
* Log: `Logs\Blanton_BER_Cycle_<ts>.log`, timestamps always on.
## 🐛 Bug fixes
**`prbsstat Ber` was read before the first interval had been published — BER read 40–60× low**
* The BER cycle originally read `prbsstat Ber` 10 s after `prbsstat STArt Interval=30`. Checked against the error counts that `prbs get` reports in the same cycle, that read **Diag ~60× low and SONiC ~40× low**.
* Moving to `sleep 30` (equal to the interval) fixed SONiC but **not Diag**: its `Ber` goes out 30.15 s after `STArt`, just before the first interval is published. SONiC's `bcmcmd` adds ~0.3 s and just makes it.
* The macro now uses **`Interval=30` + `sleep 40`**. Over 73 cycles both sides agree with the `prbs get` estimate to within 0.1 decade. The rule: **the sleep must be longer than the interval.**
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.2.4.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
```bash
chmod +x ~/Blanton_Script/*.sh
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
## ⚠️ Before you run
* **`chmod +x` after deploying.** Script A and B call `tray_id_stress.sh` by path; without the exec bit every call is `Permission denied` and the round carries on without the check.
* **Any BER log taken before 2026-09-30 14:13 reads 40–60× low** (BER cycle with `sleep ≤ Interval`). Relative Diag-vs-SONiC trends are usable; absolute values are not.
* **Script A / C's BER is the same edge case**: `blanton_ber.sh start` (Interval=30) → `sleep 30` → `report`, on SONiC. Whether it catches the first interval has **not been verified**. Lengthening that sleep to 40 is the safe change.
* **The BER cycle's SONiC → Diag boot writes a hard-coded BDF** (`pcimem /sys/bus/pci/devices/0000:05:00.0/resource0 0x480`). Check the CB FPGA BDF on every unit before running it.
* **The BER cycle expects the hostname `sonic`.** A unit with another hostname (e.g. `Margin02`) needs `prompt_sonic` / `prompt_sonic_root` edited, or the macro waits forever.
* **The BER cycle sets the fan to 30 % on the SONiC side only** — SONiC runs ~11 °C hotter than Diag, a variable in any Diag-vs-SONiC comparison.
* **Its SONiC password is the `YourPaSsWoRd` placeholder**, and it does not read `config.ttl` or `secret/`.
* **Script 4 has no teardown**: finish it with `blanton_tr518.sh stop` **and** `systemctl stop mlucas-amm`.
* **`FAN_SPEED` is 100.**
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.2.3...V1.2.4](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.2.3...V1.2.4)
+56
View File
@@ -0,0 +1,56 @@
# v1.2.5 — Switch-board rail power in every snapshot, a raw BER run, and tools to turn off unused lanes
## ✨ New features
**PMON snapshots now carry the switch-board rail power**
* `utils/setup_pmon.ttl` calls `TH6_SWB0_power_readback.sh` and `TH6_SWB1_power_readback.sh` right after `show platform current` — the 19 rails of each switch board with V × I and a `TOTAL POWER` line.
* `setup_pmon` is shared, so this lands in Script A, B, C, 4 and 5 alike.
**`blanton_ber_debug.sh` — the hand-run BER flow as one command**
* Runs exactly what `tools/BER_Test.txt` does: `prbs set p=p31` → `prbs get` twice → `prbsstat STArt Interval=30` → `sleep 40` → `prbsstat Ber` → `STOp` → `prbs clear`.
* Every `bcmcmd` output is printed **as is**, under a `### [time] unit N: ...` header — no parsing, no PASS/FAIL, no summary. For looking at the raw output on the bench; `blanton_ber.sh` remains the judged version.
* `-u 0` / `-u 1` for one switch unit; both by default. `BER_POLY`, `BER_INTERVAL`, `BER_WAIT` and `BER_PORTS` can be overridden from the environment.
**`retimer_lanes.sh` / `unused_lanes.sh` — turn off TX on lanes nothing is cabled to**
* `retimer_lanes.sh <asic> <addr> <lane_map> <off|on|status>` acts on one Agera3 retimer, sys **and** line side. `--method squelch` (default, TX squelch, lanes stay powered) or `--method power` (TX+RX power-down, needs an `agera3` that has the `power` command). It reads the state back afterwards and prints `PASS` / `FAIL`.
* `unused_lanes.sh <off|on|status>` applies that to a built-in table — 14 retimer rows and one direct-TH6 row (TSC31, `cd112-cd115`) — on both switch boards. `--asic 0|1|all`, `--th6` to also disable the TH6 ports behind the retimer rows, `--only <target>` for a single row. Ends with `ok / refused / failed` counts.
* **`off` is refused on a lane that receives a signal** (RX PMD lock, or link up on a TH6 port) unless `--force` is given.
**`5_1_Blanton_Script_Boot_Cycle_Fast.ttl` — the boot cycle without the traffic run (standalone)**
* Identical to Script 5, except Check Pt8 only runs `blanton_traffic_linespeed ps` — no `init` / `start` / 15 s / `stop` / `report`. A shorter cycle when the point is the number of boots.
**Boot cycle shows its count in the window title**
* Script 5 and 5_1 set the Tera Term title to `Reboot Cycle Test : n` or `Power Cycle Test : n` each round.
## 🐛 Bug fixes
**`qfx5252-stress-usb` now runs with `--force`** in Script B and in the boot cycles.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.2.5.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
```bash
chmod +x ~/Blanton_Script/*.sh
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
## ⚠️ Before you run
* **`chmod +x` after deploying.** The power readbacks are called by path from every PMON snapshot, and `unused_lanes.sh` refuses to start unless `retimer_lanes.sh` next to it is executable.
* **Script 4 now reads the switch-board power twice per round** — once inside `setup_pmon`, once from its own loop. Harmless, but the log carries both.
* **`blanton_ber_debug.sh` uses `p=p31` (verified on the bench); `blanton_ber.sh`, and so Script A / C, still sets `p=3`.** The two may not be measuring the same pattern — do not compare their BER directly until that is settled.
* **`blanton_ber_debug.sh` leaves out port 268**, the same list as `BER_Test.txt`. Add it with `BER_PORTS="...,268"`.
* **`EN_Cold_Warm_boot = 0` (the `config.ttl` default) hangs Script 5 and 5_1.** Set it to `1` (reboot) or `2` (power cycle).
* **Script 5 and 5_1 are two copies of the same macro** — a fix to one has to be made to the other.
* **Script 4 has no teardown**: finish it with `blanton_tr518.sh stop` **and** `systemctl stop mlucas-amm`.
* **`FAN_SPEED` is 100.**
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.2.4...V1.2.5](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.2.4...V1.2.5)
+47
View File
@@ -0,0 +1,47 @@
# v1.2.6 — FDR statistics around the traffic run, and unused lanes turned off before the baseline
## ✨ New features
**`blanton_fdr.sh` — FDR statistics through `phydiag fdrstat`**
* Four sub-commands, each run on unit 0 then unit 1, over ports `'1-259,270-565'`:
`start` (`fdrstat STArt bin_group=both Interval=30`), `clear` (`fdrstat clear`), `rdcnt` (`fdrstat Counters`), `stop` (`fdrstat STOp`).
* Output is printed as is, under a `### [time] unit N: ...` header — no parsing, no PASS/FAIL.
* `-u 0` / `-u 1` for one switch unit, `-i <sec>` for the interval, `-n` for a dry run. `FDR_PORTS` overrides the port list.
**FDR runs alongside the traffic test in Script A, B and C**
* **Script A** wraps its traffic baseline: `fdr start` after `init`, `fdr clear` after `clear`, `fdr rdcnt` after the run, `fdr stop` after the traffic stop. The traffic run is now **40 s instead of 15 s**, so the counters are read after the first 30 s interval has been published — the same rule as `prbsstat Ber`.
* **Script B** starts and clears FDR with the traffic setup, before the soak loop — the counters run for the whole soak — and reads them (`rdcnt`) in every soak round, after the Tray ID stress.
* **Script C** reads them (`rdcnt`) before stopping the traffic and stops FDR after it — the closing read of the counters Script B started.
**Script A turns off the unused lanes before the BER baseline**
* `unused_lanes.sh off` — TX squelch on the unused retimer lanes and TSC31 (`cd112-cd115`) disabled on the TH6, on both switch boards.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.2.6.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
```bash
chmod +x ~/Blanton_Script/*.sh
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
## ⚠️ Before you run
* **`chmod +x` after deploying.** `blanton_fdr.sh`, `unused_lanes.sh` and `retimer_lanes.sh` are all called by path; `unused_lanes.sh` also refuses to start if `retimer_lanes.sh` is not executable.
* **`blanton_fdr.sh stop` sends `fdrstat STOp` — that keyword is inferred from `prbsstat STOp` and has not been checked on the bench.** `bcmcmd` exits 0 even when the BCM shell rejects a command, so if it is wrong, FDR keeps running and only the log shows it. Check the first run.
* **FDR only runs when both switch units are enabled** (`SWB_UNIT0 = SWB_UNIT1 = 1`). The single-unit branches have no FDR, and Script A's single-unit traffic run is still 15 s.
* **Script B's per-round `fdr rdcnt` is not gated by the unit settings** — with one unit enabled, FDR was never started and each round just logs whatever `fdrstat Counters` returns.
* **Nothing turns the unused lanes back on.** Script C has no `unused_lanes.sh on`; run it by hand when the DUT is needed in its normal state. Whether a reboot clears it has not been checked.
* **`unused_lanes.sh off` is not gated by `SWB_UNIT0` / `SWB_UNIT1`** — it always acts on both boards.
* **`blanton_ber.sh` (Script A / C) still uses `p=3` and `sleep 30`**; see v1.2.5.
* **Script 4 has no teardown**: finish it with `blanton_tr518.sh stop` **and** `systemctl stop mlucas-amm`.
* **`FAN_SPEED` is 100.**
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.2.5...V1.2.6](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.2.5...V1.2.6)
+69
View File
@@ -0,0 +1,69 @@
# v1.2.7 — FDR on the cabled ports only, vendor NFC tool v2.5, and a tester user guide
## ✨ New features
**`Script_User_Guide.md` — the tester guide, shipped in the package**
* Part 1: copying `Blanton_Script/` from a USB stick onto the DUT (mount, copy, `chmod +x`, CRLF check), every `config.ttl` setting, and what Scripts A, B and C run, step by step.
* Part 2: the usage of every tool in `Blanton_Script/`, including the full LTC2980 margin guide.
**`4_1_Blanton_Script_thermal.ttl` — Script 4 with an idle phase and the thermal tr 518 load**
* 300 idle rounds first (PMON snapshot, SWB0/SWB1 rail power, AMD CPU power), then `blanton_tr518_thermal.sh start` and the full-load loop.
* The full-load loop also logs `nvme smart-log` / `smartctl -x` every round and waits with a DUT-side `sleep 1` instead of `pause 60`.
**`blanton_tr518_thermal.sh` — `tr 518` with the thermal-test arguments**
* Same as `blanton_tr518.sh` (start / stop, `-u`, `-w`, `--no-wait`, `-n`), but runs
`tr 518 Scenario=6 Profile=2 portstopktszstride=1 Count=260 PktSize=603,218 CheckLinkTime=20 CheckDataTime=200 TestPhase=1`.
* Override the arguments with `TR_THERMAL_ARGS`, not `TR_TEST_ARGS`.
**`blanton_multiphase_read.sh` — read back the SWB multiphase VRMs**
* Reads the controllers `blanton_multiphase_margin.sh` writes (SWB0 = i2c-13/15, SWB1 = i2c-14/16): one row per chip with VOUT / VOUT2, IOUT / IOUT2, POUT (V × I) and TEMP, plus the total power per board.
* Every voltage and current is followed by the raw PMBus word in hex, e.g. `0.740(0x0128)`.
## 🐛 Bug fixes
**`blanton_fdr.sh` no longer prints the uncabled ports** (v1.0.1)
* The default port list was `'1-259,270-565'`, which also covered ports nothing is cabled to (cd15..19, cd47..51, cd111..115, ...).
* It is now the cabled-port list from `blanton_traffic_linespeed.sh` (`TL_PS_PORTS`), the same one `blanton_ber_debug.sh` uses:
`1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565`.
* Script A, B and C pick this up with no change to the TTLs.
## 📦 Vendor tool update
**`blantons_nfc_validate.py` v2.3 → v2.5** — the customer's `qfx5252-nfc-validate`, renamed to keep the name `nfc_polling.sh` calls.
* New: `--read-ndef` (Type 2 / Type 4 NDEF, Text and AMD FRU records), `--write-ndef` / `--set-location`, `--max-ndef-bytes`; NCI data packets with credit flow control.
* Fixed: a `FileNotFoundError` crash while listing the processes that hold the NFC device open.
* Bad arguments now print `[FAIL]` and exit 1 — `nfc_polling.sh` counts that as **FAIL**, not ERROR.
* The default `test --debug` output (`[PASS]` / `[FAIL]` lines, `NFCID1=`) is unchanged, so `nfc_polling.sh` is not modified.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.2.7.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
```bash
chmod +x ~/Blanton_Script/*.sh
grep -rlU $'\r' ~/Blanton_Script # expect no output
python3 ~/Blanton_Script/blantons_nfc_validate.py --version # expect 2.5
```
## ⚠️ Before you run
* **`4_1_Blanton_Script_thermal.ttl`, `blanton_tr518_thermal.sh` and `blanton_multiphase_read.sh` have not been run on the bench yet.** Check that `tr 518` prints `TR 518 TEST PARAMETERS` on both units the first time.
* **`4_1_Blanton_Script_thermal.ttl` has no teardown, like Script 4**: finish it with `blanton_tr518_thermal.sh stop` **and** `systemctl stop mlucas-amm`.
* **`blanton_multiphase_read.sh` names 0x21 / 0x22 PU105 / PU102** (from `blanton_pwr_data.sh`), the reverse of the PHYTILE mapping in `blanton_multiphase_margin.sh`; the totals are not affected. Do not run it while `blanton_multiphase_margin.sh` is writing.
* **Port 268 (ce0, 100G uplink) is not in the FDR list** — as before. Add it with `FDR_PORTS="...,268"` if FDR is wanted there.
* **The cabled-port list now lives in three scripts** — `blanton_traffic_linespeed.sh`, `blanton_ber_debug.sh`, `blanton_fdr.sh`. Change all three when the cabling changes.
* **Never put the NFC write flags (`--write-ndef`, `--set-location`, `--confirm-write`) in `NFC_ARGS`** — polling would rewrite the tag every round.
* **`blanton_fdr.sh stop` (`fdrstat STOp`) is still unverified on the bench**; see v1.2.6.
* **Nothing turns the unused lanes back on**; run `unused_lanes.sh on` by hand. See v1.2.6.
* **`blanton_ber.sh` (Script A / C) still uses `p=3` and `sleep 30`**; see v1.2.5.
* **Script 4 has no teardown**: finish it with `blanton_tr518.sh stop` **and** `systemctl stop mlucas-amm`.
* **`FAN_SPEED` is 100.**
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.2.6...V1.2.7](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.2.6...V1.2.7)
+247 -3
View File
@@ -1,7 +1,7 @@
; ============================================================================= ; =============================================================================
; Script A for Blanton ; Script A for Blanton
; Version : V1.2.2 ; Version : V1.2.7
; Date : 2026-09-15 ; Date : 2026-10-22
; Author : ETWen ; Author : ETWen
; ============================================================================= ; =============================================================================
; Version History: ; Version History:
@@ -692,6 +692,234 @@
; version of the commands, kept so the .sh can be checked ; version of the commands, kept so the .sh can be checked
; against what a person would actually type. Change one and ; against what a person would actually type. Change one and
; change the other ; change the other
; V1.2.3 2026-09-23 utils/setup_pmon.ttl Add DDR5 DIMM temperature + hot-swap controller temperature
; ~/Blanton_Script/ddr5_temp.sh, then hsc_temp_readback.sh,
; right after 'show platform temperature'
; setup_pmon is shared, so this lands in every PMON snapshot:
; ScriptA baseline, every ScriptB soak round, ScriptC, the
; Script 4 loop and each Script 5 check point
; !! hsc_temp_readback.sh sleeps 0.5 s twice per reading and
; takes four readings - ~4 s added to every PMON snapshot
; !! both are called by path, not through bash, so they need
; the exec bit on the DUT: chmod +x ~/Blanton_Script/*.sh
; after deploying. Without it each call is Permission
; denied and the snapshot just goes on without the rows
; Blanton_Script/ddr5_temp.sh Created v1.0.1 - DDR5 DIMM temperature from the SPD5118 hub
; i2cget bus 5, DIMM 0x50 / 0x51, register 0x31 (MR49/MR50)
; bit[12:2], sign bit 12, 0.25 C/LSB. Bus and addresses can
; be given as arguments: ddr5_temp.sh [bus] [addr ...]
; A failed read prints 'read fail' and moves on to the next
; DIMM - it never prints a number it did not read
; Blanton_Script/hsc_temp_readback.sh Created - LTC4287 hot-swap controller temperatures
; Native i2c bus 28. HSC_MAIN @ 0x40 (PU11 internal / PQ1
; external) and HSC_STBY @ 0x45 (PU46 internal / PQ53
; external). Source picked by writing 0xF3 (0xEB internal,
; 0xEF external), then READ_TEMPERATURE 0x8D, Kelvin -> C
; v1.0.1 Add the header + Version History, fix the delay
; comments (they said 100 ms; DELAY is 0.5 s)
; !! v1.0.0 was saved with CRLF line endings. On SONiC that
; fails outright ($'\r': command not found) - now LF
; Blanton_Script/avt_pmpower.sh Created v1.0.0 - AMD CPU package power from the AVT PM table
; AVTCMD -module pmm "get_pmdata()", then a summary of
; SktPwr, PPT Fast / Slow against their limits, and MemPwr
; -p <AVTCMD path>, -q for the summary without the raw table
; Exit 2 = AVTCMD not found, 3 = AVTCMD failed, 4 = the table
; parsed to nothing (format changed)
; !! SMU telemetry, not a measurement - its absolute accuracy
; is whatever the BIOS SVI calibration gives. Cross-check
; against the VR's PMBus READ_POUT when the number matters
; 4_Blanton_Script_thermal_safety.ttl Add CPU package power to every loop round
; avt_pmpower.sh -p ~/AVT_Linux_NDA_2.8.37/AVTCMD, after the
; two TH6_SWB power readbacks - so each round now has the
; switch rails and the CPU package side by side
; !! AVT is NOT in Blanton_Script and does not travel with
; this package (NDA). It has to be unpacked on the DUT at
; exactly ~/AVT_Linux_NDA_2.8.37/ beforehand. If it is not
; there the script exits 2 every round and the loop carries
; on without a CPU power reading
; !! without -q the full PM table is printed every round, and
; Script 4 loops once a minute - the log grows by one full
; table per minute
; V1.2.4 2026-10-01 Blanton_Script/tray_id_stress.sh Created v1.0.0 - Tray ID I2C write / read-back stress
; Buses 34 / 35 / 38 / 39, device 0x70, register 0x02. Each
; bus: write 0xA5, read back, compare; write 0x5A, read back,
; compare - the two patterns put every bit in both states
; One line per step (PASS / FAIL / ERROR), then a per-bus
; Summary table and 'Tray ID stress RESULT: PASS|FAIL'
; Exit 0 = all PASS, 1 = any FAIL or I2C error, 2 = usage
; -n N repeats the sequence N times; buses / addr / reg /
; patterns are editable at the top of the file
; The original value is read first and written back at the
; end (verified by a read). -R leaves the register at 0x5A
; !! FAIL = the read worked but returned the wrong value;
; ERROR = i2cset / i2cget itself failed. They are counted
; apart because they point at different faults
; !! a bus whose original value cannot be read is NOT
; restored (there is nothing to restore to) - the line
; says so
; !! called by path, so it needs the exec bit on the DUT:
; chmod +x ~/Blanton_Script/*.sh
; ScriptA Add Tray ID stress after show_dmesg (one pass, baseline)
; ScriptB Add Tray ID stress to every soak round, before sleep 60
; Each round now writes 0xA5 / 0x5A to four Tray ID
; registers and restores them - 12 writes per round
; 6_Blanton_Script_BER_Cycle.ttl Added - Diag / SONiC BER cycle, a STANDALONE macro (not A/B/C)
; Each cycle: PRBS BER on unit 0 in the Diag OS, cold boot
; into SONiC, the same PRBS BER again, cold boot back to
; Diag; while 1, no end. Boot selection drives the BIOS
; Boot Manager ('USB Device' = Diag, 'Hard Drive' = SONiC)
; Log: Logs\Blanton_BER_Cycle_<ts>.log, timestamps always on
; Report tools (not shipped): tmp/BER_Test_Cycle/
; parse_multi.py, gen_multi_html.py, validate_prbsget.py
; prbsstat STArt Interval=30, then sleep 40, then Ber
; !! the sleep MUST be longer than the Interval. Checked
; against the error counts that 'prbs get' reports in the
; same cycle: with sleep 10 Diag read ~60x low and SONiC
; ~40x low; with sleep 30 (= Interval) Diag was still
; ~60x low - its Ber is sent 30.15 s after STArt, just
; before the first interval is published. Interval=30 +
; sleep 40 matched on both sides over 73 cycles. Every
; BER log taken before 2026-09-30 14:13 is low by 40-60x
; !! SONiC -> Diag cold boot writes pcimem
; /sys/bus/pci/devices/0000:05:00.0/resource0 0x480 with a
; hard-coded BDF (the Diag side uses fpga_switch.sh, which
; finds the FPGA itself). Check the BDF on every unit
; !! the SONiC password is the YourPaSsWoRd placeholder and
; the macro does not include config.ttl or secret/
; !! prompt_sonic_root is 'root@sonic:~#'. A unit whose
; hostname is not 'sonic' (M02 = Margin02) needs the
; prompts edited or the macro waits forever
; !! fan-speed-control.sh 30 is set on the SONiC side only;
; SONiC runs ~11 C hotter than Diag, a variable in any
; Diag vs SONiC comparison
; !! measures unit 0 only, port 268 not in the list, yet
; wait_init still waits for BOTH units (SWB_UNIT0/1 = 1)
; V1.2.5 2026-10-21 Blanton_Script/blanton_ber_debug.sh Created v1.0.0 - raw BER run of tools/BER_Test.txt
; prbs set p=p31, prbs get x2, prbsstat STArt Interval=30,
; sleep 40, Ber, STOp, prbs clear. Every bcmcmd output is
; printed as is under a '### [time] unit N: ...' header - no
; parsing, no PASS/FAIL, no summary. -u 0 / -u 1, default both
; BER_POLY / BER_INTERVAL / BER_WAIT / BER_PORTS overridable
; !! the port list is the 200G ports only, no 268 - same as
; BER_Test.txt. BER_PORTS="...,268" adds the 100G uplink
; !! p=p31 is verified on the bench. blanton_ber.sh (and so
; Script A / C) still sets p=3 - the two runs do not measure
; the same pattern unless p=3 is PRBS31 as well
; !! standalone, no TTL calls it
; Blanton_Script/retimer_lanes.sh Created - TX off / on / status for lanes of one Agera3 retimer
; retimer_lanes.sh <asic 0|1> <addr> <lane_map> <off|on|status>
; Acts on the sys AND the line side. --method squelch (default,
; TX squelch, lanes stay powered) or power (TX+RX power-down,
; needs an agera3 with the 'power' command - exit 4 if not)
; Reads back after the change: PASS / FAIL, exit 3 on mismatch
; !! 'off' is REFUSED (exit 2) on a lane with RX PMD lock, i.e.
; one that receives a signal. --force overrides
; !! runs agera3 through sudo, 30 s timeout per call
; Blanton_Script/unused_lanes.sh Created - apply off / on / status to every unused lane
; Table at the top: 14 retimer rows (7 fully unused, 7 with
; lanes 4,5 unused) and 1 direct-TH6 row (TSC31, cd112-cd115),
; the same rows on both switch boards. Retimer rows go through
; retimer_lanes.sh, TH6 rows through 'port ... enable=' in
; syncdN's bcmcmd. --asic 0|1|all; --th6 also turns off the TH6
; ports behind the retimer rows; --only <target> for one row
; Ends with ok / refused / failed counts, exit 1 if any failed
; !! calls retimer_lanes.sh from its own directory and checks
; its exec bit - chmod +x both after deploying
; !! bash only (mapfile, [[ =~ ]]), not sh
; utils/setup_pmon.ttl Add TH6_SWB0 / TH6_SWB1 power readback after show platform current
; Every PMON snapshot (A / B / C / 4 / 5) now has the 19 rails
; of each switch board with V x I and TOTAL POWER
; !! Script 4 already called both readbacks in its loop right
; after setup_pmon - it now reads them TWICE per round
; !! every Script B soak round gets longer by both readbacks
; ScriptB Add --force to qfx5252-stress-usb
; 5_.._Boot_Cycle.ttl Window title shows the cycle count every round
; 'Reboot Cycle Test : n' (EN_Cold_Warm_boot = 1) or
; 'Power Cycle Test : n' (= 2), set with settitle
; Add --force to qfx5252-stress-usb, same as Script B
; 5_1_Blanton_Script_Boot_Cycle_Fast.ttl Added - Script 5 without the traffic run, a STANDALONE macro
; Identical to 5_.._Boot_Cycle.ttl except that Check Pt8 runs
; only 'blanton_traffic_linespeed ps' - no init / clear / show
; / start / pause 15 / stop / report. A shorter cycle when the
; point is the number of boots
; !! a second copy of the same macro: a fix to one has to be
; made to the other as well
; !! EN_Cold_Warm_boot = 0 (the config.ttl default) hangs it,
; same as Script 5
; tools/BER_Test.txt p=3 -> p=p31; add a unit 1 block, a both-units block and
; port en=0 / en=1 for all cabled ports on each unit
; V1.2.6 2026-10-21 Blanton_Script/blanton_fdr.sh Created v1.0.0 - FDR statistics through phydiag fdrstat
; start / clear / rdcnt / stop on ports '1-259,270-565':
; fdrstat STArt bin_group=both Interval=30 / clear / Counters /
; STOp. bcmcmd output printed as is, no parsing or PASS/FAIL
; -u 0 / -u 1 (default both), -i <sec> Interval, -n dry run
; !! 'stop' sends 'fdrstat STOp', by analogy with prbsstat STOp
; - NOT verified on the bench. If the BCM shell rejects it,
; FDR keeps running and only the log shows it (bcmcmd exits 0)
; !! called by path - chmod +x ~/Blanton_Script/*.sh
; ScriptA Turn off unused lanes before the BER baseline
; unused_lanes.sh off - both units, TX squelch on the unused
; retimer lanes and TSC31 (cd112-cd115) disabled on the TH6
; !! nothing turns them back on: no 'unused_lanes.sh on' in
; Script C. They stay off until 'unused_lanes.sh on' is run
; by hand (whether a reboot clears them is not checked)
; !! not gated by SWB_UNIT0 / SWB_UNIT1 - always both units
; !! needs the exec bit on unused_lanes.sh AND retimer_lanes.sh
; ScriptA FDR around the traffic baseline (SWB_UNIT0 = SWB_UNIT1 = 1 only)
; init -> fdr start -> clear -> fdr clear -> ... -> start ->
; sleep 40 -> fdr rdcnt -> traffic stop -> fdr stop -> report
; Traffic sleep 15 -> 40 so rdcnt reads after the first 30 s
; Interval is published (same rule as prbsstat Ber)
; !! the single-unit branches have no FDR and still sleep 15
; ScriptB fdr start + fdr clear with the traffic setup, before the loop
; (SWB_UNIT0 = SWB_UNIT1 = 1 only) - the counters run for the
; whole soak
; fdr rdcnt in every soak round, after the Tray ID stress
; !! not gated by SWB_UNIT0 / SWB_UNIT1, unlike the start -
; with one unit enabled FDR was never started, and the
; round just logs whatever fdrstat Counters returns
; ScriptC fdr rdcnt before traffic stop, fdr stop after it
; (SWB_UNIT0 = SWB_UNIT1 = 1 only) - the closing read of the
; counters Script B started, bracketing the soak
; V1.2.7 2026-10-22 Blanton_Script/blanton_fdr.sh v1.0.1 - default ports are the cabled ports only
; '1-259,270-565' -> the TL_PS_PORTS list of
; blanton_traffic_linespeed.sh (same as blanton_ber_debug.sh)
; The old range also printed the uncabled ports (cd15..19,
; cd47..51, cd111..115, ...)
; !! port 268 (ce0) is still left out - add ',268' through
; FDR_PORTS if FDR is wanted on the 100G uplink
; !! the port list now lives in three scripts (traffic,
; BER debug, FDR) - change all three when the cabling changes
; Blanton_Script/blantons_nfc_validate.py Vendor tool v2.3 -> v2.5 (qfx5252-nfc-validate, renamed)
; Adds --read-ndef / --write-ndef / --set-location, NCI data
; packets with credit flow control; fixes a FileNotFoundError
; crash while listing the processes holding the NFC device
; Bad arguments now print [FAIL] and exit 1, so nfc_polling
; counts them as FAIL instead of ERROR
; The default "test --debug" output ([PASS]/[FAIL], NFCID1=)
; is unchanged - nfc_polling.sh is not modified
; !! never put the write flags in NFC_ARGS
; 4_1_Blanton_Script_thermal.ttl Created - Script 4 with an idle phase and the thermal tr 518
; 300 idle rounds first (PMON + SWB0/1 power + AVT CPU power,
; sleep 1), then blanton_tr518_thermal.sh start and the full-
; load loop, which also logs nvme smart-log / smartctl -x and
; waits with DUT 'sleep 1' instead of 'pause 60'
; !! no teardown, same as Script 4 - finish with
; blanton_tr518_thermal.sh stop + systemctl stop mlucas-amm
; Blanton_Script/blanton_tr518_thermal.sh Created v1.0.0 - blanton_tr518.sh with the thermal tr 518 args
; Scenario=6 Profile=2 portstopktszstride=1 Count=260
; PktSize=603,218 CheckLinkTime=20 CheckDataTime=200 TestPhase=1
; Override through TR_THERMAL_ARGS (not TR_TEST_ARGS)
; !! not run on the bench yet
; Blanton_Script/blanton_multiphase_read.sh Created v1.0.0 - read back the SWB multiphase VRMs
; Native i2c (SWB0 = i2c-13/15, SWB1 = i2c-14/16), one row per
; chip in the pu_show.sh layout with the raw PMBus word in hex
; after every V / I, plus the total power per board
; !! not run on the bench yet; the PU105 / PU102 names of 0x21 /
; 0x22 are the reverse of blanton_multiphase_margin.sh
; Script_User_Guide.md Created - tester guide, shipped in the package: deploying
; Blanton_Script/ from USB, config.ttl, Scripts A/B/C, and the
; usage of every Blanton_Script tool incl. LTC2980 margin
; ============================================================================= ; =============================================================================
include "config.ttl" include "config.ttl"
@@ -849,6 +1077,10 @@ endif
include "utils/setup_pmon.ttl" include "utils/setup_pmon.ttl"
include "utils/show_dmesg.ttl" include "utils/show_dmesg.ttl"
; ========== Tray ID Stress Test ==========
wait prompt_sonic_root
sendln "~/Blanton_Script/tray_id_stress.sh"
;include "utils/xxx.ttl" ;include "utils/xxx.ttl"
;wait prompt_sonic_root ;wait prompt_sonic_root
;flushrecv ;flushrecv
@@ -901,6 +1133,10 @@ sendln "config feature state lldp disabled"
wait prompt_sonic_root wait prompt_sonic_root
sendln "config save -y" sendln "config save -y"
; ========== Turn off unused lanes ==========
wait prompt_sonic_root
sendln "~/Blanton_Script/unused_lanes.sh off"
; ========== BER ========== ; ========== BER ==========
; Baseline sweep, taken BEFORE the traffic run - ScriptC takes the closing ; Baseline sweep, taken BEFORE the traffic run - ScriptC takes the closing
; one after its traffic report, so the pair brackets the soak. ; one after its traffic report, so the pair brackets the soak.
@@ -957,18 +1193,26 @@ if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root wait prompt_sonic_root
sendln "blanton_traffic_linespeed init" sendln "blanton_traffic_linespeed init"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh start"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed clear" sendln "blanton_traffic_linespeed clear"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh clear"
wait prompt_sonic_root
sendln "sleep 5" sendln "sleep 5"
wait prompt_sonic_root wait prompt_sonic_root
sendln "blanton_traffic_linespeed show" sendln "blanton_traffic_linespeed show"
wait prompt_sonic_root wait prompt_sonic_root
sendln "blanton_traffic_linespeed start" sendln "blanton_traffic_linespeed start"
wait prompt_sonic_root wait prompt_sonic_root
sendln "sleep 15" sendln "sleep 40"
wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh rdcnt"
wait prompt_sonic_root wait prompt_sonic_root
sendln "blanton_traffic_linespeed stop" sendln "blanton_traffic_linespeed stop"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh stop"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed report" sendln "blanton_traffic_linespeed report"
elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then
wait prompt_sonic_root wait prompt_sonic_root
+14 -1
View File
@@ -60,7 +60,7 @@ usb_dev = groupmatchstr1
wait prompt_sonic_root wait prompt_sonic_root
;sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime 86400 --passes 1 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev ;sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime 86400 --passes 1 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev
sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime %d --passes %d --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev USB_RUNTIME USB_COUNT sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime %d --passes %d --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log --force" usb_dev USB_RUNTIME USB_COUNT
sendln cmd sendln cmd
;wait prompt_sonic_root ;wait prompt_sonic_root
@@ -138,8 +138,12 @@ if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root wait prompt_sonic_root
sendln "blanton_traffic_linespeed init" sendln "blanton_traffic_linespeed init"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh start"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed clear" sendln "blanton_traffic_linespeed clear"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh clear"
wait prompt_sonic_root
sendln "sleep 5" sendln "sleep 5"
wait prompt_sonic_root wait prompt_sonic_root
sendln "blanton_traffic_linespeed show" sendln "blanton_traffic_linespeed show"
@@ -186,6 +190,15 @@ while 1
sendln "jobs" sendln "jobs"
wait prompt_sonic_root wait prompt_sonic_root
sendln "systemctl is-active mlucas-amm" sendln "systemctl is-active mlucas-amm"
; ========== Tray ID Stress Test ==========
wait prompt_sonic_root
sendln "~/Blanton_Script/tray_id_stress.sh"
; ========== FDR Counter Read ==========
wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh rdcnt"
wait prompt_sonic_root wait prompt_sonic_root
sendln "sleep 60" sendln "sleep 60"
endwhile endwhile
@@ -85,9 +85,13 @@ sendln "show interfaces status Ethernet513,Ethernet514"
; ========== CHECK Traffic counters ========== ; ========== CHECK Traffic counters ==========
if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh rdcnt"
wait prompt_sonic_root wait prompt_sonic_root
sendln "blanton_traffic_linespeed stop" sendln "blanton_traffic_linespeed stop"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_fdr.sh stop"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed report" sendln "blanton_traffic_linespeed report"
elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then
wait prompt_sonic_root wait prompt_sonic_root
@@ -0,0 +1,193 @@
include "config.ttl"
flushrecv
;================================================================
; Log File Creation
;================================================================
gettime str_starttime "%Y%m%d-%H%M%S"
getdir mdir
if EN_log = 1 then
sprintf2 filename '%s\Logs\%s_%s_%s.log' mdir project_name strTestcase str_starttime
logopen filename 0 1 1 1
endif
; ========== Root Login ==========
wait prompt_login
sendln "admin"
wait "Password:"
sendln "YourPaSsWoRd"
wait prompt_sonic
sendln "sudo -i"
; ========== Pre Setting ==========
; Make log directory
wait prompt_sonic_root
sendln "mkdir ./logs"
; Setting System Time
getdate datestr
gettime timestr
sprintf2 cmd 'sudo date -s "%s %s"' datestr timestr
sendln cmd
;Stress log clear
wait prompt_sonic_root
sendln "rm /host/hw-eval/jobs/*"
; ========== HW Test Session ==========
; Clear session
wait prompt_sonic_root
sendln "hw-test-session finish"
wait prompt_sonic_root
sendln "bgctl reset --yes"
wait prompt_sonic_root
sendln "bgctl stop --all"
wait prompt_sonic_root
sendln "bgctl list"
wait prompt_sonic_root
sendln "hw-test-session start"
wait prompt_sonic_root
sendln "hw-test-session log"
wait prompt_sonic_root
sendln "hw-test-session status"
; ========== FAN SPEED ==========
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sprintf2 fan_ctrl_cmd 'fan-speed-control.sh %d' FAN_SPEED
sendln fan_ctrl_cmd
wait "Set all configured fan channels to"
sendln "y"
; ========== Wait DUT Init ==========
include "utils/wait_init.ttl"
; ========== DUT Info ==========
wait prompt_sonic_root
sendln "show boot"
wait prompt_sonic_root
sendln "show version"
wait prompt_sonic_root
sendln "fwutil show status"
wait prompt_sonic_root
sendln "show system-memory"
wait prompt_sonic_root
sendln "show service"
wait prompt_sonic_root
sendln "show platform syseeprom"
wait prompt_sonic_root
sendln "show platform ssdhealth"
wait prompt_sonic_root
sendln "qfx5252-tpm-version"
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
wait prompt_sonic_root
sendln "/usr/sbin/smartctl -x /dev/nvme0"
; ========== BMC version ==========
;wait prompt_sonic_root
;sendln "bmc-manager run 'cat /etc/issue'"
wait prompt_sonic_root
sendln "bmc-first-enroll"
wait prompt_sonic_root
sendln "bmc-manager version"
wait prompt_sonic_root
sendln "bmc-manager status"
; ========== CLEAR PCIE Error ==========
include "utils/show_pcie_error_reg_TH6_SWB0.ttl"
include "utils/show_pcie_error_reg_TH6_SWB1.ttl"
include "utils/show_pcie_error_reg_FPGA.ttl"
include "utils/show_pcie_error_reg_BMC.ttl"
include "utils/show_pcie_error_reg_DDR.ttl"
include "utils/show_pcie_error_reg_I210.ttl"
include "utils/show_pcie_error_reg_SSD.ttl"
wait prompt_sonic_root
sendln "/usr/sbin/ras-mc-ctl --summary"
; ========== Check PCIE tree + PCIE link status + GET PCIE bandwidth Test ==========
include "utils/pcie_bus.ttl"
; ========== TAKE DATA ==========
include "utils/setup_pmon.ttl"
include "utils/show_dmesg.ttl"
idle_cnt = 0
while idle_cnt < 300
sprintf2 title 'Idle Loop - %d' idle_cnt
settitle title
; Base info polling
include "utils/setup_pmon.ttl"
; TH6 Power Polling
wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB0_power_readback.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB1_power_readback.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/avt_pmpower.sh -p ~/AVT_Linux_NDA_2.8.37/AVTCMD"
wait prompt_sonic_root
sendln "sleep 1"
idle_cnt = idle_cnt + 1
endwhile
; ========== Full Load ==========
; AMD CPU STRESS TEST
; Clear the log file first
wait prompt_sonic_root
sendln "> ~/hammer/tools/amd/mlucas_amm_log"
wait prompt_sonic_root
sendln 'chmod +x ~/hammer/tools/amd/mlucas-avx2'
wait prompt_sonic_root
;sendln "~/hammer/tools/amd/mlucas-avx2 -s l -cpu 0:15 > ~/hammer/tools/amd/mlucas_amm_log 2>&1 &"
sendln "systemd-run --unit=mlucas-amm --property=Type=exec --property=Restart=always --property=RestartSec=2 /bin/bash -c '~/hammer/tools/amd/mlucas-avx2 -s l -cpu 0:15 >> ~/hammer/tools/amd/mlucas_amm_log 2>&1'"
; TR518 TEST
wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_tr518_thermal.sh start"
settitle 'Full Load Loop'
while 1
; Base info polling
include "utils/setup_pmon.ttl"
; TH6 Power Polling
wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB0_power_readback.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB1_power_readback.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/avt_pmpower.sh -p ~/AVT_Linux_NDA_2.8.37/AVTCMD"
; Background jobs Check
wait prompt_sonic_root
sendln "bgctl list"
wait prompt_sonic_root
sendln "jobs"
wait prompt_sonic_root
sendln "systemctl is-active mlucas-amm"
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
wait prompt_sonic_root
sendln "/usr/sbin/smartctl -x /dev/nvme0"
wait prompt_sonic_root
sendln "sleep 1"
endwhile
@@ -152,6 +152,8 @@ while 1
sendln "~/Blanton_Script/TH6_SWB0_power_readback.sh" sendln "~/Blanton_Script/TH6_SWB0_power_readback.sh"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB1_power_readback.sh" sendln "~/Blanton_Script/TH6_SWB1_power_readback.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/avt_pmpower.sh -p ~/AVT_Linux_NDA_2.8.37/AVTCMD"
; Background jobs Check ; Background jobs Check
wait prompt_sonic_root wait prompt_sonic_root
@@ -0,0 +1,412 @@
include "config.ttl"
flushrecv
;================================================================
; Log File Creation
;================================================================
gettime str_starttime "%Y%m%d-%H%M%S"
getdir mdir
if EN_log = 1 then
if EN_Cold_Warm_boot = 1 then
sprintf2 filename '%s\Logs\%s_%s_%s.log' mdir project_name "Reboot_Cycle" str_starttime
logopen filename 0 1 1 1
elseif EN_Cold_Warm_boot = 2 then
sprintf2 filename '%s\Logs\%s_%s_%s.log' mdir project_name "Power_Cycle" str_starttime
logopen filename 0 1 1 1
else
endif
endif
cnt_cycle = 0
while 1
cnt_cycle = cnt_cycle + 1
if EN_Cold_Warm_boot = 1 then
sprintf2 log_cycle_msg 'Reboot Cycle Test : %d' cnt_cycle
settitle log_cycle_msg
elseif EN_Cold_Warm_boot = 2 then
sprintf2 log_cycle_msg 'Power Cycle Test : %d' cnt_cycle
settitle log_cycle_msg
else
endif
; ========== Root Login ==========
wait prompt_login
sendln "admin"
wait "Password:"
sendln "YourPaSsWoRd"
wait prompt_sonic
sendln "sudo -i"
wait prompt_sonic_root
sendln "sleep 10"
if EN_Cold_Warm_boot = 1 then
wait prompt_sonic_root
sprintf2 strTitle "echo -e '\033[1;32mReboot Cycle : %d \033[0m'" cnt_cycle
sendln strTitle
elseif EN_Cold_Warm_boot = 2 then
wait prompt_sonic_root
sprintf2 strTitle "echo -e '\033[1;32mPower Cycle : %d \033[0m'" cnt_cycle
sendln strTitle
else
endif
; ========== Pre Setting ==========
; Make log directory
wait prompt_sonic_root
sendln "mkdir ./logs"
; Setting System Time
getdate datestr
gettime timestr
sprintf2 cmd 'sudo date -s "%s %s"' datestr timestr
sendln cmd
; ========== FAN SPEED ==========
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sprintf2 fan_ctrl_cmd 'fan-speed-control.sh %d' FAN_SPEED
sendln fan_ctrl_cmd
wait "Set all configured fan channels to"
sendln "y"
; ========== Wait DUT Init ==========
include "utils/wait_init.ttl"
; ========== DUT Info ==========
wait prompt_sonic_root
sprintf2 strCKPt1 "echo -e '\033[36mCheck Pt1 : DUT Info\033[0m'"
sendln strCKPt1
wait prompt_sonic_root
sendln "show boot"
wait prompt_sonic_root
sendln "show version"
wait prompt_sonic_root
sendln "fwutil show status"
wait prompt_sonic_root
sendln "show system-memory"
wait prompt_sonic_root
sendln "show service"
wait prompt_sonic_root
sendln "show platform syseeprom"
wait prompt_sonic_root
sendln "show platform ssdhealth"
wait prompt_sonic_root
sendln "qfx5252-tpm-version"
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
wait prompt_sonic_root
sendln "/usr/sbin/smartctl -x /dev/nvme0"
; ========== BMC version ==========
wait prompt_sonic_root
sprintf2 strCKPt2 "echo -e '\033[36mCheck Pt2 : BMC Info\033[0m'"
sendln strCKPt2
wait prompt_sonic_root
sendln "bmc-first-enroll"
wait prompt_sonic_root
sendln "bmc-manager version"
wait prompt_sonic_root
sendln "bmc-manager status"
; ========== Load Shell Script ==========
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_fpga_pcimem.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_cb_i2c.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_icb_vi2c.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_pwr_data.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_traffic_linespeed.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/LTC2980_Margin_Script/margin.sh"
; ========== CLEAR PCIE Error ==========
include "utils/show_pcie_error_reg_TH6_SWB0.ttl"
include "utils/show_pcie_error_reg_TH6_SWB1.ttl"
include "utils/show_pcie_error_reg_FPGA.ttl"
include "utils/show_pcie_error_reg_BMC.ttl"
include "utils/show_pcie_error_reg_DDR.ttl"
include "utils/show_pcie_error_reg_I210.ttl"
include "utils/show_pcie_error_reg_SSD.ttl"
wait prompt_sonic_root
sendln "/usr/sbin/ras-mc-ctl --summary"
; ========== Check PCIE tree + PCIE link status + GET PCIE bandwidth Test ==========
include "utils/pcie_bus.ttl"
; ========== TAKE DATA ==========
include "utils/setup_pmon.ttl"
include "utils/show_dmesg.ttl"
; ========== 10G/1G MGMT Ping Test ==========
wait prompt_sonic_root
sprintf2 strCKPt3 "echo -e '\033[36mCheck Pt3 : Mgmt Ping Test\033[0m'"
sendln strCKPt3
wait prompt_sonic_root
sendln "./Blanton_Script/mgmt_ping_monitor.sh start"
wait prompt_sonic_root
pause 30
sendln "~/Blanton_Script/mgmt_ping_monitor.sh stop"
wait prompt_sonic_root
sendln "cat ~/Blanton_Script/log/mgmt_ping.log"
wait prompt_sonic_root
sendln "~/Blanton_Script/mgmt_ping_monitor.sh clear"
; ========== NFC Test ==========
wait prompt_sonic_root
sprintf2 strCKPt4 "echo -e '\033[36mCheck Pt4 : NFC Test\033[0m'"
sendln strCKPt4
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh start"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh status"
wait prompt_sonic_root
sendln "sleep 20"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh stop"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh report"
; ========== SSD read/write ==========
wait prompt_sonic_root
sprintf2 strCKPt5 "echo -e '\033[36mCheck Pt5 : SSD Test\033[0m'"
sendln strCKPt5
wait prompt_sonic_root
sendln "rm -rf /host/hw-eval/jobs/qfx5252-stress-ssd.log"
wait prompt_sonic_root
sendln "qfx5252-stress-ssd 1G --runtime 30 --passes 2 --write --force --log /host/hw-eval/jobs/qfx5252-stress-ssd.log"
wait prompt_sonic_root
sendln "cat /host/hw-eval/jobs/qfx5252-stress-ssd.log"
; ========== USB read/write ==========
wait prompt_sonic_root
sprintf2 strCKPt6 "echo -e '\033[36mCheck Pt6 : USB Test\033[0m'"
sendln strCKPt6
; ---- Get USB partition node -> usb_dev ----
usb_dev = ''
wait prompt_sonic_root
sendln 'D=$(bash ~/Blanton_Script/usb_target.sh -o dev 2>/dev/null); echo "<<D""EV=${D:-NONE}>>"'
waitregex '<<DEV=([^>]*)>>'
usb_dev = groupmatchstr1
wait prompt_sonic_root
sendln "rm -rf /host/hw-eval/jobs/qfx5252-stress-usb.log"
wait prompt_sonic_root
sprintf2 cmd "qfx5252-stress-usb %s 256M --runtime 30 --passes 2 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log --force" usb_dev
sendln cmd
wait prompt_sonic_root
sendln "cat /host/hw-eval/jobs/qfx5252-stress-usb.log"
; ========== BMC USB Test ==========
wait prompt_sonic_root
sprintf2 strCKPt7 "echo -e '\033[36mCheck Pt7 : BMC USB Test\033[0m'"
sendln strCKPt7
wait prompt_sonic_root
sendln 'echo "NCMIF=$(ls -d /sys/bus/usb/drivers/cdc_ncm/*/net/* 2>/dev/null | head -n 1 | xargs -r basename)"'
; timeout is GLOBAL and sticky: left at 15, every 'wait' below gives up after
; 15 s instead of blocking, the macro runs ahead of the DUT and the whole
; cycle desynchronises. Restore it BEFORE the branch so both paths are
; covered - the ping block below waits on 'sleep 10', which is already two
; thirds of the 15 s cap on a loaded DUT.
timeout = 15
waitregex 'NCMIF=[A-Za-z0-9_-]+'
ncm_found = result ; hold it: 'result' is reused below
timeout = 0 ; restore, both paths
if ncm_found = 0 then
messagebox 'cdc_ncm interface not found. Ping test skipped.' 'ERROR'
goto skip_ping
endif
strlen matchstr
cut_len = result - 6 ; 'NCMIF=' = 6 chars
strcopy matchstr 7 cut_len ncm_if ; -> ncm_if = "eth2" / "eth3"
sprintf2 cmd 'ip -br link show %s' ncm_if
wait prompt_sonic_root
sendln cmd
wait prompt_sonic_root
sendln 'systemctl stop qfx5252-bmc-usb-net-test.service 2>/dev/null || true'
wait prompt_sonic_root
sendln 'systemctl reset-failed qfx5252-bmc-usb-net-test.service 2>/dev/null || true'
sprintf2 cmd 'systemd-run --unit=qfx5252-bmc-usb-net-test --property=Type=exec /usr/bin/ping -I %s -i 1 -W 2 -w 14400 192.168.200.200' ncm_if
wait prompt_sonic_root
sendln cmd
wait prompt_sonic_root
sendln "sleep 10"
wait prompt_sonic_root
sendln "systemctl stop qfx5252-bmc-usb-net-test.service"
wait prompt_sonic_root
sendln "journalctl -u qfx5252-bmc-usb-net-test.service --no-pager"
:skip_ping
timeout = 0 ; backstop, same as Script B
; ========== 100G Port Setting ==========
wait prompt_sonic_root
sendln "sudo sfputil lpmode off Ethernet513"
wait prompt_sonic_root
sendln "sudo sfputil lpmode off Ethernet514"
wait prompt_sonic_root
sendln "config interface -n asic0 startup Ethernet513"
wait prompt_sonic_root
sendln "config interface -n asic1 startup Ethernet514"
wait prompt_sonic_root
sendln "config save -y"
; ========== First Traffic Test ==========
; Silent MAC
wait prompt_sonic_root
sendln "config feature state lldp disabled"
wait prompt_sonic_root
sendln "config save -y"
; ========== 100G Port Status ==========
wait prompt_sonic_root
sprintf2 strCKPt8 "echo -e '\033[36mCheck Pt8 : Port Status and 15sec Traffic \033[0m'"
sendln strCKPt8
wait prompt_sonic_root
sendln "show interfaces status Ethernet513,Ethernet514"
; ========== Traffic Test ==========
if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "blanton_traffic_linespeed ps"
elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then
wait prompt_sonic_root
sendln "blanton_traffic_linespeed ps -u 0"
elseif SWB_UNIT0 = 0 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "blanton_traffic_linespeed ps -u 1"
else
endif
; ========== BER ==========
; PRBS takes the SerDes out of normal operation, so this runs AFTER the
; traffic report. sleep 30 matches blanton_ber.sh BER_INTERVAL - reporting
; earlier reads an interval that has not finished accumulating.
wait prompt_sonic_root
sprintf2 strCKPt8 "echo -e '\033[36mCheck Pt9 : BER Test \033[0m'"
sendln strCKPt8
if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear"
elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start -u 0"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear -u 0"
elseif SWB_UNIT0 = 0 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start -u 1"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear -u 1"
else
endif
; ========== NVME Err Info ==========
wait prompt_sonic_root
sprintf2 strCKPt9 "echo -e '\033[36mCheck Pt10 : NVME Err Info \033[0m'"
sendln strCKPt9
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
wait prompt_sonic_root
sendln "/usr/sbin/smartctl -x /dev/nvme0"
; ========== TAKE DATA ==========
wait prompt_sonic_root
sprintf2 strCKPt10 "echo -e '\033[36mCheck Pt11 : Platform Data \033[0m'"
sendln strCKPt10
include "utils/setup_pmon.ttl"
wait prompt_sonic_root
sprintf2 strCKPt12 "echo -e '\033[36mCheck Pt12 : Dmesg_i2c \033[0m'"
sendln strCKPt12
include "utils/show_dmesg.ttl"
; ========== Check PCIE error counters ==========
wait prompt_sonic_root
sprintf2 strCKPt13 "echo -e '\033[36mCheck Pt13 : PCIE Error Counters \033[0m'"
sendln strCKPt13
include "utils/show_pcie_error_reg_TH6_SWB0.ttl"
include "utils/show_pcie_error_reg_TH6_SWB1.ttl"
include "utils/show_pcie_error_reg_FPGA.ttl"
include "utils/show_pcie_error_reg_BMC.ttl"
include "utils/show_pcie_error_reg_DDR.ttl"
include "utils/show_pcie_error_reg_I210.ttl"
include "utils/show_pcie_error_reg_SSD.ttl"
wait prompt_sonic_root
sendln "/usr/sbin/ras-mc-ctl --summary"
; ========== Show Power on uptime ==========
wait prompt_sonic_root
sendln "show uptime"
; ========== Show Power on uptime ==========
if EN_Cold_Warm_boot = 1 then
wait prompt_sonic_root
sendln "reboot"
elseif EN_Cold_Warm_boot = 2 then
wait prompt_sonic_root
sendln "pcimem /sys/bus/pci/devices/0000:05:00.0/resource0 0x480 w 0xD0000"
else
endif
wait "Booting in blind mode"
endwhile
@@ -22,6 +22,14 @@ cnt_cycle = 0
while 1 while 1
cnt_cycle = cnt_cycle + 1 cnt_cycle = cnt_cycle + 1
if EN_Cold_Warm_boot = 1 then
sprintf2 log_cycle_msg 'Reboot Cycle Test : %d' cnt_cycle
settitle log_cycle_msg
elseif EN_Cold_Warm_boot = 2 then
sprintf2 log_cycle_msg 'Power Cycle Test : %d' cnt_cycle
settitle log_cycle_msg
else
endif
; ========== Root Login ========== ; ========== Root Login ==========
wait prompt_login wait prompt_login
sendln "admin" sendln "admin"
@@ -207,7 +215,7 @@ while 1
wait prompt_sonic_root wait prompt_sonic_root
sendln "rm -rf /host/hw-eval/jobs/qfx5252-stress-usb.log" sendln "rm -rf /host/hw-eval/jobs/qfx5252-stress-usb.log"
wait prompt_sonic_root wait prompt_sonic_root
sprintf2 cmd "qfx5252-stress-usb %s 256M --runtime 30 --passes 2 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev sprintf2 cmd "qfx5252-stress-usb %s 256M --runtime 30 --passes 2 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log --force" usb_dev
sendln cmd sendln cmd
wait prompt_sonic_root wait prompt_sonic_root
sendln "cat /host/hw-eval/jobs/qfx5252-stress-usb.log" sendln "cat /host/hw-eval/jobs/qfx5252-stress-usb.log"
@@ -0,0 +1,315 @@
;================================================================
; Prompt Definitions
;================================================================
prompt_login = "sonic login:"
prompt_sonic = "admin@sonic:~$"
prompt_sonic_root = "root@sonic:~#"
prompt_diag = "root@(none):~#"
; ============================================================
; [1] Config
; ============================================================
SWB_UNIT0 = 1 ; 1 = this DUT has switch unit 0, wait for it ; 0 = skip
SWB_UNIT1 = 1 ; 1 = this DUT has switch unit 1, wait for it ; 0 = skip
bb_post_hotkey = 'Post Code>>:0226' ; 看到此 POST code 後開始送 ESC
bb_esc_ack = 'Esc is pressed' ; BIOS 收到 ESC 的回應訊息
bb_fp_continue = 'continue to booting' ; Front Page:Continue 反白時的說明欄(同一 row 內的字串)
bb_fp_bootmgr = 'you to the Boot Manager' ; Front Page:Boot Manager 反白時的說明欄
bb_bm_header = 'EFI Boot Devices' ; Boot Manager 清單標題
bb_bm_footer = 'ESC to exit' ; Boot Manager 頁面最後一段文字(畫完判定)
bb_key_esc = #27
bb_key_down = #27'[B'
bb_key_enter = #13
;diag_tok = 'KINGSHARKS' ; EFI USB Device (KINGSHARKS-ANTU04)
;sonic_tok = 'J983670007' ; EFI Hard Drive (J983670007-TS2TMTE712P-VS2)
diag_tok = 'USB Device' ; EFI USB Device (KINGSHARKS-ANTU04)
sonic_tok = 'Hard Drive' ; EFI Hard Drive (J983670007-TS2TMTE712P-VS2)
diag_sig = 'ast1813b_diag' ; EFI Shell 執行 startup.nsh 載入的 diag kernel
sonic_sig = 'SONiC-OS' ; SONiC GRUB entry 名稱(請依實際 GRUB 畫面確認)
gettime str_starttime "%Y%m%d-%H%M%S"
getdir mdir
sprintf2 filename '%s\Logs\%s_%s_%s.log' mdir "Blanton" "BER_Cycle" str_starttime
; logopen <file> <binary> <append> <PlainText> <timestamp>
; binary=0 text mode, so PlainText / timestamp are honoured
; append=1 keep earlier cycles, do not overwrite
; PlainText=1 strip the ANSI colour codes SONiC emits
logopen filename 0 1 1 1
test_cycle = 0
while 1
test_cycle = test_cycle + 1
flushrecv
logwrite ''#13#10
sprintf2 log_cycle_msg 'BER Diag/SONiC Cycle Test : %d'#13#10 test_cycle
logwrite '#####################################'#13#10
logwrite log_cycle_msg
logwrite '#####################################'#13#10
settitle log_cycle_msg
; ============================================================
; [2] Call : Script where switching is needed
; ============================================================
; ====== Diag Test ======
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30"'
wait prompt_diag
sendln "sleep 40"
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 256-259 dsc"'
wait prompt_diag
sendln 'swutil 0:show temp'
wait prompt_diag
sendln "swutil *:extphy core_diag all"
wait prompt_diag
; ---- Diag -> SONiC ----
sendln 'fpga_switch.sh cb 0 0x480 0xD0000'
bb_target_tok = sonic_tok
bb_sig_target = sonic_sig
bb_sig_other = diag_sig
call bb_boot_to
if bb_ok = 0 then
sprintf2 bb_msg 'Boot to SONiC failed: %s' bb_err
messagebox bb_msg 'bios_boot'
end
endif
; ========== SONiC Test ==========
wait prompt_login
sendln "admin"
wait "Password:"
sendln "YourPaSsWoRd"
wait prompt_sonic
sendln "sudo -i"
wait prompt_sonic_root
sendln "sleep 10"
; ========== FAN SPEED ==========
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sprintf2 fan_ctrl_cmd 'fan-speed-control.sh %d' 30
sendln fan_ctrl_cmd
wait "Set all configured fan channels to"
sendln "y"
; ========== Wait DUT Init ==========
include "utils/wait_init.ttl"
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' 39 ' "'
wait prompt_sonic_root
sendln "sleep 40"
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c "dsh -c ' 39 'phydiag 256-259 dsc' 39 '"'
wait prompt_sonic_root
sendln 'show plat temperature'
; ---- SONiC -> Diag ----
wait prompt_sonic_root
sendln 'pcimem /sys/bus/pci/devices/0000:05:00.0/resource0 0x480 w 0xD0000'
bb_target_tok = diag_tok
bb_sig_target = diag_sig
bb_sig_other = sonic_sig
call bb_boot_to
if bb_ok = 0 then
sprintf2 bb_msg 'Boot to Diag failed: %s' bb_err
messagebox bb_msg 'bios_boot'
end
endif
endwhile
logclose
end
; ============================================================
; [3] Subroutine
; ============================================================
:bb_boot_to
bb_saved_to = timeout
call bb_run
timeout = bb_saved_to
mtimeout = 0
return
:bb_run
bb_ok = 0
bb_err = ''
call bb_enter_bios
if bb_ok = 0 return
call bb_goto_bootmgr
if bb_ok = 0 return
call bb_find_idx
if bb_ok = 0 return
call bb_select
call bb_verify
return
; ------------------------------------------------------------
; 等 POST 0226,之後連送 ESC 直到 BIOS 回應 'Esc is pressed'
; ------------------------------------------------------------
:bb_enter_bios
bb_ok = 0
flushrecv ; 清掉 reboot 前的舊資料,避免誤比對
timeout = 300
mtimeout = 0
wait bb_post_hotkey
if result = 0 then
bb_err = 'timeout waiting POST code 0226'
return
endif
timeout = 0
mtimeout = 300
for bb_i 1 200 ; 300 ms x 200 = 最多約 60 秒
send bb_key_esc
wait bb_esc_ack
if result > 0 then
bb_ok = 1
break ; 收到 ack 立即停送,避免多餘 ESC 把 Front Page 退掉
endif
next
mtimeout = 0
if bb_ok = 0 bb_err = 'no ESC ack from BIOS'
return
; ------------------------------------------------------------
; Front Page:預設反白在 Continue,按一次 Down 到 Boot Manager
; 以右側說明欄文字確認反白位置,再按 Enter
; ------------------------------------------------------------
:bb_goto_bootmgr
bb_ok = 0
timeout = 30
wait bb_fp_continue
if result = 0 then
bb_err = 'Front Page not shown'
return
endif
mpause 500
send bb_key_down
timeout = 5
wait bb_fp_bootmgr
if result = 0 then
bb_err = 'cannot highlight Boot Manager'
return
endif
mpause 300
send bb_key_enter
timeout = 15
wait bb_bm_header
if result = 0 then
bb_err = 'Boot Manager page not shown'
return
endif
bb_ok = 1
return
; ------------------------------------------------------------
; 解析 Boot Manager 清單,計算目標 entry 的 index(0-based)
; 每個 entry 以 'EFI '(含 UEFI)或 'SVOS' 開頭計數,命中目標字串即停止
; ------------------------------------------------------------
:bb_find_idx
bb_ok = 0
bb_idx = -1
bb_cnt = 0
timeout = 0
mtimeout = 3000
for bb_i 1 20
wait 'EFI ' 'SVOS' bb_target_tok
if result = 0 break ; 清單畫完仍未命中
if result = 3 then
bb_idx = bb_cnt - 1 ; 目標字串前的 'EFI ' 屬於目標 entry 本身
break
endif
bb_cnt = bb_cnt + 1
next
mtimeout = 0
if bb_idx < 0 then
bb_err = 'target entry not found in Boot Manager'
return
endif
timeout = 5
wait bb_bm_footer ; 等整頁畫完才開始按鍵
bb_ok = 1
return
; ------------------------------------------------------------
; 預設反白在第一個 entry,往下移 bb_idx 格後按 Enter
; ------------------------------------------------------------
:bb_select
mpause 300
if bb_idx > 0 then ; TTL 的 for 1 0 會倒數執行,必須先擋掉
for bb_i 1 bb_idx
send bb_key_down
timeout = 3
wait bb_bm_footer ; BIOS 每按一次會整頁重畫,畫完再按下一次
mpause 200
next
endif
send bb_key_enter
; 之後不可再送任何按鍵:Diag 走 EFI Shell,
; 任何按鍵都會被當成「跳過 / 中斷 startup.nsh」
return
; ------------------------------------------------------------
; 同時等目標與另一個 image 的特徵字串
; ------------------------------------------------------------
:bb_verify
bb_ok = 0
timeout = 300
wait bb_sig_target bb_sig_other
if result = 1 then
bb_ok = 1
elseif result = 2 then
bb_err = 'booted into wrong image'
else
bb_err = 'timeout waiting boot signature'
endif
return
@@ -0,0 +1,137 @@
#!/bin/bash
#===============================================================================
# Script : avt_pmpower.sh
# Purpose : Dump AMD AVT PM table (get_pmdata) and summarize package power.
#
# Author : ETWen
# Date : 20260923
#
# Version History
# V1.0.0 20260923 Initial Version
#
# Usage : ./avt_pmpower.sh [-p <AVTCMD path>] [-q] [-h]
# -p Path to AVTCMD (default: $AVTCMD_PATH or ./AVTCMD)
# -q Quiet: summary only, suppress raw PM table
# -h Help
#
# Exit : 0 ok / 1 usage / 2 AVTCMD not found / 3 AVTCMD failed
# 4 parse failed (no power fields found)
#
# Note : Values come from SMU telemetry, not direct measurement. Absolute
# accuracy depends on BIOS SVI telemetry calibration. Cross-check
# against VR PMBus READ_POUT when accuracy matters.
#===============================================================================
set -u
set -o pipefail
#------------------------------------------------------------------------------
# Defaults
#------------------------------------------------------------------------------
AVTCMD_BIN="${AVTCMD_PATH:-./AVTCMD}"
AVT_MODULE="pmm"
AVT_CMD="get_pmdata()"
QUIET=0
#------------------------------------------------------------------------------
# usage - print help
#------------------------------------------------------------------------------
usage() {
sed -n '/^# Usage/,/^# Exit/p' "$0" | sed 's/^# \{0,1\}//'
}
#------------------------------------------------------------------------------
# Argument parsing
#------------------------------------------------------------------------------
while getopts ":p:qh" opt; do
case "$opt" in
p) AVTCMD_BIN="$OPTARG" ;;
q) QUIET=1 ;;
h) usage; exit 0 ;;
:) echo "ERROR: -$OPTARG requires an argument" >&2; usage >&2; exit 1 ;;
\?) echo "ERROR: unknown option -$OPTARG" >&2; usage >&2; exit 1 ;;
esac
done
#------------------------------------------------------------------------------
# Pre-flight check
#------------------------------------------------------------------------------
if [ ! -x "$AVTCMD_BIN" ]; then
echo "ERROR: AVTCMD not found or not executable: $AVTCMD_BIN" >&2
echo " Use -p <path> or export AVTCMD_PATH=<path>" >&2
exit 2
fi
if [ "$(id -u)" -ne 0 ]; then
echo "WARN : not running as root, AVTCMD may fail to access SMU." >&2
fi
#------------------------------------------------------------------------------
# Collect PM table
#------------------------------------------------------------------------------
RAW="$("$AVTCMD_BIN" -module "$AVT_MODULE" "$AVT_CMD" 2>&1)"
RC=$?
if [ $RC -ne 0 ]; then
echo "ERROR: AVTCMD exited with code $RC" >&2
echo "$RAW" >&2
exit 3
fi
if [ "$QUIET" -eq 0 ]; then
printf '%s\n' "$RAW"
fi
#------------------------------------------------------------------------------
# Parse & summarize
# - split on whitespace and comma, keep only "key:number" tokens
# - bracketed tokens ([Pkg:0], [MISC]) are skipped by the regex anchor
#------------------------------------------------------------------------------
printf '%s\n' "$RAW" | awk '
{
n = split($0, a, /[ ,]+/)
for (i = 1; i <= n; i++) {
if (a[i] ~ /^[A-Za-z0-9_()]+:[-0-9.]+$/) {
split(a[i], kv, ":")
m[kv[1]] = kv[2]
found++
}
}
}
# pct - usage against limit, guard divide-by-zero
function pct(v, l) {
return (l > 0) ? sprintf("%5.1f%%", 100 * v / l) : " n/a"
}
# has - field present in PM table
function has(k) {
return (k in m)
}
END {
if (found == 0) {
print "ERROR: no PM fields parsed, PM table format may have changed." > "/dev/stderr"
exit 4
}
print "===== Package Power (live) ====="
if (has("SktPwr(W)"))
printf "%-9s: %7.2f W\n", "SktPwr", m["SktPwr(W)"]
if (has("PPT_VALUE_FAST"))
printf "%-9s: %7.2f / %3d W %s\n", "PPT Fast",
m["PPT_VALUE_FAST"], m["PPT_LIMIT_FAST"],
pct(m["PPT_VALUE_FAST"], m["PPT_LIMIT_FAST"])
if (has("PPT_VALUE_SLOW"))
printf "%-9s: %7.2f / %3d W %s (%ss avg)\n", "PPT Slow",
m["PPT_VALUE_SLOW"], m["PPT_LIMIT_SLOW"],
pct(m["PPT_VALUE_SLOW"], m["PPT_LIMIT_SLOW"]),
(has("SlowPPTTimeConstant") ? m["SlowPPTTimeConstant"] : "?")
if (has("MemPwr(W)"))
printf "%-9s: %7.2f W\n", "MemPwr", m["MemPwr(W)"]
}
'
exit $?
@@ -0,0 +1,100 @@
#!/usr/bin/env bash
# =============================================================================
# blanton_ber_debug.sh -- SerDes BER, raw run of tools/BER_Test.txt
# =============================================================================
# Version History:
# V1.0.0 2026-10-07 First version. Runs the hand-pasted BER flow end to end
# (prbs set p=p31 / prbs get x2 / STArt / sleep 40 / Ber /
# STOp / clear) and prints every bcmcmd output as is --
# no parsing, no PASS/FAIL, no summary. blanton_ber.sh is
# the judged version; this one is for looking at the raw
# output on the bench.
#
# Order of operations (per step, unit 0 first, then unit 1):
# phydiag <ports> prbs set p=p31
# phydiag <ports> prbs get twice: the 1st clears the sticky
# phydiag <ports> prbs get "unlocked since last call", the 2nd
# is the current lock state
# phydiag <ports> prbsstat STArt Interval=30
# sleep 40 MUST be > Interval, or Ber is read
# before the first interval settles
# phydiag <ports> prbsstat Ber
# phydiag <ports> prbsstat STOp
# phydiag <ports> prbs clear releases the lanes back to normal
#
# ⚠️ Links show DOWN while PRBS runs -- that is expected.
# ⚠️ Do not run together with blanton_ber.sh / blanton_traffic_linespeed.sh /
# blanton_tr518.sh -- they all take over the same ports.
#
# Usage:
# ./blanton_ber_debug.sh # unit 0 and 1
# ./blanton_ber_debug.sh -u 0 # unit 0 only
# ./blanton_ber_debug.sh -u 1 # unit 1 only
#
# Env overrides:
# BCMCMD_CMD=bcmcmd BER_POLY=p=p31 BER_INTERVAL=30 BER_WAIT=40
# BER_PORTS="1-24,..." (default: the 200G ports, no 268 -- same as
# tools/BER_Test.txt; add ",268" for the 100G uplink)
# =============================================================================
BCMCMD_CMD="${BCMCMD_CMD:-bcmcmd}"
BER_UNITS="0 1"
BER_PORTS="${BER_PORTS:-1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565}"
BER_POLY="${BER_POLY:-p=p31}"
BER_INTERVAL="${BER_INTERVAL:-30}"
BER_WAIT="${BER_WAIT:-40}"
usage() {
sed -n '/^# Usage:/,/^# =====/p' "$0" | sed '$d; s/^# \{0,1\}//'
}
while [ $# -gt 0 ]; do
case "$1" in
-u|--unit)
case "$2" in
0|1) BER_UNITS="$2" ;;
*) echo "[ERR ] invalid unit '$2' (use 0 or 1)" >&2; exit 2 ;;
esac
shift 2 ;;
-h|--help) usage; exit 0 ;;
*) echo "[ERR ] unknown option '$1'" >&2; usage >&2; exit 2 ;;
esac
done
# bcmcmd reads stdin -- keep it on /dev/null (see blanton_traffic_linespeed.sh V0.3.1)
_bcm() {
local unit="$1"; shift
local cmd="dsh -c 'phydiag ${BER_PORTS} $*'"
echo
echo "### [$(date '+%F %T')] unit $unit: phydiag <ports> $*"
"$BCMCMD_CMD" -n "$unit" -c " ${cmd} " </dev/null 2>&1
}
for u in $BER_UNITS; do
_bcm "$u" "prbs set ${BER_POLY}"
_bcm "$u" "prbs get"
_bcm "$u" "prbs get"
done
for u in $BER_UNITS; do
_bcm "$u" "prbsstat STArt Interval=${BER_INTERVAL}"
done
echo
echo "### [$(date '+%F %T')] sleep ${BER_WAIT}"
sleep "$BER_WAIT"
for u in $BER_UNITS; do
_bcm "$u" "prbsstat Ber"
done
for u in $BER_UNITS; do
_bcm "$u" "prbsstat STOp"
done
for u in $BER_UNITS; do
_bcm "$u" "prbs clear"
done
echo
echo "### [$(date '+%F %T')] BER_DEBUG_DONE units: $BER_UNITS"
@@ -0,0 +1,106 @@
#!/usr/bin/env bash
# =============================================================================
# blanton_fdr.sh -- SerDes FDR statistics (phydiag fdrstat), raw output
# =============================================================================
# Version History:
# V1.0.0 2026-10-21 First version. start / clear / rdcnt / stop over
# 'phydiag <ports> fdrstat ...' through bcmcmd, the same
# way blanton_ber_debug.sh drives prbsstat. Every bcmcmd
# output is printed as is -- no parsing, no PASS/FAIL.
# V1.0.1 2026-10-22 Change: default FDR_PORTS is now the cabled-port list of
# blanton_traffic_linespeed.sh (TL_PS_PORTS), not
# '1-259,270-565' -- the old range also printed the
# uncabled ports (cd15..19, cd47..51, ...). Port 268 (ce0)
# is still left out; add ',268' through FDR_PORTS.
#
# Sub-commands (each one runs on unit 0, then unit 1):
# start phydiag '<ports>' fdrstat STArt bin_group=both Interval=30
# clear phydiag '<ports>' fdrstat clear
# rdcnt phydiag '<ports>' fdrstat Counters
# stop phydiag '<ports>' fdrstat STOp
#
# ⚠️ 'stop' sends 'fdrstat STOp', by analogy with 'prbsstat STOp'. It has
# not been checked on the bench -- if the BCM shell rejects it, look at
# 'phydiag help' (or 'fdrstat' with no argument) for the right keyword.
# ⚠️ bcmcmd exits 0 even when the BCM shell refuses a command, so this
# script cannot tell success from failure. Read the output.
#
# Usage:
# ./blanton_fdr.sh <start|clear|rdcnt|stop> [-u 0|1] [-i <sec>] [-n]
# -u 0 | -u 1 one switch unit only (default: both, 0 then 1)
# -i <sec> start: fdrstat Interval (default 30)
# -n dry run: print the bcmcmd lines, do not run them
#
# Env overrides:
# BCMCMD_CMD=bcmcmd FDR_INTERVAL=30 FDR_BIN_GROUP=both
# FDR_PORTS="1-24,40-96,..." (default: the cabled ports, same list as
# TL_PS_PORTS in blanton_traffic_linespeed.sh
# and BER_PORTS in blanton_ber_debug.sh; no 268)
# =============================================================================
BCMCMD_CMD="${BCMCMD_CMD:-bcmcmd}"
FDR_UNITS="0 1"
# Cabled ports only -- keep in sync with TL_PS_PORTS in blanton_traffic_linespeed.sh
FDR_PORTS="${FDR_PORTS:-1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565}"
FDR_INTERVAL="${FDR_INTERVAL:-30}"
FDR_BIN_GROUP="${FDR_BIN_GROUP:-both}"
FDR_DRY_RUN=0
usage() {
sed -n '/^# Usage:/,/^# =====/p' "$0" | sed '$d; s/^# \{0,1\}//'
}
[ $# -ge 1 ] || { usage >&2; exit 2; }
ACT=$1; shift
case "$ACT" in
start|clear|rdcnt|stop) ;;
-h|--help|help) usage; exit 0 ;;
*) echo "[ERR ] unknown sub-command '$ACT'" >&2; usage >&2; exit 2 ;;
esac
while [ $# -gt 0 ]; do
case "$1" in
-u|--unit)
case "$2" in
0|1) FDR_UNITS="$2" ;;
*) echo "[ERR ] invalid unit '$2' (use 0 or 1)" >&2; exit 2 ;;
esac
shift 2 ;;
-i|--interval)
case "$2" in
''|*[!0-9]*) echo "[ERR ] invalid interval '$2'" >&2; exit 2 ;;
*) FDR_INTERVAL="$2" ;;
esac
shift 2 ;;
-n|--dry-run) FDR_DRY_RUN=1; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "[ERR ] unknown option '$1'" >&2; usage >&2; exit 2 ;;
esac
done
# bcmcmd reads stdin -- keep it on /dev/null (see blanton_traffic_linespeed.sh V0.3.1)
_bcm() {
local unit="$1"; shift
local cmd="dsh -c \"phydiag '${FDR_PORTS}' fdrstat $*\""
echo
echo "### [$(date '+%F %T')] unit $unit: phydiag '${FDR_PORTS}' fdrstat $*"
if [ "$FDR_DRY_RUN" = "1" ]; then
echo "[DRY ] $BCMCMD_CMD -n $unit -c ' ${cmd} '"
return 0
fi
"$BCMCMD_CMD" -n "$unit" -c " ${cmd} " </dev/null 2>&1
}
case "$ACT" in
start) SUB="STArt bin_group=${FDR_BIN_GROUP} Interval=${FDR_INTERVAL}" ;;
clear) SUB="clear" ;;
rdcnt) SUB="Counters" ;;
stop) SUB="STOp" ;;
esac
for u in $FDR_UNITS; do
_bcm "$u" "$SUB"
done
echo
echo "### [$(date '+%F %T')] FDR_${ACT^^}_DONE units: $FDR_UNITS"
@@ -0,0 +1,202 @@
#!/usr/bin/env bash
# =============================================================================
# blanton_multiphase_read.sh -- read back the SWB multiphase VRMs (V / I / P / T)
# =============================================================================
# Version History:
# V1.0.0 2026-11-04 First version. Reads the same controllers that
# blanton_multiphase_margin.sh writes (native i2c,
# SWB0 = i2c-13/15, SWB1 = i2c-14/16) and prints one row
# per chip in the pu_show.sh layout, with the raw PMBus
# word in hex after every voltage and current.
# =============================================================================
#
# Per chip, per PAGE (page 0 -> VOUT/IOUT, page 1 -> VOUT2/IOUT2):
# PAGE 0x00 i2cset <page>
# READ_VOUT 0x8B MP29816 : bits[11:0] x LSB from MFR_VOUT_SCALE_LOOP
# (0x29) bits[12:10], read from the chip
# MP2985B : bits[11:0] x 1 mV
# READ_IOUT 0x8C SLINEAR11
# READ_TEMP1 0x8D page 0 only. MP29816 SLINEAR11, MP2985B bits[10:0]
# two's complement degC
# POUT computed V x I (not READ_POUT) -- same as pu_show.sh
# Conversions are the ones verified in blanton_pwr_data.sh V1.0.0.
#
# The kernel / platform daemons may talk to the same chips and move PAGE
# between our page select and our read. After every page's reads the PAGE
# register is read back; if it moved, that page is re-read (MP_RETRY times)
# and printed NA if it never holds still. 0xFFFF is also treated as NA.
#
# Read only -- nothing but PAGE is written. PAGE is put back to 0 afterwards.
# ⚠️ Do not run while blanton_multiphase_margin.sh is writing: both select
# PAGE on the same chips and neither one knows about the other.
#
# Usage:
# ./blanton_multiphase_read.sh # both boards
# ./blanton_multiphase_read.sh -u 0 # SWB0 only
# ./blanton_multiphase_read.sh -n # print the i2c commands only
#
# Options:
# -u|--unit <0|1|all> which switch board (default: both)
# -d|--debug print every i2c command and the word it returned
# -n|--dry-run print the commands only, do not touch the DUT
# -h|--help help
# =============================================================================
MP_UNITS="${MP_UNITS:-0 1}"
MP_RETRY="${MP_RETRY:-3}"
MP_DRY_RUN=${MP_DRY_RUN:-0}
DEBUG_MODE=${DEBUG_MODE:-0}
MP_NA="NA"
# --- Chip map ----------------------------------------------------------------
# "name:part:bus_swb0:addr:pages" SWB1 = same addr on bus + 1 (13->14, 15->16)
# PU numbers are from PWR_Data.xlsx (blanton_pwr_data.sh PWR_RAILS).
MP_CHIPS=(
"PU2:MP29816:13:0x20:0"
"PU105:MP2985B:13:0x21:0 1"
"PU102:MP2985B:13:0x22:0 1"
"PU114:MP2985B:13:0x25:0 1"
"PU122:MP2985B:13:0x27:0 1"
"PU142:MP2985B:13:0x29:0 1"
"PU108:MP2985B:15:0x23:0 1"
"PU111:MP2985B:15:0x24:0 1"
"PU118:MP2985B:15:0x26:0 1"
"PU127:MP2985B:15:0x28:0 1"
)
_mp_err() { echo -e "[\033[31mERR \033[0m] $*" >&2; }
_mp_dbg() { [ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] $*\033[0m" >&2; return 0; }
# --- i2c ---------------------------------------------------------------------
_mp_setpage() { # <bus> <addr> <page>
if [ "$MP_DRY_RUN" = "1" ]; then echo "i2cset -f -y $1 $2 0x00 $3"; return 0; fi
_mp_dbg "i2cset -f -y $1 $2 0x00 $3"
i2cset -f -y "$1" "$2" 0x00 "$3" 2>/dev/null
}
_mp_rd() { # <bus> <addr> <reg> <b|w> -> decimal on stdout
local out
if [ "$MP_DRY_RUN" = "1" ]; then echo "i2cget -f -y $1 $2 $3 $4" >&2; echo 0; return 0; fi
out=$(i2cget -f -y "$1" "$2" "$3" "$4" 2>/dev/null) || { _mp_dbg "i2cget -f -y $1 $2 $3 $4 -> fail"; return 1; }
_mp_dbg "i2cget -f -y $1 $2 $3 $4 -> $out"
case "$out" in 0x[0-9a-fA-F]*) echo $(( out )) ;; *) return 1 ;; esac
}
# --- decoders ----------------------------------------------------------------
_mp_l11() { # SLINEAR11 word -> value
local w=$(( $1 & 0xFFFF )) e m
e=$(( (w >> 11) & 0x1F )); (( e > 15 )) && e=$(( e - 32 ))
m=$(( w & 0x7FF )); (( m > 1023 )) && m=$(( m - 2048 ))
awk -v m="$m" -v e="$e" 'BEGIN { printf "%.3f", m * (2.0 ^ e) }'
}
_mp_res() { # MP29816 Vout LSB (V) from MFR_VOUT_SCALE_LOOP bits[12:10]
case $(( ($1 >> 10) & 0x7 )) in
0) echo 0.00625 ;; 1) echo 0.005 ;; 2) echo 0.0025 ;; 3) echo 0.002 ;;
4) echo 0.001 ;; 5) echo 0.00390625 ;; 6) echo 0.001953125 ;; 7) echo 0.0009765625 ;;
esac
}
# --- one page: sets V_STR / I_STR / V_VAL / I_VAL ----------------------------
_mp_read_page() { # <part> <bus> <addr> <page> <res>
local part="$1" bus="$2" addr="$3" pg="$4" res="$5" try wv wi wp
V_STR="$MP_NA"; I_STR="$MP_NA"; V_VAL=""; I_VAL=""
for (( try=0; try<MP_RETRY; try++ )); do
_mp_setpage "$bus" "$addr" "$pg" || continue
wv=$(_mp_rd "$bus" "$addr" 0x8B w) || wv=""
wi=$(_mp_rd "$bus" "$addr" 0x8C w) || wi=""
[ "$MP_DRY_RUN" = "1" ] && { _mp_rd "$bus" "$addr" 0x00 b >/dev/null; return 0; }
wp=$(_mp_rd "$bus" "$addr" 0x00 b) || continue
(( wp == pg )) || { _mp_dbg "$bus/$addr: PAGE moved to $wp, re-reading page $pg"; continue; }
break
done
(( try == MP_RETRY )) && return 1
if [ -n "$wv" ] && (( wv != 0xFFFF )); then
if [ "$part" = "MP29816" ]; then
V_VAL=$(awk -v c=$(( wv & 0xFFF )) -v r="$res" 'BEGIN { printf "%.3f", c * r }')
else
V_VAL=$(awk -v c=$(( wv & 0xFFF )) 'BEGIN { printf "%.3f", c / 1000 }')
fi
V_STR=$(printf '%s(0x%04X)' "$V_VAL" "$wv")
fi
if [ -n "$wi" ] && (( wi != 0xFFFF )); then
I_VAL=$(_mp_l11 "$wi")
I_STR=$(printf '%s(0x%04X)' "$I_VAL" "$wi")
fi
return 0
}
_mp_pout() { [ -n "$1" ] && [ -n "$2" ] && awk -v v="$1" -v i="$2" 'BEGIN { printf "%.3f", v * i }' || echo "$MP_NA"; }
# --- main --------------------------------------------------------------------
blanton_multiphase_read() {
while [ $# -gt 0 ]; do
case "$1" in
-u|--unit)
case "$2" in
all|ALL) MP_UNITS="0 1" ;;
0|1) MP_UNITS="$2" ;;
*) _mp_err "invalid unit '$2' (use 0, 1 or all)"; return 2 ;;
esac
shift 2 ;;
-d|--debug) DEBUG_MODE=1; shift ;;
-n|--dry-run) MP_DRY_RUN=1; shift ;;
-h|--help) sed -n '/^# Usage:/,/^# =====/p' "${BASH_SOURCE[0]}" | sed '$d; s/^# \{0,1\}//'; return 0 ;;
*) _mp_err "unknown option '$1'"; return 2 ;;
esac
done
command -v i2cget >/dev/null 2>&1 || [ "$MP_DRY_RUN" = "1" ] || { _mp_err "i2cget not found"; return 1; }
local fmt='%-16s| %-17s| %-17s| %-18s| %-18s| %-9s| %-9s| %s\n'
local rule='--------------------------------------------------------------------------------------------------------------------------'
local u e name part bus0 addr pages bus res w temp tot sums=""
local V1 I1 V1v I1v V2 I2 V2v I2v P1 P2 m
printf "$fmt" NAME "VOUT" "VOUT2" "IOUT" "IOUT2" "POUT" "POUT2" "TEMP"
echo "$rule"
for u in $MP_UNITS; do
tot=0
for e in "${MP_CHIPS[@]}"; do
IFS=: read -r name part bus0 addr pages <<< "$e"
bus=$(( bus0 + u ))
res=""; temp="$MP_NA"
V1="$MP_NA"; I1="$MP_NA"; V1v=""; I1v=""
V2="$MP_NA"; I2="$MP_NA"; V2v=""; I2v=""
# page 0: scale (MP29816), temperature, VOUT/IOUT
_mp_setpage "$bus" "$addr" 0
if [ "$part" = "MP29816" ]; then
w=$(_mp_rd "$bus" "$addr" 0x29 w) && res=$(_mp_res "$w")
[ -n "$res" ] || res=0.0025
fi
if w=$(_mp_rd "$bus" "$addr" 0x8D w) && (( w != 0xFFFF )); then
if [ "$part" = "MP29816" ]; then temp=$(printf '%.2f' "$(_mp_l11 "$w")")
else m=$(( w & 0x7FF )); (( m > 1023 )) && m=$(( m - 2048 )); temp=$(printf '%.2f' "$m"); fi
fi
if _mp_read_page "$part" "$bus" "$addr" 0 "$res"; then
V1="$V_STR"; I1="$I_STR"; V1v="$V_VAL"; I1v="$I_VAL"
fi
if [[ " $pages " == *" 1 "* ]] && _mp_read_page "$part" "$bus" "$addr" 1 "$res"; then
V2="$V_STR"; I2="$I_STR"; V2v="$V_VAL"; I2v="$I_VAL"
fi
_mp_setpage "$bus" "$addr" 0 >/dev/null
P1=$(_mp_pout "$V1v" "$I1v")
if [[ " $pages " == *" 1 "* ]]; then P2=$(_mp_pout "$V2v" "$I2v"); else P2="$MP_NA"; fi
[ "$P1" != "$MP_NA" ] && tot=$(awk -v a="$tot" -v b="$P1" 'BEGIN { printf "%.3f", a + b }')
[ "$P2" != "$MP_NA" ] && tot=$(awk -v a="$tot" -v b="$P2" 'BEGIN { printf "%.3f", a + b }')
[ "$MP_DRY_RUN" = "1" ] && continue
printf "$fmt" "SWB${u}-MP_${name}" "$V1" "$V2" "$I1" "$I2" "$P1" "$P2" "$temp"
done
sums="${sums}SWB${u} Total Power: ${tot} W"$'\n'
done
[ "$MP_DRY_RUN" = "1" ] && return 0
echo "$rule"
printf '%s' "$sums"
echo "(hex = raw PMBus word; POUT = VOUT x IOUT; an NA row means the chip did not answer or PAGE kept moving)"
}
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
blanton_multiphase_read "$@"
fi
@@ -0,0 +1,320 @@
#!/usr/bin/env bash
# =============================================================================
# blanton_tr518_thermal.sh -- TH6 tr 518 load for thermal tests, via bcmcmd
# =============================================================================
# Version History:
# V1.0.0 2026-10-28 First version. Copy of blanton_tr518.sh V1.0.1 with the
# thermal tr 518 arguments:
# Scenario=6 Profile=2 portstopktszstride=1 Count=260
# PktSize=603,218 CheckLinkTime=20 CheckDataTime=200
# TestPhase=1
# (no PortList / rm=ext, unlike blanton_tr518.sh). The
# per-unit sequence is unchanged: port cd lb=mac,
# l2 learn off, test mode nr=yes, tr 518. The argument
# string is read from TR_THERMAL_ARGS, not TR_TEST_ARGS,
# so an override meant for blanton_tr518.sh does not
# leak into this one.
# =============================================================================
#
# What this is for: tr 518 loads the switch so the power rails can be measured
# under traffic. The usual sequence is
#
# blanton_tr518_thermal.sh start # loads both units, waits to settle
# TH6_SWB0_power_readback.sh # now the numbers mean something
# TH6_SWB1_power_readback.sh
# blanton_tr518_thermal.sh stop
#
# ⚠️ tr 518 and blanton_traffic_linespeed CANNOT run at the same time. Both take
# over the cd ports and L2 learning; running one while the other is set up
# gives numbers from neither test. Stop one before the other starts.
#
# ⚠️ stop only undoes the loopback -- see TR_RESTORE_* below.
#
# Usage (run directly):
# ./blanton_tr518_thermal.sh start # both units
# ./blanton_tr518_thermal.sh start -u 0 # unit 0 only
# ./blanton_tr518_thermal.sh start -u 1 # unit 1 only
# ./blanton_tr518_thermal.sh stop [-u 0|1]
# ./blanton_tr518_thermal.sh help
#
# Usage (sourced, like the other blanton_*.sh tools):
# source blanton_tr518_thermal.sh
# blanton_tr518_thermal start -u 0
#
# Options:
# -u|--unit <0|1|all|0,1> bcmcmd unit(s). Default: $TR_UNITS ("0 1")
# -w|--wait <sec> start: settle wait after tr 518 (default $TR_SETTLE_SEC)
# --no-wait start: skip the settle wait entirely
# -d|--debug print every bcmcmd and its output
# -n|--dry-run print commands only, do not touch the DUT
# -h|--help help
#
# Environment overrides:
# BCMCMD_CMD=bcmcmd TR_UNITS="0 1" TR_SETTLE_SEC=120 TR_UNIT_GAP_SEC=1
# TR_THERMAL_ARGS="..." TR_LB_PORTS=cd TR_RESTORE_LEARN=0 TR_RESTORE_TESTMODE=0
# DEBUG_MODE=1
# =============================================================================
# === Config ==================================================================
BCMCMD_CMD="${BCMCMD_CMD:-bcmcmd}"
TR_UNITS="${TR_UNITS:-0 1}" # one DUT = two switch boards (0 and 1)
# Settle wait after tr 518 is issued. The point is NOT the test itself -- it is
# to stop someone reading power while traffic is still ramping and reporting a
# number that is neither idle nor loaded. Lower it only if you know the rails
# have already settled.
TR_SETTLE_SEC="${TR_SETTLE_SEC:-120}"
# Gap between unit 0 and unit 1 (each unit is set up as a complete block, the
# way TR518.txt does it -- the cd ports are in MAC loopback, so a unit does not
# depend on the other one being ready).
TR_UNIT_GAP_SEC="${TR_UNIT_GAP_SEC:-1}"
# Ports put into MAC loopback. 'cd' = the cd port group, per TR518.txt.
TR_LB_PORTS="${TR_LB_PORTS:-cd}"
# Printed by the BCM shell only after tr 518 has accepted its arguments and
# started. Used as the success marker, because bcmcmd's own exit status is not
# trustworthy for a command that runs longer than its response poll.
TR_TEST_OK_PAT="${TR_TEST_OK_PAT:-TR 518 TEST PARAMETERS}"
# The thermal tr 518 argument string. One editable line so it can be pasted
# straight from / into a manual bcmcmd.
TR_THERMAL_ARGS="${TR_THERMAL_ARGS:-Scenario=6 Profile=2 portstopktszstride=1 Count=260 PktSize=603,218 CheckLinkTime=20 CheckDataTime=200 TestPhase=1}"
# TR518.txt stops with 'port cd lb=none' and nothing else, so that is the
# default here too. But note what start changed and stop does NOT put back:
# l2 learn off -> the unit keeps learning disabled
# test mode nr=yes -> the unit stays in test mode
# Both persist until something else changes them or the box reboots. Set these
# to 1 if you want stop to be a true inverse; they are off by default because
# they are not in the bench-verified list.
TR_RESTORE_LEARN="${TR_RESTORE_LEARN:-0}"
TR_RESTORE_TESTMODE="${TR_RESTORE_TESTMODE:-0}"
DEBUG_MODE=${DEBUG_MODE:-0}
TR_DRY_RUN=${TR_DRY_RUN:-0}
TR_NO_WAIT=${TR_NO_WAIT:-0}
# === Logging =================================================================
_tr_info() { echo -e "[\033[34mINFO\033[0m] $*"; }
_tr_ok() { echo -e "[\033[32m OK \033[0m] $*"; }
_tr_warn() { echo -e "[\033[33mWARN\033[0m] $*" >&2; }
_tr_err() { echo -e "[\033[31mERR \033[0m] $*" >&2; }
_tr_dbg() { [ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] $*\033[0m" >&2; return 0; }
# === bcmcmd wrapper ==========================================================
# stdin is closed for the same reason as in blanton_traffic_linespeed.sh:
# bcmcmd otherwise inherits the caller's stdin and eats whatever a surrounding
# loop was reading.
#
# bcmcmd exits 0 even when the BCM shell refused the command, so the output is
# pattern-matched as well (the V0.3.1 lesson from blanton_traffic_linespeed.sh).
TR_ERR_PAT="${TR_ERR_PAT:-ERROR|Failed to execute|Invalid|Syntax error|Unavailable|Unknown command}"
# ...and the reverse also happens: bcmcmd exits NON-zero on a command that was
# accepted and is running. 'tr 518' outlives bcmcmd's response poll, so bcmcmd
# gives up with "polling socket timeout: Success" and a non-zero status while
# the test carries on inside the BCM shell. Treating that as a failure is what
# made V1.0.0 report ERR on a run that was actually fine.
TR_BENIGN_PAT="${TR_BENIGN_PAT:-polling socket timeout}"
# _tr_bcm <unit> <cmd> -> 0 ok, 1 failed
# _tr_bcm_ok <unit> <ok_marker> <cmd> -> as above, but if the output contains
# <ok_marker> the command is a success
# regardless of exit status.
#
# The marker is a POSITIVE proof of success ("the shell printed the thing it
# only prints when it accepted this command"), which is far more reliable than
# trying to enumerate every way bcmcmd can look unhappy.
_tr_bcm() { _tr_bcm_ok "$1" "" "${@:2}"; }
_tr_bcm_ok() {
local unit="$1" okpat="$2"; shift 2
local cmd="$*" out rc why=""
_tr_dbg "$BCMCMD_CMD -n $unit -c '$cmd'"
if [ "$TR_DRY_RUN" = "1" ]; then
echo "[DRY ] $BCMCMD_CMD -n $unit -c '$cmd'"
return 0
fi
out=$("$BCMCMD_CMD" -n "$unit" -c "$cmd" </dev/null 2>&1); rc=$?
[ "$DEBUG_MODE" = "1" ] && [ -n "$out" ] && echo "$out"
# 1. positive proof wins over everything else
if [ -n "$okpat" ] && echo "$out" | grep -qF "$okpat"; then
[ "$rc" -ne 0 ] && _tr_dbg "unit $unit: bcmcmd rc=$rc but '$okpat' seen -> accepted"
return 0
fi
# 2. the BCM shell said no
if echo "$out" | grep -qiE "$TR_ERR_PAT"; then
why="the BCM shell rejected it"
# 3. bcmcmd itself was unhappy -- unless it is the known transport artifact
elif [ "$rc" -ne 0 ]; then
if echo "$out" | grep -qiE "$TR_BENIGN_PAT"; then
_tr_dbg "unit $unit: bcmcmd rc=$rc (${TR_BENIGN_PAT}) -> tolerated"
return 0
fi
why="bcmcmd exited $rc"
else
return 0
fi
_tr_err "unit $unit: $why -- '$cmd'"
[ "$DEBUG_MODE" = "1" ] || { [ -n "$out" ] && echo "$out" >&2; }
return 1
}
_tr_units_check() {
local u ok=""
for u in $TR_UNITS; do
case "$u" in
0|1) ok="$ok $u" ;;
*) _tr_err "invalid unit '$u' (use 0, 1 or all)"; return 1 ;;
esac
done
[ -n "$ok" ] || { _tr_err "no unit selected"; return 1; }
TR_UNITS="${ok# }"
return 0
}
_tr_is_uint() { case "$1" in ''|*[!0-9]*) return 1 ;; *) return 0 ;; esac; }
_tr_gap() {
[ "$TR_DRY_RUN" = "1" ] && return 0
[ "$TR_UNIT_GAP_SEC" = "0" ] && return 0
sleep "$TR_UNIT_GAP_SEC"
}
# === start ===================================================================
# One complete block per unit, exactly the order in tools/TR518.txt.
blanton_tr518_thermal_start() {
_tr_units_check || return 1
_tr_is_uint "$TR_SETTLE_SEC" || { _tr_err "settle wait '$TR_SETTLE_SEC' is not an integer (-w <sec>)"; return 1; }
local unit fail=0 first=1
_tr_info "TR518 start on unit(s): $TR_UNITS"
for unit in $TR_UNITS; do
[ "$first" = "0" ] && _tr_gap
first=0
_tr_info "unit $unit: port $TR_LB_PORTS lb=mac -> l2 learn off -> test mode nr=yes -> tr 518"
_tr_bcm "$unit" "port $TR_LB_PORTS lb=mac" || fail=$((fail+1))
_tr_bcm "$unit" "l2 learn off" || fail=$((fail+1))
_tr_bcm "$unit" 'dsh -c "test mode nr=yes"' || fail=$((fail+1))
# "TR 518 TEST PARAMETERS" is printed only once the shell has parsed the
# arguments and started the test -- that is the proof we check for.
_tr_bcm_ok "$unit" "$TR_TEST_OK_PAT" "dsh -c \"tr 518 $TR_THERMAL_ARGS\"" || fail=$((fail+1))
done
if [ "$fail" -ne 0 ]; then
_tr_err "$fail command(s) failed -- traffic may not be running, not waiting"
_tr_warn "the unit(s) may still be in loopback: blanton_tr518_thermal.sh stop"
return 1
fi
if [ "$TR_NO_WAIT" = "1" ] || [ "$TR_SETTLE_SEC" = "0" ]; then
_tr_ok "TR518 running on unit(s): $TR_UNITS (settle wait skipped)"
_tr_warn "rails may still be ramping -- a power reading taken now is not a settled one"
return 0
fi
_tr_info "settling ${TR_SETTLE_SEC}s before the rails are worth reading ..."
[ "$TR_DRY_RUN" = "1" ] || sleep "$TR_SETTLE_SEC"
_tr_ok "TR518 running and settled on unit(s): $TR_UNITS"
_tr_info "read power now: TH6_SWB0_power_readback.sh / TH6_SWB1_power_readback.sh"
_tr_info "when finished: blanton_tr518_thermal.sh stop"
return 0
}
# === stop ====================================================================
# TR518.txt stops with 'port cd lb=none' only. l2 learning and test mode are
# left as start set them unless TR_RESTORE_* is turned on.
blanton_tr518_thermal_stop() {
_tr_units_check || return 1
local unit fail=0 first=1
_tr_info "TR518 stop on unit(s): $TR_UNITS"
for unit in $TR_UNITS; do
[ "$first" = "0" ] && _tr_gap
first=0
_tr_bcm "$unit" "port $TR_LB_PORTS lb=none" || fail=$((fail+1))
[ "$TR_RESTORE_LEARN" = "1" ] && { _tr_bcm "$unit" "l2 learn on" || fail=$((fail+1)); }
[ "$TR_RESTORE_TESTMODE" = "1" ] && { _tr_bcm "$unit" 'dsh -c "test mode nr=no"' || fail=$((fail+1)); }
done
if [ "$fail" -eq 0 ]; then
_tr_ok "unit(s) $TR_UNITS: port $TR_LB_PORTS lb=none"
[ "$TR_RESTORE_LEARN" = "1" ] || \
_tr_info "l2 learning is still off (TR_RESTORE_LEARN=1 to put it back)"
[ "$TR_RESTORE_TESTMODE" = "1" ] || \
_tr_info "test mode is still nr=yes (TR_RESTORE_TESTMODE=1 to put it back)"
else
_tr_warn "$fail command(s) failed -- check the unit is not still in loopback:"
_tr_warn " bcmcmd -n <u> -c 'port $TR_LB_PORTS' | head"
return 1
fi
return 0
}
# === Help ====================================================================
blanton_tr518_thermal_help() {
echo -e "\033[1mblanton_tr518_thermal.sh - TH6 built-in packet test (tr 518) for thermal loading\033[0m"
echo ""
echo -e " Units : \033[36m$TR_UNITS\033[0m"
echo -e " Settle wait : \033[36m${TR_SETTLE_SEC}s\033[0m after tr 518 (so power is read loaded, not ramping)"
echo -e " Loopback : \033[36mport $TR_LB_PORTS lb=mac\033[0m"
echo -e " tr 518 args : \033[36m$TR_THERMAL_ARGS\033[0m"
echo ""
echo -e "\033[1mSubcommands\033[0m"
echo -e " \033[33mstart\033[0m per unit: port $TR_LB_PORTS lb=mac -> l2 learn off -> test mode nr=yes -> tr 518 -> wait"
echo -e " \033[33mstop\033[0m per unit: port $TR_LB_PORTS lb=none"
echo -e " \033[33mhelp\033[0m"
echo ""
echo -e "\033[1mOptions\033[0m"
echo -e " \033[33m-u|--unit\033[0m <0|1|all> bcmcmd unit(s); 'all' = 0 1 (default: $TR_UNITS)"
echo -e " \033[33m-w|--wait\033[0m <sec> start: settle wait (default $TR_SETTLE_SEC)"
echo -e " \033[33m--no-wait\033[0m start: skip the settle wait"
echo -e " \033[33m-d|--debug\033[0m print every bcmcmd and its output"
echo -e " \033[33m-n|--dry-run\033[0m print commands only, do not touch the DUT"
echo ""
echo -e "\033[1mExamples\033[0m"
echo -e " ./blanton_tr518_thermal.sh start # both units, then wait ${TR_SETTLE_SEC}s"
echo -e " ./blanton_tr518_thermal.sh start -u 0 # unit 0 only"
echo -e " ./blanton_tr518_thermal.sh stop -u 1 # release unit 1"
echo -e " ./blanton_tr518_thermal.sh start -n # show the bcmcmds, touch nothing"
echo ""
echo -e "\033[33m stop only sends 'port $TR_LB_PORTS lb=none'. l2 learning stays off and test mode\033[0m"
echo -e "\033[33m stays nr=yes -- TR_RESTORE_LEARN=1 / TR_RESTORE_TESTMODE=1 to put them back.\033[0m"
echo -e "\033[33m tr 518 and blanton_traffic_linespeed cannot run together.\033[0m"
}
# === Argument parsing ========================================================
blanton_tr518_thermal() {
local sub="${1:-help}"; shift 2>/dev/null
while [ $# -gt 0 ]; do
case "$1" in
-u|--unit)
case "$2" in
all|ALL) TR_UNITS="0 1" ;;
*) TR_UNITS="$(echo "$2" | tr ',' ' ')" ;;
esac
shift 2 ;;
-w|--wait) TR_SETTLE_SEC="$2"; shift 2 ;;
--no-wait) TR_NO_WAIT=1; shift ;;
-d|--debug) DEBUG_MODE=1; shift ;;
-n|--dry-run) TR_DRY_RUN=1; shift ;;
-h|--help) blanton_tr518_thermal_help; return 0 ;;
*) _tr_err "unknown option '$1'"; return 1 ;;
esac
done
case "$sub" in
start) blanton_tr518_thermal_start ;;
stop) blanton_tr518_thermal_stop ;;
help|-h|--help) blanton_tr518_thermal_help ;;
*) _tr_err "unknown subcommand '$sub'"; blanton_tr518_thermal_help; return 1 ;;
esac
}
# Run when executed, define-only when sourced (same as the other blanton_*.sh).
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
blanton_tr518_thermal "$@"
fi
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
#!/bin/bash
#==============================================================================
# Author : ETWen
# Date : 20260923
# Purpose : Read DDR5 DIMM temperature from SPD5118 hub (MR49/MR50 @ 0x31)
# Usage : ./ddr5_temp_V1.0.1.sh [bus] [addr ...]
# default: bus=5, addr=0x50 0x51
#
# Version History:
# V1.0.0 20260923 Initial Version
# V1.0.1 20260923 Output label "DDR temp"
#==============================================================================
BUS=${1:-5}
shift 2>/dev/null
ADDRS=("$@")
[[ ${#ADDRS[@]} -eq 0 ]] && ADDRS=(0x50 0x51)
REG_TEMP=0x31
for ADDR in "${ADDRS[@]}"; do
raw=$(i2cget -y "$BUS" "$ADDR" "$REG_TEMP" w 2>&1)
if [[ $? -ne 0 || ! $raw =~ ^0x[0-9a-fA-F]+$ ]]; then
echo "[bus $BUS $ADDR] read fail: $raw"
continue
fi
# bit[12:2] = temperature, bit12 = sign, 0.25 C/LSB
v=$(( (raw >> 2) & 0x7FF ))
(( v & 0x400 )) && v=$(( v - 0x800 ))
awk -v b="$BUS" -v a="$ADDR" -v r="$raw" -v v="$v" \
'BEGIN { printf "[bus %s %s] DDR temp: %.2f C (raw=%s)\n", b, a, v * 0.25, r }'
done
@@ -0,0 +1,65 @@
#!/bin/bash
#==============================================================================
# Author : ETWen
# Date : 20260923
# Purpose : Read LTC4287 hot-swap controller temperatures (HSC_MAIN / HSC_STBY)
# Select source via 0xF3 (0xEB internal / 0xEF external), then read
# READ_TEMPERATURE 0x8D (Kelvin) and convert to Celsius
# Usage : ./hsc_temp_readback.sh
# bus = BUS (28), HSC_MAIN @ 0x40, HSC_STBY @ 0x45
#
# Version History:
# V1.0.0 20260922 Initial Version
# V1.0.1 20260923 Add header; fix delay comments (DELAY is 0.5 s, not 100 ms);
# CRLF -> LF (CRLF breaks bash on SONiC)
#==============================================================================
BUS=28
DELAY=0.5 # seconds between I2C transactions; ~4 s per run (4 readings x 2)
read_temp() {
local addr="$1"
local name="$2"
local sel="$3"
# Select temperature source
i2ctransfer -f -y "$BUS" w3@"$addr" 0xF3 "$sel" 0x00 > /dev/null
# DELAY between I2C transactions
sleep "$DELAY"
# Read temperature register 0x8D
raw=$(i2cget -f -y "$BUS" "$addr" 0x8D w 2>/dev/null)
if [ -z "$raw" ]; then
printf "%-32s : READ ERROR\n" "$name"
sleep "$DELAY"
return
fi
# Remove 0x prefix and convert hexadecimal to decimal
raw_dec=$((16#${raw#0x}))
# LTC4287 temperature is in Kelvin
temp_c=$(awk "BEGIN {printf \"%.2f\", $raw_dec - 273.15}")
printf "%-32s : %8s °C (raw %s)\n" \
"$name" "$temp_c" "$raw"
# DELAY before next I2C transaction
sleep "$DELAY"
}
echo "=========================================================="
echo " LTC4287 Temperature Readback"
echo "=========================================================="
# HSC_MAIN - LTC4287 @ 0x40
read_temp 0x40 "HSC_MAIN Internal (PU11)" 0xEB
read_temp 0x40 "HSC_MAIN External (PQ1)" 0xEF
# HSC_STBY - LTC4287 @ 0x45
read_temp 0x45 "HSC_STBY Internal (PU46)" 0xEB
read_temp 0x45 "HSC_STBY External (PQ53)" 0xEF
echo "=========================================================="
@@ -0,0 +1,98 @@
#!/bin/bash
# Turn TX off/on, or show state, for lanes of one Agera3 retimer on the sys and line side.
usage() {
cat <<USAGE
Usage: $0 <asic 0|1> <retimer-addr> <lane_map> <off|on|status> [--method squelch|power] [--force]
squelch TX squelch on sys and line side; lanes stay powered (works with the installed agera3)
power TX+RX lane power-down, the call SONiC makes on admin down; needs an agera3 with 'power'
--force allow 'off' on lanes that receive a signal
USAGE
exit 1
}
[ $# -ge 4 ] || usage
ASIC=$1; ADDR=$2; MAP=$3; ACT=$4; shift 4
METHOD=squelch; FORCE=0
while [ $# -gt 0 ]; do
case $1 in
--method) METHOD=$2; shift 2 ;;
--force) FORCE=1; shift ;;
*) usage ;;
esac
done
case $ASIC in 0|1) ;; *) usage ;; esac
case $ACT in off|on|status) ;; *) usage ;; esac
case $METHOD in squelch|power) ;; *) usage ;; esac
[[ $ADDR =~ ^0x[0-9a-fA-F]+$ && $MAP =~ ^0x[0-9a-fA-F]{1,2}$ ]] || usage
MAPV=$((MAP))
[ "$MAPV" -ge 1 ] || usage
ag() { sudo timeout 30 agera3 "$ASIC" "$ADDR" --no-cleanup "$@" </dev/null 2>&1; }
if [ "$METHOD" = power ] && ! sudo agera3 -h 2>&1 | grep -q -E '^\s+power '; then
echo "agera3 on this system has no 'power' command; use --method squelch"
exit 4
fi
lock_mask() {
ag rx-pmd-lock get side "$1" lane_map=0xff | awk '$2=="|" && $3=="LOCKED" {m += 2^$1} END {printf "%d", m}'
}
lane_tx() {
local lm
lm=$(printf '0x%02x' $((1 << $2)))
if [ "$METHOD" = squelch ]; then
ag squelch get tx "$1" lane_map=$lm | sed -n 's/.*squelch is \([A-Z]*\).*/\1/p' | awk '{print ($1 == "CLEAR") ? "on" : "off"}'
else
ag power get "$1" lane_map=$lm | awk -v l="$2" '$1 == l && $2 == "|" {print $3}'
fi
}
txoff_mask() {
local m=0 l s
for l in 0 1 2 3 4 5 6 7; do
[ $((MAPV >> l & 1)) = 1 ] || continue
s=$(lane_tx "$1" $l)
case $s in
off) m=$((m | 1 << l)) ;;
on) ;;
*) echo "unknown"; return ;;
esac
done
printf '0x%02x' $m
}
report() {
local side
for side in sys line; do
printf 'asic%s %-6s %-4s lane_map=0x%02x rx_lock=0x%02x tx_off=%s (%s)\n' \
"$ASIC" "$ADDR" "$side" "$MAPV" "$(lock_mask $side)" "$(txoff_mask $side)" "$METHOD"
done
}
[ "$ACT" = status ] && { report; exit 0; }
if [ "$ACT" = off ] && [ $FORCE = 0 ]; then
live=$(( ($(lock_mask sys) | $(lock_mask line)) & MAPV ))
if [ $live != 0 ]; then
printf 'REFUSED: asic%s %s lanes 0x%02x receive a signal; use --force to override\n' "$ASIC" "$ADDR" $live
exit 2
fi
fi
for side in sys line; do
if [ "$METHOD" = squelch ]; then
ag squelch set tx $side lane_map=$MAP $([ $ACT = off ] && echo enable || echo disable)
else
ag power set $side lane_map=$MAP $ACT
fi | grep -E 'FAIL|Error'
done
want=0x00; [ "$ACT" = off ] && want=$(printf '0x%02x' $MAPV)
rc=0
for side in sys line; do
got=$(txoff_mask $side)
printf 'asic%s %-6s %-4s lane_map=0x%02x tx_off=%s expected=%s (%s)\n' "$ASIC" "$ADDR" "$side" "$MAPV" "$got" "$want" "$METHOD"
[ "$got" = "$want" ] || rc=3
done
[ $rc = 0 ] && echo "PASS" || echo "FAIL"
exit $rc
@@ -0,0 +1,155 @@
#!/bin/bash
#==============================================================================
# Author : ETWen
# Date : 20261001
# Purpose : Tray ID I2C stress - write a pattern to the Tray ID register on each
# bus, read it back and compare. Patterns 0xA5 and 0x5A exercise every
# bit in both states (1010_0101 / 0101_1010).
# Usage : ./tray_id_stress.sh [-n loops] [-R] [-h]
# -n N repeat the whole sequence N times (default 1)
# -R do NOT restore the original register value at the end
# -h help
# Buses / address / register / patterns are set in the block below.
#
# Exit : 0 = all PASS, 1 = any FAIL or I2C error, 2 = usage
#
# Version History:
# V1.0.0 20261001 Initial Version
#==============================================================================
#------------------------------------------------------------------------------
# Settings - edit here
#------------------------------------------------------------------------------
BUSES=(34 35 38 39) # i2c buses, one Tray ID device each
ADDR=0x70 # device address
REG=0x02 # Tray ID register
PATTERNS=(0xa5 0x5a) # written in this order, each read back and compared
RESTORE=1 # 1 = write the original value back when done
LOOPS=1
usage() {
sed -n '/^# Usage/,/^# Exit/p' "$0" | sed 's/^# \{0,1\}//'
}
while getopts ":n:Rh" opt; do
case "$opt" in
n) LOOPS="$OPTARG" ;;
R) RESTORE=0 ;;
h) usage; exit 0 ;;
:) echo "ERROR: -$OPTARG needs a value" >&2; usage >&2; exit 2 ;;
\?) echo "ERROR: unknown option -$OPTARG" >&2; usage >&2; exit 2 ;;
esac
done
if ! [[ "$LOOPS" =~ ^[1-9][0-9]*$ ]]; then
echo "ERROR: -n must be a positive integer (got '$LOOPS')" >&2; exit 2
fi
for t in i2cset i2cget; do
command -v "$t" >/dev/null 2>&1 || { echo "ERROR: $t not found" >&2; exit 2; }
done
# Counters per bus
declare -A N_PASS N_FAIL N_ERR ORIG
for b in "${BUSES[@]}"; do N_PASS[$b]=0; N_FAIL[$b]=0; N_ERR[$b]=0; ORIG[$b]=""; done
# Read one byte; prints the value (0xNN) on success, returns 1 on failure.
rd() {
local out
out=$(i2cget -f -y "$1" "$ADDR" "$REG" 2>&1)
if [[ $? -ne 0 || ! "$out" =~ ^0x[0-9a-fA-F]{1,2}$ ]]; then
echo "$out"; return 1
fi
echo "$out"
}
TS() { date '+%Y-%m-%d %H:%M:%S'; }
echo "=========================================================="
echo " Tray ID I2C stress $(TS)"
echo " buses: ${BUSES[*]} addr $ADDR reg $REG"
echo " patterns: ${PATTERNS[*]} loops: $LOOPS restore: $RESTORE"
echo "=========================================================="
#------------------------------------------------------------------------------
# Original values (so they can be put back)
#------------------------------------------------------------------------------
for b in "${BUSES[@]}"; do
if v=$(rd "$b"); then
ORIG[$b]="$v"
printf "[bus %-2s %s reg %s] original value: %s\n" "$b" "$ADDR" "$REG" "$v"
else
printf "[bus %-2s %s reg %s] original value: READ ERROR (%s)\n" "$b" "$ADDR" "$REG" "$v"
fi
done
echo "----------------------------------------------------------"
#------------------------------------------------------------------------------
# Write / read-back
#------------------------------------------------------------------------------
for (( loop = 1; loop <= LOOPS; loop++ )); do
(( LOOPS > 1 )) && echo "--- loop $loop / $LOOPS ---"
for b in "${BUSES[@]}"; do
for p in "${PATTERNS[@]}"; do
tag=$(printf "[bus %-2s %s reg %s]" "$b" "$ADDR" "$REG")
if ! werr=$(i2cset -f -y "$b" "$ADDR" "$REG" "$p" 2>&1); then
N_ERR[$b]=$(( N_ERR[$b] + 1 ))
echo "$tag write $p -> WRITE ERROR (${werr:-no message}) ERROR"
continue
fi
if ! got=$(rd "$b"); then
N_ERR[$b]=$(( N_ERR[$b] + 1 ))
echo "$tag write $p -> READ ERROR (${got:-no message}) ERROR"
continue
fi
if (( got == p )); then
N_PASS[$b]=$(( N_PASS[$b] + 1 ))
echo "$tag write $p -> read $got PASS"
else
N_FAIL[$b]=$(( N_FAIL[$b] + 1 ))
echo "$tag write $p -> read $got FAIL"
fi
done
done
done
#------------------------------------------------------------------------------
# Restore
#------------------------------------------------------------------------------
if (( RESTORE )); then
echo "----------------------------------------------------------"
for b in "${BUSES[@]}"; do
o=${ORIG[$b]}; v=""
if [[ -z "$o" ]]; then
printf "[bus %-2s] restore skipped: original value was not readable\n" "$b"
continue
fi
if i2cset -f -y "$b" "$ADDR" "$REG" "$o" >/dev/null 2>&1 && v=$(rd "$b") && (( v == o )); then
printf "[bus %-2s] restored %s\n" "$b" "$o"
else
printf "[bus %-2s] RESTORE FAILED: wanted %s, read %s\n" "$b" "$o" "${v:-?}"
N_ERR[$b]=$(( N_ERR[$b] + 1 ))
fi
done
fi
#------------------------------------------------------------------------------
# Summary
#------------------------------------------------------------------------------
per_bus=$(( LOOPS * ${#PATTERNS[@]} ))
tp=0; tf=0; te=0
echo
echo "=========================== Summary =========================="
printf "%-6s %-6s %-6s %8s %6s %6s %6s %s\n" "BUS" "ADDR" "REG" "CHECKS" "PASS" "FAIL" "ERROR" "RESULT"
for b in "${BUSES[@]}"; do
p=${N_PASS[$b]}; f=${N_FAIL[$b]}; e=${N_ERR[$b]}
tp=$(( tp + p )); tf=$(( tf + f )); te=$(( te + e ))
r=PASS; (( f > 0 || e > 0 || p != per_bus )) && r=FAIL
printf "%-6s %-6s %-6s %8s %6s %6s %6s %s\n" "$b" "$ADDR" "$REG" "$per_bus" "$p" "$f" "$e" "$r"
done
total=$(( per_bus * ${#BUSES[@]} ))
overall=PASS; (( tf > 0 || te > 0 || tp != total )) && overall=FAIL
printf "%-6s %-6s %-6s %8s %6s %6s %6s %s\n" "TOTAL" "" "" "$total" "$tp" "$tf" "$te" "$overall"
echo "=============================================================="
echo "Tray ID stress RESULT: $overall ($(TS))"
[[ "$overall" == PASS ]] && exit 0 || exit 1
@@ -0,0 +1,103 @@
#!/bin/bash
# Apply off/on/status to the unused retimer lanes and TH6 ports listed below, on each ASIC.
# Same rows apply to both switch boards. lanes: retimer lane_map, sys and line side.
# tsc: TH6 TSC as in HW docs and the "#TSCn" labels in th6-helios.config.yml.
# th6_ports: BCM shell port name or range; used by th6 rows, and by retimer rows with --th6.
UNUSED=$(cat <<'TABLE'
# kind target lanes refdes tsc th6_ports note
retimer 0x102 0xff U22 23 cd80-cd83 no used ports
retimer 0x142 0xff U32 38 cd148-cd151 no used ports
retimer 0x21 0xff U39 7 cd16-cd19 no used ports
retimer 0x240 0xff U67 54 cd212-cd215 no used ports
retimer 0x264 0xff U73 62 cd244-cd247 no used ports
retimer 0x48 0xff U82 15 cd48-cd51 no used ports
retimer 0x202 0xff U92 46 cd180-cd183 no used ports
retimer 0x122 0x30 U18 27 cd111 lanes 4,5 unused
retimer 0x248 0x30 U63 58 cd235 lanes 4,5 unused
retimer 0x2 0x30 U70 3 cd15 lanes 4,5 unused
retimer 0x40 0x30 U75 11 cd47 lanes 4,5 unused
retimer 0x162 0x30 U80 42 cd171 lanes 4,5 unused
retimer 0x222 0x30 U87 50 cd203 lanes 4,5 unused
retimer 0x62 0x30 U96 19 cd79 lanes 4,5 unused
th6 TSC31 - - 31 cd112-cd115 direct TH6 TSC, no retimer
# th6 TSC34 - - 34 cd139 direct TH6 TSC34 lanes 6,7; down and unused in full rack, not in HW list
TABLE
)
DIR=$(cd "$(dirname "$0")" && pwd)
usage() {
cat <<USAGE
Usage: $0 <off|on|status> [--asic 0|1|all] [--method squelch|power] [--th6] [--only <target>] [--force]
retimer rows: retimer lanes on sys and line side, via retimer_lanes.sh
th6 rows : TH6 ports in the th6_ports column, via the BCM shell
--th6 : also act on the th6_ports of retimer rows (TH6 ports feeding those retimer lanes)
--only : act on one row, matched by its target column (e.g. 0x102 or TSC31)
USAGE
exit 1
}
[ $# -ge 1 ] || usage
ACT=$1; shift
ASICS="0 1"; METHOD=squelch; TH6=0; ONLY=""; FORCE=""
while [ $# -gt 0 ]; do
case $1 in
--asic) case $2 in all) ASICS="0 1" ;; 0|1) ASICS=$2 ;; *) usage ;; esac; shift 2 ;;
--method) METHOD=$2; shift 2 ;;
--th6) TH6=1; shift ;;
--only) ONLY=$2; shift 2 ;;
--force) FORCE=--force; shift ;;
*) usage ;;
esac
done
case $ACT in off|on|status) ;; *) usage ;; esac
[ -x "$DIR/retimer_lanes.sh" ] || { echo "retimer_lanes.sh not found next to $0"; exit 1; }
bcm() { docker exec "syncd$1" bcmcmd -t 60 "$2" </dev/null 2>&1 | tr -d '\r'; }
ps_state() { bcm "$1" "ps $2" | sed -E 's/\( +/(/' | awk '$1 ~ /^cd[0-9]+\(/ {print $1, $2}'; }
th6_ports() {
local a=$1 act=$2 ports=$3 st
st=$(ps_state "$a" "$ports")
[ -n "$st" ] || { echo "asic$a th6 $ports: no such ports"; return 3; }
if [ "$act" = status ]; then
echo "$st" | sed "s/^/asic$a th6 /"
return 0
fi
if [ "$act" = off ] && [ -z "$FORCE" ] && echo "$st" | awk '$2 == "up"' | grep -q .; then
echo "REFUSED: asic$a th6 $ports has link up: $(echo "$st" | awk '$2 == "up" {printf "%s ", $1}')"
return 2
fi
bcm "$a" "port $ports enable=$([ "$act" = off ] && echo false || echo true)" >/dev/null
sleep 1
st=$(ps_state "$a" "$ports")
echo "$st" | sed "s/^/asic$a th6 /"
if [ "$act" = off ]; then
echo "$st" | awk '$2 != "!ena"' | grep -q . && return 3
else
echo "$st" | awk '$2 == "!ena"' | grep -q . && return 3
fi
return 0
}
mapfile -t ROWS < <(grep -v -E '^[[:space:]]*(#|$)' <<<"$UNUSED")
ok=0; refused=0; failed=0
for a in $ASICS; do
for row in "${ROWS[@]}"; do
read -r kind target lanes refdes tsc ports note <<<"$row"
[ -n "$ONLY" ] && [ "$target" != "$ONLY" ] && continue
echo "== asic$a $kind $target refdes=$refdes TSC$tsc th6=$ports: $note"
rc=0
case $kind in
retimer)
"$DIR/retimer_lanes.sh" "$a" "$target" "$lanes" "$ACT" --method "$METHOD" $FORCE; rc=$?
if [ $TH6 = 1 ] && [ "$ports" != "-" ] && [ $rc != 2 ]; then
th6_ports "$a" "$ACT" "$ports" || rc=$?
fi ;;
th6) th6_ports "$a" "$ACT" "$ports"; rc=$? ;;
*) echo "unknown kind '$kind'"; rc=1 ;;
esac
case $rc in 0) ok=$((ok + 1)) ;; 2) refused=$((refused + 1)) ;; *) failed=$((failed + 1)) ;; esac
done
done
echo "== $ACT done: ok=$ok refused=$refused failed=$failed"
[ $failed = 0 ]
+949
View File
@@ -0,0 +1,949 @@
# Blanton Script User Guide
> 適用版本:Script A **V1.2.7**(2026-11)
> 對象:上機跑 A → B → C 的測試員,以及要在 DUT 上手動下 `Blanton_Script/` 工具的人
![version](https://img.shields.io/badge/version-1.2.7-blue.svg) ![host](https://img.shields.io/badge/host-Windows-0078D6.svg) ![Tera Term](https://img.shields.io/badge/Tera%20Term-5.x-2ea043.svg) ![DUT](https://img.shields.io/badge/DUT-SONiC-E95420.svg) ![shell](https://img.shields.io/badge/shell-bash-4EAA25.svg)
本指南分兩部分:
1. [TTL Script A / B / C](#part-1--ttl-script-a--b--c):Host 端準備、把 `Blanton_Script/` 從 USB 放進 DUT、A → B → C 的跑法
2. [Blanton_Script 工具說明](#part-2--blanton_script-工具說明):DUT 上每一支 `.sh` 的用法
---
## 目錄
- [Part 1 — TTL Script A / B / C](#part-1--ttl-script-a--b--c)
- [1.1 交付包內容](#11-交付包內容)
- [1.2 Host 端準備(Windows)](#12-host-端準備windows)
- [1.3 把 Blanton_Script 從 USB 放到 DUT](#13-把-blanton_script-從-usb-放到-dut)
- [1.4 config.ttl 設定](#14-configttl-設定)
- [1.5 跑一輪測試:A → B → C](#15-跑一輪測試a--b--c)
- [1.6 Script A 做了什麼](#16-script-a-做了什麼)
- [1.7 Script B 做了什麼](#17-script-b-做了什麼)
- [1.8 Script C 做了什麼](#18-script-c-做了什麼)
- [1.9 Log 在哪裡](#19-log-在哪裡)
- [1.10 常見問題](#110-常見問題)
- [Part 2 — Blanton_Script 工具說明](#part-2--blanton_script-工具說明)
- [2.0 通用規則](#20-通用規則)
- [2.1 總覽表](#21-總覽表)
- [2.2 平台存取底層(source 進來用)](#22-平台存取底層source-進來用)
- [2.3 溫度 / 電壓 / 電流 / 功耗](#23-溫度--電壓--電流--功耗)
- [2.4 電壓 Margin(含 LTC2980 Margin Script 完整說明)](#24-電壓-margin)
- [2.5 交換晶片:流量 / BER / FDR / 負載](#25-交換晶片流量--ber--fdr--負載)
- [2.6 SerDes DSC 擷取](#26-serdes-dsc-擷取)
- [2.7 背景監控(start / stop 型)](#27-背景監控start--stop-型)
- [2.8 其他](#28-其他)
---
# Part 1 — TTL Script A / B / C
## 1.1 交付包內容
```
Script_ABC_Blanton_<Ver>/ ← Tera Term 的工作目錄(整包放在 Windows 上)
├── 1_Blanton_Script_A.ttl ← 基線(開頭收殘留 → 取基線數據 → 第一輪流量 / BER)
├── 2_Blanton_Script_B.ttl ← 壓力 soak(背景壓力 + while 1 每 60 秒取一次數據)
├── 3_Blanton_Script_C.ttl ← 收工(停壓力 → 收尾數據 → 判定 → log 拷 USB)
├── config.ttl ← 所有設定都在這裡
├── utils/*.ttl ← A/B/C 共用的片段(PMON、dmesg、PCIe 錯誤…)
├── logs/ ← Tera Term log 寫在這
├── 4_*.ttl / 5_*.ttl / 6_*.ttl ← 其他獨立測試(熱 / 開機循環 / BER 循環),不接 A→B→C
└── Blanton_Script/ ← ★ 要放到 DUT 的 ~/Blanton_Script/
```
| 腳本 | 用途 | 跟 A→B→C 的關係 |
|---|---|---|
| `1_Blanton_Script_A.ttl` | 基線 | 第一支,**唯一會開 log** 的 |
| `2_Blanton_Script_B.ttl` | 壓力 soak | A 之後,同一個 Tera Term 視窗 |
| `3_Blanton_Script_C.ttl` | 收工 + 判定 | B 停掉之後,同一個視窗 |
| `4_Blanton_Script_thermal_safety.ttl` | 熱 / 安規 | 獨立跑,**沒有收尾段** |
| `4_1_Blanton_Script_thermal.ttl` | 熱測:先 idle 300 輪,再 `blanton_tr518_thermal.sh` 滿載 | 獨立跑,**沒有收尾段**(結束要手動 `blanton_tr518_thermal.sh stop` + `systemctl stop mlucas-amm`) |
| `5_Blanton_Script_Boot_Cycle.ttl` | 斷電開機循環 | 獨立跑,`while 1` 無止境 |
| `5_1_Blanton_Script_Boot_Cycle_Fast.ttl` | 同上,拿掉流量只留 `ps` | 獨立跑 |
| `6_Blanton_Script_BER_Cycle.ttl` | Diag ↔ SONiC 冷開機量 BER | 獨立跑 |
## 1.2 Host 端準備(Windows)
1. 把整個 `Script_ABC_Blanton_<Ver>/` 複製到 Windows(例如 `D:\Blanton\`)。
2. **改密碼**:`1_Blanton_Script_A.ttl` 的登入段是
```
sendln "admin"
wait "Password:"
sendln "YourPaSsWoRd" ← 換成 DUT 實際的 admin 密碼
```
`YourPaSsWoRd` 是佔位字,不改 A 會卡在登入。(B / C 不登入,沿用 A 的 session。)
3. 確認 `config.ttl` 的 prompt 跟 DUT hostname 一致(見 [1.4](#14-configttl-設定))。
4. Tera Term 連 DUT 的 COM port:**115200-8-N-1**。
5. (建議)Tera Term → Setup → Additional settings → Log,確認時戳格式;格式存在**這台電腦的 `TERATERM.INI`**,不在腳本裡。
## 1.3 把 Blanton_Script 從 USB 放到 DUT
TTL 會直接呼叫 `~/Blanton_Script/xxx.sh`(root 的家目錄 = `/root`),所以 **跑 Script A 之前**,DUT 上要先有 `/root/Blanton_Script/`。
### Step 1:Windows 端把資料夾放進 USB
把交付包裡的 `Blanton_Script/` 整個資料夾拷到 USB 隨身碟**根目錄**:
```
USB:\
└── Blanton_Script\
├── blanton_ber.sh
├── ...
└── LTC2980_Margin_Script\
```
> ⚠️ **不要在 Windows 上用記事本打開再存 `.sh` / `.conf`**。存檔可能變成 CRLF 換行,
> 在 SONiC 上會直接掛(`$'\r': command not found`),`.conf` 被 source 時更會安靜地讀錯值。
### Step 2:DUT 端掛 USB
```bash
# 登入並切 root
admin / <密碼>
sudo -i
# 找 USB 的 partition(通常是 /dev/sda1;看 TRAN 欄 = usb 的那顆)
lsblk -o NAME,SIZE,TRAN,FSTYPE,MOUNTPOINT
# 掛載(已掛過可跳過)
mkdir -p /mnt/usb
mount /dev/sda1 /mnt/usb # ← 依 lsblk 結果改 sda1
ls /mnt/usb # 應看到 Blanton_Script
```
### Step 3:複製到家目錄
```bash
# 已經有舊版的話先備份(可略過)
[ -d ~/Blanton_Script ] && mv ~/Blanton_Script ~/Blanton_Script.bak_$(date +%Y%m%d-%H%M%S)
cp -r /mnt/usb/Blanton_Script ~/
```
### Step 4:加執行權限 + 檢查換行(**每次佈署都要做**)
```bash
find ~/Blanton_Script -name '*.sh' -exec chmod +x {} +
grep -rlU $'\r' ~/Blanton_Script # ← 應該「沒有任何輸出」
```
- **為什麼一定要 `chmod +x`**:從 Windows → USB 拷過來的檔案沒有執行權限。
`mgmt_ping_monitor.sh` / `bmc_monitor.sh` / `nfc_polling.sh` 的 `start` 內部是直接執行自己的路徑,
沒有 exec bit 會 Permission denied,**而且不會報錯**,只會得到一份空的 log。
`unused_lanes.sh` 也會檢查 `retimer_lanes.sh` 有沒有 exec bit。
- **`grep` 有輸出 = 有檔案是 CRLF**,修法:
```bash
grep -rlU $'\r' ~/Blanton_Script | xargs sed -i 's/\r$//'
```
### Step 5:確認 + 卸載
```bash
ls ~/Blanton_Script
bash ~/Blanton_Script/usb_target.sh -n -o both # 確認 USB 偵測得到(Script B/C 會用)
sync
umount /mnt/usb
```
> **USB 不要拔**:Script B 會對它跑 USB 讀寫壓力,Script C 最後會把 log 拷進去。
> 測試期間 DUT 上只能插**一支** USB 隨身碟(偵測到多支時 `usb_target.sh` 會拒絕猜測,exit 2)。
### 另一個方法:base64 貼上
沒有 USB 時,可以把 `Blanton_Script/` 打成 `tar.gz` 再轉 base64,在 Tera Term 分段貼上、
DUT 端解碼解壓。每段後面附 md5,對不上就重貼該段。(貼上檔請向開發端索取。)
## 1.4 config.ttl 設定
| 變數 | 預設 | 說明 |
|---|---|---|
| `project_name` | `"Blanton"` | log 檔名前綴 |
| `strTestcase` | `"ENV"` | log 檔名的測試類別(ENV / EMC / Margin…) |
| `EN_Margin` | `0` | 1 = A / C 會跑 `margin_status`(9 顆 LTC2980 的電壓狀態) |
| `EN_TX_FIR` | `0` | 1 = A / C 各跑一次 `bcm_dsc_scan.sh`(每次約 10 分鐘,整輪多 ~20 分鐘) |
| `EN_log` | `1` | 1 = Script A 開 log |
| `EN_timestamp` | `1` | 1 = log 每行帶時戳(**必要變數,不可刪**) |
| `FAN_SPEED` | `100` | 風扇轉速 %,soak 是熱測試,預設全速 |
| `SWB_UNIT0` / `SWB_UNIT1` | `1` / `1` | 這台 DUT 有沒有 switch unit 0 / 1。**FDR 只在兩個都是 1 時才跑** |
| `SSD_RUNTIME` / `SSD_COUNT` | `3600` / `240` | SSD 壓力:`--runtime` 是**整個 job 的總時限(秒)**,`COUNT` = `--passes` |
| `USB_RUNTIME` / `USB_COUNT` | `3600` / `240` | USB 壓力,同上 |
| `BMC_USB_RUNTIME` | `172800` | BMC USB 網路 ping 的總秒數(2 天)**必要變數** |
| `prompt_login` | `"sonic login:"` | 登入提示 |
| `prompt_sonic` | `"admin@sonic:~$"` | admin prompt |
| `prompt_sonic_root` | `"root@sonic:~#"` | root prompt,**每個 `wait` 都靠它** |
> ⚠️ **hostname 不是 `sonic` 的 DUT**(例如 `root@Margin02:~#`),要把三個 prompt 改成對應的字串,
> 否則 macro 會卡在第一個 `wait`。
>
> ⚠️ **`config.ttl` 少一個變數,macro 會當場中止**(不是當成 0)。換新版 TTL 時,`config.ttl` 一起換,
> 再把自己的設定值填回去。
>
> ⚠️ **SSD / USB 壓力的時間**:`--runtime` 跑滿就停,`--passes` 不會把它延長。
> 2 天 soak 要把 `SSD_RUNTIME` / `USB_RUNTIME` 改成 `172800`。壓力提早結束時唯一線索是
> Script B 每輪印的 `bgctl list` 數量變少,**不會報警**。
## 1.5 跑一輪測試:A → B → C
```
Tera Term 連 COM port (115200-8-N-1),DUT 停在 "sonic login:" 或正在開機
│
├─ Control → Macro → 1_Blanton_Script_A.ttl
│ 自動登入 → 基線 → 跳出 messagebox「Script A DONE / Start Script B」
│
├─ Control → Macro → 2_Blanton_Script_B.ttl
│ 起背景壓力 → while 1 每 ~60 秒取一次數據(不會自己停)
│ 泡到時間後:在 Tera Term 的 MACRO 小視窗按 End 停掉 macro,不要關 Tera Term 主視窗
│
└─ Control → Macro → 3_Blanton_Script_C.ttl
停壓力 → 收尾數據 → 流量報表 / BER → log 拷 USB →「GOOD JOB! Test Case DONE」
```
**鐵則:**
- **A → B → C 必須在同一個 Tera Term 視窗、同一個 shell session。** B 的背景 job 跟 C 的 `kill $(jobs -p)`
綁在同一個 shell;log 也只有 A 會開,B / C 是續寫。中途關掉視窗就得手動收程序,log 也斷了。
- B 停掉時,DUT 可能停在某個指令中間。**等 prompt 回來再跑 C**(必要時按一下 Enter)。
- DUT 上要有 `~/hammer/tools/amd/mlucas-avx2`(CPU 壓力,由 DUT image 帶,不在交付包裡)。
## 1.6 Script A 做了什麼
依序:
| # | 段落 | 主要指令 |
|---|---|---|
| 1 | 開 log、登入、切 root | `logopen`、`sudo -i` |
| 2 | 前置 | `mkdir ./logs`、`date -s`(用 Host 時間對時)、`rm /host/hw-eval/jobs/*` |
| 3 | 收前一輪殘留 | `hw-test-session finish` → `bgctl reset --yes` → `bgctl stop --all` → `bgctl list` → `hw-test-session start` |
| 4 | 風扇 | max31790 driver rebind → `fan-speed-control.sh <FAN_SPEED>` → 回答 `y` |
| 5 | 等 DUT 初始化 | `utils/wait_init.ttl`:每 60 秒 `bcmcmd ps` 數 up port,每個開啟的 unit ≥ 216 才往下 |
| 6 | DUT 資訊 | `show boot / version / system-memory / service / platform syseeprom / ssdhealth`、`fwutil show status`、TPM 版本、NVMe SMART |
| 7 | BMC | `bmc-first-enroll`、`bmc-manager version / status` |
| 8 | 載入工具 | `source` 6 支:`blanton_fpga_pcimem` / `cb_i2c` / `icb_vi2c` / `pwr_data` / `traffic_linespeed` / `margin.sh` |
| 9 | PCIe AER 基線 | `utils/show_pcie_error_reg_*.ttl`(TH6×2 / FPGA / BMC / DDR / I210 / SSD)、`ras-mc-ctl --summary` |
| 10 | PCIe tree | `lspci -tvvv`、`lspci -vv` |
| 11 | Margin(`EN_Margin=1`) | `utils/show_margin_status.ttl` |
| 12 | PMON 快照 | `utils/setup_pmon.ttl`(溫度 / 風扇 / 電壓 / 電流 / SWB 功耗 / DDR5 / HSC / SSD / leak / TPM)+ `utils/show_dmesg.ttl`(**最後會 `dmesg -C`**) |
| 13 | Tray ID I2C stress | `tray_id_stress.sh` |
| 14 | 管理網路 ping | `mgmt_ping_monitor.sh start` → `sleep 15` → `stop` → `cat log` → `clear` |
| 15 | NFC | `nfc_polling.sh start` → `sleep 30` → `stop` → `report` |
| 16 | 100G port | `sfputil lpmode off`、`config interface startup Ethernet513/514` |
| 17 | 關沒接線的 lane | `unused_lanes.sh off`(**之後沒有任何地方 `on` 回來**) |
| 18 | BER 基線 | `blanton_ber.sh init → start → sleep 30 → report → stop → clear` |
| 19 | 第一輪流量 + FDR | `blanton_traffic_linespeed ps → init` → `fdr start` → `clear` → `fdr clear` → `show` → `start` → `sleep 40` → `fdr rdcnt` → `stop` → `fdr stop` → `report` |
| 20 | DSC(`EN_TX_FIR=1`) | `bcm_dsc_scan.sh -f blanton_dsc_ScriptA.log -F` |
| 21 | 結束 | `show uptime` → messagebox |
> 單一 unit 的 DUT(`SWB_UNIT0` / `SWB_UNIT1` 只有一個是 1)會走 `-u 0` / `-u 1` 分支,**沒有 FDR**,流量只跑 15 秒。
## 1.7 Script B 做了什麼
**起壓力(一次)**
| 壓力 | 指令 |
|---|---|
| AMD CPU | `systemd-run --unit=mlucas-amm ... mlucas-avx2`(`Restart=always`,掉了會自己重起) |
| BMC DDR | `bgctl run bmc-manager run '/usr/bin/memtester 64M'` |
| BMC I2C 監控 | `bmc_monitor.sh start` |
| Host DDR | `bgctl run /usr/sbin/memtester 1G` |
| SSD | `bgctl run qfx5252-stress-ssd 1G --runtime <SSD_RUNTIME> --passes <SSD_COUNT> ...` |
| USB | `bgctl run qfx5252-stress-usb <usb_dev> 256M --runtime <USB_RUNTIME> --passes <USB_COUNT> ...` |
| BMC USB 網路 | `systemd-run --unit=qfx5252-bmc-usb-net-test ... ping -I <cdc_ncm 網卡> 192.168.200.200` |
| 管理網路 | `mgmt_ping_monitor.sh start` |
| NFC | `nfc_polling.sh start` |
| SWB 流量 | `blanton_traffic_linespeed init / clear / start` + `blanton_fdr.sh start / clear` |
> 找不到 cdc_ncm 網卡時會跳 messagebox「cdc_ncm interface not found. Ping test skipped.」,按 OK 後繼續跑,只是少了 BMC USB 網路測試。
**Soak 迴圈(`while 1`,每輪)**
`setup_pmon.ttl` 快照 → `bgctl list` → `jobs` → `systemctl is-active mlucas-amm` → `tray_id_stress.sh` → `blanton_fdr.sh rdcnt` → `sleep 60`
> 每輪間隔 = 指令執行時間 + 60 秒,不是固定 1 分鐘。
> 看 `bgctl list` 的 job 數有沒有變少,是判斷壓力有沒有提早結束的唯一方法。
## 1.8 Script C 做了什麼
| # | 段落 | 主要指令 |
|---|---|---|
| 1 | 停壓力 | `kill $(jobs -p)`、`systemctl stop mlucas-amm`、`bgctl stop --all`×2、`systemctl stop qfx5252-bmc-usb-net-test`、`mgmt_ping_monitor.sh stop`、`nfc_polling.sh stop` |
| 2 | 收尾快照 | `setup_pmon.ttl`、`show_dmesg.ttl` |
| 3 | PCIe AER / EDAC | 同 Script A 的 7 組 + `ras-mc-ctl --summary` → **跟 A 相減才是本輪錯誤** |
| 4 | BMC | `bmc_monitor.sh stop`;`journalctl -u qfx5252-bmc-usb-net-test > ~/Blanton_Script/log/bmc_usb_net.log` |
| 5 | 壓力結果 | `cat` SSD / USB stress log、`mgmt_ping.log`、`nfc_polling.sh report` |
| 6 | 流量判定 | `blanton_fdr.sh rdcnt` → `blanton_traffic_linespeed stop` → `fdr stop` → `report` |
| 7 | BER 收尾 | `blanton_ber.sh init → start → sleep 30 → report → stop → clear` |
| 8 | DSC(`EN_TX_FIR=1`) | `bcm_dsc_scan.sh -f blanton_dsc_ScriptC.log -F` |
| 9 | NVMe / 開機原因 | `nvme smart-log`、`smartctl -x`、`show reboot-cause` |
| 10 | Margin(`EN_Margin=1`) | `show_margin_status.ttl` |
| 11 | Log 拷 USB | 掛 USB 到 `/mnt/usb` → 把 mlucas / bmc_usb_net / bmc_poll / mgmt_ping / nfc_poll log 拷進 `/host/hw-eval/jobs/` → `cp -r /host/hw-eval/jobs/ /mnt/usb/jobs-<YYYYMMDD>_<HHMM>` |
| 12 | 收工 | `exit` → 等 `Script done` → `hw-test-session finish` → `bgctl reset --yes` → messagebox |
## 1.9 Log 在哪裡
| Log | 位置 | 誰寫的 |
|---|---|---|
| **主 log(A+B+C 全部 console)** | Windows:`<Tera Term 工作目錄>\Logs\Blanton_<strTestcase>_<YYYYMMDD-HHMMSS>.log` | Script A `logopen` |
| 壓力 job log | DUT:`/host/hw-eval/jobs/` | `qfx5252-stress-*`、Script C 拷進來的 |
| 工具 log | DUT:`~/Blanton_Script/log/`(`mgmt_ping.log` / `nfc_poll.log` / `bmc_poll.log` / `bmc_usb_net.log` / `blanton_dsc_*.log`) | 各 `.sh` |
| **USB 備份** | USB:`/jobs-<YYYYMMDD>_<HHMM>/` | Script C 最後一步 |
> ⚠️ `bmc_usb_net.log` **不進主 log**,USB 上那份是唯一一份。
> ⚠️ `show_dmesg.ttl` 會 `dmesg -C`,事後在 DUT 上 `dmesg` 撈不到舊訊息,只存在主 log 裡。
## 1.10 常見問題
| 症狀 | 原因 / 處理 |
|---|---|
| A 一開始就停在 `logopen` | `config.ttl` 是舊版,少了 `EN_timestamp` 之類的必要變數 → 換新版 `config.ttl` |
| A 卡在登入 | 密碼還是 `YourPaSsWoRd`,或 prompt 跟 hostname 不符 |
| A 卡在風扇那段 | 在等 `Set all configured fan channels to` 提示再回 `y`;提示字串改了就會永遠卡住 |
| A 卡在 wait_init | 有 unit 的 up port 一直 < 216,或 `SWB_UNITx=1` 但 DUT 沒那張板子 |
| `xxx.sh: Permission denied` | 沒做 [1.3 Step 4](#step-4加執行權限--檢查換行每次佈署都要做) 的 `chmod +x` |
| `$'\r': command not found` | `.sh` 變成 CRLF → `sed -i 's/\r$//'` |
| mgmt_ping / nfc / bmc log 是空的 | 沒 `chmod +x`(`start` 不會報錯) |
| Script C 沒把 log 拷到 USB | USB 沒插、插了兩支、或檔案系統不能寫 → `bash ~/Blanton_Script/usb_target.sh -o both` 看錯誤碼 |
| 跑完 C 之後 CPU 還是滿載 | `systemctl stop mlucas-amm` 沒跑到 → 手動下一次 |
---
# Part 2 — Blanton_Script 工具說明
## 2.0 通用規則
- 一律在 **root** 下跑:`sudo -i`,工具在 `~/Blanton_Script/`。
- 兩種用法:
- **直接執行**:`~/Blanton_Script/xxx.sh <子指令> [選項]`(需要 exec bit)
- **source 後呼叫函式**:`source ~/Blanton_Script/xxx.sh` 再下 `xxx <子指令>`(A/B/C 對 `blanton_traffic_linespeed` 就是這樣用)
- 大部分工具都支援:`-u 0|1`(只做一個 switch unit,預設兩個都做)、`-n`(dry-run,只印指令不碰硬體)、`-d`(印每一個底層指令)、`-h`(help)。
- **`bcmcmd` 的 exit code 不能信**:BCM shell 拒絕指令時照樣回 0,看輸出內容判斷。
- **互斥**:下面這幾支都會接管同一批 switch port,**一次只能跑一支**:
`blanton_traffic_linespeed` / `blanton_ber` / `blanton_ber_debug` / `blanton_tr518` / `blanton_tr518_thermal` / `port_prbs_monitor` / `bcm_100g_dsc_cycle`
- **會寫 NVM(永久)的指令**:`margin_save*`、`blanton_multiphase_margin.sh save` —— **測試流程中絕不執行**。
## 2.1 總覽表
| 工具 | 類別 | TTL 有沒有接 | 一句話 |
|---|---|---|---|
| `blanton_fpga_pcimem.sh` | 底層 | A(source) | CB / PMC / ICB FPGA 暫存器讀寫,自動偵測 BDF |
| `blanton_cb_i2c.sh` | 底層 | A(source) | CB FPGA 的 I2C master(Ch0~Ch17) |
| `blanton_icb_vi2c.sh` | 底層 | A(source) | 經 CB 的 VI2C 走到 ICB / PDB(Ch0~Ch4) |
| `blanton_temp_sensor.sh` | 量測 | — | CB + ICB 溫感 |
| `ddr5_temp.sh` | 量測 | PMON | DDR5 DIMM 溫度 |
| `hsc_temp_readback.sh` | 量測 | PMON | LTC4287 HSC 溫度 |
| `TH6_SWB0/1_power_readback.sh` | 量測 | PMON | SWB 19 條軌 V×I + 總功耗(平台 sensor) |
| `blanton_multiphase_read.sh` | 量測 | — | 直接讀多相 VRM 的 V / I / T(含原始 hex) |
| `blanton_pwr_data.sh` | 量測 | A(source) | SWB VRM + PDB 讀值(經 CB FPGA I2C) |
| `pwr_brick.sh` | 量測 | — | PDB / CPB power brick |
| `avt_pmpower.sh` | 量測 | Script 4 / 4_1 | AMD CPU 封裝功耗(需 NDA 工具) |
| `LTC2980_Margin_Script/margin.sh` | Margin | A/C(`EN_Margin`) | 9 顆 LTC2980 電壓 margin |
| `blanton_multiphase_margin.sh` | Margin | — | 多相 VRM 38 條軌 margin |
| `blanton_traffic_linespeed.sh` | 交換晶片 | A/B/C | SWB loopback 線速流量 + 判定 |
| `blanton_fdr.sh` | 交換晶片 | A/B/C | FDR 統計(`phydiag fdrstat`) |
| `blanton_ber.sh` | 交換晶片 | A/C | 全機 SerDes BER(PRBS)+ 判定 |
| `blanton_ber_debug.sh` | 交換晶片 | — | BER 原始輸出(`p=p31`) |
| `blanton_tr518.sh` | 交換晶片 | Script 4 | `tr 518` 負載(量功耗用) |
| `blanton_tr518_thermal.sh` | 交換晶片 | Script 4_1 | `tr 518` 熱測參數版(**未上機驗證**) |
| `port_prbs_monitor.sh` | 交換晶片 | — | 100G Ethernet513/514 PRBS |
| `unused_lanes.sh` / `retimer_lanes.sh` | 交換晶片 | A(`off`) | 沒接線的 retimer lane / TH6 port 關 TX |
| `bcm_dsc_scan.sh` / `bcm_dsc_parse.sh` | DSC | A/C(`EN_TX_FIR`) | SerDes DSC 擷取 / 轉 CSV |
| `bcm_100g_dsc_cycle.sh` | DSC | — | 100G link down/up 循環 + DSC(**未上機驗證**) |
| `mgmt_ping_monitor.sh` | 背景監控 | A/B/C | 10G + 1G 管理網路 ping |
| `nfc_polling.sh` | 背景監控 | A/B/C | NFC tag 輪詢 |
| `bmc_monitor.sh` | 背景監控 | B/C | BMC `free -m` + I2C 寫讀圖樣 |
| `bmc_monitor_ddr.sh` | 背景監控 | 已停用 | BMC memtester(改走 `bgctl`) |
| `tray_id_stress.sh` | 其他 | A/B | Tray ID I2C 寫讀比對 |
| `usb_target.sh` | 其他 | B/C | 找 USB 隨身碟、掛載 |
| `blantons_nfc_validate.py` | 其他 | 由 nfc_polling 呼叫 | 客戶 NFC 驗證工具 v2.5 |
## 2.2 平台存取底層(source 進來用)
這三支是其他工具的基礎,平常不用直接下;debug 時 source 進來用。
```bash
source ~/Blanton_Script/blanton_fpga_pcimem.sh # 會印 [INFO] CB FPGA BDF = ...
source ~/Blanton_Script/blanton_cb_i2c.sh
source ~/Blanton_Script/blanton_icb_vi2c.sh
```
### blanton_fpga_pcimem.sh
| 指令 | 說明 |
|---|---|
| `cb_fpga <offset> [value]` | 讀 / 寫 CB FPGA 暫存器(32-bit) |
| `pmc_fpga` / `icb_fpga` | 同上,其他 FPGA |
| `fpga_rescan` | 重新偵測 BDF(換 DUT / 重新列舉後) |
| `FPGA_BDF=0000:05:00 fpga_rescan` | 手動指定 BDF(偵測到多顆或選錯時) |
| `echo $FPGA_BDF_ACTIVE` | 目前用的 BDF |
| `blanton_fpga_help` | help |
```bash
cb_fpga 0 0xD90 # 讀 RST_CAUSE_REG,讀得到 = BAR 通了
```
### blanton_cb_i2c.sh
| 指令 | 說明 |
|---|---|
| `cb_i2c_init <ch>` | 初始化通道 |
| `cb_i2c_scan <ch>` | 掃描通道上的裝置 |
| `cb_i2c_read` / `cb_i2c_write` | 讀寫 |
| `cb_pmbus_read` / `cb_pmbus_write` | PMBus 讀寫 |
| `cb_i2c_muxsel` / `cb_i2c_reset` | 切 mux / 重置 |
| `blanton_cb_i2c_help` | help |
```bash
cb_i2c_init 11 && cb_i2c_scan 11 # Ch11 風扇控制器,應看到 0x20
```
### blanton_icb_vi2c.sh
ICB / PDB **一律走這支(VI2C)**,不要走 VSPI(太慢會踩 SMBus timeout)。
| 指令 | 說明 |
|---|---|
| `vi2c_scan_all` | 掃 ICB / PDB 五個通道 |
| `vi2c_scan <ch>` / `vi2c_init <ch>` | 單一通道 |
| `vi2c_read` / `vi2c_write` / `vi2c_pmbus_read` / `vi2c_dump` | 讀寫 |
| `vi2c_help` | help |
> `vi2c_scan` 只看 ACK,**仲裁失敗(ARB_LOST)會被誤報成有裝置**。
## 2.3 溫度 / 電壓 / 電流 / 功耗
### blanton_temp_sensor.sh — CB + ICB 溫感
```bash
~/Blanton_Script/blanton_temp_sensor.sh # CB + ICB 一次
~/Blanton_Script/blanton_temp_sensor.sh -r # 多印 TMP432 remote1/remote2
~/Blanton_Script/blanton_temp_sensor.sh -c # 只 CB(-i 只 ICB)
~/Blanton_Script/blanton_temp_sensor.sh -n 10 -t 5 # 10 次、每次間隔 5 秒(-n 0 = 無限)
```
### ddr5_temp.sh — DDR5 DIMM 溫度
```bash
~/Blanton_Script/ddr5_temp.sh # 預設 bus 5,位址 0x50 0x51
~/Blanton_Script/ddr5_temp.sh 5 0x50 # 指定 bus / 位址
```
### hsc_temp_readback.sh — HSC 溫度
```bash
~/Blanton_Script/hsc_temp_readback.sh # LTC4287 HSC_MAIN(0x40) / HSC_STBY(0x45),bus 28,約 4 秒
```
### TH6_SWB0_power_readback.sh / TH6_SWB1_power_readback.sh — SWB 軌功耗
```bash
~/Blanton_Script/TH6_SWB0_power_readback.sh
~/Blanton_Script/TH6_SWB1_power_readback.sh
```
- 讀 `show platform voltage` / `show platform current` 各一次,算 19 條軌的 V×I,最後印 `TOTAL POWER`。
- 某條軌在 sensor 表裡找不到時,stderr 印 `WARN` 並當 0 W 計。
- 要量**有負載**的功耗:先 `blanton_tr518.sh start`。
### blanton_multiphase_read.sh — 多相 VRM 讀值(含原始 hex)
```bash
~/Blanton_Script/blanton_multiphase_read.sh # 兩片 SWB
~/Blanton_Script/blanton_multiphase_read.sh -u 0 # 只 SWB0
~/Blanton_Script/blanton_multiphase_read.sh -n # 只印 i2c 指令
~/Blanton_Script/blanton_multiphase_read.sh -d # 印每個 i2c 指令與讀到的值
```
- 直接 `i2cget` 讀 VRM(SWB0 = i2c-13/15,SWB1 = i2c-14/16),每顆一列:`VOUT / VOUT2 / IOUT / IOUT2 / POUT / POUT2 / TEMP`,
電壓電流後面括號是讀到的 PMBus 原始 word,例如 `0.740(0x0128)`;最後印每片 SWB 的 Total Power。
- POUT = V × I。讀完會把 PAGE 讀回確認沒被別人切走,被切走就重讀,一直不穩印 `NA`。
- **不要跟 `blanton_multiphase_margin.sh` 同時跑**(兩支都會切 PAGE)。
- ⚠️ 0x21 / 0x22 的 PU 名稱(PU105 / PU102)與 `blanton_multiphase_margin.sh` 的 PHYTILE 對應相反,待上機確認;總功耗不受影響。
### blanton_pwr_data.sh — SWB VRM / PDB(經 CB FPGA I2C)
```bash
source ~/Blanton_Script/blanton_pwr_data.sh
pwr_data # SWB0(預設)
pwr_data swb1 # SWB1
pwr_data pdb # PDB power brick + EFUSE(ICB VI2C ch4,mux 0x72 ch0)
pwr_data all # 三個都印
pwr_pdb_id # 讀 PDB 上每顆裝置的 MFR_ID / MFR_MODEL
pwr_data_help
```
> 讀不到或數值不合理時印 `NA`——寧可 NA 也不印看起來像數據的錯值。
### pwr_brick.sh — PDB / CPB power brick
```bash
~/Blanton_Script/pwr_brick.sh show # Vin / Iin / Vout / Iout / Temp × 5 顆
~/Blanton_Script/pwr_brick.sh show -r # 多印 raw word
PB_TRIES=1 ~/Blanton_Script/pwr_brick.sh show -r # 看不經重試的原始行為
```
### avt_pmpower.sh — AMD CPU 封裝功耗
```bash
~/Blanton_Script/avt_pmpower.sh -p ~/AVT_Linux_NDA_2.8.37/AVTCMD # 印 PM table + 摘要
~/Blanton_Script/avt_pmpower.sh -q -p ~/AVT_Linux_NDA_2.8.37/AVTCMD # 只印摘要
```
- **AVT 是 NDA 工具,不在交付包裡**:要先解壓到 `~/AVT_Linux_NDA_2.8.37/`,沒有就 exit 2。
- 數值是 SMU telemetry 不是量測,要準就對照 VR 的 PMBus READ_POUT。
- exit:0 OK / 1 參數錯 / 2 找不到 AVTCMD / 3 AVTCMD 失敗 / 4 解析不到功耗欄位。
## 2.4 電壓 Margin
> ⚠️ **改電壓會弄壞 DUT**:套 profile 前確認該軌 OV / UV limit。
> ⚠️ `margin.sh`(LTC2980)跟 `blanton_multiphase_margin.sh`(多相 VRM)**摸的是同一批軌**,兩支不要同時用。
> ⚠️ 會寫 NVM 的指令(`margin_save*`、`... save`)**測試中絕不執行**,斷電也不會還原。
### LTC2980_Margin_Script/margin.sh — 9 顆 LTC2980
用 PMBus 控制 LTC2980 的電壓 margin。**一個 `.conf` = 一顆 LTC2980**(= 2 顆 LTC2977,每顆 8 channel,合起來 CH0~CH15)。
```
~/Blanton_Script/LTC2980_Margin_Script/
├── margin.sh ← 主程式(source 進來用)
├── settings/*.conf ← 每顆 LTC2980 的 channel 定義(Vnom、Net 名稱、I2C 位址)
├── profiles/*.conf ← 批次套用的 margin 組合
├── script/*.sh ← 多顆一起跑(status / apply / save)
└── logs/ ← 操作 log(主 log + detail log)
```
#### 載入
```bash
cd ~/Blanton_Script/LTC2980_Margin_Script # ← profile 路徑是相對於目前目錄,先 cd 進來
source margin.sh
margin_init Blanton_SWB0_CONN14 # 指定要操作哪一顆(支援 TAB 補全)
```
可以載入的 9 顆:
| `margin_init` 名稱 | 板 / 接頭 |
|---|---|
| `Blanton_CB_CONN13` | CB 板 CONN13 |
| `Blanton_SWB0_CONN13` ~ `Blanton_SWB0_CONN16` | SWB0 板 CONN13 ~ 16 |
| `Blanton_SWB1_CONN13` ~ `Blanton_SWB1_CONN16` | SWB1 板 CONN13 ~ 16 |
#### 函式一覽
| 函式 | 說明 |
|---|---|
| `margin_init <NAME>` | 載入 `settings/<NAME>.conf`,之後的指令都作用在這一顆 |
| `margin_status [ch]` | 讀 CH0~CH15(或指定 channel)的 Vout 與偏差 % |
| `margin_set <ch> <op> <change%>` | 三合一:寫 margin 值 + 切 operation + 讀回驗證 |
| `margin_set_value <ch> <vnom> <change%>` | 只寫 HIGH / LOW / OV / UV 暫存器 |
| `margin_operation <ch> <op>` | 只切 OPERATION(不改 margin 值) |
| `margin_apply_profile <file>` | 把一個 profile 套到目前載入的那顆 |
| `margin_save` | ⚠️ 寫 NVM:目前這顆(2 顆 LTC2977) |
| `margin_save all` | ⚠️ 寫 NVM:`settings/` 底下全部 9 顆,跑完切回原本那顆 |
| `margin_save blanton` | ⚠️ 寫 NVM:Blanton 專用,18 顆 LTC2977 走原生 i2c,不需 `margin_init` |
| `margin_debug [on\|off]` | 印出所有 i2c 指令(不帶參數 = 切換) |
| `margin_log [on\|off]` | 開關 log 記錄(預設開) |
`<op>` 對應的 OPERATION(PMBus 0x01)值:
| op | 值 | 說明 |
|---|---|---|
| `high` | 0xA8 | margin high |
| `low` | 0x98 | margin low |
| `nominal` | 0x80 | 回標稱值 |
| `off` | 0x00 | **關閉輸出** |
Channel 編號:`ch / 8` 決定是哪顆 LTC2977(0 = 低位址、1 = 高位址),`ch % 8` 是該顆的 page(0~7)。
#### 常用範例
```bash
margin_status # 全部 channel
margin_status 3 # 只看 ch3
margin_set 0 high 8 # ch0 margin high 8%
margin_set 5 low 5 # ch5 margin low 5%
margin_set 3 nominal 8 # ch3 回標稱值
margin_operation 0 high # 只切 operation
margin_operation 0 nominal
margin_apply_profile profiles/combo_SWB_CONN13_high.conf # 批次套用(要在 LTC2980_Margin_Script/ 底下)
margin_apply_profile profiles/combo_normal.conf # 全部回 nominal
margin_init Blanton_SWB1_CONN16 # 換一顆
margin_apply_profile profiles/combo_SWB_CONN16_high.conf
```
#### Profile 一覽
| Profile | 適用 | 說明 |
|---|---|---|
| `combo_SWB_CONN13_high` / `_low` | **只能套 SWB CONN13** | 每個 channel 依該板的軌給 3% 或 5% |
| `combo_SWB_CONN14_high` / `_low` | **只能套 SWB CONN14** | 同上 |
| `combo_SWB_CONN15_high` / `_low` | **只能套 SWB CONN15** | 同上 |
| `combo_SWB_CONN16_high` / `_low` | **只能套 SWB CONN16** | 同上 |
| `comboA_SWB_CONN13~16` / `comboB_SWB_CONN13~16` | **只能套對應 CONN** | 棋盤式:相鄰軌一高一低;A、B 互補,兩個都跑完每條軌兩個方向都測到 |
| `comboA_CB` / `comboB_CB` | **只能套 CB** | 同上,CB 版 |
| `combo_high3` / `combo_low3` | 通用 | 全部 channel ±3%(CB 用這組) |
| `combo_high5` / `combo_low5` | 通用 | 全部 channel ±5% |
| `combo_normal` | 通用 | 全部回 nominal |
| `all_off` | 通用 | ⚠️ 全部 OPERATION **off(關輸出)** |
- SWB0 與 SWB1 的同號 CONN 共用同一個 profile(兩片板子的軌相同,只差 I2C bus)。
- ⚠️ **per-CONN profile 套到別的 CONN 會 margin 到錯的軌,而且不會報錯。** 套之前確認 `margin_init` 載入的是哪一顆。
- 回到正常狀態用 `combo_normal`,**不是 `all_off`**。
#### 多顆一起跑(script/)
```bash
cd ~/Blanton_Script/LTC2980_Margin_Script
source script/margin_status_all.sh # 9 顆依序 margin_init + margin_status
source script/margin_apply_profile_all.sh # 每顆套各自的 profile(預設 SWB 用自己 CONN 的 _high,CB 用 combo_high3)
source script/margin_save_all.sh # ⚠️ 只寫其中幾顆的 NVM(全部 9 顆請用 margin_save all)
```
- 要改範圍:編各支 script 開頭的 `BOARDS=( ... )` 陣列,註解掉不想跑的那行。
- `margin_apply_profile_all.sh` 另有 `PROFILES=( ... )` 陣列,`PROFILES[i]` 套在 `BOARDS[i]`,只寫名稱(不含路徑和 `.conf`),兩個陣列長度不同會直接報錯。
- 跑 LOW 那一輪:把 `PROFILES` 裡的 `_high` 全換成 `_low` 再跑一次。
- Script A / C 的 `EN_Margin=1` 走的就是 `margin_status_all.sh` + 逐顆 `margin_status`。
#### 寫 NVM(⚠️ 永久,測試流程中絕不執行)
`margin_save*` 會把目前的 margin / OV / UV 設定**永久寫進 NVM**,斷電不會還原,可能蓋掉客戶出廠設定。
真的要寫之前,先用 `margin_status_all.sh` 確認每個 channel 的狀態正確。
| 指令 | 寫哪些 | 備註 |
|---|---|---|
| `margin_save` | 目前載入的那顆(2 顆 LTC2977) | |
| `margin_save all` | `settings/` 全部 9 顆 | 中途失敗不會停,最後印成功 / 失敗總結 |
| `margin_save blanton` | 18 顆 LTC2977,走原生 i2c | 不需 `margin_init`、不動目前載入的那顆;2026-08-27 上機驗證 |
`margin_save blanton` 送出的就是這 18 行(PMBus `STORE_USER_ALL` = `0x15`,send-byte,不帶 data):
```bash
i2cset -f -y 4 0x5C 0x15 ; i2cset -f -y 4 0x5E 0x15 # CB CONN13
i2cset -f -y 15 0x5C 0x15 ; i2cset -f -y 15 0x5E 0x15 # SWB0 CONN13
i2cset -f -y 13 0x5C 0x15 ; i2cset -f -y 13 0x5E 0x15 # SWB0 CONN14
i2cset -f -y 15 0x62 0x15 ; i2cset -f -y 15 0x64 0x15 # SWB0 CONN15
i2cset -f -y 13 0x62 0x15 ; i2cset -f -y 13 0x64 0x15 # SWB0 CONN16
i2cset -f -y 16 0x5C 0x15 ; i2cset -f -y 16 0x5E 0x15 # SWB1 CONN13
i2cset -f -y 14 0x5C 0x15 ; i2cset -f -y 14 0x5E 0x15 # SWB1 CONN14
i2cset -f -y 16 0x62 0x15 ; i2cset -f -y 16 0x64 0x15 # SWB1 CONN15
i2cset -f -y 14 0x62 0x15 ; i2cset -f -y 14 0x64 0x15 # SWB1 CONN16
```
| Linux bus | CB FPGA F3 通道 | 板 / 接頭 |
|---|---|---|
| 4 | (CPU 原生) | CB CONN13 |
| 13 | Ch6 | SWB0 CONN14 / CONN16 |
| 15 | Ch8 | SWB0 CONN13 / CONN15 |
| 14 | Ch7 | SWB1 CONN14 / CONN16 |
| 16 | Ch9 | SWB1 CONN13 / CONN15 |
- **DUT 沒裝滿板子時**:把 `margin.sh` 開頭 `MARGIN_BLANTON_STORE` 陣列裡對應的行註解掉。
- 回報 `/dev/i2c-N` 不存在 = FPGA 的 i2c adapter 沒起來;回報 NACK = 板子 / 晶片的問題。
- 每顆之間預設等 0.5 秒(`MARGIN_STORE_SETTLE`),工具沒有去讀晶片的 busy bit,這段等待是唯一的緩衝。
#### 注意事項
- **改電壓會弄壞 DUT**:套 profile 前確認該軌的 OV / UV limit;部分 margin 電阻沒 populate,那些軌的電壓不會動,不是腳本壞了。
- `margin_status` 的偏差 % 是以 `VNOM`(Blanton 實測中位數,2026-08-30 起)為分母;**跨這個日期的 margin log 不能直接互比**。
- SWB 的 LTC2977 有兩條路可以到:一般功能走 CB FPGA(`cb_pmbus_*`),`margin_save blanton` 走原生 i2c。**同一顆晶片不要兩條路同時用。**
- margin 之前 `margin.sh` 會自動把該 channel 的 `ON_OFF_CONFIG` 設成 `0x1a`(否則 margin 不會生效),這只改 RAM,斷電會還原,不是 NVM 寫入;`MARGIN_AUTO_ENABLE=0` 可關掉。
- log 在 `LTC2980_Margin_Script/logs/`:主 log 是摘要,每行帶 `(detail Line:N)` 對到 detail log 的完整輸出。
### blanton_multiphase_margin.sh — 多相 VRM(38 條軌)
```bash
~/Blanton_Script/blanton_multiphase_margin.sh high3 # 全部 +3%
~/Blanton_Script/blanton_multiphase_margin.sh low3 # 全部 -3%
~/Blanton_Script/blanton_multiphase_margin.sh comboA # 混合 A
~/Blanton_Script/blanton_multiphase_margin.sh comboB # 混合 B(comboA 的高低對調)
~/Blanton_Script/blanton_multiphase_margin.sh normal # 回標稱值
~/Blanton_Script/blanton_multiphase_margin.sh high3 -u 0 # 只 SWB0
~/Blanton_Script/blanton_multiphase_margin.sh high3 -n # 只印指令
~/Blanton_Script/blanton_multiphase_margin.sh save # ⚠️ 永久寫 NVM
```
- 每條軌印一行:`SWB0_0V9_ANLG0 - 0.930V Configure Done`。
- 改完用 `blanton_multiphase_read.sh` 讀回確認。
- `normal` 之後 TH6_CORE 讀回約 0.859 V 不是 0.8 V,那是 load line,不是寫失敗。
## 2.5 交換晶片:流量 / BER / FDR / 負載
### blanton_traffic_linespeed.sh — SWB loopback 線速流量
```bash
source ~/Blanton_Script/blanton_traffic_linespeed.sh
blanton_traffic_linespeed ps # 看有接線的 port link / speed
blanton_traffic_linespeed init # 建 VLAN 30..137,cdN <-> cdN+32
blanton_traffic_linespeed clear # 清計數器
blanton_traffic_linespeed show # 看計數器
blanton_traffic_linespeed start # 打流量
blanton_traffic_linespeed stop # 移除 VLAN 成員(--destroy 連 VLAN 一起砍)
blanton_traffic_linespeed report # 每一對 TX/RX 交叉比對 → PASS / FAIL / NA
blanton_traffic_linespeed run # ps → init → clear → start → report 一條龍
blanton_traffic_linespeed report -f <log> # 離線重解一份存下來的 console log
```
- `ps` 實際下的是 `bcmcmd -n <u> -c 'ps <有接線的 port 清單>'`;`-p "<list>"` 換清單、`TL_PS_PORTS=all` 看全部。
- `report` 的 exit:0 全 PASS、2 有 FAIL / NA。
- 判定是**成對交叉比對**(cdA 的 TX = cdB 的 RX),不看絕對值。
### blanton_fdr.sh — FDR 統計
```bash
~/Blanton_Script/blanton_fdr.sh start # fdrstat STArt bin_group=both Interval=30
~/Blanton_Script/blanton_fdr.sh clear # fdrstat clear
~/Blanton_Script/blanton_fdr.sh rdcnt # fdrstat Counters(至少等 Interval 之後再讀)
~/Blanton_Script/blanton_fdr.sh stop # fdrstat STOp(⚠️ 關鍵字未上機驗證)
~/Blanton_Script/blanton_fdr.sh rdcnt -u 0 # 只 unit 0
~/Blanton_Script/blanton_fdr.sh start -i 60 # Interval 改 60 秒
```
- 原始輸出照印,不判定 PASS / FAIL。
- 印目前參數:`grep -E '^FDR_[A-Z_]+=' ~/Blanton_Script/blanton_fdr.sh`
- port 清單同 traffic 的有接線 port(不含 268),`FDR_PORTS="..."` 可改。
### blanton_ber.sh — 全機 SerDes BER(PRBS)
```bash
~/Blanton_Script/blanton_ber.sh init # prbs set p=3 + prbs get(檢查每條 lane 有沒有鎖上)
~/Blanton_Script/blanton_ber.sh start # prbsstat STArt Interval=30
sleep 40 # ⚠️ 必須「大於」Interval
~/Blanton_Script/blanton_ber.sh report # 每條 lane 一列,BER < 1e-6 才 PASS,最後 summary
~/Blanton_Script/blanton_ber.sh stop # prbsstat STOp
~/Blanton_Script/blanton_ber.sh clear # prbs clear(解除 PRBS,lane 回正常運作)
```
- 選項:`-u 0|1`、`-c 1e-9`(換門檻)、`-F`(只列失敗)、`-f <log>`(離線重解)、`--tsv`、`--raw`。
- summary 每個 unit 三列:`200G ports` / `100G p268` / `TOTAL`。
- **PRBS 跑的時候 `show interfaces status` 會顯示 DOWN,這是正常的。** `clear` 之後才回正常。
- 某一組「一條 lane 都沒回報」算 FAIL。
### blanton_ber_debug.sh — BER 原始輸出
```bash
~/Blanton_Script/blanton_ber_debug.sh # unit 0+1:set p=p31 → get×2 → STArt 30 → sleep 40 → Ber → STOp → clear
~/Blanton_Script/blanton_ber_debug.sh -u 0 # 單一 unit
BER_PORTS="...,268" ~/Blanton_Script/blanton_ber_debug.sh # 加 port 268
```
> 這支是 `p=p31`(已上機驗證),`blanton_ber.sh` 是 `p=3`,兩者量的碼型可能不同。
### blanton_tr518.sh — `tr 518` 負載(量功耗用)
```bash
~/Blanton_Script/blanton_tr518.sh start # 兩個 unit,跑完等 120 秒讓功耗穩定
~/Blanton_Script/blanton_tr518.sh start -u 0 # 只 unit 0
~/Blanton_Script/blanton_tr518.sh start --no-wait # 不等
~/Blanton_Script/blanton_tr518.sh start -w 60 # 等 60 秒
~/Blanton_Script/blanton_tr518.sh stop # port cd lb=none
```
`start` 每個 unit 依序下:
```bash
bcmcmd -n <u> -c 'port cd lb=mac'
bcmcmd -n <u> -c 'l2 learn off'
bcmcmd -n <u> -c 'dsh -c "test mode nr=yes"'
bcmcmd -n <u> -c 'dsh -c "tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=1"'
```
- 輸出有 `TR 518 TEST PARAMETERS` 才算真的開始跑。
- **`stop` 只解 loopback**,`l2 learn off` 與 `test mode nr=yes` 會留著。要一起還原:
```bash
TR_RESTORE_LEARN=1 TR_RESTORE_TESTMODE=1 ~/Blanton_Script/blanton_tr518.sh stop
# 每個 unit 多送:'l2 learn on'、'dsh -c "test mode nr=no"'(這兩行未上機驗證)
```
### blanton_tr518_thermal.sh — `tr 518` 熱測參數版(未上機驗證)
用法、選項、`stop` 都跟 `blanton_tr518.sh` 一樣,只有 `tr 518` 參數不同:
```bash
bcmcmd -n <u> -c 'dsh -c "tr 518 Scenario=6 Profile=2 portstopktszstride=1 Count=260 PktSize=603,218 CheckLinkTime=20 CheckDataTime=200 TestPhase=1"'
```
參數覆蓋用 `TR_THERMAL_ARGS="..."`(不是 `TR_TEST_ARGS`)。
### port_prbs_monitor.sh — 100G PRBS
```bash
bash ~/Blanton_Script/port_prbs_monitor.sh start # Ethernet513 + 514
bash ~/Blanton_Script/port_prbs_monitor.sh start a # 只 Ethernet513
bash ~/Blanton_Script/port_prbs_monitor.sh start b # 只 Ethernet514
bash ~/Blanton_Script/port_prbs_monitor.sh report # PASS / FAIL(沒跑的顯示 SKIP)
bash ~/Blanton_Script/port_prbs_monitor.sh stop # prbsstat STOp + prbs clear
```
> PRBS 打起來時 link 顯示 down 是正常的,所以 `start` 刻意不印 port status。
### unused_lanes.sh / retimer_lanes.sh — 沒接線的 lane 關 TX
```bash
~/Blanton_Script/unused_lanes.sh status # 兩個 unit 全部列出 rx_lock / tx_off
~/Blanton_Script/unused_lanes.sh off # 預設 TX squelch
~/Blanton_Script/unused_lanes.sh off --asic 0 --th6 # 只 unit 0,連 retimer 後面的 TH6 port 一起關
~/Blanton_Script/unused_lanes.sh on # 開回來
~/Blanton_Script/retimer_lanes.sh 0 0x102 0xff status # 單顆 retimer:<asic> <addr> <lane_map> <off|on|status>
```
- lane 有 RX lock(有訊號進來)時 `off` 會被拒絕(exit 2),`--force` 才硬關。
- Script A 會 `off`,**沒有任何腳本 `on` 回來**;需要 DUT 回正常狀態時手動 `on`。
- 兩支都要 `chmod +x`(`unused_lanes.sh` 會檢查 `retimer_lanes.sh` 的 exec bit)。
## 2.6 SerDes DSC 擷取
### bcm_dsc_scan.sh — DUT 端擷取
```bash
~/Blanton_Script/bcm_dsc_scan.sh # unit 0+1 全掃,約 10 分鐘
~/Blanton_Script/bcm_dsc_scan.sh -u 0 # 只掃一個 unit
~/Blanton_Script/bcm_dsc_scan.sh -f my.log -F # 自訂檔名 + 覆蓋
~/Blanton_Script/bcm_dsc_scan.sh -n # dry-run,只列要掃的 port
```
- log 在 `~/Blanton_Script/log/`,掃完自動 cp 到 `/host/hw-eval/jobs`(`-C` 關掉)。
- 結尾固定印 `### DSC_SCAN_DONE rc=<n>`,**rc=0 才是全部 port 都拿到完整 dump**。
### bcm_dsc_parse.sh — raw log 轉 CSV
```bash
sh ~/Blanton_Script/bcm_dsc_parse.sh -i blanton_dsc_ScriptA_u0.log -o u0
# 產出 u0_lane.csv(每 lane 一列)+ u0_pm.csv(每 pm_id 一列)
```
Host / DUT 都能跑(純 sh + awk)。解不出來的列標成 `UNPARSED` 印到 stderr。
### bcm_100g_dsc_cycle.sh — 100G link down/up 循環(未上機驗證)
```bash
~/Blanton_Script/bcm_100g_dsc_cycle.sh # 印說明
~/Blanton_Script/bcm_100g_dsc_cycle.sh 200 # 跑 200 輪
~/Blanton_Script/bcm_100g_dsc_cycle.sh 200 -d # 每行指令以 [CMD] 印出
~/Blanton_Script/bcm_100g_dsc_cycle.sh 20 -T # 跳過 tuning
~/Blanton_Script/bcm_100g_dsc_cycle.sh 1 -n # dry-run
```
log:`~/dsc_log/100G_dsc_cycle_test_<ts>.log`。
## 2.7 背景監控(start / stop 型)
這幾支共通:`start` 只等 1 秒就返回(**不是跑完一輪**)、`start` 會先清空 log、需要 exec bit。
> ⚠️ **`bmc_monitor.sh tail` 是 `tail -f`,永遠不返回**,TTL 裡絕對不要用。看 log 請用 `cat`(`nfc_polling.sh tail N` 不會卡住)。
### mgmt_ping_monitor.sh — 10G + 1G 管理網路 ping
```bash
~/Blanton_Script/mgmt_ping_monitor.sh start # 背景,log/mgmt_ping.log
~/Blanton_Script/mgmt_ping_monitor.sh status
~/Blanton_Script/mgmt_ping_monitor.sh stop # 停 + 產出報表(每張卡最近 N 筆 + 統計 + 判定)
~/Blanton_Script/mgmt_ping_monitor.sh summary # 只看每段的 RESULT 行
~/Blanton_Script/mgmt_ping_monitor.sh clear
cat ~/Blanton_Script/log/mgmt_ping.log
```
- IP 設定在腳本開頭的 **User Configurable Section**(預設 eth0 `192.168.1.99` → `192.168.1.30`、eth1 `192.168.1.101` → `192.168.1.31`),依現場網路改。
- 兩張卡同網段會 ARP flux:判讀看 `RESULT` 行的 `nic_tx` / `nic_rx`——**ping 成功但 `nic_tx` 接近 0 = 封包從另一張卡出去的**。
### nfc_polling.sh — NFC tag 輪詢
```bash
~/Blanton_Script/nfc_polling.sh start # 背景
~/Blanton_Script/nfc_polling.sh status # pid、已跑幾輪、最後一筆結果
~/Blanton_Script/nfc_polling.sh report # PASS / FAIL / ERROR 統計(輪詢中也能跑)
~/Blanton_Script/nfc_polling.sh tail 50 # 最後 50 行(不會卡住)
~/Blanton_Script/nfc_polling.sh stop
~/Blanton_Script/nfc_polling.sh fg # 前景跑
```
- 每輪呼叫同目錄的 `blantons_nfc_validate.py test --debug`。
- `ERROR` = 工具沒印出 `[PASS]` / `[FAIL]` 或逾時,跟「tag 讀不到(FAIL)」分開算。
- `NFC_INTERVAL_SEC` / `NFC_TIMEOUT_SEC` / `NFC_ARGS` 可調(**每個子指令都要帶**)。
### bmc_monitor.sh — BMC 記憶體 + I2C 圖樣
```bash
~/Blanton_Script/bmc_monitor.sh start # 背景,log/bmc_poll.log
~/Blanton_Script/bmc_monitor.sh status
~/Blanton_Script/bmc_monitor.sh stop
~/Blanton_Script/bmc_monitor.sh fg # 前景跑
cat ~/Blanton_Script/log/bmc_poll.log
```
每輪透過 `bmc-manager run` 在 BMC 上跑 `free -m` + I2C(bus 1, 0x41)寫 `55 AA 55 AA` / `AA 55 AA 55` 再讀回比對,間隔 10 秒。要加減指令改腳本開頭的 `COMMANDS=( ... )`。
### bmc_monitor_ddr.sh — 已停用
BMC DDR 壓力已改成 Script B 的 `bgctl run bmc-manager run '/usr/bin/memtester 64M'`。檔案保留,用法同 `bmc_monitor.sh`(log 為 `log/bmc_ddr.log`)。
## 2.8 其他
### tray_id_stress.sh — Tray ID I2C stress
```bash
~/Blanton_Script/tray_id_stress.sh # bus 34/35/38/39,0x70 reg 0x02:寫 0xA5/0x5A 讀回比對 → Summary
~/Blanton_Script/tray_id_stress.sh -n 100 # 重複 100 輪
~/Blanton_Script/tray_id_stress.sh -R # 跑完不還原(預設會寫回原值並讀回確認)
```
exit:0 全 PASS / 1 有 FAIL(讀回不符)或 ERROR(i2c 指令本身失敗)/ 2 參數錯。
### usb_target.sh — 找 USB 隨身碟
```bash
bash ~/Blanton_Script/usb_target.sh # 掛好並印掛載點(預設 /mnt/usb)
bash ~/Blanton_Script/usb_target.sh -o dev # 印 partition(例如 /dev/sda1)
bash ~/Blanton_Script/usb_target.sh -o both # 印 "<dev> <mnt>"
bash ~/Blanton_Script/usb_target.sh -o id # 印 /dev/disk/by-id/... 路徑
bash ~/Blanton_Script/usb_target.sh -n -o both # 只偵測,不掛載
```
| exit | 意思 |
|---|---|
| 0 | 成功 |
| 1 | 找不到 USB 隨身碟 |
| 2 | 偵測到多支(拒絕猜) |
| 3 | 沒有可用的檔案系統 |
| 4 | 掛載失敗 |
| 5 | 掛上了但不能寫 |
### blantons_nfc_validate.py — 客戶 NFC 驗證工具(v2.5)
```bash
python3 ~/Blanton_Script/blantons_nfc_validate.py inventory # 唯讀探測,不送 I2C、不寫硬體
python3 ~/Blanton_Script/blantons_nfc_validate.py test --debug # 切 VEN 並跑廠商 NCI 輪詢流程
python3 ~/Blanton_Script/blantons_nfc_validate.py --version
```
平常由 `nfc_polling.sh` 呼叫,不需要手動跑。
---
## 附錄:一頁速查
```bash
# 佈署
mount /dev/sda1 /mnt/usb && cp -r /mnt/usb/Blanton_Script ~/
find ~/Blanton_Script -name '*.sh' -exec chmod +x {} + ; grep -rlU $'\r' ~/Blanton_Script
# 載入(Script A 也是這 6 支)
source ~/Blanton_Script/blanton_fpga_pcimem.sh
source ~/Blanton_Script/blanton_cb_i2c.sh
source ~/Blanton_Script/blanton_icb_vi2c.sh
source ~/Blanton_Script/blanton_pwr_data.sh
source ~/Blanton_Script/blanton_traffic_linespeed.sh
source ~/Blanton_Script/LTC2980_Margin_Script/margin.sh
# 收拾一個被中斷的測試
kill $(jobs -p); systemctl stop mlucas-amm; bgctl stop --all; bgctl reset --yes
~/Blanton_Script/mgmt_ping_monitor.sh stop; ~/Blanton_Script/nfc_polling.sh stop; ~/Blanton_Script/bmc_monitor.sh stop
systemctl stop qfx5252-bmc-usb-net-test.service
blanton_traffic_linespeed stop; ~/Blanton_Script/blanton_fdr.sh stop
~/Blanton_Script/blanton_tr518.sh stop # 跑過 Script 4 / tr 518 時
~/Blanton_Script/unused_lanes.sh on # 需要 DUT 回正常狀態時
```
@@ -5,12 +5,20 @@ sendln "show platform fan"
wait prompt_sonic_root wait prompt_sonic_root
sendln "show platform temperature" sendln "show platform temperature"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/ddr5_temp.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/hsc_temp_readback.sh"
wait prompt_sonic_root
sendln "show platform psustatus" sendln "show platform psustatus"
wait prompt_sonic_root wait prompt_sonic_root
sendln "show platform voltage" sendln "show platform voltage"
wait prompt_sonic_root wait prompt_sonic_root
sendln "show platform current" sendln "show platform current"
wait prompt_sonic_root wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB0_power_readback.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB1_power_readback.sh"
wait prompt_sonic_root
sendln "show platform ssdhealth" sendln "show platform ssdhealth"
wait prompt_sonic_root wait prompt_sonic_root
sendln "show platform leak status" sendln "show platform leak status"
+44 -1
View File
@@ -1,4 +1,4 @@
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' " bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=p31' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' " bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' " bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' "
@@ -7,6 +7,49 @@ bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' " bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' " bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=p31' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' "
//BER SWB0/1
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=p31' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=p31' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' "
bcmcmd -n 1 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' "
bcmcmd -n 0 "port 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 en=0"
bcmcmd -n 0 "port 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 en=1"
bcmcmd -n 1 "port 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 en=0"
bcmcmd -n 1 "port 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 en=1"
root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' " root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' "
dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3'
drivshell> drivshell>