Lines Matching +full:usb3 +full:- +full:if
1 // SPDX-License-Identifier: GPL-2.0
3 * Thunderbolt driver - Tunneling support
22 /* USB3 adapters use always HopID of 8 for both directions */
40 static const char * const tb_tunnel_names[] = { "PCI", "DP", "DMA", "USB3" };
45 level(__tunnel->tb, "%llx:%x <-> %llx:%x (%s): " fmt, \
46 tb_route(__tunnel->src_port->sw), \
47 __tunnel->src_port->port, \
48 tb_route(__tunnel->dst_port->sw), \
49 __tunnel->dst_port->port, \
50 tb_tunnel_names[__tunnel->type], \
69 if (!tunnel) in tb_tunnel_alloc()
72 tunnel->paths = kcalloc(npaths, sizeof(tunnel->paths[0]), GFP_KERNEL); in tb_tunnel_alloc()
73 if (!tunnel->paths) { in tb_tunnel_alloc()
78 INIT_LIST_HEAD(&tunnel->list); in tb_tunnel_alloc()
79 tunnel->tb = tb; in tb_tunnel_alloc()
80 tunnel->npaths = npaths; in tb_tunnel_alloc()
81 tunnel->type = type; in tb_tunnel_alloc()
90 res = tb_pci_port_enable(tunnel->src_port, activate); in tb_pci_activate()
91 if (res) in tb_pci_activate()
94 if (tb_port_is_pcie_up(tunnel->dst_port)) in tb_pci_activate()
95 return tb_pci_port_enable(tunnel->dst_port, activate); in tb_pci_activate()
102 /* If the path is complete sw is not NULL */ in tb_initial_credits()
103 if (sw) { in tb_initial_credits()
105 switch (sw->link_speed * sw->link_width) { in tb_initial_credits()
118 path->egress_fc_enable = TB_PATH_SOURCE | TB_PATH_INTERNAL; in tb_pci_init_path()
119 path->egress_shared_buffer = TB_PATH_NONE; in tb_pci_init_path()
120 path->ingress_fc_enable = TB_PATH_ALL; in tb_pci_init_path()
121 path->ingress_shared_buffer = TB_PATH_NONE; in tb_pci_init_path()
122 path->priority = 3; in tb_pci_init_path()
123 path->weight = 1; in tb_pci_init_path()
124 path->drop_packages = 0; in tb_pci_init_path()
125 path->nfc_credits = 0; in tb_pci_init_path()
126 path->hops[0].initial_credits = 7; in tb_pci_init_path()
127 if (path->path_length > 1) in tb_pci_init_path()
128 path->hops[1].initial_credits = in tb_pci_init_path()
129 tb_initial_credits(path->hops[1].in_port->sw); in tb_pci_init_path()
133 * tb_tunnel_discover_pci() - Discover existing PCIe tunnels
137 * If @down adapter is active, follows the tunnel to the PCIe upstream
138 * adapter and back. Returns the discovered tunnel or %NULL if there was
146 if (!tb_pci_port_is_enabled(down)) in tb_tunnel_discover_pci()
150 if (!tunnel) in tb_tunnel_discover_pci()
153 tunnel->activate = tb_pci_activate; in tb_tunnel_discover_pci()
154 tunnel->src_port = down; in tb_tunnel_discover_pci()
157 * Discover both paths even if they are not complete. We will in tb_tunnel_discover_pci()
161 path = tb_path_discover(down, TB_PCI_HOPID, NULL, -1, in tb_tunnel_discover_pci()
162 &tunnel->dst_port, "PCIe Up"); in tb_tunnel_discover_pci()
163 if (!path) { in tb_tunnel_discover_pci()
168 tunnel->paths[TB_PCI_PATH_UP] = path; in tb_tunnel_discover_pci()
169 tb_pci_init_path(tunnel->paths[TB_PCI_PATH_UP]); in tb_tunnel_discover_pci()
171 path = tb_path_discover(tunnel->dst_port, -1, down, TB_PCI_HOPID, NULL, in tb_tunnel_discover_pci()
173 if (!path) in tb_tunnel_discover_pci()
175 tunnel->paths[TB_PCI_PATH_DOWN] = path; in tb_tunnel_discover_pci()
176 tb_pci_init_path(tunnel->paths[TB_PCI_PATH_DOWN]); in tb_tunnel_discover_pci()
179 if (!tb_port_is_pcie_up(tunnel->dst_port)) { in tb_tunnel_discover_pci()
180 tb_port_warn(tunnel->dst_port, in tb_tunnel_discover_pci()
185 if (down != tunnel->src_port) { in tb_tunnel_discover_pci()
190 if (!tb_pci_port_is_enabled(tunnel->dst_port)) { in tb_tunnel_discover_pci()
208 * tb_tunnel_alloc_pci() - allocate a pci tunnel
225 if (!tunnel) in tb_tunnel_alloc_pci()
228 tunnel->activate = tb_pci_activate; in tb_tunnel_alloc_pci()
229 tunnel->src_port = down; in tb_tunnel_alloc_pci()
230 tunnel->dst_port = up; in tb_tunnel_alloc_pci()
234 if (!path) { in tb_tunnel_alloc_pci()
239 tunnel->paths[TB_PCI_PATH_DOWN] = path; in tb_tunnel_alloc_pci()
243 if (!path) { in tb_tunnel_alloc_pci()
248 tunnel->paths[TB_PCI_PATH_UP] = path; in tb_tunnel_alloc_pci()
266 if (!tb_dp_is_usb4(in->sw) || !tb_dp_is_usb4(out->sw)) in tb_dp_cm_handshake()
270 out->cap_adap + DP_STATUS_CTRL, 1); in tb_dp_cm_handshake()
271 if (ret) in tb_dp_cm_handshake()
277 out->cap_adap + DP_STATUS_CTRL, 1); in tb_dp_cm_handshake()
278 if (ret) in tb_dp_cm_handshake()
283 out->cap_adap + DP_STATUS_CTRL, 1); in tb_dp_cm_handshake()
284 if (ret) in tb_dp_cm_handshake()
286 if (!(val & DP_STATUS_CTRL_CMHS)) in tb_dp_cm_handshake()
289 } while (timeout--); in tb_dp_cm_handshake()
291 return -ETIMEDOUT; in tb_dp_cm_handshake()
405 if (dp_bw[i][0] > out_rate || dp_bw[i][1] > out_lanes) in tb_dp_reduce_bandwidth()
408 if (dp_bw[i][0] > in_rate || dp_bw[i][1] > in_lanes) in tb_dp_reduce_bandwidth()
411 if (tb_dp_bandwidth(dp_bw[i][0], dp_bw[i][1]) <= max_bw) { in tb_dp_reduce_bandwidth()
418 return -ENOSR; in tb_dp_reduce_bandwidth()
424 struct tb_port *out = tunnel->dst_port; in tb_dp_xchg_caps()
425 struct tb_port *in = tunnel->src_port; in tb_dp_xchg_caps()
432 if (in->sw->generation < 2 || out->sw->generation < 2) in tb_dp_xchg_caps()
440 if (ret) in tb_dp_xchg_caps()
445 in->cap_adap + DP_LOCAL_CAP, 1); in tb_dp_xchg_caps()
446 if (ret) in tb_dp_xchg_caps()
450 out->cap_adap + DP_LOCAL_CAP, 1); in tb_dp_xchg_caps()
451 if (ret) in tb_dp_xchg_caps()
456 out->cap_adap + DP_REMOTE_CAP, 1); in tb_dp_xchg_caps()
457 if (ret) in tb_dp_xchg_caps()
466 * If the tunnel bandwidth is limited (max_bw is set) then see in tb_dp_xchg_caps()
467 * if we need to reduce bandwidth to fit there. in tb_dp_xchg_caps()
475 if (in->sw->config.depth < out->sw->config.depth) in tb_dp_xchg_caps()
476 max_bw = tunnel->max_down; in tb_dp_xchg_caps()
478 max_bw = tunnel->max_up; in tb_dp_xchg_caps()
480 if (max_bw && bw > max_bw) { in tb_dp_xchg_caps()
486 if (ret) { in tb_dp_xchg_caps()
504 in->cap_adap + DP_REMOTE_CAP, 1); in tb_dp_xchg_caps()
511 if (active) { in tb_dp_activate()
515 paths = tunnel->paths; in tb_dp_activate()
516 last = paths[TB_DP_VIDEO_PATH_OUT]->path_length - 1; in tb_dp_activate()
518 tb_dp_port_set_hops(tunnel->src_port, in tb_dp_activate()
519 paths[TB_DP_VIDEO_PATH_OUT]->hops[0].in_hop_index, in tb_dp_activate()
520 paths[TB_DP_AUX_PATH_OUT]->hops[0].in_hop_index, in tb_dp_activate()
521 paths[TB_DP_AUX_PATH_IN]->hops[last].next_hop_index); in tb_dp_activate()
523 tb_dp_port_set_hops(tunnel->dst_port, in tb_dp_activate()
524 paths[TB_DP_VIDEO_PATH_OUT]->hops[last].next_hop_index, in tb_dp_activate()
525 paths[TB_DP_AUX_PATH_IN]->hops[0].in_hop_index, in tb_dp_activate()
526 paths[TB_DP_AUX_PATH_OUT]->hops[last].next_hop_index); in tb_dp_activate()
528 tb_dp_port_hpd_clear(tunnel->src_port); in tb_dp_activate()
529 tb_dp_port_set_hops(tunnel->src_port, 0, 0, 0); in tb_dp_activate()
530 if (tb_port_is_dpout(tunnel->dst_port)) in tb_dp_activate()
531 tb_dp_port_set_hops(tunnel->dst_port, 0, 0, 0); in tb_dp_activate()
534 ret = tb_dp_port_enable(tunnel->src_port, active); in tb_dp_activate()
535 if (ret) in tb_dp_activate()
538 if (tb_port_is_dpout(tunnel->dst_port)) in tb_dp_activate()
539 return tb_dp_port_enable(tunnel->dst_port, active); in tb_dp_activate()
547 struct tb_port *in = tunnel->src_port; in tb_dp_consumed_bandwidth()
548 const struct tb_switch *sw = in->sw; in tb_dp_consumed_bandwidth()
552 if (tb_dp_is_usb4(sw)) { in tb_dp_consumed_bandwidth()
561 in->cap_adap + DP_COMMON_CAP, 1); in tb_dp_consumed_bandwidth()
562 if (ret) in tb_dp_consumed_bandwidth()
565 if (val & DP_COMMON_CAP_DPRX_DONE) { in tb_dp_consumed_bandwidth()
571 } while (timeout--); in tb_dp_consumed_bandwidth()
573 if (!timeout) in tb_dp_consumed_bandwidth()
574 return -ETIMEDOUT; in tb_dp_consumed_bandwidth()
575 } else if (sw->generation >= 2) { in tb_dp_consumed_bandwidth()
578 * account if capabilities were reduced during exchange. in tb_dp_consumed_bandwidth()
581 in->cap_adap + DP_REMOTE_CAP, 1); in tb_dp_consumed_bandwidth()
582 if (ret) in tb_dp_consumed_bandwidth()
594 if (in->sw->config.depth < tunnel->dst_port->sw->config.depth) { in tb_dp_consumed_bandwidth()
609 path->egress_fc_enable = TB_PATH_SOURCE | TB_PATH_INTERNAL; in tb_dp_init_aux_path()
610 path->egress_shared_buffer = TB_PATH_NONE; in tb_dp_init_aux_path()
611 path->ingress_fc_enable = TB_PATH_ALL; in tb_dp_init_aux_path()
612 path->ingress_shared_buffer = TB_PATH_NONE; in tb_dp_init_aux_path()
613 path->priority = 2; in tb_dp_init_aux_path()
614 path->weight = 1; in tb_dp_init_aux_path()
616 for (i = 0; i < path->path_length; i++) in tb_dp_init_aux_path()
617 path->hops[i].initial_credits = 1; in tb_dp_init_aux_path()
622 u32 nfc_credits = path->hops[0].in_port->config.nfc_credits; in tb_dp_init_video_path()
624 path->egress_fc_enable = TB_PATH_NONE; in tb_dp_init_video_path()
625 path->egress_shared_buffer = TB_PATH_NONE; in tb_dp_init_video_path()
626 path->ingress_fc_enable = TB_PATH_NONE; in tb_dp_init_video_path()
627 path->ingress_shared_buffer = TB_PATH_NONE; in tb_dp_init_video_path()
628 path->priority = 1; in tb_dp_init_video_path()
629 path->weight = 1; in tb_dp_init_video_path()
631 if (discover) { in tb_dp_init_video_path()
632 path->nfc_credits = nfc_credits & ADP_CS_4_NFC_BUFFERS_MASK; in tb_dp_init_video_path()
639 path->nfc_credits = min(max_credits - 2, 12U); in tb_dp_init_video_path()
644 * tb_tunnel_discover_dp() - Discover existing Display Port tunnels
648 * If @in adapter is active, follows the tunnel to the DP out adapter
649 * and back. Returns the discovered tunnel or %NULL if there was no
652 * Return: DP tunnel or %NULL if no tunnel found.
660 if (!tb_dp_port_is_enabled(in)) in tb_tunnel_discover_dp()
664 if (!tunnel) in tb_tunnel_discover_dp()
667 tunnel->init = tb_dp_xchg_caps; in tb_tunnel_discover_dp()
668 tunnel->activate = tb_dp_activate; in tb_tunnel_discover_dp()
669 tunnel->consumed_bandwidth = tb_dp_consumed_bandwidth; in tb_tunnel_discover_dp()
670 tunnel->src_port = in; in tb_tunnel_discover_dp()
672 path = tb_path_discover(in, TB_DP_VIDEO_HOPID, NULL, -1, in tb_tunnel_discover_dp()
673 &tunnel->dst_port, "Video"); in tb_tunnel_discover_dp()
674 if (!path) { in tb_tunnel_discover_dp()
679 tunnel->paths[TB_DP_VIDEO_PATH_OUT] = path; in tb_tunnel_discover_dp()
680 tb_dp_init_video_path(tunnel->paths[TB_DP_VIDEO_PATH_OUT], true); in tb_tunnel_discover_dp()
682 path = tb_path_discover(in, TB_DP_AUX_TX_HOPID, NULL, -1, NULL, "AUX TX"); in tb_tunnel_discover_dp()
683 if (!path) in tb_tunnel_discover_dp()
685 tunnel->paths[TB_DP_AUX_PATH_OUT] = path; in tb_tunnel_discover_dp()
686 tb_dp_init_aux_path(tunnel->paths[TB_DP_AUX_PATH_OUT]); in tb_tunnel_discover_dp()
688 path = tb_path_discover(tunnel->dst_port, -1, in, TB_DP_AUX_RX_HOPID, in tb_tunnel_discover_dp()
690 if (!path) in tb_tunnel_discover_dp()
692 tunnel->paths[TB_DP_AUX_PATH_IN] = path; in tb_tunnel_discover_dp()
693 tb_dp_init_aux_path(tunnel->paths[TB_DP_AUX_PATH_IN]); in tb_tunnel_discover_dp()
696 if (!tb_port_is_dpout(tunnel->dst_port)) { in tb_tunnel_discover_dp()
701 if (!tb_dp_port_is_enabled(tunnel->dst_port)) in tb_tunnel_discover_dp()
704 if (!tb_dp_port_hpd_is_active(tunnel->dst_port)) in tb_tunnel_discover_dp()
707 if (port != tunnel->src_port) { in tb_tunnel_discover_dp()
724 * tb_tunnel_alloc_dp() - allocate a Display Port tunnel
729 * if not limited)
731 * (%0 if not limited)
746 if (WARN_ON(!in->cap_adap || !out->cap_adap)) in tb_tunnel_alloc_dp()
750 if (!tunnel) in tb_tunnel_alloc_dp()
753 tunnel->init = tb_dp_xchg_caps; in tb_tunnel_alloc_dp()
754 tunnel->activate = tb_dp_activate; in tb_tunnel_alloc_dp()
755 tunnel->consumed_bandwidth = tb_dp_consumed_bandwidth; in tb_tunnel_alloc_dp()
756 tunnel->src_port = in; in tb_tunnel_alloc_dp()
757 tunnel->dst_port = out; in tb_tunnel_alloc_dp()
758 tunnel->max_up = max_up; in tb_tunnel_alloc_dp()
759 tunnel->max_down = max_down; in tb_tunnel_alloc_dp()
761 paths = tunnel->paths; in tb_tunnel_alloc_dp()
765 if (!path) in tb_tunnel_alloc_dp()
772 if (!path) in tb_tunnel_alloc_dp()
779 if (!path) in tb_tunnel_alloc_dp()
795 max_credits = (nhi->config.nfc_credits & ADP_CS_4_TOTAL_BUFFERS_MASK) >> in tb_dma_credits()
802 struct tb_port *nhi = tunnel->src_port; in tb_dma_activate()
814 path->egress_fc_enable = efc; in tb_dma_init_path()
815 path->ingress_fc_enable = TB_PATH_ALL; in tb_dma_init_path()
816 path->egress_shared_buffer = TB_PATH_NONE; in tb_dma_init_path()
817 path->ingress_shared_buffer = isb; in tb_dma_init_path()
818 path->priority = 5; in tb_dma_init_path()
819 path->weight = 1; in tb_dma_init_path()
820 path->clear_fc = true; in tb_dma_init_path()
822 for (i = 0; i < path->path_length; i++) in tb_dma_init_path()
823 path->hops[i].initial_credits = credits; in tb_dma_init_path()
827 * tb_tunnel_alloc_dma() - allocate a DMA tunnel
850 if (!tunnel) in tb_tunnel_alloc_dma()
853 tunnel->activate = tb_dma_activate; in tb_tunnel_alloc_dma()
854 tunnel->src_port = nhi; in tb_tunnel_alloc_dma()
855 tunnel->dst_port = dst; in tb_tunnel_alloc_dma()
860 if (!path) { in tb_tunnel_alloc_dma()
866 tunnel->paths[TB_DMA_PATH_IN] = path; in tb_tunnel_alloc_dma()
869 if (!path) { in tb_tunnel_alloc_dma()
874 tunnel->paths[TB_DMA_PATH_OUT] = path; in tb_tunnel_alloc_dma()
884 if (ret < 0) in tb_usb3_max_link_rate()
889 if (ret < 0) in tb_usb3_max_link_rate()
899 tunnel->allocated_up, tunnel->allocated_down); in tb_usb3_init()
901 return usb4_usb3_port_allocate_bandwidth(tunnel->src_port, in tb_usb3_init()
902 &tunnel->allocated_up, in tb_usb3_init()
903 &tunnel->allocated_down); in tb_usb3_init()
910 res = tb_usb3_port_enable(tunnel->src_port, activate); in tb_usb3_activate()
911 if (res) in tb_usb3_activate()
914 if (tb_port_is_usb3_up(tunnel->dst_port)) in tb_usb3_activate()
915 return tb_usb3_port_enable(tunnel->dst_port, activate); in tb_usb3_activate()
924 * PCIe tunneling affects the USB3 bandwidth so take that it in tb_usb3_consumed_bandwidth()
927 *consumed_up = tunnel->allocated_up * (3 + 1) / 3; in tb_usb3_consumed_bandwidth()
928 *consumed_down = tunnel->allocated_down * (3 + 1) / 3; in tb_usb3_consumed_bandwidth()
936 ret = usb4_usb3_port_release_bandwidth(tunnel->src_port, in tb_usb3_release_unused_bandwidth()
937 &tunnel->allocated_up, in tb_usb3_release_unused_bandwidth()
938 &tunnel->allocated_down); in tb_usb3_release_unused_bandwidth()
939 if (ret) in tb_usb3_release_unused_bandwidth()
943 tunnel->allocated_up, tunnel->allocated_down); in tb_usb3_release_unused_bandwidth()
953 ret = usb4_usb3_port_actual_link_rate(tunnel->src_port); in tb_usb3_reclaim_available_bandwidth()
954 if (ret < 0) { in tb_usb3_reclaim_available_bandwidth()
957 } else if (!ret) { in tb_usb3_reclaim_available_bandwidth()
958 /* Use maximum link rate if the link valid is not set */ in tb_usb3_reclaim_available_bandwidth()
959 ret = usb4_usb3_port_max_link_rate(tunnel->src_port); in tb_usb3_reclaim_available_bandwidth()
960 if (ret < 0) { in tb_usb3_reclaim_available_bandwidth()
972 /* No need to reclaim if already at maximum */ in tb_usb3_reclaim_available_bandwidth()
973 if (tunnel->allocated_up >= max_rate && in tb_usb3_reclaim_available_bandwidth()
974 tunnel->allocated_down >= max_rate) in tb_usb3_reclaim_available_bandwidth()
979 if (allocate_up < tunnel->allocated_up) in tb_usb3_reclaim_available_bandwidth()
980 allocate_up = tunnel->allocated_up; in tb_usb3_reclaim_available_bandwidth()
983 if (allocate_down < tunnel->allocated_down) in tb_usb3_reclaim_available_bandwidth()
984 allocate_down = tunnel->allocated_down; in tb_usb3_reclaim_available_bandwidth()
986 /* If no changes no need to do more */ in tb_usb3_reclaim_available_bandwidth()
987 if (allocate_up == tunnel->allocated_up && in tb_usb3_reclaim_available_bandwidth()
988 allocate_down == tunnel->allocated_down) in tb_usb3_reclaim_available_bandwidth()
991 ret = usb4_usb3_port_allocate_bandwidth(tunnel->src_port, &allocate_up, in tb_usb3_reclaim_available_bandwidth()
993 if (ret) { in tb_usb3_reclaim_available_bandwidth()
998 tunnel->allocated_up = allocate_up; in tb_usb3_reclaim_available_bandwidth()
999 *available_up -= tunnel->allocated_up; in tb_usb3_reclaim_available_bandwidth()
1001 tunnel->allocated_down = allocate_down; in tb_usb3_reclaim_available_bandwidth()
1002 *available_down -= tunnel->allocated_down; in tb_usb3_reclaim_available_bandwidth()
1005 tunnel->allocated_up, tunnel->allocated_down); in tb_usb3_reclaim_available_bandwidth()
1010 path->egress_fc_enable = TB_PATH_SOURCE | TB_PATH_INTERNAL; in tb_usb3_init_path()
1011 path->egress_shared_buffer = TB_PATH_NONE; in tb_usb3_init_path()
1012 path->ingress_fc_enable = TB_PATH_ALL; in tb_usb3_init_path()
1013 path->ingress_shared_buffer = TB_PATH_NONE; in tb_usb3_init_path()
1014 path->priority = 3; in tb_usb3_init_path()
1015 path->weight = 3; in tb_usb3_init_path()
1016 path->drop_packages = 0; in tb_usb3_init_path()
1017 path->nfc_credits = 0; in tb_usb3_init_path()
1018 path->hops[0].initial_credits = 7; in tb_usb3_init_path()
1019 if (path->path_length > 1) in tb_usb3_init_path()
1020 path->hops[1].initial_credits = in tb_usb3_init_path()
1021 tb_initial_credits(path->hops[1].in_port->sw); in tb_usb3_init_path()
1025 * tb_tunnel_discover_usb3() - Discover existing USB3 tunnels
1027 * @down: USB3 downstream adapter
1029 * If @down adapter is active, follows the tunnel to the USB3 upstream
1030 * adapter and back. Returns the discovered tunnel or %NULL if there was
1038 if (!tb_usb3_port_is_enabled(down)) in tb_tunnel_discover_usb3()
1042 if (!tunnel) in tb_tunnel_discover_usb3()
1045 tunnel->activate = tb_usb3_activate; in tb_tunnel_discover_usb3()
1046 tunnel->src_port = down; in tb_tunnel_discover_usb3()
1049 * Discover both paths even if they are not complete. We will in tb_tunnel_discover_usb3()
1053 path = tb_path_discover(down, TB_USB3_HOPID, NULL, -1, in tb_tunnel_discover_usb3()
1054 &tunnel->dst_port, "USB3 Down"); in tb_tunnel_discover_usb3()
1055 if (!path) { in tb_tunnel_discover_usb3()
1060 tunnel->paths[TB_USB3_PATH_DOWN] = path; in tb_tunnel_discover_usb3()
1061 tb_usb3_init_path(tunnel->paths[TB_USB3_PATH_DOWN]); in tb_tunnel_discover_usb3()
1063 path = tb_path_discover(tunnel->dst_port, -1, down, TB_USB3_HOPID, NULL, in tb_tunnel_discover_usb3()
1064 "USB3 Up"); in tb_tunnel_discover_usb3()
1065 if (!path) in tb_tunnel_discover_usb3()
1067 tunnel->paths[TB_USB3_PATH_UP] = path; in tb_tunnel_discover_usb3()
1068 tb_usb3_init_path(tunnel->paths[TB_USB3_PATH_UP]); in tb_tunnel_discover_usb3()
1071 if (!tb_port_is_usb3_up(tunnel->dst_port)) { in tb_tunnel_discover_usb3()
1072 tb_port_warn(tunnel->dst_port, in tb_tunnel_discover_usb3()
1073 "path does not end on an USB3 adapter, cleaning up\n"); in tb_tunnel_discover_usb3()
1077 if (down != tunnel->src_port) { in tb_tunnel_discover_usb3()
1082 if (!tb_usb3_port_is_enabled(tunnel->dst_port)) { in tb_tunnel_discover_usb3()
1088 if (!tb_route(down->sw)) { in tb_tunnel_discover_usb3()
1096 &tunnel->allocated_up, &tunnel->allocated_down); in tb_tunnel_discover_usb3()
1097 if (ret) in tb_tunnel_discover_usb3()
1101 tunnel->allocated_up, tunnel->allocated_down); in tb_tunnel_discover_usb3()
1103 tunnel->init = tb_usb3_init; in tb_tunnel_discover_usb3()
1104 tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth; in tb_tunnel_discover_usb3()
1105 tunnel->release_unused_bandwidth = in tb_tunnel_discover_usb3()
1107 tunnel->reclaim_available_bandwidth = in tb_tunnel_discover_usb3()
1123 * tb_tunnel_alloc_usb3() - allocate a USB3 tunnel
1125 * @up: USB3 upstream adapter port
1126 * @down: USB3 downstream adapter port
1127 * @max_up: Maximum available upstream bandwidth for the USB3 tunnel (%0
1128 * if not limited).
1129 * @max_down: Maximum available downstream bandwidth for the USB3 tunnel
1130 * (%0 if not limited).
1132 * Allocate an USB3 tunnel. The ports must be of type @TB_TYPE_USB3_UP and
1147 * USB3 tunnel. in tb_tunnel_alloc_usb3()
1149 if (max_up > 0 || max_down > 0) { in tb_tunnel_alloc_usb3()
1151 if (max_rate < 0) in tb_tunnel_alloc_usb3()
1154 /* Only 90% can be allocated for USB3 isochronous transfers */ in tb_tunnel_alloc_usb3()
1156 tb_port_dbg(up, "required bandwidth for USB3 tunnel %d Mb/s\n", in tb_tunnel_alloc_usb3()
1159 if (max_rate > max_up || max_rate > max_down) { in tb_tunnel_alloc_usb3()
1160 tb_port_warn(up, "not enough bandwidth for USB3 tunnel\n"); in tb_tunnel_alloc_usb3()
1166 if (!tunnel) in tb_tunnel_alloc_usb3()
1169 tunnel->activate = tb_usb3_activate; in tb_tunnel_alloc_usb3()
1170 tunnel->src_port = down; in tb_tunnel_alloc_usb3()
1171 tunnel->dst_port = up; in tb_tunnel_alloc_usb3()
1172 tunnel->max_up = max_up; in tb_tunnel_alloc_usb3()
1173 tunnel->max_down = max_down; in tb_tunnel_alloc_usb3()
1176 "USB3 Down"); in tb_tunnel_alloc_usb3()
1177 if (!path) { in tb_tunnel_alloc_usb3()
1182 tunnel->paths[TB_USB3_PATH_DOWN] = path; in tb_tunnel_alloc_usb3()
1185 "USB3 Up"); in tb_tunnel_alloc_usb3()
1186 if (!path) { in tb_tunnel_alloc_usb3()
1191 tunnel->paths[TB_USB3_PATH_UP] = path; in tb_tunnel_alloc_usb3()
1193 if (!tb_route(down->sw)) { in tb_tunnel_alloc_usb3()
1194 tunnel->allocated_up = max_rate; in tb_tunnel_alloc_usb3()
1195 tunnel->allocated_down = max_rate; in tb_tunnel_alloc_usb3()
1197 tunnel->init = tb_usb3_init; in tb_tunnel_alloc_usb3()
1198 tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth; in tb_tunnel_alloc_usb3()
1199 tunnel->release_unused_bandwidth = in tb_tunnel_alloc_usb3()
1201 tunnel->reclaim_available_bandwidth = in tb_tunnel_alloc_usb3()
1209 * tb_tunnel_free() - free a tunnel
1218 if (!tunnel) in tb_tunnel_free()
1221 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_free()
1222 if (tunnel->paths[i]) in tb_tunnel_free()
1223 tb_path_free(tunnel->paths[i]); in tb_tunnel_free()
1226 kfree(tunnel->paths); in tb_tunnel_free()
1231 * tb_tunnel_is_invalid - check whether an activated path is still valid
1238 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_is_invalid()
1239 WARN_ON(!tunnel->paths[i]->activated); in tb_tunnel_is_invalid()
1240 if (tb_path_is_invalid(tunnel->paths[i])) in tb_tunnel_is_invalid()
1248 * tb_tunnel_restart() - activate a tunnel after a hardware reset
1251 * Return: 0 on success and negative errno in case if failure
1263 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_restart()
1264 if (tunnel->paths[i]->activated) { in tb_tunnel_restart()
1265 tb_path_deactivate(tunnel->paths[i]); in tb_tunnel_restart()
1266 tunnel->paths[i]->activated = false; in tb_tunnel_restart()
1270 if (tunnel->init) { in tb_tunnel_restart()
1271 res = tunnel->init(tunnel); in tb_tunnel_restart()
1272 if (res) in tb_tunnel_restart()
1276 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_restart()
1277 res = tb_path_activate(tunnel->paths[i]); in tb_tunnel_restart()
1278 if (res) in tb_tunnel_restart()
1282 if (tunnel->activate) { in tb_tunnel_restart()
1283 res = tunnel->activate(tunnel, true); in tb_tunnel_restart()
1284 if (res) in tb_tunnel_restart()
1297 * tb_tunnel_activate() - activate a tunnel
1306 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_activate()
1307 if (tunnel->paths[i]->activated) { in tb_tunnel_activate()
1310 return -EINVAL; in tb_tunnel_activate()
1318 * tb_tunnel_deactivate() - deactivate a tunnel
1327 if (tunnel->activate) in tb_tunnel_deactivate()
1328 tunnel->activate(tunnel, false); in tb_tunnel_deactivate()
1330 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_deactivate()
1331 if (tunnel->paths[i] && tunnel->paths[i]->activated) in tb_tunnel_deactivate()
1332 tb_path_deactivate(tunnel->paths[i]); in tb_tunnel_deactivate()
1337 * tb_tunnel_port_on_path() - Does the tunnel go through port
1341 * Returns true if @tunnel goes through @port (direction does not matter),
1349 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_port_on_path()
1350 if (!tunnel->paths[i]) in tb_tunnel_port_on_path()
1353 if (tb_path_port_on_path(tunnel->paths[i], port)) in tb_tunnel_port_on_path()
1364 for (i = 0; i < tunnel->npaths; i++) { in tb_tunnel_is_active()
1365 if (!tunnel->paths[i]) in tb_tunnel_is_active()
1367 if (!tunnel->paths[i]->activated) in tb_tunnel_is_active()
1375 * tb_tunnel_consumed_bandwidth() - Return bandwidth consumed by the tunnel
1391 if (!tb_tunnel_is_active(tunnel)) in tb_tunnel_consumed_bandwidth()
1394 if (tunnel->consumed_bandwidth) { in tb_tunnel_consumed_bandwidth()
1397 ret = tunnel->consumed_bandwidth(tunnel, &up_bw, &down_bw); in tb_tunnel_consumed_bandwidth()
1398 if (ret) in tb_tunnel_consumed_bandwidth()
1406 if (consumed_up) in tb_tunnel_consumed_bandwidth()
1408 if (consumed_down) in tb_tunnel_consumed_bandwidth()
1415 * tb_tunnel_release_unused_bandwidth() - Release unused bandwidth
1418 * If tunnel supports dynamic bandwidth management (USB3 tunnels at the
1425 if (!tb_tunnel_is_active(tunnel)) in tb_tunnel_release_unused_bandwidth()
1428 if (tunnel->release_unused_bandwidth) { in tb_tunnel_release_unused_bandwidth()
1431 ret = tunnel->release_unused_bandwidth(tunnel); in tb_tunnel_release_unused_bandwidth()
1432 if (ret) in tb_tunnel_release_unused_bandwidth()
1440 * tb_tunnel_reclaim_available_bandwidth() - Reclaim available bandwidth
1447 * reclaimed by the tunnel). If nothing was reclaimed the values are
1454 if (!tb_tunnel_is_active(tunnel)) in tb_tunnel_reclaim_available_bandwidth()
1457 if (tunnel->reclaim_available_bandwidth) in tb_tunnel_reclaim_available_bandwidth()
1458 tunnel->reclaim_available_bandwidth(tunnel, available_up, in tb_tunnel_reclaim_available_bandwidth()