From nobody Wed Apr 15 12:12:51 2026 X-Original-To: dev-commits-src-all@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 4fwg5P3NzFz6Zn6n for ; Wed, 15 Apr 2026 12:12:57 +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 "R12" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4fwg5P0rCBz3ZXZ for ; Wed, 15 Apr 2026 12:12:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1776255177; 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=b8Hsa5EtXl5chhke/tx/R6h0f5rZJrGJYEneitTk2gI=; b=sjgQIzf5OCwuntSSbuXdWneLV2cCzAZNV5ySHgNVvD6gPdguMNC+9518BjEWuPY7U0kotO NPiqpe7A55Z0ab1XolOv566E/lQiQKpvvu3Zp6RrPTuvKOV3vJYulFf+XCRbZ5h4Ps2xLP 4YZSh+sF4E1ecmj1QuLGDsGSyjz6erCkmmlVJe1+c8ibsIH6nsaKxokhqGu/0+k9+eDi4R QUG6pATu3mdJml3dMr7HTznAVAB162mvU1ZgM0KaZKJ+SYFK9OVOHVJIqQ9Z3qwhMdnY+l wmsnxlBG3DRZpc1fKqiU9By5zDIysK66rsqMO2yuETI1nEDNX/0nJq+BrzK5+g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1776255177; a=rsa-sha256; cv=none; b=pWJmhS6HnQi7jq5PZ3DJ616htzG+nsTP5bEQUkpWlH9QhhebliBIRlvA+OlwDqJNFNt0IO HRq2rLXjVL+3vSO5sZG6enPIBiiCML14GI/pzk3s1/HFj5fJ8lI0jVhXSKRa3i7djzHHxZ OoImC+dGvSGlFug9AUQiVb6pMwbRJEClf7QXAcDlLv/ny6n/4l+fV6WPMyuRXWns4Wu+y/ c4oMDoWzzHLh+8oQnLcY+3++5SetDL/5Q1GKXLKyf9UsMgLbRiXo1V4LY/0a+OT1pnC3kI TOcOSg5hzZFSTZAEr/vgZKbiy8Gw9lu13nC5tkYeEnxeY0eNrZPw9qyiDRGP6A== 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=1776255177; 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=b8Hsa5EtXl5chhke/tx/R6h0f5rZJrGJYEneitTk2gI=; b=fRrswWBqvMTxUMTLdjIeoqestM5+jCNACWUsbDJjus1Arx56G7NWsZiPQyfE/XkzvjoZs0 HnHINaiytTedBVZalJkHCBpD7M2/TZAE1jmwlXF36N7ZC/Z0kfqke1qNmaEyAPDGf8GOOR tHvFngbtLlKa+LAOHrBLzLHmrbjbganwtS923LbUkcTIzqnpf2WLeo9o+9kWk0ymLXstoC s922d3cjlsCK9LOQj2QaFaFcmng3EPCqIU/+pWzJLJNn+BYSA2QrTRKXQcWGbU/oTzHlEb XEAYQaYn1EvjQ6TN+VSnRvLWSiiAgZ+yx49rIeqtkWUuih8ELjt7z92zq7KLZw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4fwg5P03G7z4dN for ; Wed, 15 Apr 2026 12:12:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3bd7d by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 15 Apr 2026 12:12:51 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Aymeric Wibo Subject: git: bb36c457ea49 - main - thunderbolt: Support generic USB4 NHIs List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: obiwac X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: bb36c457ea49d80ca3109ef25ca41a614f9738b8 Auto-Submitted: auto-generated Date: Wed, 15 Apr 2026 12:12:51 +0000 Message-Id: <69df80c3.3bd7d.59a4f11d@gitrepo.freebsd.org> The branch main has been updated by obiwac: URL: https://cgit.FreeBSD.org/src/commit/?id=bb36c457ea49d80ca3109ef25ca41a614f9738b8 commit bb36c457ea49d80ca3109ef25ca41a614f9738b8 Author: Aymeric Wibo AuthorDate: 2026-04-15 12:04:17 +0000 Commit: Aymeric Wibo CommitDate: 2026-04-15 12:10:24 +0000 thunderbolt: Support generic USB4 NHIs Check a PCI device's class, subclass, and progif to figure out if it is a USB4 NHI. nhi_identifiers is completely removed as only these generic USB4 NHIs are supported anyway, and all remnants of ICM-supporting code are removed too. All devices now use the HCM. PR: 290827 Reviewed by: jhb, ngie Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D52861 --- sys/dev/pci/pcireg.h | 1 + sys/dev/thunderbolt/nhi.c | 49 ++--------------- sys/dev/thunderbolt/nhi_pci.c | 121 ++---------------------------------------- sys/dev/thunderbolt/nhi_var.h | 18 ------- sys/dev/thunderbolt/tb_pcib.c | 12 ----- 5 files changed, 9 insertions(+), 192 deletions(-) diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index f6aaf30611e4..3ec7879b8a09 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -464,6 +464,7 @@ #define PCIP_SERIALBUS_USB_OHCI 0x10 #define PCIP_SERIALBUS_USB_EHCI 0x20 #define PCIP_SERIALBUS_USB_XHCI 0x30 +#define PCIP_SERIALBUS_USB_USB4 0x40 #define PCIP_SERIALBUS_USB_DEVICE 0xfe #define PCIS_SERIALBUS_FC 0x04 #define PCIS_SERIALBUS_SMBUS 0x05 diff --git a/sys/dev/thunderbolt/nhi.c b/sys/dev/thunderbolt/nhi.c index 30a72652535a..74cefbb50ca1 100644 --- a/sys/dev/thunderbolt/nhi.c +++ b/sys/dev/thunderbolt/nhi.c @@ -84,11 +84,6 @@ MALLOC_DEFINE(M_NHI, "nhi", "nhi driver memory"); #define NHI_DEBUG_LEVEL 0 #endif -/* 0 = default, 1 = force-on, 2 = force-off */ -#ifndef NHI_FORCE_HCM -#define NHI_FORCE_HCM 0 -#endif - void nhi_get_tunables(struct nhi_softc *sc) { @@ -100,7 +95,6 @@ nhi_get_tunables(struct nhi_softc *sc) /* Set local defaults */ sc->debug = NHI_DEBUG_LEVEL; sc->max_ring_count = NHI_DEFAULT_NUM_RINGS; - sc->force_hcm = NHI_FORCE_HCM; /* Inherit setting from the upstream thunderbolt switch node */ val = TB_GET_DEBUG(sc->dev, &sc->debug); @@ -128,8 +122,6 @@ nhi_get_tunables(struct nhi_softc *sc) val = min(val, NHI_MAX_NUM_RINGS); sc->max_ring_count = max(val, 1); } - if (TUNABLE_INT_FETCH("hw.nhi.force_hcm", &val) != 0) - sc->force_hcm = val; /* Grab instance variables */ bzero(oid, 80); @@ -143,24 +135,10 @@ nhi_get_tunables(struct nhi_softc *sc) val = min(val, NHI_MAX_NUM_RINGS); sc->max_ring_count = max(val, 1); } - snprintf(tmpstr, sizeof(tmpstr), "dev, nhi.%d.force_hcm", - device_get_unit(sc->dev)); - if (TUNABLE_INT_FETCH(tmpstr, &val) != 0) - sc->force_hcm = val; return; } -static void -nhi_configure_caps(struct nhi_softc *sc) -{ - - if (NHI_IS_USB4(sc) || (sc->force_hcm == NHI_FORCE_HCM_ON)) - sc->caps |= NHI_CAP_HCM; - if (sc->force_hcm == NHI_FORCE_HCM_OFF) - sc->caps &= ~NHI_CAP_HCM; -} - struct nhi_cmd_frame * nhi_alloc_tx_frame(struct nhi_ring_pair *r) { @@ -268,16 +246,14 @@ nhi_attach(struct nhi_softc *sc) mtx_init(&sc->nhi_mtx, "nhimtx", "NHI Control Mutex", MTX_DEF); - nhi_configure_caps(sc); - /* * Get the number of TX/RX paths. This sizes some of the register * arrays during allocation and initialization. USB4 spec says that - * the max is 21. Alpine Ridge appears to default to 12. + * the max is 21. */ val = GET_HOST_CAPS_PATHS(nhi_read_reg(sc, NHI_HOST_CAPS)); tb_debug(sc, DBG_INIT|DBG_NOISY, "Total Paths= %d\n", val); - if ((val == 0) || (val > 21) || ((NHI_IS_AR(sc) && val != 12))) { + if (val == 0 || val > 21) { tb_printf(sc, "WARN: unexpected number of paths: %d\n", val); /* return (ENXIO); */ } @@ -297,10 +273,6 @@ nhi_attach(struct nhi_softc *sc) if (error == 0) error = tbdev_add_interface(sc); - if ((error == 0) && (NHI_USE_ICM(sc))) - tb_printf(sc, "WARN: device uses an internal connection manager\n"); - if ((error == 0) && (NHI_USE_HCM(sc))) - ; error = hcm_attach(sc); if (error == 0) @@ -312,9 +284,7 @@ nhi_attach(struct nhi_softc *sc) int nhi_detach(struct nhi_softc *sc) { - - if (NHI_USE_HCM(sc)) - hcm_detach(sc); + hcm_detach(sc); if (sc->root_rsc != NULL) tb_router_detach(sc->root_rsc); @@ -706,16 +676,6 @@ nhi_init(struct nhi_softc *sc) tb_debug(sc, DBG_INIT, "Setting interrupt auto-ACK, 0x%08x\n", val); nhi_write_reg(sc, NHI_DMA_MISC, val); - if (NHI_IS_AR(sc) || NHI_IS_TR(sc) || NHI_IS_ICL(sc)) - tb_printf(sc, "WARN: device uses an internal connection manager\n"); - - /* - * Populate the controller (local) UUID, necessary for cross-domain - * communications. - if (NHI_IS_ICL(sc)) - nhi_pci_get_uuid(sc); - */ - /* * Attach the router to the root thunderbolt bridge now that the DMA * channel is configured and ready. @@ -1163,9 +1123,6 @@ nhi_setup_sysctl(struct nhi_softc *sc) SYSCTL_ADD_U16(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "max_rings", CTLFLAG_RD, &sc->max_ring_count, 0, "Max number of rings available"); - SYSCTL_ADD_U8(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "force_hcm", CTLFLAG_RD, &sc->force_hcm, 0, - "Force on/off the function of the host connection manager"); return (0); } diff --git a/sys/dev/thunderbolt/nhi_pci.c b/sys/dev/thunderbolt/nhi_pci.c index 14cae7427448..777f8dd5352e 100644 --- a/sys/dev/thunderbolt/nhi_pci.c +++ b/sys/dev/thunderbolt/nhi_pci.c @@ -68,7 +68,6 @@ static int nhi_pci_resume(device_t); static void nhi_pci_free(struct nhi_softc *); static int nhi_pci_allocate_interrupts(struct nhi_softc *); static void nhi_pci_free_resources(struct nhi_softc *); -static int nhi_pci_icl_poweron(struct nhi_softc *); static device_method_t nhi_methods[] = { DEVMETHOD(device_probe, nhi_pci_probe), @@ -89,67 +88,18 @@ static driver_t nhi_pci_driver = { sizeof(struct nhi_softc) }; -struct nhi_ident { - uint16_t vendor; - uint16_t device; - uint16_t subvendor; - uint16_t subdevice; - uint32_t flags; - const char *desc; -} nhi_identifiers[] = { - { VENDOR_INTEL, DEVICE_AR_2C_NHI, 0xffff, 0xffff, NHI_TYPE_AR, - "Thunderbolt 3 NHI (Alpine Ridge 2C)" }, - { VENDOR_INTEL, DEVICE_AR_DP_B_NHI, 0xffff, 0xffff, NHI_TYPE_AR, - "Thunderbolt 3 NHI (Alpine Ridge 4C Rev B)" }, - { VENDOR_INTEL, DEVICE_AR_DP_C_NHI, 0xffff, 0xffff, NHI_TYPE_AR, - "Thunderbolt 3 NHI (Alpine Ridge 4C Rev C)" }, - { VENDOR_INTEL, DEVICE_AR_LP_NHI, 0xffff, 0xffff, NHI_TYPE_AR, - "Thunderbolt 3 NHI (Alpine Ridge LP 2C)" }, - { VENDOR_INTEL, DEVICE_ICL_NHI_0, 0xffff, 0xffff, NHI_TYPE_ICL, - "Thunderbolt 3 NHI Port 0 (IceLake)" }, - { VENDOR_INTEL, DEVICE_ICL_NHI_1, 0xffff, 0xffff, NHI_TYPE_ICL, - "Thunderbolt 3 NHI Port 1 (IceLake)" }, - { VENDOR_AMD, DEVICE_PINK_SARDINE_0, 0xffff, 0xffff, NHI_TYPE_USB4, - "USB4 NHI Port 0 (Pink Sardine)" }, - { VENDOR_AMD, DEVICE_PINK_SARDINE_1, 0xffff, 0xffff, NHI_TYPE_USB4, - "USB4 NHI Port 1 (Pink Sardine)" }, - { 0, 0, 0, 0, 0, NULL } -}; - DRIVER_MODULE_ORDERED(nhi, pci, nhi_pci_driver, NULL, NULL, SI_ORDER_ANY); -static struct nhi_ident * -nhi_find_ident(device_t dev) -{ - struct nhi_ident *n; - - for (n = nhi_identifiers; n->vendor != 0; n++) { - if (n->vendor != pci_get_vendor(dev)) - continue; - if (n->device != pci_get_device(dev)) - continue; - if ((n->subvendor != 0xffff) && - (n->subvendor != pci_get_subvendor(dev))) - continue; - if ((n->subdevice != 0xffff) && - (n->subdevice != pci_get_subdevice(dev))) - continue; - return (n); - } - - return (NULL); -} - static int nhi_pci_probe(device_t dev) { - struct nhi_ident *n; - if (resource_disabled("tb", 0)) return (ENXIO); - if ((n = nhi_find_ident(dev)) != NULL) { - device_set_desc(dev, n->desc); + if ((pci_get_class(dev) == PCIC_SERIALBUS) + && (pci_get_subclass(dev) == PCIS_SERIALBUS_USB) + && (pci_get_progif(dev) == PCIP_SERIALBUS_USB_USB4)) { + device_set_desc(dev, "Generic USB4 NHI"); return (BUS_PROBE_DEFAULT); } return (ENXIO); @@ -161,14 +111,12 @@ nhi_pci_attach(device_t dev) devclass_t dc; bus_dma_template_t t; struct nhi_softc *sc; - struct nhi_ident *n; int error = 0; sc = device_get_softc(dev); bzero(sc, sizeof(*sc)); sc->dev = dev; - n = nhi_find_ident(dev); - sc->hwflags = n->flags; + sc->hwflags = NHI_TYPE_USB4; nhi_get_tunables(sc); tb_debug(sc, DBG_INIT|DBG_FULL, "busmaster status was %s\n", @@ -188,12 +136,6 @@ nhi_pci_attach(device_t dev) tb_printf(sc, "Upstream Facing Port is %s\n", device_get_nameunit(sc->ufp)); - if (NHI_IS_ICL(sc)) { - if ((error = nhi_pci_icl_poweron(sc)) != 0) - return (error); - } - - /* Allocate BAR0 DMA registers */ sc->regs_rid = PCIR_BAR(0); if ((sc->regs_resource = bus_alloc_resource_any(dev, @@ -476,56 +418,3 @@ nhi_pci_disable_interrupts(struct nhi_softc *sc) nhi_read_reg(sc, NHI_ISR0); nhi_read_reg(sc, NHI_ISR1); } - -/* - * Icelake controllers need to be notified of power-on - */ -static int -nhi_pci_icl_poweron(struct nhi_softc *sc) -{ - device_t dev; - uint32_t val; - int i, error = 0; - - dev = sc->dev; - val = pci_read_config(dev, ICL_VSCAP_9, 4); - tb_debug(sc, DBG_INIT, "icl_poweron val= 0x%x\n", val); - if (val & ICL_VSCAP9_FWREADY) - return (0); - - val = pci_read_config(dev, ICL_VSCAP_22, 4); - val |= ICL_VSCAP22_FORCEPWR; - tb_debug(sc, DBG_INIT|DBG_FULL, "icl_poweron writing 0x%x\n", val); - pci_write_config(dev, ICL_VSCAP_22, val, 4); - - error = ETIMEDOUT; - for (i = 0; i < 15; i++) { - DELAY(1000000); - val = pci_read_config(dev, ICL_VSCAP_9, 4); - if (val & ICL_VSCAP9_FWREADY) { - error = 0; - break; - } - } - - return (error); -} - -/* - * Icelake and Alderlake controllers store their UUID in PCI config space - */ -int -nhi_pci_get_uuid(struct nhi_softc *sc) -{ - device_t dev; - uint32_t val[4]; - - dev = sc->dev; - val[0] = pci_read_config(dev, ICL_VSCAP_10, 4); - val[1] = pci_read_config(dev, ICL_VSCAP_11, 4); - val[2] = 0xffffffff; - val[3] = 0xffffffff; - - bcopy(val, &sc->uuid, 16); - return (0); -} diff --git a/sys/dev/thunderbolt/nhi_var.h b/sys/dev/thunderbolt/nhi_var.h index e79ecc954c1f..e22c0f4a2bae 100644 --- a/sys/dev/thunderbolt/nhi_var.h +++ b/sys/dev/thunderbolt/nhi_var.h @@ -142,19 +142,9 @@ struct nhi_softc { u_int debug; u_int hwflags; #define NHI_TYPE_UNKNOWN 0x00 -#define NHI_TYPE_AR 0x01 /* Alpine Ridge */ -#define NHI_TYPE_TR 0x02 /* Titan Ridge */ -#define NHI_TYPE_ICL 0x03 /* IceLake */ -#define NHI_TYPE_MR 0x04 /* Maple Ridge */ -#define NHI_TYPE_ADL 0x05 /* AlderLake */ #define NHI_TYPE_USB4 0x0f #define NHI_TYPE_MASK 0x0f #define NHI_MBOX_BUSY 0x10 - u_int caps; -#define NHI_CAP_ICM 0x01 -#define NHI_CAP_HCM 0x02 -#define NHI_USE_ICM(sc) ((sc)->caps & NHI_CAP_ICM) -#define NHI_USE_HCM(sc) ((sc)->caps & NHI_CAP_HCM) struct hcm_softc *hcm; struct router_softc *root_rsc; @@ -194,11 +184,6 @@ struct nhi_softc { struct intr_config_hook ich; - uint8_t force_hcm; -#define NHI_FORCE_HCM_DEFAULT 0x00 -#define NHI_FORCE_HCM_ON 0x01 -#define NHI_FORCE_HCM_OFF 0x02 - uint8_t uuid[16]; uint8_t lc_uuid[16]; }; @@ -209,9 +194,6 @@ struct nhi_dispatch { void *context; }; -#define NHI_IS_AR(sc) (((sc)->hwflags & NHI_TYPE_MASK) == NHI_TYPE_AR) -#define NHI_IS_TR(sc) (((sc)->hwflags & NHI_TYPE_MASK) == NHI_TYPE_TR) -#define NHI_IS_ICL(sc) (((sc)->hwflags & NHI_TYPE_MASK) == NHI_TYPE_ICL) #define NHI_IS_USB4(sc) (((sc)->hwflags & NHI_TYPE_MASK) == NHI_TYPE_USB4) int nhi_pci_configure_interrupts(struct nhi_softc *sc); diff --git a/sys/dev/thunderbolt/tb_pcib.c b/sys/dev/thunderbolt/tb_pcib.c index ffb85ebec9ae..b30de5a7493c 100644 --- a/sys/dev/thunderbolt/tb_pcib.c +++ b/sys/dev/thunderbolt/tb_pcib.c @@ -90,18 +90,6 @@ struct tb_pcib_ident { uint32_t flags; /* This follows the tb_softc flags */ const char *desc; } tb_pcib_identifiers[] = { - { VENDOR_INTEL, TB_DEV_AR_2C, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, - "Thunderbolt 3 PCI-PCI Bridge (Alpine Ridge 2C)" }, - { VENDOR_INTEL, TB_DEV_AR_LP, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, - "Thunderbolt 3 PCI-PCI Bridge (Alpine Ridge LP)" }, - { VENDOR_INTEL, TB_DEV_AR_C_4C, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, - "Thunderbolt 3 PCI-PCI Bridge (Alpine Ridge C 4C)" }, - { VENDOR_INTEL, TB_DEV_AR_C_2C, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, - "Thunderbolt 3 PCI-PCI Bridge C (Alpine Ridge C 2C)" }, - { VENDOR_INTEL, TB_DEV_ICL_0, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_ICL, - "Thunderbolt 3 PCI-PCI Bridge (IceLake)" }, - { VENDOR_INTEL, TB_DEV_ICL_1, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_ICL, - "Thunderbolt 3 PCI-PCI Bridge (IceLake)" }, { 0, 0, 0, 0, 0, NULL } };