From nobody Thu Oct 15 02:19:04 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 4j4sFh4G0vz6w6K9 for ; Thu, 15 Oct 2026 02:19:04 +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 4j4sFh3fdTz4h9f for ; Thu, 15 Oct 2026 02:19:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792030744; 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=/T8h+L81dfOUIgkjS+TOKpTVswvWOLY8Vl9o6yE+tZw=; b=UfAnrVHxWBChfSUgKYbq4CGC4cnXe8BGqflybj2aTHf7ux39JfUGKnXRd7T7JN9Uo/CTbY ShjAMOQAbRfJVFTBZ/a/kH8gzb+p+5ZmlmEwcIgW4lHE3wGLXOcUYD/uDMusDT7gSebdFE dQALZfNTFM1ZmnaCtyuTJlbCjtAJ/lFczc2Oy86VjITQTi3zFnxTqNupIiREAq2Fmapu/a lvRPIMLkC2ttfyeFf1JBx23ms/YnBjEBONC0ZxqpSnDYAIKxO1yFHj8Vfkr3krwE8G731e 3AEpm/8HEx5ni60hadw8AQuyUqL0qjCXZ5POIiR1AbA7+KvzGfvO1WO2obLvqg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1792030744; b=lvgz4hgNe8URv6OdpmZKJe9XU/y6BCDVT+/UldaA1YTz+0Gb2IQMgB8yzNjRm3APTNPH4I TOlflWOAaJlnigqKZ0sMn1U8gjKquYObySGb8Ld1Vj9hv3oZRizTHx5Sygsirkyv55nX1E oePlkvKAab6mCKGFgYcdPApTv8Qsh3UXdxg2vou0H/Bv9vJMotJyt4Irtoe7vRK6Vvrg8u AeKZdp3hh2i884RY5ZopY7C/S3rMRy22Iqe7TJ4Z9b4tL/t89JjDcjEtrCoiJpcHza7mIw VlsWm0cK//sUw+Dy3iDA60ZOLcCFwmnmHT7xArtVuMgTMwgvYQUS37eLZXritg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792030744; 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=/T8h+L81dfOUIgkjS+TOKpTVswvWOLY8Vl9o6yE+tZw=; b=E82AsTrQ/mmWgvisCSf+LgPyxNbFczmOXRBN/y3zrP0VSsEOwcqBq2eM0pTuVq0ZF7Vf0+ vVIxpKRceeKlDrD+ibgJVFxSpYNjDYtoz48Yvll83eCN17Myupv0AgA+cFBp5LPr/RgndH 4PN3NWgGfLl2PxjRNQsqDrcU9xGZwdU+2m+9LMHlWomBgxUEWTVGfRhe3MGRhiL9ijO5xp vZQ5G9ZudECMD6h8drtsG4MnhBMSPNVCKbgPY61my+iJnM4ArnlOTClGqyzPSWKbxjG5Nf UMttCcSG0ZTY2jLsOBD2T2sphLjRwmbuoqEN2D9sI8xuhH3FIfeI7S7W8TT5/w== 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 4j4sFh2jLjz1Rcp for ; Thu, 15 Oct 2026 02:19:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 22e53 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 15 Oct 2026 02:19:04 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Adrian Chadd Subject: git: 8d53176ef83d - main - iwm: add DQA (dynamic queue assignment) 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: 8d53176ef83dad3a0962cdffdae98871c0379c35 Auto-Submitted: auto-generated Date: Thu, 15 Oct 2026 02:19:04 +0000 Message-Id: <6ad03818.22e53.74bba102@gitrepo.freebsd.org> The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=8d53176ef83dad3a0962cdffdae98871c0379c35 commit 8d53176ef83dad3a0962cdffdae98871c0379c35 Author: Adrian Chadd AuthorDate: 2026-10-15 01:48:49 +0000 Commit: Adrian Chadd CommitDate: 2026-10-15 01:48:50 +0000 iwm: add DQA (dynamic queue assignment) This is the minimum set of DQA bits from iwm at the given openbsd commit place. * add a method to map ac to queue / ring * use the DQA command queue if needed * glue to wire it up Locally tested: * Intel 7260, STA mode * Intel 9260, STA mode * Intel 8260, STA mode * Intel 3160, STA mode Obtained from: OpenBSD a6e25c727a2214219715b51ba6af2221d7e0d674 Differential Revision: https://reviews.freebsd.org/D60080 --- sys/dev/iwm/if_iwm.c | 87 +++++++++++++++++++++++++++++++++++++++-------- sys/dev/iwm/if_iwm_sta.c | 28 +++++++++++---- sys/dev/iwm/if_iwm_util.c | 2 +- sys/dev/iwm/if_iwmvar.h | 1 + 4 files changed, 97 insertions(+), 21 deletions(-) diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c index ddf781d247b6..610156681272 100644 --- a/sys/dev/iwm/if_iwm.c +++ b/sys/dev/iwm/if_iwm.c @@ -1147,10 +1147,25 @@ iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid) ring->desc = ring->desc_dma.vaddr; /* - * We only use rings 0 through 9 (4 EDCA + cmd) so there is no need - * to allocate commands space for other rings. + * There is no need to allocate DMA buffers for unused rings. + * 7k/8k/9k hardware supports up to 31 Tx rings which is more + * than we currently need. + * + * In DQA mode we use 1 command queue + 4 DQA mgmt/data queues. + * The command is queue 0 (sc->txq[0]), and 4 mgmt/data frame queues + * are sc->tqx[IWM_DQA_MIN_MGMT_QUEUE + ac], i.e. sc->txq[5:8], + * in order to provide one queue per EDCA category. + * Tx aggregation requires additional queues, one queue per TID for + * which aggregation is enabled. We map TID 0-7 to sc->txq[10:17]. + * + * In non-DQA mode, we use rings 0 through 9 (0-3 are EDCA, 9 is cmd), + * and Tx aggregation is not supported. + * + * Unfortunately, we cannot tell if DQA will be used until the + * firmware gets loaded later, so just allocate sufficient rings + * in order to satisfy both cases. */ - if (qid > IWM_CMD_QUEUE) + if (qid > IWM_LAST_AGG_TX_QUEUE) return 0; size = IWM_TX_RING_COUNT * sizeof(struct iwm_device_cmd); @@ -1162,8 +1177,13 @@ iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid) } ring->cmd = ring->cmd_dma.vaddr; - /* FW commands may require more mapped space than packets. */ - if (qid == IWM_CMD_QUEUE) { + /* + * FW commands may require more mapped space than packets. The + * DQA command queue is ring 0 and we can't tell at allocation + * time which command queue id will be used, so give both the + * command-sized DMA tag. + */ + if (qid == IWM_CMD_QUEUE || qid == IWM_DQA_CMD_QUEUE) { maxsize = IWM_RBUF_SIZE; nsegments = 1; } else { @@ -1227,7 +1247,7 @@ iwm_reset_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring) ring->queued = 0; ring->cur = 0; - if (ring->qid == IWM_CMD_QUEUE && sc->cmd_hold_nic_awake) + if (ring->qid == sc->cmdqid && sc->cmd_hold_nic_awake) iwm_pcie_clear_cmd_in_flight(sc); } @@ -1692,9 +1712,11 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo) IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0); - if (qid == IWM_CMD_QUEUE) { + if (qid == sc->cmdqid) { +#if 0 /* Disable the scheduler. */ iwm_write_prph(sc, IWM_SCD_EN_CTRL, 0); +#endif /* Stop the TX queue prior to configuration. */ iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid), @@ -1737,7 +1759,8 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo) IWM_SCD_QUEUE_STTS_REG_MSK); /* Enable the scheduler for this queue. */ - iwm_write_prph(sc, IWM_SCD_EN_CTRL, qmsk); + iwm_write_prph(sc, IWM_SCD_EN_CTRL, + iwm_read_prph(sc, IWM_SCD_EN_CTRL) | qmsk); } else { struct iwm_scd_txq_cfg_cmd cmd; int error; @@ -1813,7 +1836,8 @@ iwm_trans_pcie_fw_alive(struct iwm_softc *sc, uint32_t scd_base_addr) iwm_nic_unlock(sc); /* enable command channel */ - error = iwm_enable_txq(sc, 0 /* unused */, IWM_CMD_QUEUE, 7); + error = iwm_enable_txq(sc, 0 /* unused */, sc->cmdqid, + IWM_TX_FIFO_CMD); if (error) return error; @@ -2929,6 +2953,11 @@ iwm_load_ucode_wait_alive(struct iwm_softc *sc, sc->cur_ucode = ucode_type; sc->ucode_loaded = FALSE; + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + sc->cmdqid = IWM_DQA_CMD_QUEUE; + else + sc->cmdqid = IWM_CMD_QUEUE; + memset(&alive_data, 0, sizeof(alive_data)); iwm_init_notification_wait(sc->sc_notif_wait, &alive_wait, alive_cmd, nitems(alive_cmd), @@ -3672,10 +3701,10 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt) static void iwm_cmd_done(struct iwm_softc *sc, struct iwm_rx_packet *pkt) { - struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE]; + struct iwm_tx_ring *ring = &sc->txq[sc->cmdqid]; struct iwm_tx_data *data; - if (pkt->hdr.qid != IWM_CMD_QUEUE) { + if (pkt->hdr.qid != sc->cmdqid) { return; /* Not a command ack. */ } @@ -3851,13 +3880,22 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac) int nsegs; uint8_t tid, type; int i, totlen, error, pad; + int qid; wh = mtod(m, struct ieee80211_frame *); hdrlen = ieee80211_anyhdrsize(wh); type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; tid = 0; - ring = &sc->txq[ac]; + + /* Map EDCA categories to Tx data queues. */ + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + qid = IWM_DQA_MIN_MGMT_QUEUE + ac; + else + qid = ac; + + ring = &sc->txq[qid]; desc = &ring->desc[ring->cur]; + memset(desc, 0, sizeof(*desc)); data = &ring->data[ring->cur]; /* Fill out iwm_tx_cmd to send to the firmware */ @@ -4767,6 +4805,17 @@ iwm_send_soc_conf(struct iwm_softc *sc) return err; } +static int +iwm_send_dqa_cmd(struct iwm_softc *sc) +{ + struct iwm_dqa_enable_cmd dqa_cmd; + uint32_t cmd_id; + + dqa_cmd.cmd_queue = htole32(IWM_DQA_CMD_QUEUE); + cmd_id = iwm_cmd_id(IWM_DQA_ENABLE_CMD, IWM_DATA_PATH_GROUP, 0); + return iwm_send_cmd_pdu(sc, cmd_id, 0, sizeof(dqa_cmd), &dqa_cmd); +} + static int iwm_send_temp_report_ths_cmd(struct iwm_softc *sc) { @@ -4907,7 +4956,7 @@ static int iwm_init_hw(struct iwm_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - int error, i, ac; + int error, i, ac, qid; sc->sf_state = IWM_SF_UNINIT; @@ -4973,6 +5022,11 @@ iwm_init_hw(struct iwm_softc *sc) goto error; } + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) { + if ((error = iwm_send_dqa_cmd(sc)) != 0) + goto error; + } + /* Add auxiliary station for scanning */ if ((error = iwm_add_aux_sta(sc)) != 0) { device_printf(sc->sc_dev, "add_aux_sta failed\n"); @@ -5011,7 +5065,12 @@ iwm_init_hw(struct iwm_softc *sc) /* Enable Tx queues. */ for (ac = 0; ac < WME_NUM_AC; ac++) { - error = iwm_enable_txq(sc, IWM_STATION_ID, ac, + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + qid = ac + IWM_DQA_MIN_MGMT_QUEUE; + else + qid = ac; + + error = iwm_enable_txq(sc, IWM_STATION_ID, qid, iwm_ac_to_tx_fifo[ac]); if (error) goto error; diff --git a/sys/dev/iwm/if_iwm_sta.c b/sys/dev/iwm/if_iwm_sta.c index 4c0fbd24658c..1c2725d33f90 100644 --- a/sys/dev/iwm/if_iwm_sta.c +++ b/sys/dev/iwm/if_iwm_sta.c @@ -162,8 +162,10 @@ iwm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in, if (!update) { int ac; for (ac = 0; ac < WME_NUM_AC; ac++) { - add_sta_cmd.tfd_queue_msk |= - htole32(1 << iwm_ac_to_tx_fifo[ac]); + int qid = ac; + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + qid += IWM_DQA_MIN_MGMT_QUEUE; + add_sta_cmd.tfd_queue_msk |= htole32(1 << qid); } IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid); } @@ -277,7 +279,10 @@ iwm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap, if (ret) return ret; for (ac = 0; ac < WME_NUM_AC; ac++) { - tfd_queue_msk |= htole32(1 << iwm_ac_to_tx_fifo[ac]); + int qid = ac; + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + qid += IWM_DQA_MIN_MGMT_QUEUE; + tfd_queue_msk |= htole32(1 << qid); } ret = iwm_flush_tx_path(sc, tfd_queue_msk, IWM_CMD_SYNC); if (ret) @@ -352,13 +357,24 @@ int iwm_add_aux_sta(struct iwm_softc *sc) { int ret; + int qid; + + /* + * Note: OpenBSD calls different TXQ setups here; + * + DQA calls iwm_enable_txq(), which only sends the cmd_pdu + * + non-DQA calls iwm_enable_ac_txq(), which does similar stuff to + * command setup but not the command scheduler + */ + if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + qid = IWM_DQA_AUX_QUEUE; + else + qid = IWM_AUX_QUEUE; sc->sc_aux_sta.sta_id = IWM_AUX_STA_ID; - sc->sc_aux_sta.tfd_queue_msk = (1 << IWM_AUX_QUEUE); + sc->sc_aux_sta.tfd_queue_msk = (1 << qid); /* Map Aux queue to fifo - needs to happen before adding Aux station */ - ret = iwm_enable_txq(sc, IWM_AUX_STA_ID, IWM_AUX_QUEUE, - IWM_TX_FIFO_MCAST); + ret = iwm_enable_txq(sc, IWM_AUX_STA_ID, qid, IWM_TX_FIFO_MCAST); if (ret) return ret; diff --git a/sys/dev/iwm/if_iwm_util.c b/sys/dev/iwm/if_iwm_util.c index 305a5289f4a5..7744433312d4 100644 --- a/sys/dev/iwm/if_iwm_util.c +++ b/sys/dev/iwm/if_iwm_util.c @@ -167,7 +167,7 @@ int iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd) { - struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE]; + struct iwm_tx_ring *ring = &sc->txq[sc->cmdqid]; struct iwm_tfd *desc; struct iwm_tx_data *txdata = NULL; struct iwm_device_cmd *cmd; diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h index 4231b394cfe4..8f2760f114f3 100644 --- a/sys/dev/iwm/if_iwmvar.h +++ b/sys/dev/iwm/if_iwmvar.h @@ -454,6 +454,7 @@ struct iwm_softc { struct iwm_tx_ring txq[IWM_MAX_QUEUES]; struct iwm_rx_ring rxq; int qfullmsk; + int cmdqid; /* ICT table. */ struct iwm_dma_info ict_dma;