From nobody Thu Oct 15 02:19:06 2026 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 4j4sFl32FBz6w6Lp for ; Thu, 15 Oct 2026 02:19:07 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j4sFk5GB0z4h4d for ; Thu, 15 Oct 2026 02:19:06 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792030746; 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=GPEhIDfuDyRuYDPfykwgtcIjIU5NDtgxdZD3mI6Cwag=; b=iHC0y8TY+90PYNDTG/89eSuMST5ZGDAGmR4xCWCp8wq9vAMlL9S2zPsaM2L730bEnCBmkV VgJaGitCVfcUt43NwmGXb8uOKDAjs9VAXGSxSINUzI955WWBJ1m8x8UFpeYx9JsEBkAmR4 WwJg1V1JvSo52n/tzDCY0SSpAWxDLPhEpU3cYv/g1Rt4uTupFbMhANIPkTUuWLE/VbgwgP yYzlmmNcWye4vvWojyvITQ+wyobETy3eWi98akcre7nPidEAkw61Z6EZxXJXD+ke+bERjE jvCJs5bmPiCiX/Veab/4KvP2FGIMN62fxVqcmGyAbYqhCKD098jfMoOIAV6H7g== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1792030746; b=G3oI6VH7ndoSFFg0V4z2HiQ2psC4hvNOykpF5HFrKAYezUCmSEocHs5HdU3Oe+r/cyibO+ 0O1bi12VIev9EffAPCRY4fQbEGaxYVKs5eEbi3eYlLSxz1G3e9a973ZDn2R7V6mqrdcdkd O5IOvPe1HHgQzXS6DqtwcvjgKzoFx05oKhmwZby31bkbtfRHqdDiMBL8jFufZdKc3yXF++ p5vUDhdKb7vxWFS83kBkyGrW+a2L80fc+0TcoWDIWukh4q+aED+1GGtgoLtoP229ILXp4a j4idvjUnZy7wSujllEePIBf9Jf3Eq/0K/WAPZOUDg/x7tv1jBaI1OLB/ihO2mA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792030746; 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=GPEhIDfuDyRuYDPfykwgtcIjIU5NDtgxdZD3mI6Cwag=; b=Sds7Nm+PEGTHf+IVbn51vtJnLQy5fqXRVjRg1y8uho8JB4ID/AR1dS8rpC7fmhWOBCHKvH iucVYVek8ec4LdPccTY+LY5fQhMd2ZEvgKXPVJuUyDgYEyBBR8+oU5hp0V526rQTmW4ZUQ MSGCcC2cvKucGoZAJivYwwEXIt5eGAaCcgLg6O3e8qczKDsU3MTUICYEW1rpE+jJ9plGv2 jPWbVVjakU8QhR4IqtdM97BT+FUK4NBGH8hNDoOpikf6EVejVVC9GltQUwqZGOFGbRP6bc 1BcG5Q2FN0TYVy9e66Mi6Fs4qZiAuujVg7WsDPfxgB2bGUNeo38QeGE5cHAXag== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j4sFk4Bkbz1Rdy for ; Thu, 15 Oct 2026 02:19:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 21be4 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 15 Oct 2026 02:19:06 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Adrian Chadd Subject: git: 103a4f05c77f - main - iwm: update phy context routines; add HT channel width parameter List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: Commit messages for the main branch of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: adrian X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 103a4f05c77feacacd4e8191b4bfc92a71d1673d Auto-Submitted: auto-generated Date: Thu, 15 Oct 2026 02:19:06 +0000 Message-Id: <6ad0381a.21be4.147c547a@gitrepo.freebsd.org> The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=103a4f05c77feacacd4e8191b4bfc92a71d1673d commit 103a4f05c77feacacd4e8191b4bfc92a71d1673d Author: Adrian Chadd AuthorDate: 2026-10-15 01:49:33 +0000 Commit: Adrian Chadd CommitDate: 2026-10-15 01:49:35 +0000 iwm: update phy context routines; add HT channel width parameter Update the phy context routines to match what the openbsd snapshot is doing. This involves some HT channel width stuff which although I am not doing HT right now, it was juts easier to sync these entirely versus just a partial sync. * Update the phy context routines to match what openbsd is doing * Although the openbsd driver has an iwm_phy_ctxt_update() routine instead of add and modify, I'm leaving it as-is for now. A bunch of refactoring is going to need to be done to properly use an iwm_phy_ctxt_update() call and I didn't want to tackle that in here. * Add a UHB firmware capability phy context call; I can't test it but it's mostly copy/paste. * Add in a util to turn ieee80211_channel into the 'sco' variable (the HT low/hi parameter) since it's done in openbsd in a slightly different way. Locally tested: * 3160, STA mode * 7260, STA mode * 8260, STA mode * 9260, STA mode Obtained from: OpenBSD a6e25c727a2214219715b51ba6af2221d7e0d674 Differential Revision: https://reviews.freebsd.org/D60082 --- sys/dev/iwm/if_iwm.c | 8 ++- sys/dev/iwm/if_iwm_phy_ctxt.c | 120 +++++++++++++++++++++++++++++++++++------- sys/dev/iwm/if_iwm_phy_ctxt.h | 5 ++ sys/dev/iwm/if_iwm_util.h | 18 +++++++ sys/dev/iwm/if_iwmvar.h | 1 + 5 files changed, 131 insertions(+), 21 deletions(-) diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c index dd154e44aa8f..e67aad2af7e4 100644 --- a/sys/dev/iwm/if_iwm.c +++ b/sys/dev/iwm/if_iwm.c @@ -5042,8 +5042,11 @@ iwm_init_hw(struct iwm_softc *sc) * going to be overwritten in the other flows. * For now use the first channel we have. */ - if ((error = iwm_phy_ctxt_add(sc, - &sc->sc_phyctxt[i], &ic->ic_channels[1], 1, 1)) != 0) + sc->sc_phyctxt[i].id = i; + sc->sc_phyctxt[i].channel = &ic->ic_channels[1]; + error = iwm_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1, + IWM_FW_CTXT_ACTION_ADD, 0, IEEE80211_HTINFO_2NDCHAN_NONE); + if (error) goto error; } @@ -6482,6 +6485,7 @@ iwm_attach(device_t dev) ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD; for (i = 0; i < nitems(sc->sc_phyctxt); i++) { sc->sc_phyctxt[i].id = i; + sc->sc_phyctxt[i].sco = IEEE80211_HTINFO_2NDCHAN_NONE; sc->sc_phyctxt[i].color = 0; sc->sc_phyctxt[i].ref = 0; sc->sc_phyctxt[i].channel = NULL; diff --git a/sys/dev/iwm/if_iwm_phy_ctxt.c b/sys/dev/iwm/if_iwm_phy_ctxt.c index 7ca86b31267f..7d0f115e3d07 100644 --- a/sys/dev/iwm/if_iwm_phy_ctxt.c +++ b/sys/dev/iwm/if_iwm_phy_ctxt.c @@ -188,7 +188,7 @@ iwm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt, static void iwm_phy_ctxt_cmd_data(struct iwm_softc *sc, struct iwm_phy_context_cmd *cmd, struct ieee80211_channel *chan, - uint8_t chains_static, uint8_t chains_dynamic) + uint8_t chains_static, uint8_t chains_dynamic, uint8_t sco) { struct ieee80211com *ic = &sc->sc_ic; uint8_t active_cnt, idle_cnt; @@ -209,11 +209,23 @@ iwm_phy_ctxt_cmd_data(struct iwm_softc *sc, IWM_PHY_BAND_24 : IWM_PHY_BAND_5; cmd->ci.channel = ieee80211_chan2ieee(ic, chan); - - /* TODO: HT40 */ - /* TODO: VHT40/VHT80 */ - cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20; - cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW; + if (IEEE80211_IS_CHAN_HT40(chan)) { + if (sco == IEEE80211_HTINFO_2NDCHAN_ABOVE) { + /* secondary chan above -> control chan below */ + cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW; + cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE40; + } else if (sco == IEEE80211_HTINFO_2NDCHAN_BELOW) { + /* secondary chan below -> control chan above */ + cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_ABOVE; + cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE40; + } else { + cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20; + cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW; + } + } else { + cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20; + cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW; + } /* Set rx the chains */ idle_cnt = chains_static; @@ -240,17 +252,60 @@ iwm_phy_ctxt_cmd_data(struct iwm_softc *sc, cmd->txchain_info = htole32(iwm_get_valid_tx_ant(sc)); } -/* - * Send a command - * only if something in the configuration changed: in case that this is the - * first time that the phy configuration is applied or in case that the phy - * configuration changed from the previous apply. - */ static int -iwm_phy_ctxt_apply(struct iwm_softc *sc, +iwm_phy_ctxt_cmd_uhb(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt, + uint8_t chains_static, uint8_t chains_dynamic, uint32_t action, + uint32_t apply_time, uint8_t sco) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct iwm_phy_context_cmd_uhb cmd; + uint8_t active_cnt, idle_cnt; + struct ieee80211_channel *chan = ctxt->channel; + + memset(&cmd, 0, sizeof(cmd)); + cmd.id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ctxt->id, + ctxt->color)); + cmd.action = htole32(action); + cmd.apply_time = htole32(apply_time); + + cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ? + IWM_PHY_BAND_24 : IWM_PHY_BAND_5; + cmd.ci.channel = htole32(ieee80211_chan2ieee(ic, chan)); + if (IEEE80211_IS_CHAN_HT40(chan)) { + if (sco == IEEE80211_HTINFO_2NDCHAN_ABOVE) { + /* secondary chan above -> control chan below */ + cmd.ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW; + cmd.ci.width = IWM_PHY_VHT_CHANNEL_MODE40; + } else if (sco == IEEE80211_HTINFO_2NDCHAN_BELOW) { + /* secondary chan below -> control chan above */ + cmd.ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_ABOVE; + cmd.ci.width = IWM_PHY_VHT_CHANNEL_MODE40; + } else { + cmd.ci.width = IWM_PHY_VHT_CHANNEL_MODE20; + cmd.ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW; + } + } else { + cmd.ci.width = IWM_PHY_VHT_CHANNEL_MODE20; + cmd.ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW; + } + + idle_cnt = chains_static; + active_cnt = chains_dynamic; + cmd.rxchain_info = htole32(iwm_get_valid_rx_ant(sc) << + IWM_PHY_RX_CHAIN_VALID_POS); + cmd.rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS); + cmd.rxchain_info |= htole32(active_cnt << + IWM_PHY_RX_CHAIN_MIMO_CNT_POS); + cmd.txchain_info = htole32(iwm_get_valid_tx_ant(sc)); + + return iwm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd); +} + +int +iwm_phy_ctxt_cmd(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt, uint8_t chains_static, uint8_t chains_dynamic, - uint32_t action, uint32_t apply_time) + uint32_t action, uint32_t apply_time, uint8_t sco) { struct iwm_phy_context_cmd cmd; int ret; @@ -260,12 +315,23 @@ iwm_phy_ctxt_apply(struct iwm_softc *sc, __func__, ctxt->channel); + /* + * Intel increased the size of the fw_channel_info struct and neglected + * to bump the phy_context_cmd struct, which contains an fw_channel_info + * member in the middle. + * To keep things simple we use a separate function to handle the larger + * variant of the phy context command. + */ + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS)) + return iwm_phy_ctxt_cmd_uhb(sc, ctxt, chains_static, + chains_dynamic, action, apply_time, sco); + /* Set the command header fields */ iwm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time); /* Set the command data */ iwm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel, - chains_static, chains_dynamic); + chains_static, chains_dynamic, sco); ret = iwm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, IWM_CMD_SYNC, sizeof(struct iwm_phy_context_cmd), &cmd); @@ -285,14 +351,22 @@ iwm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt, uint8_t chains_static, uint8_t chains_dynamic) { ctxt->channel = chan; + int sco, ret; + + sco = iwm_get_phy_sco(sc, chan); IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD, "%s: called; channel=%d\n", __func__, ieee80211_chan2ieee(&sc->sc_ic, chan)); - return iwm_phy_ctxt_apply(sc, ctxt, - chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_ADD, 0); + ret = iwm_phy_ctxt_cmd(sc, ctxt, + chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_ADD, 0, sco); + if (ret != 0) + return (ret); + + ctxt->sco = sco; + return (0); } /* @@ -306,14 +380,22 @@ iwm_phy_ctxt_changed(struct iwm_softc *sc, uint8_t chains_static, uint8_t chains_dynamic) { ctxt->channel = chan; + int sco, ret; + + sco = iwm_get_phy_sco(sc, chan); IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD, "%s: called; channel=%d\n", __func__, ieee80211_chan2ieee(&sc->sc_ic, chan)); - return iwm_phy_ctxt_apply(sc, ctxt, - chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_MODIFY, 0); + ret = iwm_phy_ctxt_cmd(sc, ctxt, + chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_MODIFY, 0, sco); + if (ret != 0) + return (ret); + + ctxt->sco = sco; + return (0); } /* diff --git a/sys/dev/iwm/if_iwm_phy_ctxt.h b/sys/dev/iwm/if_iwm_phy_ctxt.h index dcf07d1620a8..d9547c44a4e1 100644 --- a/sys/dev/iwm/if_iwm_phy_ctxt.h +++ b/sys/dev/iwm/if_iwm_phy_ctxt.h @@ -113,4 +113,9 @@ extern int iwm_phy_ctxt_changed(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt, struct ieee80211_channel *chan, uint8_t chains_static, uint8_t chains_dynamic); +extern int iwm_phy_ctxt_cmd(struct iwm_softc *sc, + struct iwm_phy_ctxt *ctxt, + uint8_t chains_static, uint8_t chains_dynamic, + uint32_t action, uint32_t apply_time, uint8_t sco); + #endif /* __IF_IWM_PHY_CTXT_H__ */ diff --git a/sys/dev/iwm/if_iwm_util.h b/sys/dev/iwm/if_iwm_util.h index 4154efad7992..3512b3bcf8d3 100644 --- a/sys/dev/iwm/if_iwm_util.h +++ b/sys/dev/iwm/if_iwm_util.h @@ -159,4 +159,22 @@ iwm_get_phy_config(struct iwm_softc *sc) return sc->sc_fw.phy_config & phy_config; } +/** + * @brief Return the HT above/below field for the given channel width + * + * @param sc driver softc + * @param c channel + * @return IEEE80211_HTINFO_2NDCHAN_* value + */ +static inline uint8_t +iwm_get_phy_sco(struct iwm_softc *sc, const struct ieee80211_channel *c) +{ + if (IEEE80211_IS_CHAN_HT40U(c)) + return (IEEE80211_HTINFO_2NDCHAN_ABOVE); + else if (IEEE80211_IS_CHAN_HT40D(c)) + return (IEEE80211_HTINFO_2NDCHAN_BELOW); + else + return (IEEE80211_HTINFO_2NDCHAN_NONE); +} + #endif /* __IF_IWM_UTIL_H__ */ diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h index 8f2760f114f3..55a1ec427482 100644 --- a/sys/dev/iwm/if_iwmvar.h +++ b/sys/dev/iwm/if_iwmvar.h @@ -349,6 +349,7 @@ struct iwm_phy_ctxt { uint16_t color; uint32_t ref; struct ieee80211_channel *channel; + uint8_t sco; /* 40MHz secondary channel offset */ }; struct iwm_bf_data {