Skip to content

net80211: clamp negotiated VHT width to our own capability - #1067

Open
gargamel778 wants to merge 1 commit into
OpenIntelWireless:masterfrom
gargamel778:vht-clamp-own-capability
Open

gargamel778 wants to merge 1 commit into
OpenIntelWireless:masterfrom
gargamel778:vht-clamp-own-capability

Conversation

@gargamel778

@gargamel778 gargamel778 commented Aug 30, 2026

Copy link
Copy Markdown

Problem

ieee80211_vht_negotiate() derives support_160, support_80_80, supp_chwidth and ext_nss_bw_supp — and ultimately ni->ni_chw — entirely from ni->ni_vhtcaps, the AP's advertised capability. It never intersects any of them with ic->ic_vhtcaps, ours.

The driver populates its own caps correctly — hal_iwm/mac80211.cpp only adds IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ when sc->sc_nvm.vht160_supported is set. Those caps are simply never consulted when the width is chosen.

Every iwm-generation part is 80 MHz max (7265, 8260, 8265). Associating one with an AP that advertises 160 MHz / 80+80 programs a PHY context the firmware cannot execute:

ieee80211_vht_negotiate chan_width=160 support_160=1 support_80_80=1
ieee80211_sta_set_rx_nss ni_rx_nss: 4
iwm_run -> iwm_phy_ctxt_cmd
Start Error Log Dump: Status: 0x79
0x000014FC | ADVANCED_SYSASSERT
could not update PHY context (error 35)
failed to update PHY

The device then resets and re-associates in a loop, so the link never comes up. Authentication and association themselves succeed — ieee80211_recv_assoc_resp is reached — the failure is purely in programming the negotiated width.

Evidence that the AP is not at fault

Same machine, same card, same BSSID, minutes apart, under Linux iwlwifi:

Connected to xx:xx:xx:xx:xx:xx   SSID: <redacted>   freq: 5560.0   (ch 112)
rx bitrate: 325.0 MBit/s VHT-MCS 7 80MHz short GI VHT-NSS 1
tx bitrate: 866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2
signal: -45 dBm      — zero iwlwifi errors

Linux performs the intersection in ieee80211_vht_cap_ie_to_sta_vht_cap() and lands on 80 MHz / NSS 2 against the very BSS that asserts here.

Fix

Clamp ni->ni_chw to ic_vhtcaps after the width switch. Cards that genuinely support 160 MHz are unaffected — the clamp only fires when our own caps say we cannot do the width the AP asked for.

Testing

Intel Wireless-AC 7265 (8086:095A), macOS 26.6.2 (Darwin 25.6.0), built from 53c51c2. AP advertising 160 MHz on DFS channel 112.

before after
vht_negotiate chan_width 160 80
ADVANCED_SYSASSERT 4 of 4 association attempts 0
failed to update PHY 4 0
association never completes, resets in a loop en0 associated with a DHCP lease

Notes for reviewers

  • Deliberately not gated on _OSI("Darwin") or on any hal — the intersection is correct for every card and every OS.
  • ieee80211_sta_set_rx_nss() has the same shape (it reported ni_rx_nss: 4 for a 2x2 part). Left alone here to keep the change minimal; happy to fold in a matching NSS clamp if you'd prefer it in one PR.
  • hal_iwx's ItlIwx.cpp sets ic_vhtcaps the same way, so AX parts get the same protection for free without behaviour change.
  • Possibly related, but not claimed as fixed: Killer(R) Wi-Fi 6 AX1650s 160MHz unstable 5GHz performance #850 (AX1650s unstable at 160 MHz — the inverse case, a card that does support the width).

Opened as a draft for review.

ieee80211_vht_negotiate() derives support_160, support_80_80, supp_chwidth
and ext_nss_bw_supp - and ultimately ni->ni_chw - entirely from
ni->ni_vhtcaps, the AP's advertised capability. It never intersects any of
them with ic->ic_vhtcaps, ours.

The driver sets its own caps correctly: hal_iwm/mac80211.cpp only adds
IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ when sc->sc_nvm.vht160_supported is
set. Those caps are simply never consulted when the width is chosen.

Every iwm-generation part is 80MHz max (7265, 8260, 8265). Associating one
with an AP that advertises 160MHz/80+80 therefore programs a PHY context the
firmware cannot execute:

    ieee80211_vht_negotiate chan_width=160 support_160=1 support_80_80=1
    ieee80211_sta_set_rx_nss ni_rx_nss: 4
    iwm_run -> iwm_phy_ctxt_cmd
    Start Error Log Dump: Status: 0x79
    0x000014FC | ADVANCED_SYSASSERT
    could not update PHY context (error 35) / failed to update PHY

The device then resets and re-associates in a loop, so the link never comes
up. Reproduced 4 times out of 4 on an Intel Wireless-AC 7265 (8086:095A)
against a FRITZ!Box advertising 160MHz on channel 112.

