Loading drivers/thunderbolt/tb.c +3 −0 Original line number Diff line number Diff line Loading @@ -235,6 +235,9 @@ static int tb_tunnel_usb3(struct tb *tb, struct tb_switch *sw) if (!up) return 0; if (!sw->link_usb4) return 0; /* * Look up available down port. Since we are chaining it should * be found right above this switch. Loading drivers/thunderbolt/tb.h +2 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ struct tb_switch_tmu { * @device_name: Name of the device (or %NULL if not known) * @link_speed: Speed of the link in Gb/s * @link_width: Width of the link (1 or 2) * @link_usb4: Upstream link is USB4 * @generation: Switch Thunderbolt generation * @cap_plug_events: Offset to the plug events capability (%0 if not found) * @cap_lc: Offset to the link controller capability (%0 if not found) Loading Loading @@ -136,6 +137,7 @@ struct tb_switch { const char *device_name; unsigned int link_speed; unsigned int link_width; bool link_usb4; unsigned int generation; int cap_plug_events; int cap_lc; Loading drivers/thunderbolt/tb_regs.h +1 −0 Original line number Diff line number Diff line Loading @@ -290,6 +290,7 @@ struct tb_regs_port_header { /* USB4 port registers */ #define PORT_CS_18 0x12 #define PORT_CS_18_BE BIT(8) #define PORT_CS_18_TCM BIT(9) #define PORT_CS_19 0x13 #define PORT_CS_19_PC BIT(3) Loading drivers/thunderbolt/usb4.c +21 −3 Original line number Diff line number Diff line Loading @@ -192,6 +192,20 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status) return 0; } static bool link_is_usb4(struct tb_port *port) { u32 val; if (!port->cap_usb4) return false; if (tb_port_read(port, &val, TB_CFG_PORT, port->cap_usb4 + PORT_CS_18, 1)) return false; return !(val & PORT_CS_18_TCM); } /** * usb4_switch_setup() - Additional setup for USB4 device * @sw: USB4 router to setup Loading @@ -205,6 +219,7 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status) */ int usb4_switch_setup(struct tb_switch *sw) { struct tb_port *downstream_port; struct tb_switch *parent; bool tbt3, xhci; u32 val = 0; Loading @@ -217,6 +232,11 @@ int usb4_switch_setup(struct tb_switch *sw) if (ret) return ret; parent = tb_switch_parent(sw); downstream_port = tb_port_at(tb_route(sw), parent); sw->link_usb4 = link_is_usb4(downstream_port); tb_sw_dbg(sw, "link: %s\n", sw->link_usb4 ? "USB4" : "TBT3"); xhci = val & ROUTER_CS_6_HCI; tbt3 = !(val & ROUTER_CS_6_TNS); Loading @@ -227,9 +247,7 @@ int usb4_switch_setup(struct tb_switch *sw) if (ret) return ret; parent = tb_switch_parent(sw); if (tb_switch_find_port(parent, TB_TYPE_USB3_DOWN)) { if (sw->link_usb4 && tb_switch_find_port(parent, TB_TYPE_USB3_DOWN)) { val |= ROUTER_CS_5_UTO; xhci = false; } Loading Loading
drivers/thunderbolt/tb.c +3 −0 Original line number Diff line number Diff line Loading @@ -235,6 +235,9 @@ static int tb_tunnel_usb3(struct tb *tb, struct tb_switch *sw) if (!up) return 0; if (!sw->link_usb4) return 0; /* * Look up available down port. Since we are chaining it should * be found right above this switch. Loading
drivers/thunderbolt/tb.h +2 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ struct tb_switch_tmu { * @device_name: Name of the device (or %NULL if not known) * @link_speed: Speed of the link in Gb/s * @link_width: Width of the link (1 or 2) * @link_usb4: Upstream link is USB4 * @generation: Switch Thunderbolt generation * @cap_plug_events: Offset to the plug events capability (%0 if not found) * @cap_lc: Offset to the link controller capability (%0 if not found) Loading Loading @@ -136,6 +137,7 @@ struct tb_switch { const char *device_name; unsigned int link_speed; unsigned int link_width; bool link_usb4; unsigned int generation; int cap_plug_events; int cap_lc; Loading
drivers/thunderbolt/tb_regs.h +1 −0 Original line number Diff line number Diff line Loading @@ -290,6 +290,7 @@ struct tb_regs_port_header { /* USB4 port registers */ #define PORT_CS_18 0x12 #define PORT_CS_18_BE BIT(8) #define PORT_CS_18_TCM BIT(9) #define PORT_CS_19 0x13 #define PORT_CS_19_PC BIT(3) Loading
drivers/thunderbolt/usb4.c +21 −3 Original line number Diff line number Diff line Loading @@ -192,6 +192,20 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status) return 0; } static bool link_is_usb4(struct tb_port *port) { u32 val; if (!port->cap_usb4) return false; if (tb_port_read(port, &val, TB_CFG_PORT, port->cap_usb4 + PORT_CS_18, 1)) return false; return !(val & PORT_CS_18_TCM); } /** * usb4_switch_setup() - Additional setup for USB4 device * @sw: USB4 router to setup Loading @@ -205,6 +219,7 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status) */ int usb4_switch_setup(struct tb_switch *sw) { struct tb_port *downstream_port; struct tb_switch *parent; bool tbt3, xhci; u32 val = 0; Loading @@ -217,6 +232,11 @@ int usb4_switch_setup(struct tb_switch *sw) if (ret) return ret; parent = tb_switch_parent(sw); downstream_port = tb_port_at(tb_route(sw), parent); sw->link_usb4 = link_is_usb4(downstream_port); tb_sw_dbg(sw, "link: %s\n", sw->link_usb4 ? "USB4" : "TBT3"); xhci = val & ROUTER_CS_6_HCI; tbt3 = !(val & ROUTER_CS_6_TNS); Loading @@ -227,9 +247,7 @@ int usb4_switch_setup(struct tb_switch *sw) if (ret) return ret; parent = tb_switch_parent(sw); if (tb_switch_find_port(parent, TB_TYPE_USB3_DOWN)) { if (sw->link_usb4 && tb_switch_find_port(parent, TB_TYPE_USB3_DOWN)) { val |= ROUTER_CS_5_UTO; xhci = false; } Loading