openwrt / openwrt/mt76

mt7915/mt7981: GET_MIB_INFO survey counters underflow; BSS Load freezes at a bogus value

Open
#1,135 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
888
Forks
436
PR merge metrics
No merged PRs in 30d

Description

Diagnosed with help of an AI coding agent; measurements and code cites below were taken on a live AP.

Hardware: Zyxel NWA50AX Pro (zyxel,nwa50ax-pro), MT7981, mt798x-wmac / mt7915e
OpenWrt 25.12.5 r33051-f5dae5ece4, kernel 6.12.94, mediatek/filogic
kmod-mt7915e 6.12.94.2026.03.19~39c960c3
FW: WM ____000000 20240823161304 / WA DEV_000000 20240823161841 / HW 20240823161240a
Uptime ~2.93 d. Dual-band AP, default hostapd bss_load_update_period (60).

Bug

mt7915_mcu_get_chan_mib_info() accumulates firmware airtime MIBs with unsigned subtraction and no wrap/reset check:

state->cc_tx += cc_tx - state_ts->cc_tx;          /* and same for rx / busy */
/* mt7915/mcu.c — V2 MIB path used by MT7981 (!is_mt7915) */

If a firmware counter goes backwards, the driver adds ~2^64 and survey dump is garbage forever after. Channel active time stays correct (ktime, not MIB).

Per-STA WTBL airtime already has this guard in mt7915_mac_sta_poll() (Henry Yen, "fix bogus Tx/Rx airtime duration values"). Channel survey never got it.

Live numbers (iw dev phyX-ap0 survey dump, in-use channel)

Use iw dev … survey dump, not iw phy.

                    active (ms)     busy (ms)              tx (ms)
2.4 ch11            253053261       14986490482870210      486388838753191
5 GHz ch36          253052450        9202221537544591      18446743827918618

2^64/1000 = 18446744073709552. 5 GHz TX = that minus 245790934 ms ≈ 245791 s (~uptime; a 32-bit µs wrap would leave ~4295 s, so this is not that).

~99 s later the deltas are still sane (2.4 busy +8299 ms, 5 GHz tx +5192 ms). Firmware is still producing reasonable increments; only the accumulated state is poisoned.

Off-channel rows are poisoned too (5 GHz 5200 MHz: active 133 ms, tx 7.09e15 ms). After the wrap, busy < tx on 5 GHz, which is also physically impossible.

hostapd (ubus call hostapd.<if> get_status, before setting bss_load_update_period=0):

phy0 (2.4): time=252416656  time_busy=14986490482818287  utilization=0
phy1 (5):   time=252422802  time_busy=9202221537499923   utilization=221

hostapd only updates utilization when channel_time > last AND channel_time > channel_time_busy (src/ap/hw_features.c). After the wrap that second test is permanently false, so BSS Load freezes at the last accepted sample (0 vs 221). 221/255 ≈ 87% — a stale snapshot, not wrap arithmetic. We did not pcap the IE.

How to reproduce

  1. MT7981/MT7916 AP, leave radios up ~2–3 days (maybe less).
  2. iw dev phy1-ap0 survey dump
  3. If busy/tx >> active (and especially tx ≈ 2^64/1000), this is it.
  4. ubus call hostapd.<if> get_statusairtime.utilization stuck, time_busy >> time.

wifi reload does not reset chan_state. Reboot / wifi down+up / channel switch (mac_reset_counters) does.

Suggested fix

Same idea as mt7915_mac_sta_poll: if new < old, treat as reset (delta=0 or delta=new), do not add unsigned wrap. Optionally clamp delta to elapsed survey_time.

Workaround (does not fix survey dump)

option bss_load_update_period '0'
option chan_util_avg_period '0'

then wifi reload. Stops the BSS Load IE; iw survey / usteer airtime still see the wrap.

Not claiming

  • That Apple (or any client) left 5 GHz because of 221. Same-SSID 2.4 was also ~10–14 dB stronger here.
  • A 32-bit µs wrap.
  • hostapd is wrong — it is correctly refusing busy > time.

Related, different

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in mt7915/mcu.c at mt7915_mcu_get_chan_mib_info(), then compare its counter handling with the reset guard in mt7915_mac_sta_poll(). Reproduce with iw dev phy1-ap0 survey dump on an MT7981 or MT7916 AP and verify that busy and TX values remain bounded after a counter reset, with hostapd utilization no longer frozen by busy time exceeding active time.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux
Domain
networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.