Linux performs exactly this intersection in
ieee80211_vht_cap_ie_to_sta_vht_cap(), and iwlwifi negotiates 80MHz/NSS2
against the same BSSID on the same machine minutes apart:

    rx 325.0 MBit/s VHT-MCS 7 80MHz VHT-NSS 1
    tx 866.7 MBit/s VHT-MCS 9 80MHz VHT-NSS 2

With this change the same association negotiates chan_width=80, completes,
and reports zero firmware asserts.

Cards that genuinely support 160MHz are unaffected: the clamp only applies
when ic_vhtcaps says we cannot do the width the AP asked for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gargamel778
gargamel778 force-pushed the vht-clamp-own-capability branch from 8095097 to 2ef3943 Compare August 30, 2026 16:45
@gargamel778
gargamel778 marked this pull request as ready for review August 30, 2026 16:50
gargamel778 added a commit to gargamel778/GPD-P2-Max-OpenCore-Tahoe that referenced this pull request Sep 4, 2026
The README claimed AirportItlwm cannot work on Tahoe, citing
'Apple80211Scan err[22] EINVAL' as evidence. That reading was wrong: the
error is the symptom of Tahoe shipping no userland IO80211, not of an
incompatible kext. The driver binds and scans correctly.

With the 13.7.2 IO80211 framework plus an IO80211Old.dylib re-export shim
and -amfipassbeta, AirportItlwm gives native Wi-Fi with a menu-bar item
and no HeliPort, measured at 280-314 up / 370-485 down over 10x60s runs
each way. The 7265 also needs the VHT-width clamp in OpenIntelWireless/itlwm#1067.

Notes the trade-off: the root patch needs csrutil authenticated-root
disable, so the system volume is unsealed and every macOS update reverts
it. itlwm + HeliPort remains a valid alternative.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gargamel778 added a commit to gargamel778/GPD-P2-Max-OpenCore-Tahoe that referenced this pull request Sep 4, 2026
Ships the kexts this machine actually runs, at the versions in NOTICE.md,
each with its licence and upstream.

Deliberately EXCLUDED, and documented as such:
- Apple binaries — IOSkywalkFamily, IO80211FamilyLegacy, AppleHDA, and the
  IO80211 13.7.2 userland root patch. These are macOS components and are
  not ours to redistribute, so this tree is not bootable as shipped.
- No licence granted — ECEnabler and NullEthernet carry no licence file at
  all, so no redistribution right exists. Linked upstream instead.
- Provenance unverified — AMFIPass; no authoritative upstream or licence
  could be established.
- Size — AirportItlwm 2.3.0 for the five non-Tahoe kernels (~92 MB).

fetch-restricted.sh retrieves or points at each of the above.

AirportItlwm-Tahoe is the only modified binary; its source is upstream itlwm
plus the patches in itlwm-patch/ (see OpenIntelWireless/itlwm#1067). All
others are unmodified upstream releases.

No SMBIOS serials are included — the published config.plist keeps its
placeholder values.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gargamel778 added a commit to gargamel778/GPD-P2-Max-OpenCore-Tahoe that referenced this pull request Sep 15, 2026
The README claimed AirportItlwm cannot work on Tahoe, citing
'Apple80211Scan err[22] EINVAL' as evidence. That reading was wrong: the
error is the symptom of Tahoe shipping no userland IO80211, not of an
incompatible kext. The driver binds and scans correctly.

With the 13.7.2 IO80211 framework plus an IO80211Old.dylib re-export shim
and -amfipassbeta, AirportItlwm gives native Wi-Fi with a menu-bar item
and no HeliPort, measured at 280-314 up / 370-485 down over 10x60s runs
each way. The 7265 also needs the VHT-width clamp in OpenIntelWireless/itlwm#1067.

Notes the trade-off: the root patch needs csrutil authenticated-root
disable, so the system volume is unsealed and every macOS update reverts
it. itlwm + HeliPort remains a valid alternative.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gargamel778 added a commit to gargamel778/GPD-P2-Max-OpenCore-Tahoe that referenced this pull request Sep 15, 2026
Ships the kexts this machine actually runs, at the versions in NOTICE.md,
each with its licence and upstream.

Deliberately EXCLUDED, and documented as such:
- Apple binaries — IOSkywalkFamily, IO80211FamilyLegacy, AppleHDA, and the
  IO80211 13.7.2 userland root patch. These are macOS components and are
  not ours to redistribute, so this tree is not bootable as shipped.
- No licence granted — ECEnabler and NullEthernet carry no licence file at
  all, so no redistribution right exists. Linked upstream instead.
- Provenance unverified — AMFIPass; no authoritative upstream or licence
  could be established.
- Size — AirportItlwm 2.3.0 for the five non-Tahoe kernels (~92 MB).

fetch-restricted.sh retrieves or points at each of the above.

AirportItlwm-Tahoe is the only modified binary; its source is upstream itlwm
plus the patches in itlwm-patch/ (see OpenIntelWireless/itlwm#1067). All
others are unmodified upstream releases.

No SMBIOS serials are included — the published config.plist keeps its
placeholder values.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Killer(R) Wi-Fi 6 AX1650s 160MHz unstable 5GHz performance

1 participant