The branch main has been updated by obiwac:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=efdb82413963bea5f4bf2ae52006cceeb6944a3b

commit efdb82413963bea5f4bf2ae52006cceeb6944a3b
Author:     Aymeric Wibo <[email protected]>
AuthorDate: 2026-08-12 17:40:56 +0000
Commit:     Aymeric Wibo <[email protected]>
CommitDate: 2026-08-12 21:53:13 +0000

    thunderbolt: Reset controllers
    
    Reset routine for both v1.0 and v2.0 routes, chosen depending on version
    reported in caps.
    
    Reviewed by:    imp
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D49452
---
 sys/dev/thunderbolt/nhi.c        | 63 ++++++++++++++++++++++++++++++++++++++++
 sys/dev/thunderbolt/router_var.h |  4 +++
 2 files changed, 67 insertions(+)

diff --git a/sys/dev/thunderbolt/nhi.c b/sys/dev/thunderbolt/nhi.c
index 4b45560923c3..75eb4fe6a5d9 100644
--- a/sys/dev/thunderbolt/nhi.c
+++ b/sys/dev/thunderbolt/nhi.c
@@ -235,6 +235,67 @@ nhi_outmail_cmd(struct nhi_softc *sc, uint32_t *val)
        return (0);
 }
 
+static int
+nhi_reset_v1(struct nhi_softc *sc)
+{
+
+       /* See section 2.4 of HCM guide v2. */
+       nhi_write_reg(sc, ROUTER_HIR, 1);
+       pause_sbt("nhi", ustosbt(10 * 1000), 0, C_HARDCLOCK);
+       return (0);
+}
+
+static int
+nhi_reset_v2(struct nhi_softc *sc)
+{
+       uint32_t reg;
+
+       /*
+        * TODO "The Connection Manager shall disable all Transmit Descriptor
+        * Rings and wait for at least 1 millisecond prior to setting the Host
+        * Router Reset bit to 1b. After the Connection Manager sets the Host
+        * Router Reset bit to 1b, it shall not access the Receive Descriptor
+        * Rings until the Host Router Reset bit is set to 0b."
+        */
+       /* See section 3.5 of HCM guide v2. */
+       nhi_write_reg(sc, ROUTER_HRR, 1);
+       /*
+        * "The Host Router is required to complete its reset within 500ms
+        * after the Host Router Reset bit is set to 1b."
+        */
+       for (size_t i = 0; i < 10 && reg; i++) {
+               /*
+                * Wait at least 50 ms after writing before reading this
+                * register.  If this is 1, it means that we are still
+                * resetting.
+                */
+               pause_sbt("nhi", ustosbt(50 * 1000), 0, 0);
+               reg = nhi_read_reg(sc, ROUTER_HRR);
+       }
+       if (reg == 0) {
+               tb_debug(sc, DBG_INIT|DBG_EXTRA,
+                   "Succeeded in resetting host router\n");
+               return (0);
+       }
+       tb_printf(sc, "Host router reset timed out\n");
+       return (ETIMEDOUT);
+}
+
+static int
+nhi_reset(struct nhi_softc *sc)
+{
+
+       tb_debug(sc, DBG_INIT, "Resetting host router\n");
+
+       switch (sc->ver) {
+       case NHI_VER_1_0:
+               return (nhi_reset_v1(sc));
+       case NHI_VER_2_0:
+               return (nhi_reset_v2(sc));
+       }
+       return (ENXIO);
+}
+
 int
 nhi_attach(struct nhi_softc *sc)
 {
@@ -272,6 +333,8 @@ nhi_attach(struct nhi_softc *sc)
        }
        sc->path_count = val;
 
+       nhi_reset(sc);
+
        SLIST_INIT(&sc->ring_list);
 
        error = nhi_pci_configure_interrupts(sc);
diff --git a/sys/dev/thunderbolt/router_var.h b/sys/dev/thunderbolt/router_var.h
index 8366ede852e7..06c41e636121 100644
--- a/sys/dev/thunderbolt/router_var.h
+++ b/sys/dev/thunderbolt/router_var.h
@@ -87,6 +87,10 @@ struct router_cfg_cap {
        uint16_t        vsec_len;
 };
 
+/* Router reset registers */
+#define ROUTER_HRR     0x39898
+#define ROUTER_HIR     0x39858
+
 int tb_router_attach(struct router_softc *, tb_route_t);
 int tb_router_attach_root(struct nhi_softc *, tb_route_t);
 int tb_router_detach(struct router_softc *);

Reply via email to