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