brintos

brintos / linux-shallow public Read only

0
0
Text · 87.4 KiB · 9475c66 Raw
2904 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * KUnit tests4 *5 * Copyright (C) 2020, Intel Corporation6 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>7 */8 9#include <kunit/test.h>10#include <linux/idr.h>11 12#include "tb.h"13#include "tunnel.h"14 15static int __ida_init(struct kunit_resource *res, void *context)16{17	struct ida *ida = context;18 19	ida_init(ida);20	res->data = ida;21	return 0;22}23 24static void __ida_destroy(struct kunit_resource *res)25{26	struct ida *ida = res->data;27 28	ida_destroy(ida);29}30 31static void kunit_ida_init(struct kunit *test, struct ida *ida)32{33	kunit_alloc_resource(test, __ida_init, __ida_destroy, GFP_KERNEL, ida);34}35 36static struct tb_switch *alloc_switch(struct kunit *test, u64 route,37				      u8 upstream_port, u8 max_port_number)38{39	struct tb_switch *sw;40	size_t size;41	int i;42 43	sw = kunit_kzalloc(test, sizeof(*sw), GFP_KERNEL);44	if (!sw)45		return NULL;46 47	sw->config.upstream_port_number = upstream_port;48	sw->config.depth = tb_route_length(route);49	sw->config.route_hi = upper_32_bits(route);50	sw->config.route_lo = lower_32_bits(route);51	sw->config.enabled = 0;52	sw->config.max_port_number = max_port_number;53 54	size = (sw->config.max_port_number + 1) * sizeof(*sw->ports);55	sw->ports = kunit_kzalloc(test, size, GFP_KERNEL);56	if (!sw->ports)57		return NULL;58 59	for (i = 0; i <= sw->config.max_port_number; i++) {60		sw->ports[i].sw = sw;61		sw->ports[i].port = i;62		sw->ports[i].config.port_number = i;63		if (i) {64			kunit_ida_init(test, &sw->ports[i].in_hopids);65			kunit_ida_init(test, &sw->ports[i].out_hopids);66		}67	}68 69	return sw;70}71 72static struct tb_switch *alloc_host(struct kunit *test)73{74	struct tb_switch *sw;75 76	sw = alloc_switch(test, 0, 7, 13);77	if (!sw)78		return NULL;79 80	sw->config.vendor_id = 0x8086;81	sw->config.device_id = 0x9a1b;82 83	sw->ports[0].config.type = TB_TYPE_PORT;84	sw->ports[0].config.max_in_hop_id = 7;85	sw->ports[0].config.max_out_hop_id = 7;86 87	sw->ports[1].config.type = TB_TYPE_PORT;88	sw->ports[1].config.max_in_hop_id = 19;89	sw->ports[1].config.max_out_hop_id = 19;90	sw->ports[1].total_credits = 60;91	sw->ports[1].ctl_credits = 2;92	sw->ports[1].dual_link_port = &sw->ports[2];93 94	sw->ports[2].config.type = TB_TYPE_PORT;95	sw->ports[2].config.max_in_hop_id = 19;96	sw->ports[2].config.max_out_hop_id = 19;97	sw->ports[2].total_credits = 60;98	sw->ports[2].ctl_credits = 2;99	sw->ports[2].dual_link_port = &sw->ports[1];100	sw->ports[2].link_nr = 1;101 102	sw->ports[3].config.type = TB_TYPE_PORT;103	sw->ports[3].config.max_in_hop_id = 19;104	sw->ports[3].config.max_out_hop_id = 19;105	sw->ports[3].total_credits = 60;106	sw->ports[3].ctl_credits = 2;107	sw->ports[3].dual_link_port = &sw->ports[4];108 109	sw->ports[4].config.type = TB_TYPE_PORT;110	sw->ports[4].config.max_in_hop_id = 19;111	sw->ports[4].config.max_out_hop_id = 19;112	sw->ports[4].total_credits = 60;113	sw->ports[4].ctl_credits = 2;114	sw->ports[4].dual_link_port = &sw->ports[3];115	sw->ports[4].link_nr = 1;116 117	sw->ports[5].config.type = TB_TYPE_DP_HDMI_IN;118	sw->ports[5].config.max_in_hop_id = 9;119	sw->ports[5].config.max_out_hop_id = 9;120	sw->ports[5].cap_adap = -1;121 122	sw->ports[6].config.type = TB_TYPE_DP_HDMI_IN;123	sw->ports[6].config.max_in_hop_id = 9;124	sw->ports[6].config.max_out_hop_id = 9;125	sw->ports[6].cap_adap = -1;126 127	sw->ports[7].config.type = TB_TYPE_NHI;128	sw->ports[7].config.max_in_hop_id = 11;129	sw->ports[7].config.max_out_hop_id = 11;130	sw->ports[7].config.nfc_credits = 0x41800000;131 132	sw->ports[8].config.type = TB_TYPE_PCIE_DOWN;133	sw->ports[8].config.max_in_hop_id = 8;134	sw->ports[8].config.max_out_hop_id = 8;135 136	sw->ports[9].config.type = TB_TYPE_PCIE_DOWN;137	sw->ports[9].config.max_in_hop_id = 8;138	sw->ports[9].config.max_out_hop_id = 8;139 140	sw->ports[10].disabled = true;141	sw->ports[11].disabled = true;142 143	sw->ports[12].config.type = TB_TYPE_USB3_DOWN;144	sw->ports[12].config.max_in_hop_id = 8;145	sw->ports[12].config.max_out_hop_id = 8;146 147	sw->ports[13].config.type = TB_TYPE_USB3_DOWN;148	sw->ports[13].config.max_in_hop_id = 8;149	sw->ports[13].config.max_out_hop_id = 8;150 151	return sw;152}153 154static struct tb_switch *alloc_host_usb4(struct kunit *test)155{156	struct tb_switch *sw;157 158	sw = alloc_host(test);159	if (!sw)160		return NULL;161 162	sw->generation = 4;163	sw->credit_allocation = true;164	sw->max_usb3_credits = 32;165	sw->min_dp_aux_credits = 1;166	sw->min_dp_main_credits = 0;167	sw->max_pcie_credits = 64;168	sw->max_dma_credits = 14;169 170	return sw;171}172 173static struct tb_switch *alloc_host_br(struct kunit *test)174{175	struct tb_switch *sw;176 177	sw = alloc_host_usb4(test);178	if (!sw)179		return NULL;180 181	sw->ports[10].config.type = TB_TYPE_DP_HDMI_IN;182	sw->ports[10].config.max_in_hop_id = 9;183	sw->ports[10].config.max_out_hop_id = 9;184	sw->ports[10].cap_adap = -1;185	sw->ports[10].disabled = false;186 187	return sw;188}189 190static struct tb_switch *alloc_dev_default(struct kunit *test,191					   struct tb_switch *parent,192					   u64 route, bool bonded)193{194	struct tb_port *port, *upstream_port;195	struct tb_switch *sw;196 197	sw = alloc_switch(test, route, 1, 19);198	if (!sw)199		return NULL;200 201	sw->config.vendor_id = 0x8086;202	sw->config.device_id = 0x15ef;203 204	sw->ports[0].config.type = TB_TYPE_PORT;205	sw->ports[0].config.max_in_hop_id = 8;206	sw->ports[0].config.max_out_hop_id = 8;207 208	sw->ports[1].config.type = TB_TYPE_PORT;209	sw->ports[1].config.max_in_hop_id = 19;210	sw->ports[1].config.max_out_hop_id = 19;211	sw->ports[1].total_credits = 60;212	sw->ports[1].ctl_credits = 2;213	sw->ports[1].dual_link_port = &sw->ports[2];214 215	sw->ports[2].config.type = TB_TYPE_PORT;216	sw->ports[2].config.max_in_hop_id = 19;217	sw->ports[2].config.max_out_hop_id = 19;218	sw->ports[2].total_credits = 60;219	sw->ports[2].ctl_credits = 2;220	sw->ports[2].dual_link_port = &sw->ports[1];221	sw->ports[2].link_nr = 1;222 223	sw->ports[3].config.type = TB_TYPE_PORT;224	sw->ports[3].config.max_in_hop_id = 19;225	sw->ports[3].config.max_out_hop_id = 19;226	sw->ports[3].total_credits = 60;227	sw->ports[3].ctl_credits = 2;228	sw->ports[3].dual_link_port = &sw->ports[4];229 230	sw->ports[4].config.type = TB_TYPE_PORT;231	sw->ports[4].config.max_in_hop_id = 19;232	sw->ports[4].config.max_out_hop_id = 19;233	sw->ports[4].total_credits = 60;234	sw->ports[4].ctl_credits = 2;235	sw->ports[4].dual_link_port = &sw->ports[3];236	sw->ports[4].link_nr = 1;237 238	sw->ports[5].config.type = TB_TYPE_PORT;239	sw->ports[5].config.max_in_hop_id = 19;240	sw->ports[5].config.max_out_hop_id = 19;241	sw->ports[5].total_credits = 60;242	sw->ports[5].ctl_credits = 2;243	sw->ports[5].dual_link_port = &sw->ports[6];244 245	sw->ports[6].config.type = TB_TYPE_PORT;246	sw->ports[6].config.max_in_hop_id = 19;247	sw->ports[6].config.max_out_hop_id = 19;248	sw->ports[6].total_credits = 60;249	sw->ports[6].ctl_credits = 2;250	sw->ports[6].dual_link_port = &sw->ports[5];251	sw->ports[6].link_nr = 1;252 253	sw->ports[7].config.type = TB_TYPE_PORT;254	sw->ports[7].config.max_in_hop_id = 19;255	sw->ports[7].config.max_out_hop_id = 19;256	sw->ports[7].total_credits = 60;257	sw->ports[7].ctl_credits = 2;258	sw->ports[7].dual_link_port = &sw->ports[8];259 260	sw->ports[8].config.type = TB_TYPE_PORT;261	sw->ports[8].config.max_in_hop_id = 19;262	sw->ports[8].config.max_out_hop_id = 19;263	sw->ports[8].total_credits = 60;264	sw->ports[8].ctl_credits = 2;265	sw->ports[8].dual_link_port = &sw->ports[7];266	sw->ports[8].link_nr = 1;267 268	sw->ports[9].config.type = TB_TYPE_PCIE_UP;269	sw->ports[9].config.max_in_hop_id = 8;270	sw->ports[9].config.max_out_hop_id = 8;271 272	sw->ports[10].config.type = TB_TYPE_PCIE_DOWN;273	sw->ports[10].config.max_in_hop_id = 8;274	sw->ports[10].config.max_out_hop_id = 8;275 276	sw->ports[11].config.type = TB_TYPE_PCIE_DOWN;277	sw->ports[11].config.max_in_hop_id = 8;278	sw->ports[11].config.max_out_hop_id = 8;279 280	sw->ports[12].config.type = TB_TYPE_PCIE_DOWN;281	sw->ports[12].config.max_in_hop_id = 8;282	sw->ports[12].config.max_out_hop_id = 8;283 284	sw->ports[13].config.type = TB_TYPE_DP_HDMI_OUT;285	sw->ports[13].config.max_in_hop_id = 9;286	sw->ports[13].config.max_out_hop_id = 9;287	sw->ports[13].cap_adap = -1;288 289	sw->ports[14].config.type = TB_TYPE_DP_HDMI_OUT;290	sw->ports[14].config.max_in_hop_id = 9;291	sw->ports[14].config.max_out_hop_id = 9;292	sw->ports[14].cap_adap = -1;293 294	sw->ports[15].disabled = true;295 296	sw->ports[16].config.type = TB_TYPE_USB3_UP;297	sw->ports[16].config.max_in_hop_id = 8;298	sw->ports[16].config.max_out_hop_id = 8;299 300	sw->ports[17].config.type = TB_TYPE_USB3_DOWN;301	sw->ports[17].config.max_in_hop_id = 8;302	sw->ports[17].config.max_out_hop_id = 8;303 304	sw->ports[18].config.type = TB_TYPE_USB3_DOWN;305	sw->ports[18].config.max_in_hop_id = 8;306	sw->ports[18].config.max_out_hop_id = 8;307 308	sw->ports[19].config.type = TB_TYPE_USB3_DOWN;309	sw->ports[19].config.max_in_hop_id = 8;310	sw->ports[19].config.max_out_hop_id = 8;311 312	if (!parent)313		return sw;314 315	/* Link them */316	upstream_port = tb_upstream_port(sw);317	port = tb_port_at(route, parent);318	port->remote = upstream_port;319	upstream_port->remote = port;320	if (port->dual_link_port && upstream_port->dual_link_port) {321		port->dual_link_port->remote = upstream_port->dual_link_port;322		upstream_port->dual_link_port->remote = port->dual_link_port;323 324		if (bonded) {325			/* Bonding is used */326			port->bonded = true;327			port->total_credits *= 2;328			port->dual_link_port->bonded = true;329			port->dual_link_port->total_credits = 0;330			upstream_port->bonded = true;331			upstream_port->total_credits *= 2;332			upstream_port->dual_link_port->bonded = true;333			upstream_port->dual_link_port->total_credits = 0;334		}335	}336 337	return sw;338}339 340static struct tb_switch *alloc_dev_with_dpin(struct kunit *test,341					     struct tb_switch *parent,342					     u64 route, bool bonded)343{344	struct tb_switch *sw;345 346	sw = alloc_dev_default(test, parent, route, bonded);347	if (!sw)348		return NULL;349 350	sw->ports[13].config.type = TB_TYPE_DP_HDMI_IN;351	sw->ports[13].config.max_in_hop_id = 9;352	sw->ports[13].config.max_out_hop_id = 9;353 354	sw->ports[14].config.type = TB_TYPE_DP_HDMI_IN;355	sw->ports[14].config.max_in_hop_id = 9;356	sw->ports[14].config.max_out_hop_id = 9;357 358	return sw;359}360 361static struct tb_switch *alloc_dev_without_dp(struct kunit *test,362					      struct tb_switch *parent,363					      u64 route, bool bonded)364{365	struct tb_switch *sw;366	int i;367 368	sw = alloc_dev_default(test, parent, route, bonded);369	if (!sw)370		return NULL;371	/*372	 * Device with:373	 * 2x USB4 Adapters (adapters 1,2 and 3,4),374	 * 1x PCIe Upstream (adapter 9),375	 * 1x PCIe Downstream (adapter 10),376	 * 1x USB3 Upstream (adapter 16),377	 * 1x USB3 Downstream (adapter 17)378	 */379	for (i = 5; i <= 8; i++)380		sw->ports[i].disabled = true;381 382	for (i = 11; i <= 14; i++)383		sw->ports[i].disabled = true;384 385	sw->ports[13].cap_adap = 0;386	sw->ports[14].cap_adap = 0;387 388	for (i = 18; i <= 19; i++)389		sw->ports[i].disabled = true;390 391	sw->generation = 4;392	sw->credit_allocation = true;393	sw->max_usb3_credits = 109;394	sw->min_dp_aux_credits = 0;395	sw->min_dp_main_credits = 0;396	sw->max_pcie_credits = 30;397	sw->max_dma_credits = 1;398 399	return sw;400}401 402static struct tb_switch *alloc_dev_usb4(struct kunit *test,403					struct tb_switch *parent,404					u64 route, bool bonded)405{406	struct tb_switch *sw;407 408	sw = alloc_dev_default(test, parent, route, bonded);409	if (!sw)410		return NULL;411 412	sw->generation = 4;413	sw->credit_allocation = true;414	sw->max_usb3_credits = 14;415	sw->min_dp_aux_credits = 1;416	sw->min_dp_main_credits = 18;417	sw->max_pcie_credits = 32;418	sw->max_dma_credits = 14;419 420	return sw;421}422 423static void tb_test_path_basic(struct kunit *test)424{425	struct tb_port *src_port, *dst_port, *p;426	struct tb_switch *host;427 428	host = alloc_host(test);429 430	src_port = &host->ports[5];431	dst_port = src_port;432 433	p = tb_next_port_on_path(src_port, dst_port, NULL);434	KUNIT_EXPECT_PTR_EQ(test, p, dst_port);435 436	p = tb_next_port_on_path(src_port, dst_port, p);437	KUNIT_EXPECT_TRUE(test, !p);438}439 440static void tb_test_path_not_connected_walk(struct kunit *test)441{442	struct tb_port *src_port, *dst_port, *p;443	struct tb_switch *host, *dev;444 445	host = alloc_host(test);446	/* No connection between host and dev */447	dev = alloc_dev_default(test, NULL, 3, true);448 449	src_port = &host->ports[12];450	dst_port = &dev->ports[16];451 452	p = tb_next_port_on_path(src_port, dst_port, NULL);453	KUNIT_EXPECT_PTR_EQ(test, p, src_port);454 455	p = tb_next_port_on_path(src_port, dst_port, p);456	KUNIT_EXPECT_PTR_EQ(test, p, &host->ports[3]);457 458	p = tb_next_port_on_path(src_port, dst_port, p);459	KUNIT_EXPECT_TRUE(test, !p);460 461	/* Other direction */462 463	p = tb_next_port_on_path(dst_port, src_port, NULL);464	KUNIT_EXPECT_PTR_EQ(test, p, dst_port);465 466	p = tb_next_port_on_path(dst_port, src_port, p);467	KUNIT_EXPECT_PTR_EQ(test, p, &dev->ports[1]);468 469	p = tb_next_port_on_path(dst_port, src_port, p);470	KUNIT_EXPECT_TRUE(test, !p);471}472 473struct port_expectation {474	u64 route;475	u8 port;476	enum tb_port_type type;477};478 479static void tb_test_path_single_hop_walk(struct kunit *test)480{481	/*482	 * Walks from Host PCIe downstream port to Device #1 PCIe483	 * upstream port.484	 *485	 *   [Host]486	 *   1 |487	 *   1 |488	 *  [Device]489	 */490	static const struct port_expectation test_data[] = {491		{ .route = 0x0, .port = 8, .type = TB_TYPE_PCIE_DOWN },492		{ .route = 0x0, .port = 1, .type = TB_TYPE_PORT },493		{ .route = 0x1, .port = 1, .type = TB_TYPE_PORT },494		{ .route = 0x1, .port = 9, .type = TB_TYPE_PCIE_UP },495	};496	struct tb_port *src_port, *dst_port, *p;497	struct tb_switch *host, *dev;498	int i;499 500	host = alloc_host(test);501	dev = alloc_dev_default(test, host, 1, true);502 503	src_port = &host->ports[8];504	dst_port = &dev->ports[9];505 506	/* Walk both directions */507 508	i = 0;509	tb_for_each_port_on_path(src_port, dst_port, p) {510		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));511		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);512		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);513		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,514				test_data[i].type);515		i++;516	}517 518	KUNIT_EXPECT_EQ(test, i, ARRAY_SIZE(test_data));519 520	i = ARRAY_SIZE(test_data) - 1;521	tb_for_each_port_on_path(dst_port, src_port, p) {522		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));523		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);524		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);525		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,526				test_data[i].type);527		i--;528	}529 530	KUNIT_EXPECT_EQ(test, i, -1);531}532 533static void tb_test_path_daisy_chain_walk(struct kunit *test)534{535	/*536	 * Walks from Host DP IN to Device #2 DP OUT.537	 *538	 *           [Host]539	 *            1 |540	 *            1 |541	 *         [Device #1]542	 *       3 /543	 *      1 /544	 * [Device #2]545	 */546	static const struct port_expectation test_data[] = {547		{ .route = 0x0, .port = 5, .type = TB_TYPE_DP_HDMI_IN },548		{ .route = 0x0, .port = 1, .type = TB_TYPE_PORT },549		{ .route = 0x1, .port = 1, .type = TB_TYPE_PORT },550		{ .route = 0x1, .port = 3, .type = TB_TYPE_PORT },551		{ .route = 0x301, .port = 1, .type = TB_TYPE_PORT },552		{ .route = 0x301, .port = 13, .type = TB_TYPE_DP_HDMI_OUT },553	};554	struct tb_port *src_port, *dst_port, *p;555	struct tb_switch *host, *dev1, *dev2;556	int i;557 558	host = alloc_host(test);559	dev1 = alloc_dev_default(test, host, 0x1, true);560	dev2 = alloc_dev_default(test, dev1, 0x301, true);561 562	src_port = &host->ports[5];563	dst_port = &dev2->ports[13];564 565	/* Walk both directions */566 567	i = 0;568	tb_for_each_port_on_path(src_port, dst_port, p) {569		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));570		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);571		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);572		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,573				test_data[i].type);574		i++;575	}576 577	KUNIT_EXPECT_EQ(test, i, ARRAY_SIZE(test_data));578 579	i = ARRAY_SIZE(test_data) - 1;580	tb_for_each_port_on_path(dst_port, src_port, p) {581		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));582		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);583		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);584		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,585				test_data[i].type);586		i--;587	}588 589	KUNIT_EXPECT_EQ(test, i, -1);590}591 592static void tb_test_path_simple_tree_walk(struct kunit *test)593{594	/*595	 * Walks from Host DP IN to Device #3 DP OUT.596	 *597	 *           [Host]598	 *            1 |599	 *            1 |600	 *         [Device #1]601	 *       3 /   | 5  \ 7602	 *      1 /    |     \ 1603	 * [Device #2] |    [Device #4]604	 *             | 1605	 *         [Device #3]606	 */607	static const struct port_expectation test_data[] = {608		{ .route = 0x0, .port = 5, .type = TB_TYPE_DP_HDMI_IN },609		{ .route = 0x0, .port = 1, .type = TB_TYPE_PORT },610		{ .route = 0x1, .port = 1, .type = TB_TYPE_PORT },611		{ .route = 0x1, .port = 5, .type = TB_TYPE_PORT },612		{ .route = 0x501, .port = 1, .type = TB_TYPE_PORT },613		{ .route = 0x501, .port = 13, .type = TB_TYPE_DP_HDMI_OUT },614	};615	struct tb_port *src_port, *dst_port, *p;616	struct tb_switch *host, *dev1, *dev3;617	int i;618 619	host = alloc_host(test);620	dev1 = alloc_dev_default(test, host, 0x1, true);621	alloc_dev_default(test, dev1, 0x301, true);622	dev3 = alloc_dev_default(test, dev1, 0x501, true);623	alloc_dev_default(test, dev1, 0x701, true);624 625	src_port = &host->ports[5];626	dst_port = &dev3->ports[13];627 628	/* Walk both directions */629 630	i = 0;631	tb_for_each_port_on_path(src_port, dst_port, p) {632		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));633		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);634		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);635		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,636				test_data[i].type);637		i++;638	}639 640	KUNIT_EXPECT_EQ(test, i, ARRAY_SIZE(test_data));641 642	i = ARRAY_SIZE(test_data) - 1;643	tb_for_each_port_on_path(dst_port, src_port, p) {644		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));645		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);646		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);647		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,648				test_data[i].type);649		i--;650	}651 652	KUNIT_EXPECT_EQ(test, i, -1);653}654 655static void tb_test_path_complex_tree_walk(struct kunit *test)656{657	/*658	 * Walks from Device #3 DP IN to Device #9 DP OUT.659	 *660	 *           [Host]661	 *            1 |662	 *            1 |663	 *         [Device #1]664	 *       3 /   | 5  \ 7665	 *      1 /    |     \ 1666	 * [Device #2] |    [Device #5]667	 *    5 |      | 1         \ 7668	 *    1 |  [Device #4]      \ 1669	 * [Device #3]             [Device #6]670	 *                       3 /671	 *                      1 /672	 *                    [Device #7]673	 *                  3 /      | 5674	 *                 1 /       |675	 *               [Device #8] | 1676	 *                       [Device #9]677	 */678	static const struct port_expectation test_data[] = {679		{ .route = 0x50301, .port = 13, .type = TB_TYPE_DP_HDMI_IN },680		{ .route = 0x50301, .port = 1, .type = TB_TYPE_PORT },681		{ .route = 0x301, .port = 5, .type = TB_TYPE_PORT },682		{ .route = 0x301, .port = 1, .type = TB_TYPE_PORT },683		{ .route = 0x1, .port = 3, .type = TB_TYPE_PORT },684		{ .route = 0x1, .port = 7, .type = TB_TYPE_PORT },685		{ .route = 0x701, .port = 1, .type = TB_TYPE_PORT },686		{ .route = 0x701, .port = 7, .type = TB_TYPE_PORT },687		{ .route = 0x70701, .port = 1, .type = TB_TYPE_PORT },688		{ .route = 0x70701, .port = 3, .type = TB_TYPE_PORT },689		{ .route = 0x3070701, .port = 1, .type = TB_TYPE_PORT },690		{ .route = 0x3070701, .port = 5, .type = TB_TYPE_PORT },691		{ .route = 0x503070701, .port = 1, .type = TB_TYPE_PORT },692		{ .route = 0x503070701, .port = 14, .type = TB_TYPE_DP_HDMI_OUT },693	};694	struct tb_switch *host, *dev1, *dev2, *dev3, *dev5, *dev6, *dev7, *dev9;695	struct tb_port *src_port, *dst_port, *p;696	int i;697 698	host = alloc_host(test);699	dev1 = alloc_dev_default(test, host, 0x1, true);700	dev2 = alloc_dev_default(test, dev1, 0x301, true);701	dev3 = alloc_dev_with_dpin(test, dev2, 0x50301, true);702	alloc_dev_default(test, dev1, 0x501, true);703	dev5 = alloc_dev_default(test, dev1, 0x701, true);704	dev6 = alloc_dev_default(test, dev5, 0x70701, true);705	dev7 = alloc_dev_default(test, dev6, 0x3070701, true);706	alloc_dev_default(test, dev7, 0x303070701, true);707	dev9 = alloc_dev_default(test, dev7, 0x503070701, true);708 709	src_port = &dev3->ports[13];710	dst_port = &dev9->ports[14];711 712	/* Walk both directions */713 714	i = 0;715	tb_for_each_port_on_path(src_port, dst_port, p) {716		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));717		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);718		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);719		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,720				test_data[i].type);721		i++;722	}723 724	KUNIT_EXPECT_EQ(test, i, ARRAY_SIZE(test_data));725 726	i = ARRAY_SIZE(test_data) - 1;727	tb_for_each_port_on_path(dst_port, src_port, p) {728		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));729		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);730		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);731		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,732				test_data[i].type);733		i--;734	}735 736	KUNIT_EXPECT_EQ(test, i, -1);737}738 739static void tb_test_path_max_length_walk(struct kunit *test)740{741	struct tb_switch *host, *dev1, *dev2, *dev3, *dev4, *dev5, *dev6;742	struct tb_switch *dev7, *dev8, *dev9, *dev10, *dev11, *dev12;743	struct tb_port *src_port, *dst_port, *p;744	int i;745 746	/*747	 * Walks from Device #6 DP IN to Device #12 DP OUT.748	 *749	 *          [Host]750	 *         1 /  \ 3751	 *        1 /    \ 1752	 * [Device #1]   [Device #7]753	 *     3 |           | 3754	 *     1 |           | 1755	 * [Device #2]   [Device #8]756	 *     3 |           | 3757	 *     1 |           | 1758	 * [Device #3]   [Device #9]759	 *     3 |           | 3760	 *     1 |           | 1761	 * [Device #4]   [Device #10]762	 *     3 |           | 3763	 *     1 |           | 1764	 * [Device #5]   [Device #11]765	 *     3 |           | 3766	 *     1 |           | 1767	 * [Device #6]   [Device #12]768	 */769	static const struct port_expectation test_data[] = {770		{ .route = 0x30303030301, .port = 13, .type = TB_TYPE_DP_HDMI_IN },771		{ .route = 0x30303030301, .port = 1, .type = TB_TYPE_PORT },772		{ .route = 0x303030301, .port = 3, .type = TB_TYPE_PORT },773		{ .route = 0x303030301, .port = 1, .type = TB_TYPE_PORT },774		{ .route = 0x3030301, .port = 3, .type = TB_TYPE_PORT },775		{ .route = 0x3030301, .port = 1, .type = TB_TYPE_PORT },776		{ .route = 0x30301, .port = 3, .type = TB_TYPE_PORT },777		{ .route = 0x30301, .port = 1, .type = TB_TYPE_PORT },778		{ .route = 0x301, .port = 3, .type = TB_TYPE_PORT },779		{ .route = 0x301, .port = 1, .type = TB_TYPE_PORT },780		{ .route = 0x1, .port = 3, .type = TB_TYPE_PORT },781		{ .route = 0x1, .port = 1, .type = TB_TYPE_PORT },782		{ .route = 0x0, .port = 1, .type = TB_TYPE_PORT },783		{ .route = 0x0, .port = 3, .type = TB_TYPE_PORT },784		{ .route = 0x3, .port = 1, .type = TB_TYPE_PORT },785		{ .route = 0x3, .port = 3, .type = TB_TYPE_PORT },786		{ .route = 0x303, .port = 1, .type = TB_TYPE_PORT },787		{ .route = 0x303, .port = 3, .type = TB_TYPE_PORT },788		{ .route = 0x30303, .port = 1, .type = TB_TYPE_PORT },789		{ .route = 0x30303, .port = 3, .type = TB_TYPE_PORT },790		{ .route = 0x3030303, .port = 1, .type = TB_TYPE_PORT },791		{ .route = 0x3030303, .port = 3, .type = TB_TYPE_PORT },792		{ .route = 0x303030303, .port = 1, .type = TB_TYPE_PORT },793		{ .route = 0x303030303, .port = 3, .type = TB_TYPE_PORT },794		{ .route = 0x30303030303, .port = 1, .type = TB_TYPE_PORT },795		{ .route = 0x30303030303, .port = 13, .type = TB_TYPE_DP_HDMI_OUT },796	};797 798	host = alloc_host(test);799	dev1 = alloc_dev_default(test, host, 0x1, true);800	dev2 = alloc_dev_default(test, dev1, 0x301, true);801	dev3 = alloc_dev_default(test, dev2, 0x30301, true);802	dev4 = alloc_dev_default(test, dev3, 0x3030301, true);803	dev5 = alloc_dev_default(test, dev4, 0x303030301, true);804	dev6 = alloc_dev_with_dpin(test, dev5, 0x30303030301, true);805	dev7 = alloc_dev_default(test, host, 0x3, true);806	dev8 = alloc_dev_default(test, dev7, 0x303, true);807	dev9 = alloc_dev_default(test, dev8, 0x30303, true);808	dev10 = alloc_dev_default(test, dev9, 0x3030303, true);809	dev11 = alloc_dev_default(test, dev10, 0x303030303, true);810	dev12 = alloc_dev_default(test, dev11, 0x30303030303, true);811 812	src_port = &dev6->ports[13];813	dst_port = &dev12->ports[13];814 815	/* Walk both directions */816 817	i = 0;818	tb_for_each_port_on_path(src_port, dst_port, p) {819		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));820		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);821		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);822		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,823				test_data[i].type);824		i++;825	}826 827	KUNIT_EXPECT_EQ(test, i, ARRAY_SIZE(test_data));828 829	i = ARRAY_SIZE(test_data) - 1;830	tb_for_each_port_on_path(dst_port, src_port, p) {831		KUNIT_EXPECT_TRUE(test, i < ARRAY_SIZE(test_data));832		KUNIT_EXPECT_EQ(test, tb_route(p->sw), test_data[i].route);833		KUNIT_EXPECT_EQ(test, p->port, test_data[i].port);834		KUNIT_EXPECT_EQ(test, (enum tb_port_type)p->config.type,835				test_data[i].type);836		i--;837	}838 839	KUNIT_EXPECT_EQ(test, i, -1);840}841 842static void tb_test_path_not_connected(struct kunit *test)843{844	struct tb_switch *host, *dev1, *dev2;845	struct tb_port *down, *up;846	struct tb_path *path;847 848	host = alloc_host(test);849	dev1 = alloc_dev_default(test, host, 0x3, false);850	/* Not connected to anything */851	dev2 = alloc_dev_default(test, NULL, 0x303, false);852 853	down = &dev1->ports[10];854	up = &dev2->ports[9];855 856	path = tb_path_alloc(NULL, down, 8, up, 8, 0, "PCIe Down");857	KUNIT_ASSERT_NULL(test, path);858	path = tb_path_alloc(NULL, down, 8, up, 8, 1, "PCIe Down");859	KUNIT_ASSERT_NULL(test, path);860}861 862struct hop_expectation {863	u64 route;864	u8 in_port;865	enum tb_port_type in_type;866	u8 out_port;867	enum tb_port_type out_type;868};869 870static void tb_test_path_not_bonded_lane0(struct kunit *test)871{872	/*873	 * PCIe path from host to device using lane 0.874	 *875	 *   [Host]876	 *   3 |: 4877	 *   1 |: 2878	 *  [Device]879	 */880	static const struct hop_expectation test_data[] = {881		{882			.route = 0x0,883			.in_port = 9,884			.in_type = TB_TYPE_PCIE_DOWN,885			.out_port = 3,886			.out_type = TB_TYPE_PORT,887		},888		{889			.route = 0x3,890			.in_port = 1,891			.in_type = TB_TYPE_PORT,892			.out_port = 9,893			.out_type = TB_TYPE_PCIE_UP,894		},895	};896	struct tb_switch *host, *dev;897	struct tb_port *down, *up;898	struct tb_path *path;899	int i;900 901	host = alloc_host(test);902	dev = alloc_dev_default(test, host, 0x3, false);903 904	down = &host->ports[9];905	up = &dev->ports[9];906 907	path = tb_path_alloc(NULL, down, 8, up, 8, 0, "PCIe Down");908	KUNIT_ASSERT_NOT_NULL(test, path);909	KUNIT_ASSERT_EQ(test, path->path_length, ARRAY_SIZE(test_data));910	for (i = 0; i < ARRAY_SIZE(test_data); i++) {911		const struct tb_port *in_port, *out_port;912 913		in_port = path->hops[i].in_port;914		out_port = path->hops[i].out_port;915 916		KUNIT_EXPECT_EQ(test, tb_route(in_port->sw), test_data[i].route);917		KUNIT_EXPECT_EQ(test, in_port->port, test_data[i].in_port);918		KUNIT_EXPECT_EQ(test, (enum tb_port_type)in_port->config.type,919				test_data[i].in_type);920		KUNIT_EXPECT_EQ(test, tb_route(out_port->sw), test_data[i].route);921		KUNIT_EXPECT_EQ(test, out_port->port, test_data[i].out_port);922		KUNIT_EXPECT_EQ(test, (enum tb_port_type)out_port->config.type,923				test_data[i].out_type);924	}925	tb_path_free(path);926}927 928static void tb_test_path_not_bonded_lane1(struct kunit *test)929{930	/*931	 * DP Video path from host to device using lane 1. Paths like932	 * these are only used with Thunderbolt 1 devices where lane933	 * bonding is not possible. USB4 specifically does not allow934	 * paths like this (you either use lane 0 where lane 1 is935	 * disabled or both lanes are bonded).936	 *937	 *   [Host]938	 *   1 :| 2939	 *   1 :| 2940	 *  [Device]941	 */942	static const struct hop_expectation test_data[] = {943		{944			.route = 0x0,945			.in_port = 5,946			.in_type = TB_TYPE_DP_HDMI_IN,947			.out_port = 2,948			.out_type = TB_TYPE_PORT,949		},950		{951			.route = 0x1,952			.in_port = 2,953			.in_type = TB_TYPE_PORT,954			.out_port = 13,955			.out_type = TB_TYPE_DP_HDMI_OUT,956		},957	};958	struct tb_switch *host, *dev;959	struct tb_port *in, *out;960	struct tb_path *path;961	int i;962 963	host = alloc_host(test);964	dev = alloc_dev_default(test, host, 0x1, false);965 966	in = &host->ports[5];967	out = &dev->ports[13];968 969	path = tb_path_alloc(NULL, in, 9, out, 9, 1, "Video");970	KUNIT_ASSERT_NOT_NULL(test, path);971	KUNIT_ASSERT_EQ(test, path->path_length, ARRAY_SIZE(test_data));972	for (i = 0; i < ARRAY_SIZE(test_data); i++) {973		const struct tb_port *in_port, *out_port;974 975		in_port = path->hops[i].in_port;976		out_port = path->hops[i].out_port;977 978		KUNIT_EXPECT_EQ(test, tb_route(in_port->sw), test_data[i].route);979		KUNIT_EXPECT_EQ(test, in_port->port, test_data[i].in_port);980		KUNIT_EXPECT_EQ(test, (enum tb_port_type)in_port->config.type,981				test_data[i].in_type);982		KUNIT_EXPECT_EQ(test, tb_route(out_port->sw), test_data[i].route);983		KUNIT_EXPECT_EQ(test, out_port->port, test_data[i].out_port);984		KUNIT_EXPECT_EQ(test, (enum tb_port_type)out_port->config.type,985				test_data[i].out_type);986	}987	tb_path_free(path);988}989 990static void tb_test_path_not_bonded_lane1_chain(struct kunit *test)991{992	/*993	 * DP Video path from host to device 3 using lane 1.994	 *995	 *    [Host]996	 *    1 :| 2997	 *    1 :| 2998	 *  [Device #1]999	 *    7 :| 81000	 *    1 :| 21001	 *  [Device #2]1002	 *    5 :| 61003	 *    1 :| 21004	 *  [Device #3]1005	 */1006	static const struct hop_expectation test_data[] = {1007		{1008			.route = 0x0,1009			.in_port = 5,1010			.in_type = TB_TYPE_DP_HDMI_IN,1011			.out_port = 2,1012			.out_type = TB_TYPE_PORT,1013		},1014		{1015			.route = 0x1,1016			.in_port = 2,1017			.in_type = TB_TYPE_PORT,1018			.out_port = 8,1019			.out_type = TB_TYPE_PORT,1020		},1021		{1022			.route = 0x701,1023			.in_port = 2,1024			.in_type = TB_TYPE_PORT,1025			.out_port = 6,1026			.out_type = TB_TYPE_PORT,1027		},1028		{1029			.route = 0x50701,1030			.in_port = 2,1031			.in_type = TB_TYPE_PORT,1032			.out_port = 13,1033			.out_type = TB_TYPE_DP_HDMI_OUT,1034		},1035	};1036	struct tb_switch *host, *dev1, *dev2, *dev3;1037	struct tb_port *in, *out;1038	struct tb_path *path;1039	int i;1040 1041	host = alloc_host(test);1042	dev1 = alloc_dev_default(test, host, 0x1, false);1043	dev2 = alloc_dev_default(test, dev1, 0x701, false);1044	dev3 = alloc_dev_default(test, dev2, 0x50701, false);1045 1046	in = &host->ports[5];1047	out = &dev3->ports[13];1048 1049	path = tb_path_alloc(NULL, in, 9, out, 9, 1, "Video");1050	KUNIT_ASSERT_NOT_NULL(test, path);1051	KUNIT_ASSERT_EQ(test, path->path_length, ARRAY_SIZE(test_data));1052	for (i = 0; i < ARRAY_SIZE(test_data); i++) {1053		const struct tb_port *in_port, *out_port;1054 1055		in_port = path->hops[i].in_port;1056		out_port = path->hops[i].out_port;1057 1058		KUNIT_EXPECT_EQ(test, tb_route(in_port->sw), test_data[i].route);1059		KUNIT_EXPECT_EQ(test, in_port->port, test_data[i].in_port);1060		KUNIT_EXPECT_EQ(test, (enum tb_port_type)in_port->config.type,1061				test_data[i].in_type);1062		KUNIT_EXPECT_EQ(test, tb_route(out_port->sw), test_data[i].route);1063		KUNIT_EXPECT_EQ(test, out_port->port, test_data[i].out_port);1064		KUNIT_EXPECT_EQ(test, (enum tb_port_type)out_port->config.type,1065				test_data[i].out_type);1066	}1067	tb_path_free(path);1068}1069 1070static void tb_test_path_not_bonded_lane1_chain_reverse(struct kunit *test)1071{1072	/*1073	 * DP Video path from device 3 to host using lane 1.1074	 *1075	 *    [Host]1076	 *    1 :| 21077	 *    1 :| 21078	 *  [Device #1]1079	 *    7 :| 81080	 *    1 :| 21081	 *  [Device #2]1082	 *    5 :| 61083	 *    1 :| 21084	 *  [Device #3]1085	 */1086	static const struct hop_expectation test_data[] = {1087		{1088			.route = 0x50701,1089			.in_port = 13,1090			.in_type = TB_TYPE_DP_HDMI_IN,1091			.out_port = 2,1092			.out_type = TB_TYPE_PORT,1093		},1094		{1095			.route = 0x701,1096			.in_port = 6,1097			.in_type = TB_TYPE_PORT,1098			.out_port = 2,1099			.out_type = TB_TYPE_PORT,1100		},1101		{1102			.route = 0x1,1103			.in_port = 8,1104			.in_type = TB_TYPE_PORT,1105			.out_port = 2,1106			.out_type = TB_TYPE_PORT,1107		},1108		{1109			.route = 0x0,1110			.in_port = 2,1111			.in_type = TB_TYPE_PORT,1112			.out_port = 5,1113			.out_type = TB_TYPE_DP_HDMI_IN,1114		},1115	};1116	struct tb_switch *host, *dev1, *dev2, *dev3;1117	struct tb_port *in, *out;1118	struct tb_path *path;1119	int i;1120 1121	host = alloc_host(test);1122	dev1 = alloc_dev_default(test, host, 0x1, false);1123	dev2 = alloc_dev_default(test, dev1, 0x701, false);1124	dev3 = alloc_dev_with_dpin(test, dev2, 0x50701, false);1125 1126	in = &dev3->ports[13];1127	out = &host->ports[5];1128 1129	path = tb_path_alloc(NULL, in, 9, out, 9, 1, "Video");1130	KUNIT_ASSERT_NOT_NULL(test, path);1131	KUNIT_ASSERT_EQ(test, path->path_length, ARRAY_SIZE(test_data));1132	for (i = 0; i < ARRAY_SIZE(test_data); i++) {1133		const struct tb_port *in_port, *out_port;1134 1135		in_port = path->hops[i].in_port;1136		out_port = path->hops[i].out_port;1137 1138		KUNIT_EXPECT_EQ(test, tb_route(in_port->sw), test_data[i].route);1139		KUNIT_EXPECT_EQ(test, in_port->port, test_data[i].in_port);1140		KUNIT_EXPECT_EQ(test, (enum tb_port_type)in_port->config.type,1141				test_data[i].in_type);1142		KUNIT_EXPECT_EQ(test, tb_route(out_port->sw), test_data[i].route);1143		KUNIT_EXPECT_EQ(test, out_port->port, test_data[i].out_port);1144		KUNIT_EXPECT_EQ(test, (enum tb_port_type)out_port->config.type,1145				test_data[i].out_type);1146	}1147	tb_path_free(path);1148}1149 1150static void tb_test_path_mixed_chain(struct kunit *test)1151{1152	/*1153	 * DP Video path from host to device 4 where first and last link1154	 * is bonded.1155	 *1156	 *    [Host]1157	 *    1 |1158	 *    1 |1159	 *  [Device #1]1160	 *    7 :| 81161	 *    1 :| 21162	 *  [Device #2]1163	 *    5 :| 61164	 *    1 :| 21165	 *  [Device #3]1166	 *    3 |1167	 *    1 |1168	 *  [Device #4]1169	 */1170	static const struct hop_expectation test_data[] = {1171		{1172			.route = 0x0,1173			.in_port = 5,1174			.in_type = TB_TYPE_DP_HDMI_IN,1175			.out_port = 1,1176			.out_type = TB_TYPE_PORT,1177		},1178		{1179			.route = 0x1,1180			.in_port = 1,1181			.in_type = TB_TYPE_PORT,1182			.out_port = 8,1183			.out_type = TB_TYPE_PORT,1184		},1185		{1186			.route = 0x701,1187			.in_port = 2,1188			.in_type = TB_TYPE_PORT,1189			.out_port = 6,1190			.out_type = TB_TYPE_PORT,1191		},1192		{1193			.route = 0x50701,1194			.in_port = 2,1195			.in_type = TB_TYPE_PORT,1196			.out_port = 3,1197			.out_type = TB_TYPE_PORT,1198		},1199		{1200			.route = 0x3050701,1201			.in_port = 1,1202			.in_type = TB_TYPE_PORT,1203			.out_port = 13,1204			.out_type = TB_TYPE_DP_HDMI_OUT,1205		},1206	};1207	struct tb_switch *host, *dev1, *dev2, *dev3, *dev4;1208	struct tb_port *in, *out;1209	struct tb_path *path;1210	int i;1211 1212	host = alloc_host(test);1213	dev1 = alloc_dev_default(test, host, 0x1, true);1214	dev2 = alloc_dev_default(test, dev1, 0x701, false);1215	dev3 = alloc_dev_default(test, dev2, 0x50701, false);1216	dev4 = alloc_dev_default(test, dev3, 0x3050701, true);1217 1218	in = &host->ports[5];1219	out = &dev4->ports[13];1220 1221	path = tb_path_alloc(NULL, in, 9, out, 9, 1, "Video");1222	KUNIT_ASSERT_NOT_NULL(test, path);1223	KUNIT_ASSERT_EQ(test, path->path_length, ARRAY_SIZE(test_data));1224	for (i = 0; i < ARRAY_SIZE(test_data); i++) {1225		const struct tb_port *in_port, *out_port;1226 1227		in_port = path->hops[i].in_port;1228		out_port = path->hops[i].out_port;1229 1230		KUNIT_EXPECT_EQ(test, tb_route(in_port->sw), test_data[i].route);1231		KUNIT_EXPECT_EQ(test, in_port->port, test_data[i].in_port);1232		KUNIT_EXPECT_EQ(test, (enum tb_port_type)in_port->config.type,1233				test_data[i].in_type);1234		KUNIT_EXPECT_EQ(test, tb_route(out_port->sw), test_data[i].route);1235		KUNIT_EXPECT_EQ(test, out_port->port, test_data[i].out_port);1236		KUNIT_EXPECT_EQ(test, (enum tb_port_type)out_port->config.type,1237				test_data[i].out_type);1238	}1239	tb_path_free(path);1240}1241 1242static void tb_test_path_mixed_chain_reverse(struct kunit *test)1243{1244	/*1245	 * DP Video path from device 4 to host where first and last link1246	 * is bonded.1247	 *1248	 *    [Host]1249	 *    1 |1250	 *    1 |1251	 *  [Device #1]1252	 *    7 :| 81253	 *    1 :| 21254	 *  [Device #2]1255	 *    5 :| 61256	 *    1 :| 21257	 *  [Device #3]1258	 *    3 |1259	 *    1 |1260	 *  [Device #4]1261	 */1262	static const struct hop_expectation test_data[] = {1263		{1264			.route = 0x3050701,1265			.in_port = 13,1266			.in_type = TB_TYPE_DP_HDMI_OUT,1267			.out_port = 1,1268			.out_type = TB_TYPE_PORT,1269		},1270		{1271			.route = 0x50701,1272			.in_port = 3,1273			.in_type = TB_TYPE_PORT,1274			.out_port = 2,1275			.out_type = TB_TYPE_PORT,1276		},1277		{1278			.route = 0x701,1279			.in_port = 6,1280			.in_type = TB_TYPE_PORT,1281			.out_port = 2,1282			.out_type = TB_TYPE_PORT,1283		},1284		{1285			.route = 0x1,1286			.in_port = 8,1287			.in_type = TB_TYPE_PORT,1288			.out_port = 1,1289			.out_type = TB_TYPE_PORT,1290		},1291		{1292			.route = 0x0,1293			.in_port = 1,1294			.in_type = TB_TYPE_PORT,1295			.out_port = 5,1296			.out_type = TB_TYPE_DP_HDMI_IN,1297		},1298	};1299	struct tb_switch *host, *dev1, *dev2, *dev3, *dev4;1300	struct tb_port *in, *out;1301	struct tb_path *path;1302	int i;1303 1304	host = alloc_host(test);1305	dev1 = alloc_dev_default(test, host, 0x1, true);1306	dev2 = alloc_dev_default(test, dev1, 0x701, false);1307	dev3 = alloc_dev_default(test, dev2, 0x50701, false);1308	dev4 = alloc_dev_default(test, dev3, 0x3050701, true);1309 1310	in = &dev4->ports[13];1311	out = &host->ports[5];1312 1313	path = tb_path_alloc(NULL, in, 9, out, 9, 1, "Video");1314	KUNIT_ASSERT_NOT_NULL(test, path);1315	KUNIT_ASSERT_EQ(test, path->path_length, ARRAY_SIZE(test_data));1316	for (i = 0; i < ARRAY_SIZE(test_data); i++) {1317		const struct tb_port *in_port, *out_port;1318 1319		in_port = path->hops[i].in_port;1320		out_port = path->hops[i].out_port;1321 1322		KUNIT_EXPECT_EQ(test, tb_route(in_port->sw), test_data[i].route);1323		KUNIT_EXPECT_EQ(test, in_port->port, test_data[i].in_port);1324		KUNIT_EXPECT_EQ(test, (enum tb_port_type)in_port->config.type,1325				test_data[i].in_type);1326		KUNIT_EXPECT_EQ(test, tb_route(out_port->sw), test_data[i].route);1327		KUNIT_EXPECT_EQ(test, out_port->port, test_data[i].out_port);1328		KUNIT_EXPECT_EQ(test, (enum tb_port_type)out_port->config.type,1329				test_data[i].out_type);1330	}1331	tb_path_free(path);1332}1333 1334static void tb_test_tunnel_pcie(struct kunit *test)1335{1336	struct tb_switch *host, *dev1, *dev2;1337	struct tb_tunnel *tunnel1, *tunnel2;1338	struct tb_port *down, *up;1339 1340	/*1341	 * Create PCIe tunnel between host and two devices.1342	 *1343	 *   [Host]1344	 *    1 |1345	 *    1 |1346	 *  [Device #1]1347	 *    5 |1348	 *    1 |1349	 *  [Device #2]1350	 */1351	host = alloc_host(test);1352	dev1 = alloc_dev_default(test, host, 0x1, true);1353	dev2 = alloc_dev_default(test, dev1, 0x501, true);1354 1355	down = &host->ports[8];1356	up = &dev1->ports[9];1357	tunnel1 = tb_tunnel_alloc_pci(NULL, up, down);1358	KUNIT_ASSERT_NOT_NULL(test, tunnel1);1359	KUNIT_EXPECT_EQ(test, tunnel1->type, TB_TUNNEL_PCI);1360	KUNIT_EXPECT_PTR_EQ(test, tunnel1->src_port, down);1361	KUNIT_EXPECT_PTR_EQ(test, tunnel1->dst_port, up);1362	KUNIT_ASSERT_EQ(test, tunnel1->npaths, 2);1363	KUNIT_ASSERT_EQ(test, tunnel1->paths[0]->path_length, 2);1364	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[0]->hops[0].in_port, down);1365	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[0]->hops[1].out_port, up);1366	KUNIT_ASSERT_EQ(test, tunnel1->paths[1]->path_length, 2);1367	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[1]->hops[0].in_port, up);1368	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[1]->hops[1].out_port, down);1369 1370	down = &dev1->ports[10];1371	up = &dev2->ports[9];1372	tunnel2 = tb_tunnel_alloc_pci(NULL, up, down);1373	KUNIT_ASSERT_NOT_NULL(test, tunnel2);1374	KUNIT_EXPECT_EQ(test, tunnel2->type, TB_TUNNEL_PCI);1375	KUNIT_EXPECT_PTR_EQ(test, tunnel2->src_port, down);1376	KUNIT_EXPECT_PTR_EQ(test, tunnel2->dst_port, up);1377	KUNIT_ASSERT_EQ(test, tunnel2->npaths, 2);1378	KUNIT_ASSERT_EQ(test, tunnel2->paths[0]->path_length, 2);1379	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[0]->hops[0].in_port, down);1380	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[0]->hops[1].out_port, up);1381	KUNIT_ASSERT_EQ(test, tunnel2->paths[1]->path_length, 2);1382	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[0].in_port, up);1383	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[1].out_port, down);1384 1385	tb_tunnel_free(tunnel2);1386	tb_tunnel_free(tunnel1);1387}1388 1389static void tb_test_tunnel_dp(struct kunit *test)1390{1391	struct tb_switch *host, *dev;1392	struct tb_port *in, *out;1393	struct tb_tunnel *tunnel;1394 1395	/*1396	 * Create DP tunnel between Host and Device1397	 *1398	 *   [Host]1399	 *   1 |1400	 *   1 |1401	 *  [Device]1402	 */1403	host = alloc_host(test);1404	dev = alloc_dev_default(test, host, 0x3, true);1405 1406	in = &host->ports[5];1407	out = &dev->ports[13];1408 1409	tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);1410	KUNIT_ASSERT_NOT_NULL(test, tunnel);1411	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP);1412	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in);1413	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, out);1414	KUNIT_ASSERT_EQ(test, tunnel->npaths, 3);1415	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 2);1416	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, in);1417	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[1].out_port, out);1418	KUNIT_ASSERT_EQ(test, tunnel->paths[1]->path_length, 2);1419	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].in_port, in);1420	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[1].out_port, out);1421	KUNIT_ASSERT_EQ(test, tunnel->paths[2]->path_length, 2);1422	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[0].in_port, out);1423	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[1].out_port, in);1424	tb_tunnel_free(tunnel);1425}1426 1427static void tb_test_tunnel_dp_chain(struct kunit *test)1428{1429	struct tb_switch *host, *dev1, *dev4;1430	struct tb_port *in, *out;1431	struct tb_tunnel *tunnel;1432 1433	/*1434	 * Create DP tunnel from Host DP IN to Device #4 DP OUT.1435	 *1436	 *           [Host]1437	 *            1 |1438	 *            1 |1439	 *         [Device #1]1440	 *       3 /   | 5  \ 71441	 *      1 /    |     \ 11442	 * [Device #2] |    [Device #4]1443	 *             | 11444	 *         [Device #3]1445	 */1446	host = alloc_host(test);1447	dev1 = alloc_dev_default(test, host, 0x1, true);1448	alloc_dev_default(test, dev1, 0x301, true);1449	alloc_dev_default(test, dev1, 0x501, true);1450	dev4 = alloc_dev_default(test, dev1, 0x701, true);1451 1452	in = &host->ports[5];1453	out = &dev4->ports[14];1454 1455	tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);1456	KUNIT_ASSERT_NOT_NULL(test, tunnel);1457	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP);1458	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in);1459	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, out);1460	KUNIT_ASSERT_EQ(test, tunnel->npaths, 3);1461	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 3);1462	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, in);1463	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[2].out_port, out);1464	KUNIT_ASSERT_EQ(test, tunnel->paths[1]->path_length, 3);1465	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].in_port, in);1466	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[2].out_port, out);1467	KUNIT_ASSERT_EQ(test, tunnel->paths[2]->path_length, 3);1468	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[0].in_port, out);1469	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[2].out_port, in);1470	tb_tunnel_free(tunnel);1471}1472 1473static void tb_test_tunnel_dp_tree(struct kunit *test)1474{1475	struct tb_switch *host, *dev1, *dev2, *dev3, *dev5;1476	struct tb_port *in, *out;1477	struct tb_tunnel *tunnel;1478 1479	/*1480	 * Create DP tunnel from Device #2 DP IN to Device #5 DP OUT.1481	 *1482	 *          [Host]1483	 *           3 |1484	 *           1 |1485	 *         [Device #1]1486	 *       3 /   | 5  \ 71487	 *      1 /    |     \ 11488	 * [Device #2] |    [Device #4]1489	 *             | 11490	 *         [Device #3]1491	 *             | 51492	 *             | 11493	 *         [Device #5]1494	 */1495	host = alloc_host(test);1496	dev1 = alloc_dev_default(test, host, 0x3, true);1497	dev2 = alloc_dev_with_dpin(test, dev1, 0x303, true);1498	dev3 = alloc_dev_default(test, dev1, 0x503, true);1499	alloc_dev_default(test, dev1, 0x703, true);1500	dev5 = alloc_dev_default(test, dev3, 0x50503, true);1501 1502	in = &dev2->ports[13];1503	out = &dev5->ports[13];1504 1505	tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);1506	KUNIT_ASSERT_NOT_NULL(test, tunnel);1507	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP);1508	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in);1509	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, out);1510	KUNIT_ASSERT_EQ(test, tunnel->npaths, 3);1511	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 4);1512	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, in);1513	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[3].out_port, out);1514	KUNIT_ASSERT_EQ(test, tunnel->paths[1]->path_length, 4);1515	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].in_port, in);1516	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[3].out_port, out);1517	KUNIT_ASSERT_EQ(test, tunnel->paths[2]->path_length, 4);1518	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[0].in_port, out);1519	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[3].out_port, in);1520	tb_tunnel_free(tunnel);1521}1522 1523static void tb_test_tunnel_dp_max_length(struct kunit *test)1524{1525	struct tb_switch *host, *dev1, *dev2, *dev3, *dev4, *dev5, *dev6;1526	struct tb_switch *dev7, *dev8, *dev9, *dev10, *dev11, *dev12;1527	struct tb_port *in, *out;1528	struct tb_tunnel *tunnel;1529 1530	/*1531	 * Creates DP tunnel from Device #6 to Device #12.1532	 *1533	 *          [Host]1534	 *         1 /  \ 31535	 *        1 /    \ 11536	 * [Device #1]   [Device #7]1537	 *     3 |           | 31538	 *     1 |           | 11539	 * [Device #2]   [Device #8]1540	 *     3 |           | 31541	 *     1 |           | 11542	 * [Device #3]   [Device #9]1543	 *     3 |           | 31544	 *     1 |           | 11545	 * [Device #4]   [Device #10]1546	 *     3 |           | 31547	 *     1 |           | 11548	 * [Device #5]   [Device #11]1549	 *     3 |           | 31550	 *     1 |           | 11551	 * [Device #6]   [Device #12]1552	 */1553	host = alloc_host(test);1554	dev1 = alloc_dev_default(test, host, 0x1, true);1555	dev2 = alloc_dev_default(test, dev1, 0x301, true);1556	dev3 = alloc_dev_default(test, dev2, 0x30301, true);1557	dev4 = alloc_dev_default(test, dev3, 0x3030301, true);1558	dev5 = alloc_dev_default(test, dev4, 0x303030301, true);1559	dev6 = alloc_dev_with_dpin(test, dev5, 0x30303030301, true);1560	dev7 = alloc_dev_default(test, host, 0x3, true);1561	dev8 = alloc_dev_default(test, dev7, 0x303, true);1562	dev9 = alloc_dev_default(test, dev8, 0x30303, true);1563	dev10 = alloc_dev_default(test, dev9, 0x3030303, true);1564	dev11 = alloc_dev_default(test, dev10, 0x303030303, true);1565	dev12 = alloc_dev_default(test, dev11, 0x30303030303, true);1566 1567	in = &dev6->ports[13];1568	out = &dev12->ports[13];1569 1570	tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);1571	KUNIT_ASSERT_NOT_NULL(test, tunnel);1572	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP);1573	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in);1574	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, out);1575	KUNIT_ASSERT_EQ(test, tunnel->npaths, 3);1576	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 13);1577	/* First hop */1578	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, in);1579	/* Middle */1580	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[6].in_port,1581			    &host->ports[1]);1582	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[6].out_port,1583			    &host->ports[3]);1584	/* Last */1585	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[12].out_port, out);1586	KUNIT_ASSERT_EQ(test, tunnel->paths[1]->path_length, 13);1587	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].in_port, in);1588	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[6].in_port,1589			    &host->ports[1]);1590	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[6].out_port,1591			    &host->ports[3]);1592	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[12].out_port, out);1593	KUNIT_ASSERT_EQ(test, tunnel->paths[2]->path_length, 13);1594	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[0].in_port, out);1595	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[6].in_port,1596			    &host->ports[3]);1597	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[6].out_port,1598			    &host->ports[1]);1599	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[12].out_port, in);1600	tb_tunnel_free(tunnel);1601}1602 1603static void tb_test_tunnel_3dp(struct kunit *test)1604{1605	struct tb_switch *host, *dev1, *dev2, *dev3, *dev4, *dev5;1606	struct tb_port *in1, *in2, *in3, *out1, *out2, *out3;1607	struct tb_tunnel *tunnel1, *tunnel2, *tunnel3;1608 1609	/*1610	 * Create 3 DP tunnels from Host to Devices #2, #5 and #4.1611	 *1612	 *          [Host]1613	 *           3 |1614	 *           1 |1615	 *         [Device #1]1616	 *       3 /   | 5  \ 71617	 *      1 /    |     \ 11618	 * [Device #2] |    [Device #4]1619	 *             | 11620	 *         [Device #3]1621	 *             | 51622	 *             | 11623	 *         [Device #5]1624	 */1625	host = alloc_host_br(test);1626	dev1 = alloc_dev_default(test, host, 0x3, true);1627	dev2 = alloc_dev_default(test, dev1, 0x303, true);1628	dev3 = alloc_dev_default(test, dev1, 0x503, true);1629	dev4 = alloc_dev_default(test, dev1, 0x703, true);1630	dev5 = alloc_dev_default(test, dev3, 0x50503, true);1631 1632	in1 = &host->ports[5];1633	in2 = &host->ports[6];1634	in3 = &host->ports[10];1635 1636	out1 = &dev2->ports[13];1637	out2 = &dev5->ports[13];1638	out3 = &dev4->ports[14];1639 1640	tunnel1 = tb_tunnel_alloc_dp(NULL, in1, out1, 1, 0, 0);1641	KUNIT_ASSERT_TRUE(test, tunnel1 != NULL);1642	KUNIT_EXPECT_EQ(test, tunnel1->type, TB_TUNNEL_DP);1643	KUNIT_EXPECT_PTR_EQ(test, tunnel1->src_port, in1);1644	KUNIT_EXPECT_PTR_EQ(test, tunnel1->dst_port, out1);1645	KUNIT_ASSERT_EQ(test, tunnel1->npaths, 3);1646	KUNIT_ASSERT_EQ(test, tunnel1->paths[0]->path_length, 3);1647 1648	tunnel2 = tb_tunnel_alloc_dp(NULL, in2, out2, 1, 0, 0);1649	KUNIT_ASSERT_TRUE(test, tunnel2 != NULL);1650	KUNIT_EXPECT_EQ(test, tunnel2->type, TB_TUNNEL_DP);1651	KUNIT_EXPECT_PTR_EQ(test, tunnel2->src_port, in2);1652	KUNIT_EXPECT_PTR_EQ(test, tunnel2->dst_port, out2);1653	KUNIT_ASSERT_EQ(test, tunnel2->npaths, 3);1654	KUNIT_ASSERT_EQ(test, tunnel2->paths[0]->path_length, 4);1655 1656	tunnel3 = tb_tunnel_alloc_dp(NULL, in3, out3, 1, 0, 0);1657	KUNIT_ASSERT_TRUE(test, tunnel3 != NULL);1658	KUNIT_EXPECT_EQ(test, tunnel3->type, TB_TUNNEL_DP);1659	KUNIT_EXPECT_PTR_EQ(test, tunnel3->src_port, in3);1660	KUNIT_EXPECT_PTR_EQ(test, tunnel3->dst_port, out3);1661	KUNIT_ASSERT_EQ(test, tunnel3->npaths, 3);1662	KUNIT_ASSERT_EQ(test, tunnel3->paths[0]->path_length, 3);1663 1664	tb_tunnel_free(tunnel2);1665	tb_tunnel_free(tunnel1);1666}1667 1668static void tb_test_tunnel_usb3(struct kunit *test)1669{1670	struct tb_switch *host, *dev1, *dev2;1671	struct tb_tunnel *tunnel1, *tunnel2;1672	struct tb_port *down, *up;1673 1674	/*1675	 * Create USB3 tunnel between host and two devices.1676	 *1677	 *   [Host]1678	 *    1 |1679	 *    1 |1680	 *  [Device #1]1681	 *          \ 71682	 *           \ 11683	 *         [Device #2]1684	 */1685	host = alloc_host(test);1686	dev1 = alloc_dev_default(test, host, 0x1, true);1687	dev2 = alloc_dev_default(test, dev1, 0x701, true);1688 1689	down = &host->ports[12];1690	up = &dev1->ports[16];1691	tunnel1 = tb_tunnel_alloc_usb3(NULL, up, down, 0, 0);1692	KUNIT_ASSERT_NOT_NULL(test, tunnel1);1693	KUNIT_EXPECT_EQ(test, tunnel1->type, TB_TUNNEL_USB3);1694	KUNIT_EXPECT_PTR_EQ(test, tunnel1->src_port, down);1695	KUNIT_EXPECT_PTR_EQ(test, tunnel1->dst_port, up);1696	KUNIT_ASSERT_EQ(test, tunnel1->npaths, 2);1697	KUNIT_ASSERT_EQ(test, tunnel1->paths[0]->path_length, 2);1698	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[0]->hops[0].in_port, down);1699	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[0]->hops[1].out_port, up);1700	KUNIT_ASSERT_EQ(test, tunnel1->paths[1]->path_length, 2);1701	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[1]->hops[0].in_port, up);1702	KUNIT_EXPECT_PTR_EQ(test, tunnel1->paths[1]->hops[1].out_port, down);1703 1704	down = &dev1->ports[17];1705	up = &dev2->ports[16];1706	tunnel2 = tb_tunnel_alloc_usb3(NULL, up, down, 0, 0);1707	KUNIT_ASSERT_NOT_NULL(test, tunnel2);1708	KUNIT_EXPECT_EQ(test, tunnel2->type, TB_TUNNEL_USB3);1709	KUNIT_EXPECT_PTR_EQ(test, tunnel2->src_port, down);1710	KUNIT_EXPECT_PTR_EQ(test, tunnel2->dst_port, up);1711	KUNIT_ASSERT_EQ(test, tunnel2->npaths, 2);1712	KUNIT_ASSERT_EQ(test, tunnel2->paths[0]->path_length, 2);1713	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[0]->hops[0].in_port, down);1714	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[0]->hops[1].out_port, up);1715	KUNIT_ASSERT_EQ(test, tunnel2->paths[1]->path_length, 2);1716	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[0].in_port, up);1717	KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[1].out_port, down);1718 1719	tb_tunnel_free(tunnel2);1720	tb_tunnel_free(tunnel1);1721}1722 1723static void tb_test_tunnel_port_on_path(struct kunit *test)1724{1725	struct tb_switch *host, *dev1, *dev2, *dev3, *dev4, *dev5;1726	struct tb_port *in, *out, *port;1727	struct tb_tunnel *dp_tunnel;1728 1729	/*1730	 *          [Host]1731	 *           3 |1732	 *           1 |1733	 *         [Device #1]1734	 *       3 /   | 5  \ 71735	 *      1 /    |     \ 11736	 * [Device #2] |    [Device #4]1737	 *             | 11738	 *         [Device #3]1739	 *             | 51740	 *             | 11741	 *         [Device #5]1742	 */1743	host = alloc_host(test);1744	dev1 = alloc_dev_default(test, host, 0x3, true);1745	dev2 = alloc_dev_with_dpin(test, dev1, 0x303, true);1746	dev3 = alloc_dev_default(test, dev1, 0x503, true);1747	dev4 = alloc_dev_default(test, dev1, 0x703, true);1748	dev5 = alloc_dev_default(test, dev3, 0x50503, true);1749 1750	in = &dev2->ports[13];1751	out = &dev5->ports[13];1752 1753	dp_tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);1754	KUNIT_ASSERT_NOT_NULL(test, dp_tunnel);1755 1756	KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, in));1757	KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, out));1758 1759	port = &host->ports[8];1760	KUNIT_EXPECT_FALSE(test, tb_tunnel_port_on_path(dp_tunnel, port));1761 1762	port = &host->ports[3];1763	KUNIT_EXPECT_FALSE(test, tb_tunnel_port_on_path(dp_tunnel, port));1764 1765	port = &dev1->ports[1];1766	KUNIT_EXPECT_FALSE(test, tb_tunnel_port_on_path(dp_tunnel, port));1767 1768	port = &dev1->ports[3];1769	KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, port));1770 1771	port = &dev1->ports[5];1772	KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, port));1773 1774	port = &dev1->ports[7];1775	KUNIT_EXPECT_FALSE(test, tb_tunnel_port_on_path(dp_tunnel, port));1776 1777	port = &dev3->ports[1];1778	KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, port));1779 1780	port = &dev5->ports[1];1781	KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, port));1782 1783	port = &dev4->ports[1];1784	KUNIT_EXPECT_FALSE(test, tb_tunnel_port_on_path(dp_tunnel, port));1785 1786	tb_tunnel_free(dp_tunnel);1787}1788 1789static void tb_test_tunnel_dma(struct kunit *test)1790{1791	struct tb_port *nhi, *port;1792	struct tb_tunnel *tunnel;1793	struct tb_switch *host;1794 1795	/*1796	 * Create DMA tunnel from NHI to port 1 and back.1797	 *1798	 *   [Host 1]1799	 *    1 ^ In HopID 1 -> Out HopID 81800	 *      |1801	 *      v In HopID 8 -> Out HopID 11802	 * ............ Domain border1803	 *      |1804	 *   [Host 2]1805	 */1806	host = alloc_host(test);1807	nhi = &host->ports[7];1808	port = &host->ports[1];1809 1810	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, 8, 1, 8, 1);1811	KUNIT_ASSERT_NOT_NULL(test, tunnel);1812	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DMA);1813	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, nhi);1814	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, port);1815	KUNIT_ASSERT_EQ(test, tunnel->npaths, 2);1816	/* RX path */1817	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 1);1818	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, port);1819	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].in_hop_index, 8);1820	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].out_port, nhi);1821	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].next_hop_index, 1);1822	/* TX path */1823	KUNIT_ASSERT_EQ(test, tunnel->paths[1]->path_length, 1);1824	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].in_port, nhi);1825	KUNIT_EXPECT_EQ(test, tunnel->paths[1]->hops[0].in_hop_index, 1);1826	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].out_port, port);1827	KUNIT_EXPECT_EQ(test, tunnel->paths[1]->hops[0].next_hop_index, 8);1828 1829	tb_tunnel_free(tunnel);1830}1831 1832static void tb_test_tunnel_dma_rx(struct kunit *test)1833{1834	struct tb_port *nhi, *port;1835	struct tb_tunnel *tunnel;1836	struct tb_switch *host;1837 1838	/*1839	 * Create DMA RX tunnel from port 1 to NHI.1840	 *1841	 *   [Host 1]1842	 *    1 ^1843	 *      |1844	 *      | In HopID 15 -> Out HopID 21845	 * ............ Domain border1846	 *      |1847	 *   [Host 2]1848	 */1849	host = alloc_host(test);1850	nhi = &host->ports[7];1851	port = &host->ports[1];1852 1853	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, -1, -1, 15, 2);1854	KUNIT_ASSERT_NOT_NULL(test, tunnel);1855	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DMA);1856	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, nhi);1857	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, port);1858	KUNIT_ASSERT_EQ(test, tunnel->npaths, 1);1859	/* RX path */1860	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 1);1861	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, port);1862	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].in_hop_index, 15);1863	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].out_port, nhi);1864	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].next_hop_index, 2);1865 1866	tb_tunnel_free(tunnel);1867}1868 1869static void tb_test_tunnel_dma_tx(struct kunit *test)1870{1871	struct tb_port *nhi, *port;1872	struct tb_tunnel *tunnel;1873	struct tb_switch *host;1874 1875	/*1876	 * Create DMA TX tunnel from NHI to port 1.1877	 *1878	 *   [Host 1]1879	 *    1 | In HopID 2 -> Out HopID 151880	 *      |1881	 *      v1882	 * ............ Domain border1883	 *      |1884	 *   [Host 2]1885	 */1886	host = alloc_host(test);1887	nhi = &host->ports[7];1888	port = &host->ports[1];1889 1890	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, 15, 2, -1, -1);1891	KUNIT_ASSERT_NOT_NULL(test, tunnel);1892	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DMA);1893	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, nhi);1894	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, port);1895	KUNIT_ASSERT_EQ(test, tunnel->npaths, 1);1896	/* TX path */1897	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 1);1898	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, nhi);1899	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].in_hop_index, 2);1900	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].out_port, port);1901	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].next_hop_index, 15);1902 1903	tb_tunnel_free(tunnel);1904}1905 1906static void tb_test_tunnel_dma_chain(struct kunit *test)1907{1908	struct tb_switch *host, *dev1, *dev2;1909	struct tb_port *nhi, *port;1910	struct tb_tunnel *tunnel;1911 1912	/*1913	 * Create DMA tunnel from NHI to Device #2 port 3 and back.1914	 *1915	 *   [Host 1]1916	 *    1 ^ In HopID 1 -> Out HopID x1917	 *      |1918	 *    1 | In HopID x -> Out HopID 11919	 *  [Device #1]1920	 *         7 \1921	 *          1 \1922	 *         [Device #2]1923	 *           3 | In HopID x -> Out HopID 81924	 *             |1925	 *             v In HopID 8 -> Out HopID x1926	 * ............ Domain border1927	 *             |1928	 *          [Host 2]1929	 */1930	host = alloc_host(test);1931	dev1 = alloc_dev_default(test, host, 0x1, true);1932	dev2 = alloc_dev_default(test, dev1, 0x701, true);1933 1934	nhi = &host->ports[7];1935	port = &dev2->ports[3];1936	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, 8, 1, 8, 1);1937	KUNIT_ASSERT_NOT_NULL(test, tunnel);1938	KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DMA);1939	KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, nhi);1940	KUNIT_EXPECT_PTR_EQ(test, tunnel->dst_port, port);1941	KUNIT_ASSERT_EQ(test, tunnel->npaths, 2);1942	/* RX path */1943	KUNIT_ASSERT_EQ(test, tunnel->paths[0]->path_length, 3);1944	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].in_port, port);1945	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].in_hop_index, 8);1946	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].out_port,1947			    &dev2->ports[1]);1948	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[1].in_port,1949			    &dev1->ports[7]);1950	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[1].out_port,1951			    &dev1->ports[1]);1952	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[2].in_port,1953			    &host->ports[1]);1954	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[2].out_port, nhi);1955	KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[2].next_hop_index, 1);1956	/* TX path */1957	KUNIT_ASSERT_EQ(test, tunnel->paths[1]->path_length, 3);1958	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].in_port, nhi);1959	KUNIT_EXPECT_EQ(test, tunnel->paths[1]->hops[0].in_hop_index, 1);1960	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[1].in_port,1961			    &dev1->ports[1]);1962	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[1].out_port,1963			    &dev1->ports[7]);1964	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[2].in_port,1965			    &dev2->ports[1]);1966	KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[2].out_port, port);1967	KUNIT_EXPECT_EQ(test, tunnel->paths[1]->hops[2].next_hop_index, 8);1968 1969	tb_tunnel_free(tunnel);1970}1971 1972static void tb_test_tunnel_dma_match(struct kunit *test)1973{1974	struct tb_port *nhi, *port;1975	struct tb_tunnel *tunnel;1976	struct tb_switch *host;1977 1978	host = alloc_host(test);1979	nhi = &host->ports[7];1980	port = &host->ports[1];1981 1982	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, 15, 1, 15, 1);1983	KUNIT_ASSERT_NOT_NULL(test, tunnel);1984 1985	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, 15, 1, 15, 1));1986	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 8, 1, 15, 1));1987	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, 15, 1));1988	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, 15, 1, -1, -1));1989	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, 15, -1, -1, -1));1990	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, 1, -1, -1));1991	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, 15, -1));1992	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, -1, 1));1993	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, -1, -1));1994	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 8, -1, 8, -1));1995 1996	tb_tunnel_free(tunnel);1997 1998	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, 15, 1, -1, -1);1999	KUNIT_ASSERT_NOT_NULL(test, tunnel);2000	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, 15, 1, -1, -1));2001	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, 15, -1, -1, -1));2002	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, 1, -1, -1));2003	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, -1, -1));2004	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 15, 1, 15, 1));2005	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, -1, -1, 15, 1));2006	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 15, 11, -1, -1));2007 2008	tb_tunnel_free(tunnel);2009 2010	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, -1, -1, 15, 11);2011	KUNIT_ASSERT_NOT_NULL(test, tunnel);2012	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, 15, 11));2013	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, 15, -1));2014	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, -1, 11));2015	KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, -1, -1));2016	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, -1, -1, 15, 1));2017	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, -1, -1, 10, 11));2018	KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 15, 11, -1, -1));2019 2020	tb_tunnel_free(tunnel);2021}2022 2023static void tb_test_credit_alloc_legacy_not_bonded(struct kunit *test)2024{2025	struct tb_switch *host, *dev;2026	struct tb_port *up, *down;2027	struct tb_tunnel *tunnel;2028	struct tb_path *path;2029 2030	host = alloc_host(test);2031	dev = alloc_dev_default(test, host, 0x1, false);2032 2033	down = &host->ports[8];2034	up = &dev->ports[9];2035	tunnel = tb_tunnel_alloc_pci(NULL, up, down);2036	KUNIT_ASSERT_NOT_NULL(test, tunnel);2037	KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)2);2038 2039	path = tunnel->paths[0];2040	KUNIT_ASSERT_EQ(test, path->path_length, 2);2041	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2042	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2043	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2044	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 16U);2045 2046	path = tunnel->paths[1];2047	KUNIT_ASSERT_EQ(test, path->path_length, 2);2048	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2049	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2050	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2051	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 16U);2052 2053	tb_tunnel_free(tunnel);2054}2055 2056static void tb_test_credit_alloc_legacy_bonded(struct kunit *test)2057{2058	struct tb_switch *host, *dev;2059	struct tb_port *up, *down;2060	struct tb_tunnel *tunnel;2061	struct tb_path *path;2062 2063	host = alloc_host(test);2064	dev = alloc_dev_default(test, host, 0x1, true);2065 2066	down = &host->ports[8];2067	up = &dev->ports[9];2068	tunnel = tb_tunnel_alloc_pci(NULL, up, down);2069	KUNIT_ASSERT_NOT_NULL(test, tunnel);2070	KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)2);2071 2072	path = tunnel->paths[0];2073	KUNIT_ASSERT_EQ(test, path->path_length, 2);2074	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2075	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2076	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2077	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U);2078 2079	path = tunnel->paths[1];2080	KUNIT_ASSERT_EQ(test, path->path_length, 2);2081	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2082	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2083	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2084	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U);2085 2086	tb_tunnel_free(tunnel);2087}2088 2089static void tb_test_credit_alloc_pcie(struct kunit *test)2090{2091	struct tb_switch *host, *dev;2092	struct tb_port *up, *down;2093	struct tb_tunnel *tunnel;2094	struct tb_path *path;2095 2096	host = alloc_host_usb4(test);2097	dev = alloc_dev_usb4(test, host, 0x1, true);2098 2099	down = &host->ports[8];2100	up = &dev->ports[9];2101	tunnel = tb_tunnel_alloc_pci(NULL, up, down);2102	KUNIT_ASSERT_NOT_NULL(test, tunnel);2103	KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)2);2104 2105	path = tunnel->paths[0];2106	KUNIT_ASSERT_EQ(test, path->path_length, 2);2107	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2108	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2109	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2110	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U);2111 2112	path = tunnel->paths[1];2113	KUNIT_ASSERT_EQ(test, path->path_length, 2);2114	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2115	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2116	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2117	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 64U);2118 2119	tb_tunnel_free(tunnel);2120}2121 2122static void tb_test_credit_alloc_without_dp(struct kunit *test)2123{2124	struct tb_switch *host, *dev;2125	struct tb_port *up, *down;2126	struct tb_tunnel *tunnel;2127	struct tb_path *path;2128 2129	host = alloc_host_usb4(test);2130	dev = alloc_dev_without_dp(test, host, 0x1, true);2131 2132	/*2133	 * The device has no DP therefore baMinDPmain = baMinDPaux = 02134	 *2135	 * Create PCIe path with buffers less than baMaxPCIe.2136	 *2137	 * For a device with buffers configurations:2138	 * baMaxUSB3 = 1092139	 * baMinDPaux = 02140	 * baMinDPmain = 02141	 * baMaxPCIe = 302142	 * baMaxHI = 12143	 * Remaining Buffers = Total - (CP + DP) = 120 - (2 + 0) = 1182144	 * PCIe Credits = Max(6, Min(baMaxPCIe, Remaining Buffers - baMaxUSB3)2145	 *		= Max(6, Min(30, 9) = 92146	 */2147	down = &host->ports[8];2148	up = &dev->ports[9];2149	tunnel = tb_tunnel_alloc_pci(NULL, up, down);2150	KUNIT_ASSERT_TRUE(test, tunnel != NULL);2151	KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)2);2152 2153	/* PCIe downstream path */2154	path = tunnel->paths[0];2155	KUNIT_ASSERT_EQ(test, path->path_length, 2);2156	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2157	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2158	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2159	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 9U);2160 2161	/* PCIe upstream path */2162	path = tunnel->paths[1];2163	KUNIT_ASSERT_EQ(test, path->path_length, 2);2164	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2165	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2166	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2167	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 64U);2168 2169	tb_tunnel_free(tunnel);2170}2171 2172static void tb_test_credit_alloc_dp(struct kunit *test)2173{2174	struct tb_switch *host, *dev;2175	struct tb_port *in, *out;2176	struct tb_tunnel *tunnel;2177	struct tb_path *path;2178 2179	host = alloc_host_usb4(test);2180	dev = alloc_dev_usb4(test, host, 0x1, true);2181 2182	in = &host->ports[5];2183	out = &dev->ports[14];2184 2185	tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);2186	KUNIT_ASSERT_NOT_NULL(test, tunnel);2187	KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)3);2188 2189	/* Video (main) path */2190	path = tunnel->paths[0];2191	KUNIT_ASSERT_EQ(test, path->path_length, 2);2192	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 12U);2193	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2194	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 18U);2195	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 0U);2196 2197	/* AUX TX */2198	path = tunnel->paths[1];2199	KUNIT_ASSERT_EQ(test, path->path_length, 2);2200	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2201	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 1U);2202	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2203	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2204 2205	/* AUX RX */2206	path = tunnel->paths[2];2207	KUNIT_ASSERT_EQ(test, path->path_length, 2);2208	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2209	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 1U);2210	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2211	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2212 2213	tb_tunnel_free(tunnel);2214}2215 2216static void tb_test_credit_alloc_usb3(struct kunit *test)2217{2218	struct tb_switch *host, *dev;2219	struct tb_port *up, *down;2220	struct tb_tunnel *tunnel;2221	struct tb_path *path;2222 2223	host = alloc_host_usb4(test);2224	dev = alloc_dev_usb4(test, host, 0x1, true);2225 2226	down = &host->ports[12];2227	up = &dev->ports[16];2228	tunnel = tb_tunnel_alloc_usb3(NULL, up, down, 0, 0);2229	KUNIT_ASSERT_NOT_NULL(test, tunnel);2230	KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)2);2231 2232	path = tunnel->paths[0];2233	KUNIT_ASSERT_EQ(test, path->path_length, 2);2234	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2235	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2236	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2237	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2238 2239	path = tunnel->paths[1];2240	KUNIT_ASSERT_EQ(test, path->path_length, 2);2241	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2242	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2243	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2244	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U);2245 2246	tb_tunnel_free(tunnel);2247}2248 2249static void tb_test_credit_alloc_dma(struct kunit *test)2250{2251	struct tb_switch *host, *dev;2252	struct tb_port *nhi, *port;2253	struct tb_tunnel *tunnel;2254	struct tb_path *path;2255 2256	host = alloc_host_usb4(test);2257	dev = alloc_dev_usb4(test, host, 0x1, true);2258 2259	nhi = &host->ports[7];2260	port = &dev->ports[3];2261 2262	tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, 8, 1, 8, 1);2263	KUNIT_ASSERT_NOT_NULL(test, tunnel);2264	KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)2);2265 2266	/* DMA RX */2267	path = tunnel->paths[0];2268	KUNIT_ASSERT_EQ(test, path->path_length, 2);2269	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2270	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);2271	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2272	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2273 2274	/* DMA TX */2275	path = tunnel->paths[1];2276	KUNIT_ASSERT_EQ(test, path->path_length, 2);2277	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2278	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2279	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2280	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2281 2282	tb_tunnel_free(tunnel);2283}2284 2285static void tb_test_credit_alloc_dma_multiple(struct kunit *test)2286{2287	struct tb_tunnel *tunnel1, *tunnel2, *tunnel3;2288	struct tb_switch *host, *dev;2289	struct tb_port *nhi, *port;2290	struct tb_path *path;2291 2292	host = alloc_host_usb4(test);2293	dev = alloc_dev_usb4(test, host, 0x1, true);2294 2295	nhi = &host->ports[7];2296	port = &dev->ports[3];2297 2298	/*2299	 * Create three DMA tunnels through the same ports. With the2300	 * default buffers we should be able to create two and the last2301	 * one fails.2302	 *2303	 * For default host we have following buffers for DMA:2304	 *2305	 *   120 - (2 + 2 * (1 + 0) + 32 + 64 + spare) = 202306	 *2307	 * For device we have following:2308	 *2309	 *  120 - (2 + 2 * (1 + 18) + 14 + 32 + spare) = 342310	 *2311	 * spare = 14 + 1 = 152312	 *2313	 * So on host the first tunnel gets 14 and the second gets the2314	 * remaining 1 and then we run out of buffers.2315	 */2316	tunnel1 = tb_tunnel_alloc_dma(NULL, nhi, port, 8, 1, 8, 1);2317	KUNIT_ASSERT_NOT_NULL(test, tunnel1);2318	KUNIT_ASSERT_EQ(test, tunnel1->npaths, (size_t)2);2319 2320	path = tunnel1->paths[0];2321	KUNIT_ASSERT_EQ(test, path->path_length, 2);2322	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2323	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);2324	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2325	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2326 2327	path = tunnel1->paths[1];2328	KUNIT_ASSERT_EQ(test, path->path_length, 2);2329	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2330	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2331	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2332	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2333 2334	tunnel2 = tb_tunnel_alloc_dma(NULL, nhi, port, 9, 2, 9, 2);2335	KUNIT_ASSERT_NOT_NULL(test, tunnel2);2336	KUNIT_ASSERT_EQ(test, tunnel2->npaths, (size_t)2);2337 2338	path = tunnel2->paths[0];2339	KUNIT_ASSERT_EQ(test, path->path_length, 2);2340	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2341	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);2342	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2343	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2344 2345	path = tunnel2->paths[1];2346	KUNIT_ASSERT_EQ(test, path->path_length, 2);2347	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2348	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2349	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2350	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2351 2352	tunnel3 = tb_tunnel_alloc_dma(NULL, nhi, port, 10, 3, 10, 3);2353	KUNIT_ASSERT_NULL(test, tunnel3);2354 2355	/*2356	 * Release the first DMA tunnel. That should make 14 buffers2357	 * available for the next tunnel.2358	 */2359	tb_tunnel_free(tunnel1);2360 2361	tunnel3 = tb_tunnel_alloc_dma(NULL, nhi, port, 10, 3, 10, 3);2362	KUNIT_ASSERT_NOT_NULL(test, tunnel3);2363 2364	path = tunnel3->paths[0];2365	KUNIT_ASSERT_EQ(test, path->path_length, 2);2366	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2367	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);2368	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2369	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2370 2371	path = tunnel3->paths[1];2372	KUNIT_ASSERT_EQ(test, path->path_length, 2);2373	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2374	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2375	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2376	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2377 2378	tb_tunnel_free(tunnel3);2379	tb_tunnel_free(tunnel2);2380}2381 2382static struct tb_tunnel *TB_TEST_PCIE_TUNNEL(struct kunit *test,2383			struct tb_switch *host, struct tb_switch *dev)2384{2385	struct tb_port *up, *down;2386	struct tb_tunnel *pcie_tunnel;2387	struct tb_path *path;2388 2389	down = &host->ports[8];2390	up = &dev->ports[9];2391	pcie_tunnel = tb_tunnel_alloc_pci(NULL, up, down);2392	KUNIT_ASSERT_NOT_NULL(test, pcie_tunnel);2393	KUNIT_ASSERT_EQ(test, pcie_tunnel->npaths, (size_t)2);2394 2395	path = pcie_tunnel->paths[0];2396	KUNIT_ASSERT_EQ(test, path->path_length, 2);2397	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2398	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2399	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2400	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U);2401 2402	path = pcie_tunnel->paths[1];2403	KUNIT_ASSERT_EQ(test, path->path_length, 2);2404	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2405	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2406	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2407	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 64U);2408 2409	return pcie_tunnel;2410}2411 2412static struct tb_tunnel *TB_TEST_DP_TUNNEL1(struct kunit *test,2413			struct tb_switch *host, struct tb_switch *dev)2414{2415	struct tb_port *in, *out;2416	struct tb_tunnel *dp_tunnel1;2417	struct tb_path *path;2418 2419	in = &host->ports[5];2420	out = &dev->ports[13];2421	dp_tunnel1 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);2422	KUNIT_ASSERT_NOT_NULL(test, dp_tunnel1);2423	KUNIT_ASSERT_EQ(test, dp_tunnel1->npaths, (size_t)3);2424 2425	path = dp_tunnel1->paths[0];2426	KUNIT_ASSERT_EQ(test, path->path_length, 2);2427	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 12U);2428	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2429	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 18U);2430	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 0U);2431 2432	path = dp_tunnel1->paths[1];2433	KUNIT_ASSERT_EQ(test, path->path_length, 2);2434	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2435	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 1U);2436	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2437	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2438 2439	path = dp_tunnel1->paths[2];2440	KUNIT_ASSERT_EQ(test, path->path_length, 2);2441	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2442	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 1U);2443	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2444	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2445 2446	return dp_tunnel1;2447}2448 2449static struct tb_tunnel *TB_TEST_DP_TUNNEL2(struct kunit *test,2450			struct tb_switch *host, struct tb_switch *dev)2451{2452	struct tb_port *in, *out;2453	struct tb_tunnel *dp_tunnel2;2454	struct tb_path *path;2455 2456	in = &host->ports[6];2457	out = &dev->ports[14];2458	dp_tunnel2 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0);2459	KUNIT_ASSERT_NOT_NULL(test, dp_tunnel2);2460	KUNIT_ASSERT_EQ(test, dp_tunnel2->npaths, (size_t)3);2461 2462	path = dp_tunnel2->paths[0];2463	KUNIT_ASSERT_EQ(test, path->path_length, 2);2464	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 12U);2465	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2466	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 18U);2467	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 0U);2468 2469	path = dp_tunnel2->paths[1];2470	KUNIT_ASSERT_EQ(test, path->path_length, 2);2471	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2472	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 1U);2473	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2474	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2475 2476	path = dp_tunnel2->paths[2];2477	KUNIT_ASSERT_EQ(test, path->path_length, 2);2478	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2479	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 1U);2480	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2481	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2482 2483	return dp_tunnel2;2484}2485 2486static struct tb_tunnel *TB_TEST_USB3_TUNNEL(struct kunit *test,2487			struct tb_switch *host, struct tb_switch *dev)2488{2489	struct tb_port *up, *down;2490	struct tb_tunnel *usb3_tunnel;2491	struct tb_path *path;2492 2493	down = &host->ports[12];2494	up = &dev->ports[16];2495	usb3_tunnel = tb_tunnel_alloc_usb3(NULL, up, down, 0, 0);2496	KUNIT_ASSERT_NOT_NULL(test, usb3_tunnel);2497	KUNIT_ASSERT_EQ(test, usb3_tunnel->npaths, (size_t)2);2498 2499	path = usb3_tunnel->paths[0];2500	KUNIT_ASSERT_EQ(test, path->path_length, 2);2501	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2502	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2503	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2504	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2505 2506	path = usb3_tunnel->paths[1];2507	KUNIT_ASSERT_EQ(test, path->path_length, 2);2508	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2509	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 7U);2510	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2511	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U);2512 2513	return usb3_tunnel;2514}2515 2516static struct tb_tunnel *TB_TEST_DMA_TUNNEL1(struct kunit *test,2517			struct tb_switch *host, struct tb_switch *dev)2518{2519	struct tb_port *nhi, *port;2520	struct tb_tunnel *dma_tunnel1;2521	struct tb_path *path;2522 2523	nhi = &host->ports[7];2524	port = &dev->ports[3];2525	dma_tunnel1 = tb_tunnel_alloc_dma(NULL, nhi, port, 8, 1, 8, 1);2526	KUNIT_ASSERT_NOT_NULL(test, dma_tunnel1);2527	KUNIT_ASSERT_EQ(test, dma_tunnel1->npaths, (size_t)2);2528 2529	path = dma_tunnel1->paths[0];2530	KUNIT_ASSERT_EQ(test, path->path_length, 2);2531	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2532	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);2533	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2534	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2535 2536	path = dma_tunnel1->paths[1];2537	KUNIT_ASSERT_EQ(test, path->path_length, 2);2538	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2539	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2540	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2541	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U);2542 2543	return dma_tunnel1;2544}2545 2546static struct tb_tunnel *TB_TEST_DMA_TUNNEL2(struct kunit *test,2547			struct tb_switch *host, struct tb_switch *dev)2548{2549	struct tb_port *nhi, *port;2550	struct tb_tunnel *dma_tunnel2;2551	struct tb_path *path;2552 2553	nhi = &host->ports[7];2554	port = &dev->ports[3];2555	dma_tunnel2 = tb_tunnel_alloc_dma(NULL, nhi, port, 9, 2, 9, 2);2556	KUNIT_ASSERT_NOT_NULL(test, dma_tunnel2);2557	KUNIT_ASSERT_EQ(test, dma_tunnel2->npaths, (size_t)2);2558 2559	path = dma_tunnel2->paths[0];2560	KUNIT_ASSERT_EQ(test, path->path_length, 2);2561	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2562	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 14U);2563	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2564	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2565 2566	path = dma_tunnel2->paths[1];2567	KUNIT_ASSERT_EQ(test, path->path_length, 2);2568	KUNIT_EXPECT_EQ(test, path->hops[0].nfc_credits, 0U);2569	KUNIT_EXPECT_EQ(test, path->hops[0].initial_credits, 0U);2570	KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U);2571	KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U);2572 2573	return dma_tunnel2;2574}2575 2576static void tb_test_credit_alloc_all(struct kunit *test)2577{2578	struct tb_tunnel *pcie_tunnel, *dp_tunnel1, *dp_tunnel2, *usb3_tunnel;2579	struct tb_tunnel *dma_tunnel1, *dma_tunnel2;2580	struct tb_switch *host, *dev;2581 2582	/*2583	 * Create PCIe, 2 x DP, USB 3.x and two DMA tunnels from host to2584	 * device. Expectation is that all these can be established with2585	 * the default credit allocation found in Intel hardware.2586	 */2587 2588	host = alloc_host_usb4(test);2589	dev = alloc_dev_usb4(test, host, 0x1, true);2590 2591	pcie_tunnel = TB_TEST_PCIE_TUNNEL(test, host, dev);2592	dp_tunnel1 = TB_TEST_DP_TUNNEL1(test, host, dev);2593	dp_tunnel2 = TB_TEST_DP_TUNNEL2(test, host, dev);2594	usb3_tunnel = TB_TEST_USB3_TUNNEL(test, host, dev);2595	dma_tunnel1 = TB_TEST_DMA_TUNNEL1(test, host, dev);2596	dma_tunnel2 = TB_TEST_DMA_TUNNEL2(test, host, dev);2597 2598	tb_tunnel_free(dma_tunnel2);2599	tb_tunnel_free(dma_tunnel1);2600	tb_tunnel_free(usb3_tunnel);2601	tb_tunnel_free(dp_tunnel2);2602	tb_tunnel_free(dp_tunnel1);2603	tb_tunnel_free(pcie_tunnel);2604}2605 2606static const u32 root_directory[] = {2607	0x55584401,	/* "UXD" v1 */2608	0x00000018,	/* Root directory length */2609	0x76656e64,	/* "vend" */2610	0x6f726964,	/* "orid" */2611	0x76000001,	/* "v" R 1 */2612	0x00000a27,	/* Immediate value, ! Vendor ID */2613	0x76656e64,	/* "vend" */2614	0x6f726964,	/* "orid" */2615	0x74000003,	/* "t" R 3 */2616	0x0000001a,	/* Text leaf offset, (“Apple Inc.”) */2617	0x64657669,	/* "devi" */2618	0x63656964,	/* "ceid" */2619	0x76000001,	/* "v" R 1 */2620	0x0000000a,	/* Immediate value, ! Device ID */2621	0x64657669,	/* "devi" */2622	0x63656964,	/* "ceid" */2623	0x74000003,	/* "t" R 3 */2624	0x0000001d,	/* Text leaf offset, (“Macintosh”) */2625	0x64657669,	/* "devi" */2626	0x63657276,	/* "cerv" */2627	0x76000001,	/* "v" R 1 */2628	0x80000100,	/* Immediate value, Device Revision */2629	0x6e657477,	/* "netw" */2630	0x6f726b00,	/* "ork" */2631	0x44000014,	/* "D" R 20 */2632	0x00000021,	/* Directory data offset, (Network Directory) */2633	0x4170706c,	/* "Appl" */2634	0x6520496e,	/* "e In" */2635	0x632e0000,	/* "c." ! */2636	0x4d616369,	/* "Maci" */2637	0x6e746f73,	/* "ntos" */2638	0x68000000,	/* "h" */2639	0x00000000,	/* padding */2640	0xca8961c6,	/* Directory UUID, Network Directory */2641	0x9541ce1c,	/* Directory UUID, Network Directory */2642	0x5949b8bd,	/* Directory UUID, Network Directory */2643	0x4f5a5f2e,	/* Directory UUID, Network Directory */2644	0x70727463,	/* "prtc" */2645	0x69640000,	/* "id" */2646	0x76000001,	/* "v" R 1 */2647	0x00000001,	/* Immediate value, Network Protocol ID */2648	0x70727463,	/* "prtc" */2649	0x76657273,	/* "vers" */2650	0x76000001,	/* "v" R 1 */2651	0x00000001,	/* Immediate value, Network Protocol Version */2652	0x70727463,	/* "prtc" */2653	0x72657673,	/* "revs" */2654	0x76000001,	/* "v" R 1 */2655	0x00000001,	/* Immediate value, Network Protocol Revision */2656	0x70727463,	/* "prtc" */2657	0x73746e73,	/* "stns" */2658	0x76000001,	/* "v" R 1 */2659	0x00000000,	/* Immediate value, Network Protocol Settings */2660};2661 2662static const uuid_t network_dir_uuid =2663	UUID_INIT(0xc66189ca, 0x1cce, 0x4195,2664		  0xbd, 0xb8, 0x49, 0x59, 0x2e, 0x5f, 0x5a, 0x4f);2665 2666static void tb_test_property_parse(struct kunit *test)2667{2668	struct tb_property_dir *dir, *network_dir;2669	struct tb_property *p;2670 2671	dir = tb_property_parse_dir(root_directory, ARRAY_SIZE(root_directory));2672	KUNIT_ASSERT_NOT_NULL(test, dir);2673 2674	p = tb_property_find(dir, "foo", TB_PROPERTY_TYPE_TEXT);2675	KUNIT_ASSERT_NULL(test, p);2676 2677	p = tb_property_find(dir, "vendorid", TB_PROPERTY_TYPE_TEXT);2678	KUNIT_ASSERT_NOT_NULL(test, p);2679	KUNIT_EXPECT_STREQ(test, p->value.text, "Apple Inc.");2680 2681	p = tb_property_find(dir, "vendorid", TB_PROPERTY_TYPE_VALUE);2682	KUNIT_ASSERT_NOT_NULL(test, p);2683	KUNIT_EXPECT_EQ(test, p->value.immediate, 0xa27);2684 2685	p = tb_property_find(dir, "deviceid", TB_PROPERTY_TYPE_TEXT);2686	KUNIT_ASSERT_NOT_NULL(test, p);2687	KUNIT_EXPECT_STREQ(test, p->value.text, "Macintosh");2688 2689	p = tb_property_find(dir, "deviceid", TB_PROPERTY_TYPE_VALUE);2690	KUNIT_ASSERT_NOT_NULL(test, p);2691	KUNIT_EXPECT_EQ(test, p->value.immediate, 0xa);2692 2693	p = tb_property_find(dir, "missing", TB_PROPERTY_TYPE_DIRECTORY);2694	KUNIT_ASSERT_NULL(test, p);2695 2696	p = tb_property_find(dir, "network", TB_PROPERTY_TYPE_DIRECTORY);2697	KUNIT_ASSERT_NOT_NULL(test, p);2698 2699	network_dir = p->value.dir;2700	KUNIT_EXPECT_TRUE(test, uuid_equal(network_dir->uuid, &network_dir_uuid));2701 2702	p = tb_property_find(network_dir, "prtcid", TB_PROPERTY_TYPE_VALUE);2703	KUNIT_ASSERT_NOT_NULL(test, p);2704	KUNIT_EXPECT_EQ(test, p->value.immediate, 0x1);2705 2706	p = tb_property_find(network_dir, "prtcvers", TB_PROPERTY_TYPE_VALUE);2707	KUNIT_ASSERT_NOT_NULL(test, p);2708	KUNIT_EXPECT_EQ(test, p->value.immediate, 0x1);2709 2710	p = tb_property_find(network_dir, "prtcrevs", TB_PROPERTY_TYPE_VALUE);2711	KUNIT_ASSERT_NOT_NULL(test, p);2712	KUNIT_EXPECT_EQ(test, p->value.immediate, 0x1);2713 2714	p = tb_property_find(network_dir, "prtcstns", TB_PROPERTY_TYPE_VALUE);2715	KUNIT_ASSERT_NOT_NULL(test, p);2716	KUNIT_EXPECT_EQ(test, p->value.immediate, 0x0);2717 2718	p = tb_property_find(network_dir, "deviceid", TB_PROPERTY_TYPE_VALUE);2719	KUNIT_EXPECT_TRUE(test, !p);2720	p = tb_property_find(network_dir, "deviceid", TB_PROPERTY_TYPE_TEXT);2721	KUNIT_EXPECT_TRUE(test, !p);2722 2723	tb_property_free_dir(dir);2724}2725 2726static void tb_test_property_format(struct kunit *test)2727{2728	struct tb_property_dir *dir;2729	ssize_t block_len;2730	u32 *block;2731	int ret, i;2732 2733	dir = tb_property_parse_dir(root_directory, ARRAY_SIZE(root_directory));2734	KUNIT_ASSERT_NOT_NULL(test, dir);2735 2736	ret = tb_property_format_dir(dir, NULL, 0);2737	KUNIT_ASSERT_EQ(test, ret, ARRAY_SIZE(root_directory));2738 2739	block_len = ret;2740 2741	block = kunit_kzalloc(test, block_len * sizeof(u32), GFP_KERNEL);2742	KUNIT_ASSERT_NOT_NULL(test, block);2743 2744	ret = tb_property_format_dir(dir, block, block_len);2745	KUNIT_EXPECT_EQ(test, ret, 0);2746 2747	for (i = 0; i < ARRAY_SIZE(root_directory); i++)2748		KUNIT_EXPECT_EQ(test, root_directory[i], block[i]);2749 2750	tb_property_free_dir(dir);2751}2752 2753static void compare_dirs(struct kunit *test, struct tb_property_dir *d1,2754			 struct tb_property_dir *d2)2755{2756	struct tb_property *p1, *p2, *tmp;2757	int n1, n2, i;2758 2759	if (d1->uuid) {2760		KUNIT_ASSERT_NOT_NULL(test, d2->uuid);2761		KUNIT_ASSERT_TRUE(test, uuid_equal(d1->uuid, d2->uuid));2762	} else {2763		KUNIT_ASSERT_NULL(test, d2->uuid);2764	}2765 2766	n1 = 0;2767	tb_property_for_each(d1, tmp)2768		n1++;2769	KUNIT_ASSERT_NE(test, n1, 0);2770 2771	n2 = 0;2772	tb_property_for_each(d2, tmp)2773		n2++;2774	KUNIT_ASSERT_NE(test, n2, 0);2775 2776	KUNIT_ASSERT_EQ(test, n1, n2);2777 2778	p1 = NULL;2779	p2 = NULL;2780	for (i = 0; i < n1; i++) {2781		p1 = tb_property_get_next(d1, p1);2782		KUNIT_ASSERT_NOT_NULL(test, p1);2783		p2 = tb_property_get_next(d2, p2);2784		KUNIT_ASSERT_NOT_NULL(test, p2);2785 2786		KUNIT_ASSERT_STREQ(test, &p1->key[0], &p2->key[0]);2787		KUNIT_ASSERT_EQ(test, p1->type, p2->type);2788		KUNIT_ASSERT_EQ(test, p1->length, p2->length);2789 2790		switch (p1->type) {2791		case TB_PROPERTY_TYPE_DIRECTORY:2792			KUNIT_ASSERT_NOT_NULL(test, p1->value.dir);2793			KUNIT_ASSERT_NOT_NULL(test, p2->value.dir);2794			compare_dirs(test, p1->value.dir, p2->value.dir);2795			break;2796 2797		case TB_PROPERTY_TYPE_DATA:2798			KUNIT_ASSERT_NOT_NULL(test, p1->value.data);2799			KUNIT_ASSERT_NOT_NULL(test, p2->value.data);2800			KUNIT_ASSERT_TRUE(test,2801				!memcmp(p1->value.data, p2->value.data,2802					p1->length * 4)2803			);2804			break;2805 2806		case TB_PROPERTY_TYPE_TEXT:2807			KUNIT_ASSERT_NOT_NULL(test, p1->value.text);2808			KUNIT_ASSERT_NOT_NULL(test, p2->value.text);2809			KUNIT_ASSERT_STREQ(test, p1->value.text, p2->value.text);2810			break;2811 2812		case TB_PROPERTY_TYPE_VALUE:2813			KUNIT_ASSERT_EQ(test, p1->value.immediate,2814					p2->value.immediate);2815			break;2816		default:2817			KUNIT_FAIL(test, "unexpected property type");2818			break;2819		}2820	}2821}2822 2823static void tb_test_property_copy(struct kunit *test)2824{2825	struct tb_property_dir *src, *dst;2826	u32 *block;2827	int ret, i;2828 2829	src = tb_property_parse_dir(root_directory, ARRAY_SIZE(root_directory));2830	KUNIT_ASSERT_NOT_NULL(test, src);2831 2832	dst = tb_property_copy_dir(src);2833	KUNIT_ASSERT_NOT_NULL(test, dst);2834 2835	/* Compare the structures */2836	compare_dirs(test, src, dst);2837 2838	/* Compare the resulting property block */2839	ret = tb_property_format_dir(dst, NULL, 0);2840	KUNIT_ASSERT_EQ(test, ret, ARRAY_SIZE(root_directory));2841 2842	block = kunit_kzalloc(test, sizeof(root_directory), GFP_KERNEL);2843	KUNIT_ASSERT_NOT_NULL(test, block);2844 2845	ret = tb_property_format_dir(dst, block, ARRAY_SIZE(root_directory));2846	KUNIT_EXPECT_TRUE(test, !ret);2847 2848	for (i = 0; i < ARRAY_SIZE(root_directory); i++)2849		KUNIT_EXPECT_EQ(test, root_directory[i], block[i]);2850 2851	tb_property_free_dir(dst);2852	tb_property_free_dir(src);2853}2854 2855static struct kunit_case tb_test_cases[] = {2856	KUNIT_CASE(tb_test_path_basic),2857	KUNIT_CASE(tb_test_path_not_connected_walk),2858	KUNIT_CASE(tb_test_path_single_hop_walk),2859	KUNIT_CASE(tb_test_path_daisy_chain_walk),2860	KUNIT_CASE(tb_test_path_simple_tree_walk),2861	KUNIT_CASE(tb_test_path_complex_tree_walk),2862	KUNIT_CASE(tb_test_path_max_length_walk),2863	KUNIT_CASE(tb_test_path_not_connected),2864	KUNIT_CASE(tb_test_path_not_bonded_lane0),2865	KUNIT_CASE(tb_test_path_not_bonded_lane1),2866	KUNIT_CASE(tb_test_path_not_bonded_lane1_chain),2867	KUNIT_CASE(tb_test_path_not_bonded_lane1_chain_reverse),2868	KUNIT_CASE(tb_test_path_mixed_chain),2869	KUNIT_CASE(tb_test_path_mixed_chain_reverse),2870	KUNIT_CASE(tb_test_tunnel_pcie),2871	KUNIT_CASE(tb_test_tunnel_dp),2872	KUNIT_CASE(tb_test_tunnel_dp_chain),2873	KUNIT_CASE(tb_test_tunnel_dp_tree),2874	KUNIT_CASE(tb_test_tunnel_dp_max_length),2875	KUNIT_CASE(tb_test_tunnel_3dp),2876	KUNIT_CASE(tb_test_tunnel_port_on_path),2877	KUNIT_CASE(tb_test_tunnel_usb3),2878	KUNIT_CASE(tb_test_tunnel_dma),2879	KUNIT_CASE(tb_test_tunnel_dma_rx),2880	KUNIT_CASE(tb_test_tunnel_dma_tx),2881	KUNIT_CASE(tb_test_tunnel_dma_chain),2882	KUNIT_CASE(tb_test_tunnel_dma_match),2883	KUNIT_CASE(tb_test_credit_alloc_legacy_not_bonded),2884	KUNIT_CASE(tb_test_credit_alloc_legacy_bonded),2885	KUNIT_CASE(tb_test_credit_alloc_pcie),2886	KUNIT_CASE(tb_test_credit_alloc_without_dp),2887	KUNIT_CASE(tb_test_credit_alloc_dp),2888	KUNIT_CASE(tb_test_credit_alloc_usb3),2889	KUNIT_CASE(tb_test_credit_alloc_dma),2890	KUNIT_CASE(tb_test_credit_alloc_dma_multiple),2891	KUNIT_CASE(tb_test_credit_alloc_all),2892	KUNIT_CASE(tb_test_property_parse),2893	KUNIT_CASE(tb_test_property_format),2894	KUNIT_CASE(tb_test_property_copy),2895	{ }2896};2897 2898static struct kunit_suite tb_test_suite = {2899	.name = "thunderbolt",2900	.test_cases = tb_test_cases,2901};2902 2903kunit_test_suite(tb_test_suite);2904