Files
MontaukOS/tests/wifi/decode_iwl_trace.py
T

47 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""Decode an iwlwifi host-command trace captured from Linux on the same adapter.
Linux drives this exact firmware successfully, so its host commands are ground
truth for what the firmware expects -- far more reliable than reading struct
definitions out of a kernel tree and hoping the version matches.
Capture on a Linux box with the adapter, as root:
trace-cmd record -e iwlwifi_dev_hcmd -o /tmp/iwl.dat \
sh -c 'nmcli radio wifi off; sleep 2; nmcli radio wifi on; sleep 20'
Then run this against /tmp/iwl.dat. dump_iwl_cmds.py prints full payload hex
for each command instead of a decoded summary.
Copyright (c) 2026 Daniel Hammer
"""
import re, subprocess
out = subprocess.run(['trace-cmd','report','-R','-i','/tmp/iwl.dat'],
capture_output=True, text=True).stdout
ACT={0:'STUB',1:'ADD',2:'MODIFY',3:'REMOVE'}
def u32(p,o): return p[o]|(p[o+1]<<8)|(p[o+2]<<16)|(p[o+3]<<24)
rows=[]
for line in out.splitlines():
m=re.search(r'hcmd=ARRAY\[(.*?)\]',line); t=re.search(r'\s(\d+\.\d+):',line)
if not m: continue
b=[int(x,16) for x in m.group(1).split(', ')]
if len(b)<8: continue
grp,op=b[1],b[0]; ln=b[4]|(b[5]<<8); p=b[8:8+ln]; ts=float(t.group(1)) if t else 0
if (grp,op)==(3,0x08) and ln>=52:
rows.append((ts,f"MAC_CONFIG action={ACT.get(u32(p,4)):6} id={u32(p,0)} is_assoc={p[36]} aid={p[40]|p[41]<<8} filter=0x{u32(p,20):x}"))
elif (grp,op)==(3,0x09) and ln>=208:
rows.append((ts,f"LINK_CONFIG action={ACT.get(u32(p,0)):6} link={u32(p,4)} mac={u32(p,8)} phy={u32(p,12)} mask=0x{u32(p,24):02x} active={p[28]} bi={u32(p,136)}"))
elif (grp,op)==(3,0x0a) and ln>=96:
rows.append((ts,f"STA_CONFIG sta={u32(p,0)} link={u32(p,4)} type={u32(p,24)} aid={u32(p,28)}"))
elif (grp,op)==(1,0x08) and ln>=32:
rows.append((ts,f"PHY_CONTEXT action={ACT.get(u32(p,4)):6} id={u32(p,0)} chan={u32(p,8)} band={p[12]} width={p[13]}"))
elif (grp,op)==(3,0x05):
rows.append((ts,f"SESSION_PROT action={ACT.get(u32(p,4)):6} conf_id={u32(p,8)} dur={u32(p,12)}"))
elif (grp,op)==(5,0x17):
rows.append((ts,f"SCD_QUEUE_CFG op={u32(p,0)}"))
elif (grp,op)==(3,0x0c):
rows.append((ts,"STA_REMOVE"))
rows.sort(); base=rows[0][0]
for ts,s in rows:
if ts-base > 2.3: print(f"{ts-base:7.3f} {s}")