From nobody Fri Apr 11 21:26:27 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4ZZ8rN1P7Rz5shpg; Fri, 11 Apr 2025 21:26:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ZZ8rM55v0z3tlq; Fri, 11 Apr 2025 21:26:27 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1744406787; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=NlkS5r70uPn7yOFkhuku89+cO4POUMHyKwXkO3vfoV4=; b=W7tYXRRXhbrrfrYOr0MLXtaLtf2H8QWbyxK5dASvU5jK6X1dYT5x2cvEUlOkgG5J+GjMDZ HkRnoIxJ7Oy5dlfv3PabOydD9oUUjA+Jy7WJqO+4Y9PiQCwpfY0grfbUIAjYJAgYcXdg++ 4oCaOdYYZtsE1vVof3YOHoQEheg3e9+7tacJXNoYnQ0KfaQ+/LKdeDFpoWXRxF222KQwOJ vtXN5HUbg08d5KChAVmdNkcGFTGCRY4VWNTapH5darzH4vpUI48Gurp37M5E4t8UwsT3Q6 jdxpvwL7CIah4djki0KujBQ3Y1rbCfBpkPE7tIPVNr5RuseLI4lpfHZ0/3jjnA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1744406787; a=rsa-sha256; cv=none; b=GTsGdNDCtZPJwW6Tuv65qH5tL8x2G+Izrx0y08dA0FuDxEG0sgbjNZKqKONhFlgLatFWac kQECb6K3hjhrOgs6s9fGOU36pEsWrTdQmrsGD0tYjKtu1/XMtqJpQeoSfHK/5WE7UythUD 22zUxNpBZrorE3FBPAc3aOXv1NIseFx14HBNK7Ou3qVpPAWGDPV6I86/NOgsSYsTr9vzVP hOWYGZK5dCPHMfos6TRSQ0zwdEyYuPEbh4aeFkmMIqQ/jC6gS7EYto3tPTZK6W2FGERRL7 sP1TxMNmgrQDjcHYSO69QtFE4LlExtFmNBzdFYiDoN4aqf5HbFy1rb3QP6ji/w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1744406787; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=NlkS5r70uPn7yOFkhuku89+cO4POUMHyKwXkO3vfoV4=; b=WP6lhiboJ/WAj+fZtLEEMQM/OkUIUjfnpk18HZ3EKqXmQFJJJgcQfQBgrmGh/w26ioyDaz debMnZWm9QZngZWupfKtv87EFfYf4OYtctmOIDTei53XpYiyGVbNN2HYsMpwG1hpUkhAF0 1i9rVcJEv45aSRER0lcJBEzNUgwSavKr35AiRvgi9pwDvQ+zcYJH9zQrhrhOTQAWrpq6Qk pkOJpSM93By/hlYLmQQZg0J3KyMLveC4c/E0flpTgPpJRO6KsNaaD//e49pJuAFwSJVSNq WtgH8WQGqQyit4G2IeeUZmNot08hVHHqJJcf+v3kVtjFgBJMMrkWOu6OQT/EtQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4ZZ8rM4VzPzpRY; Fri, 11 Apr 2025 21:26:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 53BLQRkS078455; Fri, 11 Apr 2025 21:26:27 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 53BLQRpn078452; Fri, 11 Apr 2025 21:26:27 GMT (envelope-from git) Date: Fri, 11 Apr 2025 21:26:27 GMT Message-Id: <202504112126.53BLQRpn078452@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Bjoern A. Zeeb" Subject: git: 62d51a43825b - main - LinuxKPI: 802.11: deal with sta bw > channel width List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 62d51a43825bb632f542f4e89d57f3dbdb08095f Auto-Submitted: auto-generated The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=62d51a43825bb632f542f4e89d57f3dbdb08095f commit 62d51a43825bb632f542f4e89d57f3dbdb08095f Author: Bjoern A. Zeeb AuthorDate: 2025-04-10 15:13:38 +0000 Commit: Bjoern A. Zeeb CommitDate: 2025-04-11 21:26:06 +0000 LinuxKPI: 802.11: deal with sta bw > channel width Especially on 2.4Ghz everything may indicate that we can use HT40 but we are stuck on a 20Mhz channel. Adjust the logic in lkpi_sta_sync_ht_from_ni() to also check the channel width before setting the sta bandwidth to 40. Further check that the sta bw is not larger than the channel width after the 'sync from ni' for HT and VHT and if it is, then update the chanctx accordingly. Firmware crashes we have seen with iwlwifi0: 0x00010000 | umac data1 iwlwifi0: 0x00000000 | umac data2 iwlwifi0: 0xDEADBEEF | umac data3 iwlwifi0: 0xXXXX050F | last host cmd likely indicate this problem. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reported by: Jonathan Vasquez (jon xyinn.org) Reported by: Michael Butler (imb protected-networks.net) Reported by: bapt Reported by: William D Pool (rotaechojunk gmail.com) Reported by: Eirik Øverby (ltning-freebsd-wireless anduin.net) Reported by: likely others before Tested by: Eirik Øverby (ltning-freebsd-wireless anduin.net) Tested by: lwhsu Tested by: Michael Butler (imb protected-networks.net) Differential Revision: https://reviews.freebsd.org/D49761 --- sys/compat/linuxkpi/common/src/linux_80211.c | 104 ++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 9 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 12897a38459e..8368ed0d563d 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -365,9 +365,81 @@ lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS) return (0); } +static enum ieee80211_sta_rx_bw +lkpi_cw_to_rx_bw(enum nl80211_chan_width cw) +{ + switch (cw) { + case NL80211_CHAN_WIDTH_320: + return (IEEE80211_STA_RX_BW_320); + case NL80211_CHAN_WIDTH_160: + case NL80211_CHAN_WIDTH_80P80: + return (IEEE80211_STA_RX_BW_160); + case NL80211_CHAN_WIDTH_80: + return (IEEE80211_STA_RX_BW_80); + case NL80211_CHAN_WIDTH_40: + return (IEEE80211_STA_RX_BW_40); + case NL80211_CHAN_WIDTH_20: + case NL80211_CHAN_WIDTH_20_NOHT: + return (IEEE80211_STA_RX_BW_20); + case NL80211_CHAN_WIDTH_5: + case NL80211_CHAN_WIDTH_10: + /* Unsupported input. */ + return (IEEE80211_STA_RX_BW_20); + } +} + +static enum nl80211_chan_width +lkpi_rx_bw_to_cw(enum ieee80211_sta_rx_bw rx_bw) +{ + switch (rx_bw) { + case IEEE80211_STA_RX_BW_20: + return (NL80211_CHAN_WIDTH_20); /* _NOHT */ + case IEEE80211_STA_RX_BW_40: + return (NL80211_CHAN_WIDTH_40); + case IEEE80211_STA_RX_BW_80: + return (NL80211_CHAN_WIDTH_80); + case IEEE80211_STA_RX_BW_160: + return (NL80211_CHAN_WIDTH_160); /* 80P80 */ + case IEEE80211_STA_RX_BW_320: + return (NL80211_CHAN_WIDTH_320); + } +} + +static void +lkpi_sync_chanctx_cw_from_rx_bw(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_sta *sta) +{ + struct ieee80211_chanctx_conf *chanctx_conf; + enum ieee80211_sta_rx_bw old_bw; + uint32_t changed; + + chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf, + lockdep_is_held(&hw->wiphy->mtx)); + if (chanctx_conf == NULL) + return; + + old_bw = lkpi_cw_to_rx_bw(chanctx_conf->def.width); + if (old_bw == sta->deflink.bandwidth) + return; + + chanctx_conf->def.width = lkpi_rx_bw_to_cw(sta->deflink.bandwidth); + if (chanctx_conf->def.width == NL80211_CHAN_WIDTH_20 && + !sta->deflink.ht_cap.ht_supported) + chanctx_conf->def.width = NL80211_CHAN_WIDTH_20_NOHT; + + chanctx_conf->min_def = chanctx_conf->def; + + vif->bss_conf.chanreq.oper.width = chanctx_conf->def.width; + + changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH; + changed |= IEEE80211_CHANCTX_CHANGE_WIDTH; + lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed); +} + #if defined(LKPI_80211_HT) static void -lkpi_sta_sync_ht_from_ni(struct ieee80211_sta *sta, struct ieee80211_node *ni) +lkpi_sta_sync_ht_from_ni(struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_node *ni) { struct ieee80211vap *vap; uint8_t *ie; @@ -399,7 +471,8 @@ lkpi_sta_sync_ht_from_ni(struct ieee80211_sta *sta, struct ieee80211_node *ni) sta->deflink.ht_cap.cap = htcap->cap_info; sta->deflink.ht_cap.mcs = htcap->mcs; - if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) != 0) + if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) != 0 && + IEEE80211_IS_CHAN_HT40(ni->ni_chan)) sta->deflink.bandwidth = IEEE80211_STA_RX_BW_40; else sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20; @@ -435,7 +508,8 @@ lkpi_sta_sync_ht_from_ni(struct ieee80211_sta *sta, struct ieee80211_node *ni) #if defined(LKPI_80211_VHT) static void -lkpi_sta_sync_vht_from_ni(struct ieee80211_sta *sta, struct ieee80211_node *ni) +lkpi_sta_sync_vht_from_ni(struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_node *ni) { uint32_t width; int rx_nss; @@ -508,15 +582,25 @@ skip_bw: #endif static void -lkpi_sta_sync_from_ni(struct ieee80211_sta *sta, struct ieee80211_node *ni) +lkpi_sta_sync_from_ni(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct ieee80211_node *ni, bool updchnctx) { #if defined(LKPI_80211_HT) - lkpi_sta_sync_ht_from_ni(sta, ni); + lkpi_sta_sync_ht_from_ni(vif, sta, ni); #endif #if defined(LKPI_80211_VHT) - lkpi_sta_sync_vht_from_ni(sta, ni); + lkpi_sta_sync_vht_from_ni(vif, sta, ni); #endif + /* + * We are also called from node allocation which net80211 + * can do even on `ifconfig down`; in that case the chanctx + * may still be valid and we get a discrepancy between + * sta and chanctx. Thus do not try to update the chanctx + * when called from lkpi_lsta_alloc(). + */ + if (updchnctx) + lkpi_sync_chanctx_cw_from_rx_bw(hw, vif, sta); } static uint8_t @@ -686,7 +770,9 @@ lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20; sta->deflink.rx_nss = 1; - lkpi_sta_sync_from_ni(sta, ni); + wiphy_lock(hw->wiphy); + lkpi_sta_sync_from_ni(hw, vif, sta, ni, false); + wiphy_unlock(hw->wiphy); IMPROVE("he, eht, bw_320, ... smps_mode, .."); @@ -1870,6 +1956,7 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int IMPROVE("Check vht_cap from band not just chan?"); KASSERT(ni->ni_chan != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC, ("%s:%d: ni %p ni_chan %p\n", __func__, __LINE__, ni, ni->ni_chan)); + #ifdef LKPI_80211_HT if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) { if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) @@ -2658,7 +2745,6 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int } bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__); - lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); /* - change_chanctx (if needed) @@ -2693,7 +2779,7 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int sta->deflink.rx_nss = MAX(1, sta->deflink.rx_nss); IMPROVE("Is this the right spot, has net80211 done all updates already?"); - lkpi_sta_sync_from_ni(sta, ni); + lkpi_sta_sync_from_ni(hw, vif, sta, ni, true); /* Update sta_state (ASSOC to AUTHORIZED). */ KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));