thunderbolt: Disable PCIe extended encapsulation upon teardown properly
authorGil Fine <gil.fine@linux.intel.com>
Wed, 15 Nov 2023 10:09:57 +0000 (12:09 +0200)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 14 Dec 2023 06:07:45 +0000 (08:07 +0200)
In case of PCIe tunnel teardown (including if caused by router unplug),
PCIe extended encapsulation bit should be cleared in downstream and
upstream routers accordingly.

Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/thunderbolt/tunnel.c

index b0c3c8373775e43086aec976f5aed7661fa45023..6fffb2c82d3d1332a9de5005b7a67099ef5d8582 100644 (file)
@@ -173,16 +173,28 @@ static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable)
        int ret;
 
        /* Only supported of both routers are at least USB4 v2 */
-       if (tb_port_get_link_generation(port) < 4)
+       if ((usb4_switch_version(tunnel->src_port->sw) < 2) ||
+          (usb4_switch_version(tunnel->dst_port->sw) < 2))
+               return 0;
+
+       if (enable && tb_port_get_link_generation(port) < 4)
                return 0;
 
        ret = usb4_pci_port_set_ext_encapsulation(tunnel->src_port, enable);
        if (ret)
                return ret;
 
+       /*
+        * Downstream router could be unplugged so disable of encapsulation
+        * in upstream router is still possible.
+        */
        ret = usb4_pci_port_set_ext_encapsulation(tunnel->dst_port, enable);
-       if (ret)
-               return ret;
+       if (ret) {
+               if (enable)
+                       return ret;
+               if (ret != -ENODEV)
+                       return ret;
+       }
 
        tb_tunnel_dbg(tunnel, "extended encapsulation %s\n",
                      str_enabled_disabled(enable));