Lines Matching +full:use +full:- +full:sw +full:- +full:pm
1 // SPDX-License-Identifier: GPL-2.0
3 * Thunderbolt driver - path/tunnel functionality
18 const struct tb_port *port = hop->in_port; in tb_dump_hop()
21 hop->in_hop_index, regs->out_port, regs->next_hop); in tb_dump_hop()
22 tb_port_dbg(port, " Weight: %d Priority: %d Credits: %d Drop: %d PM: %d\n", in tb_dump_hop()
23 regs->weight, regs->priority, regs->initial_credits, in tb_dump_hop()
24 regs->drop_packages, regs->pmps); in tb_dump_hop()
26 regs->counter_enable, regs->counter); in tb_dump_hop()
28 regs->ingress_fc, regs->egress_fc, in tb_dump_hop()
29 regs->ingress_shared_buffer, regs->egress_shared_buffer); in tb_dump_hop()
31 regs->unknown1, regs->unknown2, regs->unknown3); in tb_dump_hop()
39 struct tb_switch *sw; in tb_path_find_dst_port() local
46 sw = port->sw; in tb_path_find_dst_port()
57 out_port = &sw->ports[hop.out_port]; in tb_path_find_dst_port()
59 port = out_port->remote; in tb_path_find_dst_port()
71 for (i = TB_PATH_MIN_HOPID; i <= src->config.max_in_hop_id; i++) { in tb_path_find_src_hopid()
81 * tb_path_discover() - Discover a path
83 * @src_hopid: Starting HopID of a path (%-1 if don't care)
85 * @dst_hopid: HopID to the @dst (%-1 if don't care)
109 struct tb_switch *sw; in tb_path_discover() local
132 sw = p->sw; in tb_path_discover()
144 out_port = &sw->ports[hop.out_port]; in tb_path_discover()
149 p = out_port->remote; in tb_path_discover()
157 path->name = name; in tb_path_discover()
158 path->tb = src->sw->tb; in tb_path_discover()
159 path->path_length = num_hops; in tb_path_discover()
160 path->activated = true; in tb_path_discover()
161 path->alloc_hopid = alloc_hopid; in tb_path_discover()
163 path->hops = kcalloc(num_hops, sizeof(*path->hops), GFP_KERNEL); in tb_path_discover()
164 if (!path->hops) { in tb_path_discover()
169 tb_dbg(path->tb, "discovering %s path starting from %llx:%u\n", in tb_path_discover()
170 path->name, tb_route(src->sw), src->port); in tb_path_discover()
178 sw = p->sw; in tb_path_discover()
189 out_port = &sw->ports[hop.out_port]; in tb_path_discover()
198 path->hops[i].in_port = p; in tb_path_discover()
199 path->hops[i].in_hop_index = h; in tb_path_discover()
200 path->hops[i].in_counter_index = -1; in tb_path_discover()
201 path->hops[i].out_port = out_port; in tb_path_discover()
202 path->hops[i].next_hop_index = next_hop; in tb_path_discover()
204 tb_dump_hop(&path->hops[i], &hop); in tb_path_discover()
207 p = out_port->remote; in tb_path_discover()
210 tb_dbg(path->tb, "path discovery complete\n"); in tb_path_discover()
221 * tb_path_alloc() - allocate a thunderbolt path between two ports
270 path->hops = kcalloc(num_hops, sizeof(*path->hops), GFP_KERNEL); in tb_path_alloc()
271 if (!path->hops) { in tb_path_alloc()
276 path->alloc_hopid = true; in tb_path_alloc()
287 if (!in_port->bonded && in_port->dual_link_port && in tb_path_alloc()
288 in_port->link_nr != link_nr) in tb_path_alloc()
289 in_port = in_port->dual_link_port; in tb_path_alloc()
301 * Pick up right port when going from non-bonded to in tb_path_alloc()
302 * bonded or from bonded to non-bonded. in tb_path_alloc()
304 if (out_port->dual_link_port) { in tb_path_alloc()
305 if (!in_port->bonded && out_port->bonded && in tb_path_alloc()
306 out_port->link_nr) { in tb_path_alloc()
308 * Use primary link when going from in tb_path_alloc()
309 * non-bonded to bonded. in tb_path_alloc()
311 out_port = out_port->dual_link_port; in tb_path_alloc()
312 } else if (!out_port->bonded && in tb_path_alloc()
313 out_port->link_nr != link_nr) { in tb_path_alloc()
318 out_port = out_port->dual_link_port; in tb_path_alloc()
322 if (i == num_hops - 1) in tb_path_alloc()
326 ret = tb_port_alloc_out_hopid(out_port, -1, -1); in tb_path_alloc()
332 path->hops[i].in_hop_index = in_hopid; in tb_path_alloc()
333 path->hops[i].in_port = in_port; in tb_path_alloc()
334 path->hops[i].in_counter_index = -1; in tb_path_alloc()
335 path->hops[i].out_port = out_port; in tb_path_alloc()
336 path->hops[i].next_hop_index = out_hopid; in tb_path_alloc()
341 path->tb = tb; in tb_path_alloc()
342 path->path_length = num_hops; in tb_path_alloc()
343 path->name = name; in tb_path_alloc()
353 * tb_path_free() - free a path
360 if (path->alloc_hopid) { in tb_path_free()
363 for (i = 0; i < path->path_length; i++) { in tb_path_free()
364 const struct tb_path_hop *hop = &path->hops[i]; in tb_path_free()
366 if (hop->in_port) in tb_path_free()
367 tb_port_release_in_hopid(hop->in_port, in tb_path_free()
368 hop->in_hop_index); in tb_path_free()
369 if (hop->out_port) in tb_path_free()
370 tb_port_release_out_hopid(hop->out_port, in tb_path_free()
371 hop->next_hop_index); in tb_path_free()
375 kfree(path->hops); in tb_path_free()
382 for (i = first_hop; i < path->path_length; i++) { in __tb_path_deallocate_nfc()
383 res = tb_port_add_nfc_credits(path->hops[i].in_port, in __tb_path_deallocate_nfc()
384 -path->hops[i].nfc_credits); in __tb_path_deallocate_nfc()
386 tb_port_warn(path->hops[i].in_port, in __tb_path_deallocate_nfc()
427 * only for pre-USB4 adapters. in __tb_path_deactivate_hop()
429 if (!tb_switch_is_usb4(port->sw)) { in __tb_path_deactivate_hop()
446 return -ETIMEDOUT; in __tb_path_deactivate_hop()
450 * tb_path_deactivate_hop() - Deactivate one path in path config space
466 for (i = first_hop; i < path->path_length; i++) { in __tb_path_deactivate_hops()
467 res = __tb_path_deactivate_hop(path->hops[i].in_port, in __tb_path_deactivate_hops()
468 path->hops[i].in_hop_index, in __tb_path_deactivate_hops()
469 path->clear_fc); in __tb_path_deactivate_hops()
470 if (res && res != -ENODEV) in __tb_path_deactivate_hops()
471 tb_port_warn(path->hops[i].in_port, in __tb_path_deactivate_hops()
473 i, path->hops[i].in_hop_index); in __tb_path_deactivate_hops()
479 if (!path->activated) { in tb_path_deactivate()
480 tb_WARN(path->tb, "trying to deactivate an inactive path\n"); in tb_path_deactivate()
483 tb_dbg(path->tb, in tb_path_deactivate()
485 path->name, tb_route(path->hops[0].in_port->sw), in tb_path_deactivate()
486 path->hops[0].in_port->port, in tb_path_deactivate()
487 tb_route(path->hops[path->path_length - 1].out_port->sw), in tb_path_deactivate()
488 path->hops[path->path_length - 1].out_port->port); in tb_path_deactivate()
491 path->activated = false; in tb_path_deactivate()
495 * tb_path_activate() - activate a path
499 * caller must fill path->hops before calling tb_path_activate().
507 if (path->activated) { in tb_path_activate()
508 tb_WARN(path->tb, "trying to activate already activated path\n"); in tb_path_activate()
509 return -EINVAL; in tb_path_activate()
512 tb_dbg(path->tb, in tb_path_activate()
514 path->name, tb_route(path->hops[0].in_port->sw), in tb_path_activate()
515 path->hops[0].in_port->port, in tb_path_activate()
516 tb_route(path->hops[path->path_length - 1].out_port->sw), in tb_path_activate()
517 path->hops[path->path_length - 1].out_port->port); in tb_path_activate()
520 for (i = path->path_length - 1; i >= 0; i--) { in tb_path_activate()
521 if (path->hops[i].in_counter_index == -1) in tb_path_activate()
523 res = tb_port_clear_counter(path->hops[i].in_port, in tb_path_activate()
524 path->hops[i].in_counter_index); in tb_path_activate()
530 for (i = path->path_length - 1; i >= 0; i--) { in tb_path_activate()
531 res = tb_port_add_nfc_credits(path->hops[i].in_port, in tb_path_activate()
532 path->hops[i].nfc_credits); in tb_path_activate()
540 for (i = path->path_length - 1; i >= 0; i--) { in tb_path_activate()
544 __tb_path_deactivate_hop(path->hops[i].in_port, in tb_path_activate()
545 path->hops[i].in_hop_index, path->clear_fc); in tb_path_activate()
548 hop.next_hop = path->hops[i].next_hop_index; in tb_path_activate()
549 hop.out_port = path->hops[i].out_port->port; in tb_path_activate()
550 hop.initial_credits = path->hops[i].initial_credits; in tb_path_activate()
551 hop.pmps = path->hops[i].pm_support; in tb_path_activate()
556 out_mask = (i == path->path_length - 1) ? in tb_path_activate()
559 hop.weight = path->weight; in tb_path_activate()
561 hop.priority = path->priority; in tb_path_activate()
562 hop.drop_packages = path->drop_packages; in tb_path_activate()
563 hop.counter = path->hops[i].in_counter_index; in tb_path_activate()
564 hop.counter_enable = path->hops[i].in_counter_index != -1; in tb_path_activate()
565 hop.ingress_fc = path->ingress_fc_enable & in_mask; in tb_path_activate()
566 hop.egress_fc = path->egress_fc_enable & out_mask; in tb_path_activate()
567 hop.ingress_shared_buffer = path->ingress_shared_buffer in tb_path_activate()
569 hop.egress_shared_buffer = path->egress_shared_buffer in tb_path_activate()
573 tb_port_dbg(path->hops[i].in_port, "Writing hop %d\n", i); in tb_path_activate()
574 tb_dump_hop(&path->hops[i], &hop); in tb_path_activate()
575 res = tb_port_write(path->hops[i].in_port, &hop, TB_CFG_HOPS, in tb_path_activate()
576 2 * path->hops[i].in_hop_index, 2); in tb_path_activate()
583 path->activated = true; in tb_path_activate()
584 tb_dbg(path->tb, "%s path activation complete\n", path->name); in tb_path_activate()
587 tb_WARN(path->tb, "%s path activation failed\n", path->name); in tb_path_activate()
592 * tb_path_is_invalid() - check whether any ports on the path are invalid
600 for (i = 0; i < path->path_length; i++) { in tb_path_is_invalid()
601 if (path->hops[i].in_port->sw->is_unplugged) in tb_path_is_invalid()
603 if (path->hops[i].out_port->sw->is_unplugged) in tb_path_is_invalid()
610 * tb_path_port_on_path() - Does the path go through certain port
621 for (i = 0; i < path->path_length; i++) { in tb_path_port_on_path()
622 if (path->hops[i].in_port == port || in tb_path_port_on_path()
623 path->hops[i].out_port == port) in tb_path_port_on_path()