2020-04-29 16:38:39 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* KUnit tests
*
* Copyright ( C ) 2020 , Intel Corporation
* Author : Mika Westerberg < mika . westerberg @ linux . intel . com >
*/
# include <kunit/test.h>
# include <linux/idr.h>
# include "tb.h"
2020-05-04 17:10:40 +03:00
# include "tunnel.h"
2020-04-29 16:38:39 +03:00
static int __ida_init ( struct kunit_resource * res , void * context )
{
struct ida * ida = context ;
ida_init ( ida ) ;
2020-06-30 08:51:50 +03:00
res - > data = ida ;
2020-04-29 16:38:39 +03:00
return 0 ;
}
static void __ida_destroy ( struct kunit_resource * res )
{
2020-06-30 08:51:50 +03:00
struct ida * ida = res - > data ;
2020-04-29 16:38:39 +03:00
ida_destroy ( ida ) ;
}
static void kunit_ida_init ( struct kunit * test , struct ida * ida )
{
kunit_alloc_resource ( test , __ida_init , __ida_destroy , GFP_KERNEL , ida ) ;
}
static struct tb_switch * alloc_switch ( struct kunit * test , u64 route ,
u8 upstream_port , u8 max_port_number )
{
struct tb_switch * sw ;
size_t size ;
int i ;
sw = kunit_kzalloc ( test , sizeof ( * sw ) , GFP_KERNEL ) ;
if ( ! sw )
return NULL ;
sw - > config . upstream_port_number = upstream_port ;
sw - > config . depth = tb_route_length ( route ) ;
sw - > config . route_hi = upper_32_bits ( route ) ;
sw - > config . route_lo = lower_32_bits ( route ) ;
sw - > config . enabled = 0 ;
sw - > config . max_port_number = max_port_number ;
size = ( sw - > config . max_port_number + 1 ) * sizeof ( * sw - > ports ) ;
sw - > ports = kunit_kzalloc ( test , size , GFP_KERNEL ) ;
if ( ! sw - > ports )
return NULL ;
for ( i = 0 ; i < = sw - > config . max_port_number ; i + + ) {
sw - > ports [ i ] . sw = sw ;
sw - > ports [ i ] . port = i ;
sw - > ports [ i ] . config . port_number = i ;
if ( i ) {
kunit_ida_init ( test , & sw - > ports [ i ] . in_hopids ) ;
kunit_ida_init ( test , & sw - > ports [ i ] . out_hopids ) ;
}
}
return sw ;
}
static struct tb_switch * alloc_host ( struct kunit * test )
{
struct tb_switch * sw ;
sw = alloc_switch ( test , 0 , 7 , 13 ) ;
if ( ! sw )
return NULL ;
sw - > config . vendor_id = 0x8086 ;
sw - > config . device_id = 0x9a1b ;
sw - > ports [ 0 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 0 ] . config . max_in_hop_id = 7 ;
sw - > ports [ 0 ] . config . max_out_hop_id = 7 ;
sw - > ports [ 1 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 1 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 1 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 1 ] . total_credits = 60 ;
sw - > ports [ 1 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 1 ] . dual_link_port = & sw - > ports [ 2 ] ;
sw - > ports [ 2 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 2 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 2 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 2 ] . total_credits = 60 ;
sw - > ports [ 2 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 2 ] . dual_link_port = & sw - > ports [ 1 ] ;
sw - > ports [ 2 ] . link_nr = 1 ;
sw - > ports [ 3 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 3 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 3 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 3 ] . total_credits = 60 ;
sw - > ports [ 3 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 3 ] . dual_link_port = & sw - > ports [ 4 ] ;
sw - > ports [ 4 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 4 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 4 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 4 ] . total_credits = 60 ;
sw - > ports [ 4 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 4 ] . dual_link_port = & sw - > ports [ 3 ] ;
sw - > ports [ 4 ] . link_nr = 1 ;
sw - > ports [ 5 ] . config . type = TB_TYPE_DP_HDMI_IN ;
sw - > ports [ 5 ] . config . max_in_hop_id = 9 ;
sw - > ports [ 5 ] . config . max_out_hop_id = 9 ;
sw - > ports [ 5 ] . cap_adap = - 1 ;
sw - > ports [ 6 ] . config . type = TB_TYPE_DP_HDMI_IN ;
sw - > ports [ 6 ] . config . max_in_hop_id = 9 ;
sw - > ports [ 6 ] . config . max_out_hop_id = 9 ;
sw - > ports [ 6 ] . cap_adap = - 1 ;
sw - > ports [ 7 ] . config . type = TB_TYPE_NHI ;
sw - > ports [ 7 ] . config . max_in_hop_id = 11 ;
sw - > ports [ 7 ] . config . max_out_hop_id = 11 ;
2021-01-08 17:32:19 +03:00
sw - > ports [ 7 ] . config . nfc_credits = 0x41800000 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 8 ] . config . type = TB_TYPE_PCIE_DOWN ;
sw - > ports [ 8 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 8 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 9 ] . config . type = TB_TYPE_PCIE_DOWN ;
sw - > ports [ 9 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 9 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 10 ] . disabled = true ;
sw - > ports [ 11 ] . disabled = true ;
sw - > ports [ 12 ] . config . type = TB_TYPE_USB3_DOWN ;
sw - > ports [ 12 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 12 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 13 ] . config . type = TB_TYPE_USB3_DOWN ;
sw - > ports [ 13 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 13 ] . config . max_out_hop_id = 8 ;
return sw ;
}
2021-04-28 19:04:02 +03:00
static struct tb_switch * alloc_host_usb4 ( struct kunit * test )
{
struct tb_switch * sw ;
sw = alloc_host ( test ) ;
if ( ! sw )
return NULL ;
sw - > generation = 4 ;
sw - > credit_allocation = true ;
sw - > max_usb3_credits = 32 ;
sw - > min_dp_aux_credits = 1 ;
sw - > min_dp_main_credits = 0 ;
sw - > max_pcie_credits = 64 ;
sw - > max_dma_credits = 14 ;
return sw ;
}
2022-02-14 15:09:50 +03:00
static struct tb_switch * alloc_host_br ( struct kunit * test )
{
struct tb_switch * sw ;
sw = alloc_host_usb4 ( test ) ;
if ( ! sw )
return NULL ;
sw - > ports [ 10 ] . config . type = TB_TYPE_DP_HDMI_IN ;
sw - > ports [ 10 ] . config . max_in_hop_id = 9 ;
sw - > ports [ 10 ] . config . max_out_hop_id = 9 ;
sw - > ports [ 10 ] . cap_adap = - 1 ;
sw - > ports [ 10 ] . disabled = false ;
return sw ;
}
2020-04-29 16:38:39 +03:00
static struct tb_switch * alloc_dev_default ( struct kunit * test ,
struct tb_switch * parent ,
u64 route , bool bonded )
{
struct tb_port * port , * upstream_port ;
struct tb_switch * sw ;
sw = alloc_switch ( test , route , 1 , 19 ) ;
if ( ! sw )
return NULL ;
sw - > config . vendor_id = 0x8086 ;
sw - > config . device_id = 0x15ef ;
sw - > ports [ 0 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 0 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 0 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 1 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 1 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 1 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 1 ] . total_credits = 60 ;
sw - > ports [ 1 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 1 ] . dual_link_port = & sw - > ports [ 2 ] ;
sw - > ports [ 2 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 2 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 2 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 2 ] . total_credits = 60 ;
sw - > ports [ 2 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 2 ] . dual_link_port = & sw - > ports [ 1 ] ;
sw - > ports [ 2 ] . link_nr = 1 ;
sw - > ports [ 3 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 3 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 3 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 3 ] . total_credits = 60 ;
sw - > ports [ 3 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 3 ] . dual_link_port = & sw - > ports [ 4 ] ;
sw - > ports [ 4 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 4 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 4 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 4 ] . total_credits = 60 ;
sw - > ports [ 4 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 4 ] . dual_link_port = & sw - > ports [ 3 ] ;
sw - > ports [ 4 ] . link_nr = 1 ;
sw - > ports [ 5 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 5 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 5 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 5 ] . total_credits = 60 ;
sw - > ports [ 5 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 5 ] . dual_link_port = & sw - > ports [ 6 ] ;
sw - > ports [ 6 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 6 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 6 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 6 ] . total_credits = 60 ;
sw - > ports [ 6 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 6 ] . dual_link_port = & sw - > ports [ 5 ] ;
sw - > ports [ 6 ] . link_nr = 1 ;
sw - > ports [ 7 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 7 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 7 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 7 ] . total_credits = 60 ;
sw - > ports [ 7 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 7 ] . dual_link_port = & sw - > ports [ 8 ] ;
sw - > ports [ 8 ] . config . type = TB_TYPE_PORT ;
sw - > ports [ 8 ] . config . max_in_hop_id = 19 ;
sw - > ports [ 8 ] . config . max_out_hop_id = 19 ;
2021-04-28 19:04:02 +03:00
sw - > ports [ 8 ] . total_credits = 60 ;
sw - > ports [ 8 ] . ctl_credits = 2 ;
2020-04-29 16:38:39 +03:00
sw - > ports [ 8 ] . dual_link_port = & sw - > ports [ 7 ] ;
sw - > ports [ 8 ] . link_nr = 1 ;
sw - > ports [ 9 ] . config . type = TB_TYPE_PCIE_UP ;
sw - > ports [ 9 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 9 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 10 ] . config . type = TB_TYPE_PCIE_DOWN ;
sw - > ports [ 10 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 10 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 11 ] . config . type = TB_TYPE_PCIE_DOWN ;
sw - > ports [ 11 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 11 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 12 ] . config . type = TB_TYPE_PCIE_DOWN ;
sw - > ports [ 12 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 12 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 13 ] . config . type = TB_TYPE_DP_HDMI_OUT ;
sw - > ports [ 13 ] . config . max_in_hop_id = 9 ;
sw - > ports [ 13 ] . config . max_out_hop_id = 9 ;
sw - > ports [ 13 ] . cap_adap = - 1 ;
sw - > ports [ 14 ] . config . type = TB_TYPE_DP_HDMI_OUT ;
sw - > ports [ 14 ] . config . max_in_hop_id = 9 ;
sw - > ports [ 14 ] . config . max_out_hop_id = 9 ;
sw - > ports [ 14 ] . cap_adap = - 1 ;
sw - > ports [ 15 ] . disabled = true ;
sw - > ports [ 16 ] . config . type = TB_TYPE_USB3_UP ;
sw - > ports [ 16 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 16 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 17 ] . config . type = TB_TYPE_USB3_DOWN ;
sw - > ports [ 17 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 17 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 18 ] . config . type = TB_TYPE_USB3_DOWN ;
sw - > ports [ 18 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 18 ] . config . max_out_hop_id = 8 ;
sw - > ports [ 19 ] . config . type = TB_TYPE_USB3_DOWN ;
sw - > ports [ 19 ] . config . max_in_hop_id = 8 ;
sw - > ports [ 19 ] . config . max_out_hop_id = 8 ;
if ( ! parent )
return sw ;
/* Link them */
upstream_port = tb_upstream_port ( sw ) ;
port = tb_port_at ( route , parent ) ;
port - > remote = upstream_port ;
upstream_port - > remote = port ;
if ( port - > dual_link_port & & upstream_port - > dual_link_port ) {
port - > dual_link_port - > remote = upstream_port - > dual_link_port ;
upstream_port - > dual_link_port - > remote = port - > dual_link_port ;
2021-06-07 13:37:46 +03:00
if ( bonded ) {
/* Bonding is used */
port - > bonded = true ;
port - > total_credits * = 2 ;
port - > dual_link_port - > bonded = true ;
port - > dual_link_port - > total_credits = 0 ;
upstream_port - > bonded = true ;
upstream_port - > total_credits * = 2 ;
upstream_port - > dual_link_port - > bonded = true ;
upstream_port - > dual_link_port - > total_credits = 0 ;
}
2020-04-29 16:38:39 +03:00
}
return sw ;
}
static struct tb_switch * alloc_dev_with_dpin ( struct kunit * test ,
struct tb_switch * parent ,
u64 route , bool bonded )
{
struct tb_switch * sw ;
sw = alloc_dev_default ( test , parent , route , bonded ) ;
if ( ! sw )
return NULL ;
sw - > ports [ 13 ] . config . type = TB_TYPE_DP_HDMI_IN ;
sw - > ports [ 13 ] . config . max_in_hop_id = 9 ;
sw - > ports [ 13 ] . config . max_out_hop_id = 9 ;
sw - > ports [ 14 ] . config . type = TB_TYPE_DP_HDMI_IN ;
sw - > ports [ 14 ] . config . max_in_hop_id = 9 ;
sw - > ports [ 14 ] . config . max_out_hop_id = 9 ;
return sw ;
}
2022-05-09 23:49:04 +03:00
static struct tb_switch * alloc_dev_without_dp ( struct kunit * test ,
struct tb_switch * parent ,
u64 route , bool bonded )
{
struct tb_switch * sw ;
int i ;
sw = alloc_dev_default ( test , parent , route , bonded ) ;
if ( ! sw )
return NULL ;
/*
* Device with :
* 2 x USB4 Adapters ( adapters 1 , 2 and 3 , 4 ) ,
* 1 x PCIe Upstream ( adapter 9 ) ,
* 1 x PCIe Downstream ( adapter 10 ) ,
* 1 x USB3 Upstream ( adapter 16 ) ,
* 1 x USB3 Downstream ( adapter 17 )
*/
for ( i = 5 ; i < = 8 ; i + + )
sw - > ports [ i ] . disabled = true ;
for ( i = 11 ; i < = 14 ; i + + )
sw - > ports [ i ] . disabled = true ;
sw - > ports [ 13 ] . cap_adap = 0 ;
sw - > ports [ 14 ] . cap_adap = 0 ;
for ( i = 18 ; i < = 19 ; i + + )
sw - > ports [ i ] . disabled = true ;
sw - > generation = 4 ;
sw - > credit_allocation = true ;
sw - > max_usb3_credits = 109 ;
sw - > min_dp_aux_credits = 0 ;
sw - > min_dp_main_credits = 0 ;
sw - > max_pcie_credits = 30 ;
sw - > max_dma_credits = 1 ;
return sw ;
}
2021-04-28 19:04:02 +03:00
static struct tb_switch * alloc_dev_usb4 ( struct kunit * test ,
struct tb_switch * parent ,
u64 route , bool bonded )
{
struct tb_switch * sw ;
sw = alloc_dev_default ( test , parent , route , bonded ) ;
if ( ! sw )
return NULL ;
sw - > generation = 4 ;
sw - > credit_allocation = true ;
sw - > max_usb3_credits = 14 ;
sw - > min_dp_aux_credits = 1 ;
sw - > min_dp_main_credits = 18 ;
sw - > max_pcie_credits = 32 ;
sw - > max_dma_credits = 14 ;
return sw ;
}
2020-04-29 16:38:39 +03:00
static void tb_test_path_basic ( struct kunit * test )
{
struct tb_port * src_port , * dst_port , * p ;
struct tb_switch * host ;
host = alloc_host ( test ) ;
src_port = & host - > ports [ 5 ] ;
dst_port = src_port ;
p = tb_next_port_on_path ( src_port , dst_port , NULL ) ;
KUNIT_EXPECT_PTR_EQ ( test , p , dst_port ) ;
p = tb_next_port_on_path ( src_port , dst_port , p ) ;
KUNIT_EXPECT_TRUE ( test , ! p ) ;
}
static void tb_test_path_not_connected_walk ( struct kunit * test )
{
struct tb_port * src_port , * dst_port , * p ;
struct tb_switch * host , * dev ;
host = alloc_host ( test ) ;
/* No connection between host and dev */
dev = alloc_dev_default ( test , NULL , 3 , true ) ;
src_port = & host - > ports [ 12 ] ;
dst_port = & dev - > ports [ 16 ] ;
p = tb_next_port_on_path ( src_port , dst_port , NULL ) ;
KUNIT_EXPECT_PTR_EQ ( test , p , src_port ) ;
p = tb_next_port_on_path ( src_port , dst_port , p ) ;
KUNIT_EXPECT_PTR_EQ ( test , p , & host - > ports [ 3 ] ) ;
p = tb_next_port_on_path ( src_port , dst_port , p ) ;
KUNIT_EXPECT_TRUE ( test , ! p ) ;
/* Other direction */
p = tb_next_port_on_path ( dst_port , src_port , NULL ) ;
KUNIT_EXPECT_PTR_EQ ( test , p , dst_port ) ;
p = tb_next_port_on_path ( dst_port , src_port , p ) ;
KUNIT_EXPECT_PTR_EQ ( test , p , & dev - > ports [ 1 ] ) ;
p = tb_next_port_on_path ( dst_port , src_port , p ) ;
KUNIT_EXPECT_TRUE ( test , ! p ) ;
}
struct port_expectation {
u64 route ;
u8 port ;
enum tb_port_type type ;
} ;
static void tb_test_path_single_hop_walk ( struct kunit * test )
{
/*
* Walks from Host PCIe downstream port to Device # 1 PCIe
* upstream port .
*
* [ Host ]
* 1 |
* 1 |
* [ Device ]
*/
static const struct port_expectation test_data [ ] = {
{ . route = 0x0 , . port = 8 , . type = TB_TYPE_PCIE_DOWN } ,
{ . route = 0x0 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 9 , . type = TB_TYPE_PCIE_UP } ,
} ;
struct tb_port * src_port , * dst_port , * p ;
struct tb_switch * host , * dev ;
int i ;
host = alloc_host ( test ) ;
dev = alloc_dev_default ( test , host , 1 , true ) ;
src_port = & host - > ports [ 8 ] ;
dst_port = & dev - > ports [ 9 ] ;
/* Walk both directions */
i = 0 ;
tb_for_each_port_on_path ( src_port , dst_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i + + ;
}
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , i , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
i = ARRAY_SIZE ( test_data ) - 1 ;
tb_for_each_port_on_path ( dst_port , src_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i - - ;
}
KUNIT_EXPECT_EQ ( test , i , - 1 ) ;
}
static void tb_test_path_daisy_chain_walk ( struct kunit * test )
{
/*
* Walks from Host DP IN to Device # 2 DP OUT .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* 3 /
* 1 /
* [ Device # 2 ]
*/
static const struct port_expectation test_data [ ] = {
{ . route = 0x0 , . port = 5 , . type = TB_TYPE_DP_HDMI_IN } ,
{ . route = 0x0 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x301 , . port = 13 , . type = TB_TYPE_DP_HDMI_OUT } ,
} ;
struct tb_port * src_port , * dst_port , * p ;
struct tb_switch * host , * dev1 , * dev2 ;
int i ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x301 , true ) ;
src_port = & host - > ports [ 5 ] ;
dst_port = & dev2 - > ports [ 13 ] ;
/* Walk both directions */
i = 0 ;
tb_for_each_port_on_path ( src_port , dst_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i + + ;
}
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , i , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
i = ARRAY_SIZE ( test_data ) - 1 ;
tb_for_each_port_on_path ( dst_port , src_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i - - ;
}
KUNIT_EXPECT_EQ ( test , i , - 1 ) ;
}
static void tb_test_path_simple_tree_walk ( struct kunit * test )
{
/*
* Walks from Host DP IN to Device # 3 DP OUT .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* 3 / | 5 \ 7
* 1 / | \ 1
* [ Device # 2 ] | [ Device # 4 ]
* | 1
* [ Device # 3 ]
*/
static const struct port_expectation test_data [ ] = {
{ . route = 0x0 , . port = 5 , . type = TB_TYPE_DP_HDMI_IN } ,
{ . route = 0x0 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 5 , . type = TB_TYPE_PORT } ,
{ . route = 0x501 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x501 , . port = 13 , . type = TB_TYPE_DP_HDMI_OUT } ,
} ;
struct tb_port * src_port , * dst_port , * p ;
struct tb_switch * host , * dev1 , * dev3 ;
int i ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
alloc_dev_default ( test , dev1 , 0x301 , true ) ;
dev3 = alloc_dev_default ( test , dev1 , 0x501 , true ) ;
alloc_dev_default ( test , dev1 , 0x701 , true ) ;
src_port = & host - > ports [ 5 ] ;
dst_port = & dev3 - > ports [ 13 ] ;
/* Walk both directions */
i = 0 ;
tb_for_each_port_on_path ( src_port , dst_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i + + ;
}
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , i , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
i = ARRAY_SIZE ( test_data ) - 1 ;
tb_for_each_port_on_path ( dst_port , src_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i - - ;
}
KUNIT_EXPECT_EQ ( test , i , - 1 ) ;
}
static void tb_test_path_complex_tree_walk ( struct kunit * test )
{
/*
* Walks from Device # 3 DP IN to Device # 9 DP OUT .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* 3 / | 5 \ 7
* 1 / | \ 1
* [ Device # 2 ] | [ Device # 5 ]
* 5 | | 1 \ 7
* 1 | [ Device # 4 ] \ 1
* [ Device # 3 ] [ Device # 6 ]
* 3 /
* 1 /
* [ Device # 7 ]
* 3 / | 5
* 1 / |
* [ Device # 8 ] | 1
* [ Device # 9 ]
*/
static const struct port_expectation test_data [ ] = {
{ . route = 0x50301 , . port = 13 , . type = TB_TYPE_DP_HDMI_IN } ,
{ . route = 0x50301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x301 , . port = 5 , . type = TB_TYPE_PORT } ,
{ . route = 0x301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 7 , . type = TB_TYPE_PORT } ,
{ . route = 0x701 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x701 , . port = 7 , . type = TB_TYPE_PORT } ,
{ . route = 0x70701 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x70701 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x3070701 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x3070701 , . port = 5 , . type = TB_TYPE_PORT } ,
{ . route = 0x503070701 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x503070701 , . port = 14 , . type = TB_TYPE_DP_HDMI_OUT } ,
} ;
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev5 , * dev6 , * dev7 , * dev9 ;
struct tb_port * src_port , * dst_port , * p ;
int i ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x301 , true ) ;
dev3 = alloc_dev_with_dpin ( test , dev2 , 0x50301 , true ) ;
alloc_dev_default ( test , dev1 , 0x501 , true ) ;
dev5 = alloc_dev_default ( test , dev1 , 0x701 , true ) ;
dev6 = alloc_dev_default ( test , dev5 , 0x70701 , true ) ;
dev7 = alloc_dev_default ( test , dev6 , 0x3070701 , true ) ;
alloc_dev_default ( test , dev7 , 0x303070701 , true ) ;
dev9 = alloc_dev_default ( test , dev7 , 0x503070701 , true ) ;
src_port = & dev3 - > ports [ 13 ] ;
dst_port = & dev9 - > ports [ 14 ] ;
/* Walk both directions */
i = 0 ;
tb_for_each_port_on_path ( src_port , dst_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i + + ;
}
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , i , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
i = ARRAY_SIZE ( test_data ) - 1 ;
tb_for_each_port_on_path ( dst_port , src_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i - - ;
}
KUNIT_EXPECT_EQ ( test , i , - 1 ) ;
}
static void tb_test_path_max_length_walk ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev4 , * dev5 , * dev6 ;
struct tb_switch * dev7 , * dev8 , * dev9 , * dev10 , * dev11 , * dev12 ;
struct tb_port * src_port , * dst_port , * p ;
int i ;
/*
* Walks from Device # 6 DP IN to Device # 12 DP OUT .
*
* [ Host ]
* 1 / \ 3
* 1 / \ 1
* [ Device # 1 ] [ Device # 7 ]
* 3 | | 3
* 1 | | 1
* [ Device # 2 ] [ Device # 8 ]
* 3 | | 3
* 1 | | 1
* [ Device # 3 ] [ Device # 9 ]
* 3 | | 3
* 1 | | 1
* [ Device # 4 ] [ Device # 10 ]
* 3 | | 3
* 1 | | 1
* [ Device # 5 ] [ Device # 11 ]
* 3 | | 3
* 1 | | 1
* [ Device # 6 ] [ Device # 12 ]
*/
static const struct port_expectation test_data [ ] = {
{ . route = 0x30303030301 , . port = 13 , . type = TB_TYPE_DP_HDMI_IN } ,
{ . route = 0x30303030301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x303030301 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x303030301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x3030301 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x3030301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x30301 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x30301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x301 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x301 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x1 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x0 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x0 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x3 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x3 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x303 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x303 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x30303 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x30303 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x3030303 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x3030303 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x303030303 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x303030303 , . port = 3 , . type = TB_TYPE_PORT } ,
{ . route = 0x30303030303 , . port = 1 , . type = TB_TYPE_PORT } ,
{ . route = 0x30303030303 , . port = 13 , . type = TB_TYPE_DP_HDMI_OUT } ,
} ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x301 , true ) ;
dev3 = alloc_dev_default ( test , dev2 , 0x30301 , true ) ;
dev4 = alloc_dev_default ( test , dev3 , 0x3030301 , true ) ;
dev5 = alloc_dev_default ( test , dev4 , 0x303030301 , true ) ;
dev6 = alloc_dev_with_dpin ( test , dev5 , 0x30303030301 , true ) ;
dev7 = alloc_dev_default ( test , host , 0x3 , true ) ;
dev8 = alloc_dev_default ( test , dev7 , 0x303 , true ) ;
dev9 = alloc_dev_default ( test , dev8 , 0x30303 , true ) ;
dev10 = alloc_dev_default ( test , dev9 , 0x3030303 , true ) ;
dev11 = alloc_dev_default ( test , dev10 , 0x303030303 , true ) ;
dev12 = alloc_dev_default ( test , dev11 , 0x30303030303 , true ) ;
src_port = & dev6 - > ports [ 13 ] ;
dst_port = & dev12 - > ports [ 13 ] ;
/* Walk both directions */
i = 0 ;
tb_for_each_port_on_path ( src_port , dst_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i + + ;
}
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , i , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
i = ARRAY_SIZE ( test_data ) - 1 ;
tb_for_each_port_on_path ( dst_port , src_port , p ) {
KUNIT_EXPECT_TRUE ( test , i < ARRAY_SIZE ( test_data ) ) ;
KUNIT_EXPECT_EQ ( test , tb_route ( p - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , p - > port , test_data [ i ] . port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
2020-04-29 16:38:39 +03:00
i - - ;
}
KUNIT_EXPECT_EQ ( test , i , - 1 ) ;
}
static void tb_test_path_not_connected ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 ;
struct tb_port * down , * up ;
struct tb_path * path ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x3 , false ) ;
/* Not connected to anything */
dev2 = alloc_dev_default ( test , NULL , 0x303 , false ) ;
down = & dev1 - > ports [ 10 ] ;
up = & dev2 - > ports [ 9 ] ;
path = tb_path_alloc ( NULL , down , 8 , up , 8 , 0 , " PCIe Down " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NULL ( test , path ) ;
2020-04-29 16:38:39 +03:00
path = tb_path_alloc ( NULL , down , 8 , up , 8 , 1 , " PCIe Down " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NULL ( test , path ) ;
2020-04-29 16:38:39 +03:00
}
struct hop_expectation {
u64 route ;
u8 in_port ;
enum tb_port_type in_type ;
u8 out_port ;
enum tb_port_type out_type ;
} ;
static void tb_test_path_not_bonded_lane0 ( struct kunit * test )
{
/*
* PCIe path from host to device using lane 0.
*
* [ Host ]
* 3 | : 4
* 1 | : 2
* [ Device ]
*/
static const struct hop_expectation test_data [ ] = {
{
. route = 0x0 ,
. in_port = 9 ,
. in_type = TB_TYPE_PCIE_DOWN ,
. out_port = 3 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x3 ,
. in_port = 1 ,
. in_type = TB_TYPE_PORT ,
. out_port = 9 ,
. out_type = TB_TYPE_PCIE_UP ,
} ,
} ;
struct tb_switch * host , * dev ;
struct tb_port * down , * up ;
struct tb_path * path ;
int i ;
host = alloc_host ( test ) ;
dev = alloc_dev_default ( test , host , 0x3 , false ) ;
down = & host - > ports [ 9 ] ;
up = & dev - > ports [ 9 ] ;
path = tb_path_alloc ( NULL , down , 8 , up , 8 , 0 , " PCIe Down " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , path ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , path - > path_length , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + ) {
const struct tb_port * in_port , * out_port ;
in_port = path - > hops [ i ] . in_port ;
out_port = path - > hops [ i ] . out_port ;
KUNIT_EXPECT_EQ ( test , tb_route ( in_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , in_port - > port , test_data [ i ] . in_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
2020-04-29 16:38:39 +03:00
KUNIT_EXPECT_EQ ( test , tb_route ( out_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , out_port - > port , test_data [ i ] . out_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
2020-04-29 16:38:39 +03:00
}
tb_path_free ( path ) ;
}
static void tb_test_path_not_bonded_lane1 ( struct kunit * test )
{
/*
* DP Video path from host to device using lane 1. Paths like
* these are only used with Thunderbolt 1 devices where lane
* bonding is not possible . USB4 specifically does not allow
* paths like this ( you either use lane 0 where lane 1 is
* disabled or both lanes are bonded ) .
*
* [ Host ]
* 1 : | 2
* 1 : | 2
* [ Device ]
*/
static const struct hop_expectation test_data [ ] = {
{
. route = 0x0 ,
. in_port = 5 ,
. in_type = TB_TYPE_DP_HDMI_IN ,
. out_port = 2 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x1 ,
. in_port = 2 ,
. in_type = TB_TYPE_PORT ,
. out_port = 13 ,
. out_type = TB_TYPE_DP_HDMI_OUT ,
} ,
} ;
struct tb_switch * host , * dev ;
struct tb_port * in , * out ;
struct tb_path * path ;
int i ;
host = alloc_host ( test ) ;
dev = alloc_dev_default ( test , host , 0x1 , false ) ;
in = & host - > ports [ 5 ] ;
out = & dev - > ports [ 13 ] ;
path = tb_path_alloc ( NULL , in , 9 , out , 9 , 1 , " Video " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , path ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , path - > path_length , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + ) {
const struct tb_port * in_port , * out_port ;
in_port = path - > hops [ i ] . in_port ;
out_port = path - > hops [ i ] . out_port ;
KUNIT_EXPECT_EQ ( test , tb_route ( in_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , in_port - > port , test_data [ i ] . in_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
2020-04-29 16:38:39 +03:00
KUNIT_EXPECT_EQ ( test , tb_route ( out_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , out_port - > port , test_data [ i ] . out_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
2020-04-29 16:38:39 +03:00
}
tb_path_free ( path ) ;
}
static void tb_test_path_not_bonded_lane1_chain ( struct kunit * test )
{
/*
* DP Video path from host to device 3 using lane 1.
*
* [ Host ]
* 1 : | 2
* 1 : | 2
* [ Device # 1 ]
* 7 : | 8
* 1 : | 2
* [ Device # 2 ]
* 5 : | 6
* 1 : | 2
* [ Device # 3 ]
*/
static const struct hop_expectation test_data [ ] = {
{
. route = 0x0 ,
. in_port = 5 ,
. in_type = TB_TYPE_DP_HDMI_IN ,
. out_port = 2 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x1 ,
. in_port = 2 ,
. in_type = TB_TYPE_PORT ,
. out_port = 8 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x701 ,
. in_port = 2 ,
. in_type = TB_TYPE_PORT ,
. out_port = 6 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x50701 ,
. in_port = 2 ,
. in_type = TB_TYPE_PORT ,
. out_port = 13 ,
. out_type = TB_TYPE_DP_HDMI_OUT ,
} ,
} ;
struct tb_switch * host , * dev1 , * dev2 , * dev3 ;
struct tb_port * in , * out ;
struct tb_path * path ;
int i ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , false ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x701 , false ) ;
dev3 = alloc_dev_default ( test , dev2 , 0x50701 , false ) ;
in = & host - > ports [ 5 ] ;
out = & dev3 - > ports [ 13 ] ;
path = tb_path_alloc ( NULL , in , 9 , out , 9 , 1 , " Video " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , path ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , path - > path_length , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + ) {
const struct tb_port * in_port , * out_port ;
in_port = path - > hops [ i ] . in_port ;
out_port = path - > hops [ i ] . out_port ;
KUNIT_EXPECT_EQ ( test , tb_route ( in_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , in_port - > port , test_data [ i ] . in_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
2020-04-29 16:38:39 +03:00
KUNIT_EXPECT_EQ ( test , tb_route ( out_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , out_port - > port , test_data [ i ] . out_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
2020-04-29 16:38:39 +03:00
}
tb_path_free ( path ) ;
}
static void tb_test_path_not_bonded_lane1_chain_reverse ( struct kunit * test )
{
/*
* DP Video path from device 3 to host using lane 1.
*
* [ Host ]
* 1 : | 2
* 1 : | 2
* [ Device # 1 ]
* 7 : | 8
* 1 : | 2
* [ Device # 2 ]
* 5 : | 6
* 1 : | 2
* [ Device # 3 ]
*/
static const struct hop_expectation test_data [ ] = {
{
. route = 0x50701 ,
. in_port = 13 ,
. in_type = TB_TYPE_DP_HDMI_IN ,
. out_port = 2 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x701 ,
. in_port = 6 ,
. in_type = TB_TYPE_PORT ,
. out_port = 2 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x1 ,
. in_port = 8 ,
. in_type = TB_TYPE_PORT ,
. out_port = 2 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x0 ,
. in_port = 2 ,
. in_type = TB_TYPE_PORT ,
. out_port = 5 ,
. out_type = TB_TYPE_DP_HDMI_IN ,
} ,
} ;
struct tb_switch * host , * dev1 , * dev2 , * dev3 ;
struct tb_port * in , * out ;
struct tb_path * path ;
int i ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , false ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x701 , false ) ;
dev3 = alloc_dev_with_dpin ( test , dev2 , 0x50701 , false ) ;
in = & dev3 - > ports [ 13 ] ;
out = & host - > ports [ 5 ] ;
path = tb_path_alloc ( NULL , in , 9 , out , 9 , 1 , " Video " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , path ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , path - > path_length , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + ) {
const struct tb_port * in_port , * out_port ;
in_port = path - > hops [ i ] . in_port ;
out_port = path - > hops [ i ] . out_port ;
KUNIT_EXPECT_EQ ( test , tb_route ( in_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , in_port - > port , test_data [ i ] . in_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
2020-04-29 16:38:39 +03:00
KUNIT_EXPECT_EQ ( test , tb_route ( out_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , out_port - > port , test_data [ i ] . out_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
2020-04-29 16:38:39 +03:00
}
tb_path_free ( path ) ;
}
static void tb_test_path_mixed_chain ( struct kunit * test )
{
/*
* DP Video path from host to device 4 where first and last link
* is bonded .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* 7 : | 8
* 1 : | 2
* [ Device # 2 ]
* 5 : | 6
* 1 : | 2
* [ Device # 3 ]
* 3 |
* 1 |
* [ Device # 4 ]
*/
static const struct hop_expectation test_data [ ] = {
{
. route = 0x0 ,
. in_port = 5 ,
. in_type = TB_TYPE_DP_HDMI_IN ,
. out_port = 1 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x1 ,
. in_port = 1 ,
. in_type = TB_TYPE_PORT ,
. out_port = 8 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x701 ,
. in_port = 2 ,
. in_type = TB_TYPE_PORT ,
. out_port = 6 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x50701 ,
. in_port = 2 ,
. in_type = TB_TYPE_PORT ,
. out_port = 3 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x3050701 ,
. in_port = 1 ,
. in_type = TB_TYPE_PORT ,
. out_port = 13 ,
. out_type = TB_TYPE_DP_HDMI_OUT ,
} ,
} ;
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev4 ;
struct tb_port * in , * out ;
struct tb_path * path ;
int i ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x701 , false ) ;
dev3 = alloc_dev_default ( test , dev2 , 0x50701 , false ) ;
dev4 = alloc_dev_default ( test , dev3 , 0x3050701 , true ) ;
in = & host - > ports [ 5 ] ;
out = & dev4 - > ports [ 13 ] ;
path = tb_path_alloc ( NULL , in , 9 , out , 9 , 1 , " Video " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , path ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , path - > path_length , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + ) {
const struct tb_port * in_port , * out_port ;
in_port = path - > hops [ i ] . in_port ;
out_port = path - > hops [ i ] . out_port ;
KUNIT_EXPECT_EQ ( test , tb_route ( in_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , in_port - > port , test_data [ i ] . in_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
2020-04-29 16:38:39 +03:00
KUNIT_EXPECT_EQ ( test , tb_route ( out_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , out_port - > port , test_data [ i ] . out_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
2020-04-29 16:38:39 +03:00
}
tb_path_free ( path ) ;
}
static void tb_test_path_mixed_chain_reverse ( struct kunit * test )
{
/*
* DP Video path from device 4 to host where first and last link
* is bonded .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* 7 : | 8
* 1 : | 2
* [ Device # 2 ]
* 5 : | 6
* 1 : | 2
* [ Device # 3 ]
* 3 |
* 1 |
* [ Device # 4 ]
*/
static const struct hop_expectation test_data [ ] = {
{
. route = 0x3050701 ,
. in_port = 13 ,
. in_type = TB_TYPE_DP_HDMI_OUT ,
. out_port = 1 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x50701 ,
. in_port = 3 ,
. in_type = TB_TYPE_PORT ,
. out_port = 2 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x701 ,
. in_port = 6 ,
. in_type = TB_TYPE_PORT ,
. out_port = 2 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x1 ,
. in_port = 8 ,
. in_type = TB_TYPE_PORT ,
. out_port = 1 ,
. out_type = TB_TYPE_PORT ,
} ,
{
. route = 0x0 ,
. in_port = 1 ,
. in_type = TB_TYPE_PORT ,
. out_port = 5 ,
. out_type = TB_TYPE_DP_HDMI_IN ,
} ,
} ;
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev4 ;
struct tb_port * in , * out ;
struct tb_path * path ;
int i ;
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x701 , false ) ;
dev3 = alloc_dev_default ( test , dev2 , 0x50701 , false ) ;
dev4 = alloc_dev_default ( test , dev3 , 0x3050701 , true ) ;
in = & dev4 - > ports [ 13 ] ;
out = & host - > ports [ 5 ] ;
path = tb_path_alloc ( NULL , in , 9 , out , 9 , 1 , " Video " ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , path ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , path - > path_length , ARRAY_SIZE ( test_data ) ) ;
2020-04-29 16:38:39 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + ) {
const struct tb_port * in_port , * out_port ;
in_port = path - > hops [ i ] . in_port ;
out_port = path - > hops [ i ] . out_port ;
KUNIT_EXPECT_EQ ( test , tb_route ( in_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , in_port - > port , test_data [ i ] . in_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
2020-04-29 16:38:39 +03:00
KUNIT_EXPECT_EQ ( test , tb_route ( out_port - > sw ) , test_data [ i ] . route ) ;
KUNIT_EXPECT_EQ ( test , out_port - > port , test_data [ i ] . out_port ) ;
2021-06-24 11:48:23 +03:00
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
2020-04-29 16:38:39 +03:00
}
tb_path_free ( path ) ;
}
2020-05-04 17:10:40 +03:00
static void tb_test_tunnel_pcie ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 ;
struct tb_tunnel * tunnel1 , * tunnel2 ;
struct tb_port * down , * up ;
/*
* Create PCIe tunnel between host and two devices .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* 5 |
* 1 |
* [ Device # 2 ]
*/
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x501 , true ) ;
down = & host - > ports [ 8 ] ;
up = & dev1 - > ports [ 9 ] ;
tunnel1 = tb_tunnel_alloc_pci ( NULL , up , down ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel1 ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel1 - > type , TB_TUNNEL_PCI ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > dst_port , up ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel1 - > npaths , 2 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel1 - > paths [ 0 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 0 ] - > hops [ 0 ] . in_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 0 ] - > hops [ 1 ] . out_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel1 - > paths [ 1 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 1 ] - > hops [ 0 ] . in_port , up ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 1 ] - > hops [ 1 ] . out_port , down ) ;
down = & dev1 - > ports [ 10 ] ;
up = & dev2 - > ports [ 9 ] ;
tunnel2 = tb_tunnel_alloc_pci ( NULL , up , down ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel2 ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel2 - > type , TB_TUNNEL_PCI ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > dst_port , up ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel2 - > npaths , 2 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel2 - > paths [ 0 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 0 ] - > hops [ 0 ] . in_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 0 ] - > hops [ 1 ] . out_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel2 - > paths [ 1 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 1 ] - > hops [ 0 ] . in_port , up ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 1 ] - > hops [ 1 ] . out_port , down ) ;
tb_tunnel_free ( tunnel2 ) ;
tb_tunnel_free ( tunnel1 ) ;
}
static void tb_test_tunnel_dp ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * in , * out ;
struct tb_tunnel * tunnel ;
/*
* Create DP tunnel between Host and Device
*
* [ Host ]
* 1 |
* 1 |
* [ Device ]
*/
host = alloc_host ( test ) ;
dev = alloc_dev_default ( test , host , 0x3 , true ) ;
in = & host - > ports [ 5 ] ;
out = & dev - > ports [ 13 ] ;
2022-04-01 17:24:28 +03:00
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DP ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 3 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 1 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 1 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 1 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 2 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 0 ] . in_port , out ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 1 ] . out_port , in ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_tunnel_dp_chain ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev4 ;
struct tb_port * in , * out ;
struct tb_tunnel * tunnel ;
/*
* Create DP tunnel from Host DP IN to Device # 4 DP OUT .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* 3 / | 5 \ 7
* 1 / | \ 1
* [ Device # 2 ] | [ Device # 4 ]
* | 1
* [ Device # 3 ]
*/
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
alloc_dev_default ( test , dev1 , 0x301 , true ) ;
alloc_dev_default ( test , dev1 , 0x501 , true ) ;
dev4 = alloc_dev_default ( test , dev1 , 0x701 , true ) ;
in = & host - > ports [ 5 ] ;
out = & dev4 - > ports [ 14 ] ;
2022-04-01 17:24:28 +03:00
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DP ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 3 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 2 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 1 ] - > path_length , 3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 2 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 2 ] - > path_length , 3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 0 ] . in_port , out ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 2 ] . out_port , in ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_tunnel_dp_tree ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev5 ;
struct tb_port * in , * out ;
struct tb_tunnel * tunnel ;
/*
* Create DP tunnel from Device # 2 DP IN to Device # 5 DP OUT .
*
* [ Host ]
* 3 |
* 1 |
* [ Device # 1 ]
* 3 / | 5 \ 7
* 1 / | \ 1
* [ Device # 2 ] | [ Device # 4 ]
* | 1
* [ Device # 3 ]
* | 5
* | 1
* [ Device # 5 ]
*/
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x3 , true ) ;
dev2 = alloc_dev_with_dpin ( test , dev1 , 0x303 , true ) ;
dev3 = alloc_dev_default ( test , dev1 , 0x503 , true ) ;
alloc_dev_default ( test , dev1 , 0x703 , true ) ;
dev5 = alloc_dev_default ( test , dev3 , 0x50503 , true ) ;
in = & dev2 - > ports [ 13 ] ;
out = & dev5 - > ports [ 13 ] ;
2022-04-01 17:24:28 +03:00
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DP ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 3 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 4 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 3 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 1 ] - > path_length , 4 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 3 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 2 ] - > path_length , 4 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 0 ] . in_port , out ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 3 ] . out_port , in ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_tunnel_dp_max_length ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev4 , * dev5 , * dev6 ;
struct tb_switch * dev7 , * dev8 , * dev9 , * dev10 , * dev11 , * dev12 ;
struct tb_port * in , * out ;
struct tb_tunnel * tunnel ;
/*
* Creates DP tunnel from Device # 6 to Device # 12.
*
* [ Host ]
* 1 / \ 3
* 1 / \ 1
* [ Device # 1 ] [ Device # 7 ]
* 3 | | 3
* 1 | | 1
* [ Device # 2 ] [ Device # 8 ]
* 3 | | 3
* 1 | | 1
* [ Device # 3 ] [ Device # 9 ]
* 3 | | 3
* 1 | | 1
* [ Device # 4 ] [ Device # 10 ]
* 3 | | 3
* 1 | | 1
* [ Device # 5 ] [ Device # 11 ]
* 3 | | 3
* 1 | | 1
* [ Device # 6 ] [ Device # 12 ]
*/
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x301 , true ) ;
dev3 = alloc_dev_default ( test , dev2 , 0x30301 , true ) ;
dev4 = alloc_dev_default ( test , dev3 , 0x3030301 , true ) ;
dev5 = alloc_dev_default ( test , dev4 , 0x303030301 , true ) ;
dev6 = alloc_dev_with_dpin ( test , dev5 , 0x30303030301 , true ) ;
dev7 = alloc_dev_default ( test , host , 0x3 , true ) ;
dev8 = alloc_dev_default ( test , dev7 , 0x303 , true ) ;
dev9 = alloc_dev_default ( test , dev8 , 0x30303 , true ) ;
dev10 = alloc_dev_default ( test , dev9 , 0x3030303 , true ) ;
dev11 = alloc_dev_default ( test , dev10 , 0x303030303 , true ) ;
dev12 = alloc_dev_default ( test , dev11 , 0x30303030303 , true ) ;
in = & dev6 - > ports [ 13 ] ;
out = & dev12 - > ports [ 13 ] ;
2022-04-01 17:24:28 +03:00
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DP ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 3 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 13 ) ;
/* First hop */
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , in ) ;
/* Middle */
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 6 ] . in_port ,
& host - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 6 ] . out_port ,
& host - > ports [ 3 ] ) ;
/* Last */
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 12 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 1 ] - > path_length , 13 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 6 ] . in_port ,
& host - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 6 ] . out_port ,
& host - > ports [ 3 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 12 ] . out_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 2 ] - > path_length , 13 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 0 ] . in_port , out ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 6 ] . in_port ,
& host - > ports [ 3 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 6 ] . out_port ,
& host - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 2 ] - > hops [ 12 ] . out_port , in ) ;
tb_tunnel_free ( tunnel ) ;
}
2022-02-14 15:09:50 +03:00
static void tb_test_tunnel_3dp ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev4 , * dev5 ;
struct tb_port * in1 , * in2 , * in3 , * out1 , * out2 , * out3 ;
struct tb_tunnel * tunnel1 , * tunnel2 , * tunnel3 ;
/*
* Create 3 DP tunnels from Host to Devices # 2 , # 5 and # 4.
*
* [ Host ]
* 3 |
* 1 |
* [ Device # 1 ]
* 3 / | 5 \ 7
* 1 / | \ 1
* [ Device # 2 ] | [ Device # 4 ]
* | 1
* [ Device # 3 ]
* | 5
* | 1
* [ Device # 5 ]
*/
host = alloc_host_br ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x3 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x303 , true ) ;
dev3 = alloc_dev_default ( test , dev1 , 0x503 , true ) ;
dev4 = alloc_dev_default ( test , dev1 , 0x703 , true ) ;
dev5 = alloc_dev_default ( test , dev3 , 0x50503 , true ) ;
in1 = & host - > ports [ 5 ] ;
in2 = & host - > ports [ 6 ] ;
in3 = & host - > ports [ 10 ] ;
out1 = & dev2 - > ports [ 13 ] ;
out2 = & dev5 - > ports [ 13 ] ;
out3 = & dev4 - > ports [ 14 ] ;
tunnel1 = tb_tunnel_alloc_dp ( NULL , in1 , out1 , 1 , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel1 ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel1 - > type , TB_TUNNEL_DP ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > src_port , in1 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > dst_port , out1 ) ;
KUNIT_ASSERT_EQ ( test , tunnel1 - > npaths , 3 ) ;
KUNIT_ASSERT_EQ ( test , tunnel1 - > paths [ 0 ] - > path_length , 3 ) ;
tunnel2 = tb_tunnel_alloc_dp ( NULL , in2 , out2 , 1 , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel2 ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel2 - > type , TB_TUNNEL_DP ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > src_port , in2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > dst_port , out2 ) ;
KUNIT_ASSERT_EQ ( test , tunnel2 - > npaths , 3 ) ;
KUNIT_ASSERT_EQ ( test , tunnel2 - > paths [ 0 ] - > path_length , 4 ) ;
tunnel3 = tb_tunnel_alloc_dp ( NULL , in3 , out3 , 1 , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel3 ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel3 - > type , TB_TUNNEL_DP ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel3 - > src_port , in3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel3 - > dst_port , out3 ) ;
KUNIT_ASSERT_EQ ( test , tunnel3 - > npaths , 3 ) ;
KUNIT_ASSERT_EQ ( test , tunnel3 - > paths [ 0 ] - > path_length , 3 ) ;
tb_tunnel_free ( tunnel2 ) ;
tb_tunnel_free ( tunnel1 ) ;
}
2020-05-04 17:10:40 +03:00
static void tb_test_tunnel_usb3 ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 ;
struct tb_tunnel * tunnel1 , * tunnel2 ;
struct tb_port * down , * up ;
/*
* Create USB3 tunnel between host and two devices .
*
* [ Host ]
* 1 |
* 1 |
* [ Device # 1 ]
* \ 7
* \ 1
* [ Device # 2 ]
*/
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x701 , true ) ;
down = & host - > ports [ 12 ] ;
up = & dev1 - > ports [ 16 ] ;
tunnel1 = tb_tunnel_alloc_usb3 ( NULL , up , down , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel1 ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel1 - > type , TB_TUNNEL_USB3 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > dst_port , up ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel1 - > npaths , 2 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel1 - > paths [ 0 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 0 ] - > hops [ 0 ] . in_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 0 ] - > hops [ 1 ] . out_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel1 - > paths [ 1 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 1 ] - > hops [ 0 ] . in_port , up ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > paths [ 1 ] - > hops [ 1 ] . out_port , down ) ;
down = & dev1 - > ports [ 17 ] ;
up = & dev2 - > ports [ 16 ] ;
tunnel2 = tb_tunnel_alloc_usb3 ( NULL , up , down , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel2 ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel2 - > type , TB_TUNNEL_USB3 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > dst_port , up ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel2 - > npaths , 2 ) ;
2020-05-04 17:10:40 +03:00
KUNIT_ASSERT_EQ ( test , tunnel2 - > paths [ 0 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 0 ] - > hops [ 0 ] . in_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 0 ] - > hops [ 1 ] . out_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel2 - > paths [ 1 ] - > path_length , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 1 ] - > hops [ 0 ] . in_port , up ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > paths [ 1 ] - > hops [ 1 ] . out_port , down ) ;
tb_tunnel_free ( tunnel2 ) ;
tb_tunnel_free ( tunnel1 ) ;
}
static void tb_test_tunnel_port_on_path ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 , * dev3 , * dev4 , * dev5 ;
struct tb_port * in , * out , * port ;
struct tb_tunnel * dp_tunnel ;
/*
* [ Host ]
* 3 |
* 1 |
* [ Device # 1 ]
* 3 / | 5 \ 7
* 1 / | \ 1
* [ Device # 2 ] | [ Device # 4 ]
* | 1
* [ Device # 3 ]
* | 5
* | 1
* [ Device # 5 ]
*/
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x3 , true ) ;
dev2 = alloc_dev_with_dpin ( test , dev1 , 0x303 , true ) ;
dev3 = alloc_dev_default ( test , dev1 , 0x503 , true ) ;
dev4 = alloc_dev_default ( test , dev1 , 0x703 , true ) ;
dev5 = alloc_dev_default ( test , dev3 , 0x50503 , true ) ;
in = & dev2 - > ports [ 13 ] ;
out = & dev5 - > ports [ 13 ] ;
2022-04-01 17:24:28 +03:00
dp_tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dp_tunnel ) ;
2020-05-04 17:10:40 +03:00
KUNIT_EXPECT_TRUE ( test , tb_tunnel_port_on_path ( dp_tunnel , in ) ) ;
KUNIT_EXPECT_TRUE ( test , tb_tunnel_port_on_path ( dp_tunnel , out ) ) ;
port = & host - > ports [ 8 ] ;
KUNIT_EXPECT_FALSE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & host - > ports [ 3 ] ;
KUNIT_EXPECT_FALSE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & dev1 - > ports [ 1 ] ;
KUNIT_EXPECT_FALSE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & dev1 - > ports [ 3 ] ;
KUNIT_EXPECT_TRUE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & dev1 - > ports [ 5 ] ;
KUNIT_EXPECT_TRUE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & dev1 - > ports [ 7 ] ;
KUNIT_EXPECT_FALSE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & dev3 - > ports [ 1 ] ;
KUNIT_EXPECT_TRUE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & dev5 - > ports [ 1 ] ;
KUNIT_EXPECT_TRUE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
port = & dev4 - > ports [ 1 ] ;
KUNIT_EXPECT_FALSE ( test , tb_tunnel_port_on_path ( dp_tunnel , port ) ) ;
tb_tunnel_free ( dp_tunnel ) ;
}
2021-01-08 17:32:19 +03:00
static void tb_test_tunnel_dma ( struct kunit * test )
{
struct tb_port * nhi , * port ;
struct tb_tunnel * tunnel ;
struct tb_switch * host ;
/*
* Create DMA tunnel from NHI to port 1 and back .
*
* [ Host 1 ]
* 1 ^ In HopID 1 - > Out HopID 8
* |
* v In HopID 8 - > Out HopID 1
* . . . . . . . . . . . . Domain border
* |
* [ Host 2 ]
*/
host = alloc_host ( test ) ;
nhi = & host - > ports [ 7 ] ;
port = & host - > ports [ 1 ] ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , 8 , 1 , 8 , 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DMA ) ;
2021-01-08 17:32:19 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 2 ) ;
2021-01-08 17:32:19 +03:00
/* RX path */
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 1 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , port ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_hop_index , 8 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . out_port , nhi ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . next_hop_index , 1 ) ;
/* TX path */
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 1 ] - > path_length , 1 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_port , nhi ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_hop_index , 1 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . out_port , port ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . next_hop_index , 8 ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_tunnel_dma_rx ( struct kunit * test )
{
struct tb_port * nhi , * port ;
struct tb_tunnel * tunnel ;
struct tb_switch * host ;
/*
* Create DMA RX tunnel from port 1 to NHI .
*
* [ Host 1 ]
* 1 ^
* |
* | In HopID 15 - > Out HopID 2
* . . . . . . . . . . . . Domain border
* |
* [ Host 2 ]
*/
host = alloc_host ( test ) ;
nhi = & host - > ports [ 7 ] ;
port = & host - > ports [ 1 ] ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , - 1 , - 1 , 15 , 2 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DMA ) ;
2021-01-08 17:32:19 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 1 ) ;
2021-01-08 17:32:19 +03:00
/* RX path */
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 1 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , port ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_hop_index , 15 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . out_port , nhi ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . next_hop_index , 2 ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_tunnel_dma_tx ( struct kunit * test )
{
struct tb_port * nhi , * port ;
struct tb_tunnel * tunnel ;
struct tb_switch * host ;
/*
* Create DMA TX tunnel from NHI to port 1.
*
* [ Host 1 ]
* 1 | In HopID 2 - > Out HopID 15
* |
* v
* . . . . . . . . . . . . Domain border
* |
* [ Host 2 ]
*/
host = alloc_host ( test ) ;
nhi = & host - > ports [ 7 ] ;
port = & host - > ports [ 1 ] ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , 15 , 2 , - 1 , - 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DMA ) ;
2021-01-08 17:32:19 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 1 ) ;
2021-01-08 17:32:19 +03:00
/* TX path */
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 1 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , nhi ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_hop_index , 2 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . out_port , port ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . next_hop_index , 15 ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_tunnel_dma_chain ( struct kunit * test )
{
struct tb_switch * host , * dev1 , * dev2 ;
struct tb_port * nhi , * port ;
struct tb_tunnel * tunnel ;
/*
* Create DMA tunnel from NHI to Device # 2 port 3 and back .
*
* [ Host 1 ]
* 1 ^ In HopID 1 - > Out HopID x
* |
* 1 | In HopID x - > Out HopID 1
* [ Device # 1 ]
* 7 \
* 1 \
* [ Device # 2 ]
* 3 | In HopID x - > Out HopID 8
* |
* v In HopID 8 - > Out HopID x
* . . . . . . . . . . . . Domain border
* |
* [ Host 2 ]
*/
host = alloc_host ( test ) ;
dev1 = alloc_dev_default ( test , host , 0x1 , true ) ;
dev2 = alloc_dev_default ( test , dev1 , 0x701 , true ) ;
nhi = & host - > ports [ 7 ] ;
port = & dev2 - > ports [ 3 ] ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , 8 , 1 , 8 , 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , tunnel - > type , TB_TUNNEL_DMA ) ;
2021-01-08 17:32:19 +03:00
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , 2 ) ;
2021-01-08 17:32:19 +03:00
/* RX path */
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 0 ] - > path_length , 3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_port , port ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . in_hop_index , 8 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 0 ] . out_port ,
& dev2 - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 1 ] . in_port ,
& dev1 - > ports [ 7 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 1 ] . out_port ,
& dev1 - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 2 ] . in_port ,
& host - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 2 ] . out_port , nhi ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 0 ] - > hops [ 2 ] . next_hop_index , 1 ) ;
/* TX path */
KUNIT_ASSERT_EQ ( test , tunnel - > paths [ 1 ] - > path_length , 3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_port , nhi ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 0 ] . in_hop_index , 1 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 1 ] . in_port ,
& dev1 - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 1 ] . out_port ,
& dev1 - > ports [ 7 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 2 ] . in_port ,
& dev2 - > ports [ 1 ] ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 2 ] . out_port , port ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > paths [ 1 ] - > hops [ 2 ] . next_hop_index , 8 ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_tunnel_dma_match ( struct kunit * test )
{
struct tb_port * nhi , * port ;
struct tb_tunnel * tunnel ;
struct tb_switch * host ;
host = alloc_host ( test ) ;
nhi = & host - > ports [ 7 ] ;
port = & host - > ports [ 1 ] ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , 15 , 1 , 15 , 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-01-08 17:32:19 +03:00
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , 15 , 1 , 15 , 1 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , 8 , 1 , 15 , 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , 15 , 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , 15 , 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , 15 , - 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , 15 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , - 1 , 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , 8 , - 1 , 8 , - 1 ) ) ;
tb_tunnel_free ( tunnel ) ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , 15 , 1 , - 1 , - 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-01-08 17:32:19 +03:00
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , 15 , 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , 15 , - 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , 15 , 1 , 15 , 1 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , 15 , 1 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , 15 , 11 , - 1 , - 1 ) ) ;
tb_tunnel_free ( tunnel ) ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , - 1 , - 1 , 15 , 11 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-01-08 17:32:19 +03:00
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , 15 , 11 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , 15 , - 1 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , - 1 , 11 ) ) ;
KUNIT_ASSERT_TRUE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , - 1 , - 1 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , 15 , 1 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , - 1 , - 1 , 10 , 11 ) ) ;
KUNIT_ASSERT_FALSE ( test , tb_tunnel_match_dma ( tunnel , 15 , 11 , - 1 , - 1 ) ) ;
tb_tunnel_free ( tunnel ) ;
}
2021-04-28 19:04:02 +03:00
static void tb_test_credit_alloc_legacy_not_bonded ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * up , * down ;
struct tb_tunnel * tunnel ;
struct tb_path * path ;
host = alloc_host ( test ) ;
dev = alloc_dev_default ( test , host , 0x1 , false ) ;
down = & host - > ports [ 8 ] ;
up = & dev - > ports [ 9 ] ;
tunnel = tb_tunnel_alloc_pci ( NULL , up , down ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
path = tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 16U ) ;
path = tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 16U ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_credit_alloc_legacy_bonded ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * up , * down ;
struct tb_tunnel * tunnel ;
struct tb_path * path ;
host = alloc_host ( test ) ;
dev = alloc_dev_default ( test , host , 0x1 , true ) ;
down = & host - > ports [ 8 ] ;
up = & dev - > ports [ 9 ] ;
tunnel = tb_tunnel_alloc_pci ( NULL , up , down ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
path = tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 32U ) ;
path = tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 32U ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_credit_alloc_pcie ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * up , * down ;
struct tb_tunnel * tunnel ;
struct tb_path * path ;
host = alloc_host_usb4 ( test ) ;
dev = alloc_dev_usb4 ( test , host , 0x1 , true ) ;
down = & host - > ports [ 8 ] ;
up = & dev - > ports [ 9 ] ;
tunnel = tb_tunnel_alloc_pci ( NULL , up , down ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
path = tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 32U ) ;
path = tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 64U ) ;
tb_tunnel_free ( tunnel ) ;
}
2022-05-09 23:49:04 +03:00
static void tb_test_credit_alloc_without_dp ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * up , * down ;
struct tb_tunnel * tunnel ;
struct tb_path * path ;
host = alloc_host_usb4 ( test ) ;
dev = alloc_dev_without_dp ( test , host , 0x1 , true ) ;
/*
* The device has no DP therefore baMinDPmain = baMinDPaux = 0
*
* Create PCIe path with buffers less than baMaxPCIe .
*
* For a device with buffers configurations :
* baMaxUSB3 = 109
* baMinDPaux = 0
* baMinDPmain = 0
* baMaxPCIe = 30
* baMaxHI = 1
* Remaining Buffers = Total - ( CP + DP ) = 120 - ( 2 + 0 ) = 118
* PCIe Credits = Max ( 6 , Min ( baMaxPCIe , Remaining Buffers - baMaxUSB3 )
* = Max ( 6 , Min ( 30 , 9 ) = 9
*/
down = & host - > ports [ 8 ] ;
up = & dev - > ports [ 9 ] ;
tunnel = tb_tunnel_alloc_pci ( NULL , up , down ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
/* PCIe downstream path */
path = tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 9U ) ;
/* PCIe upstream path */
path = tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 64U ) ;
tb_tunnel_free ( tunnel ) ;
}
2021-04-28 19:04:02 +03:00
static void tb_test_credit_alloc_dp ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * in , * out ;
struct tb_tunnel * tunnel ;
struct tb_path * path ;
host = alloc_host_usb4 ( test ) ;
dev = alloc_dev_usb4 ( test , host , 0x1 , true ) ;
in = & host - > ports [ 5 ] ;
out = & dev - > ports [ 14 ] ;
2022-04-01 17:24:28 +03:00
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 3 ) ;
/* Video (main) path */
path = tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 12U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 18U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 0U ) ;
/* AUX TX */
path = tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 1U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
/* AUX RX */
path = tunnel - > paths [ 2 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 1U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_credit_alloc_usb3 ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * up , * down ;
struct tb_tunnel * tunnel ;
struct tb_path * path ;
host = alloc_host_usb4 ( test ) ;
dev = alloc_dev_usb4 ( test , host , 0x1 , true ) ;
down = & host - > ports [ 12 ] ;
up = & dev - > ports [ 16 ] ;
tunnel = tb_tunnel_alloc_usb3 ( NULL , up , down , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
path = tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
path = tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 32U ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_credit_alloc_dma ( struct kunit * test )
{
struct tb_switch * host , * dev ;
struct tb_port * nhi , * port ;
struct tb_tunnel * tunnel ;
struct tb_path * path ;
host = alloc_host_usb4 ( test ) ;
dev = alloc_dev_usb4 ( test , host , 0x1 , true ) ;
nhi = & host - > ports [ 7 ] ;
port = & dev - > ports [ 3 ] ;
tunnel = tb_tunnel_alloc_dma ( NULL , nhi , port , 8 , 1 , 8 , 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
/* DMA RX */
path = tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 14U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
/* DMA TX */
path = tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
tb_tunnel_free ( tunnel ) ;
}
static void tb_test_credit_alloc_dma_multiple ( struct kunit * test )
{
struct tb_tunnel * tunnel1 , * tunnel2 , * tunnel3 ;
struct tb_switch * host , * dev ;
struct tb_port * nhi , * port ;
struct tb_path * path ;
host = alloc_host_usb4 ( test ) ;
dev = alloc_dev_usb4 ( test , host , 0x1 , true ) ;
nhi = & host - > ports [ 7 ] ;
port = & dev - > ports [ 3 ] ;
/*
* Create three DMA tunnels through the same ports . With the
* default buffers we should be able to create two and the last
* one fails .
*
* For default host we have following buffers for DMA :
*
* 120 - ( 2 + 2 * ( 1 + 0 ) + 32 + 64 + spare ) = 20
*
* For device we have following :
*
* 120 - ( 2 + 2 * ( 1 + 18 ) + 14 + 32 + spare ) = 34
*
* spare = 14 + 1 = 15
*
* So on host the first tunnel gets 14 and the second gets the
* remaining 1 and then we run out of buffers .
*/
tunnel1 = tb_tunnel_alloc_dma ( NULL , nhi , port , 8 , 1 , 8 , 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel1 ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel1 - > npaths , ( size_t ) 2 ) ;
path = tunnel1 - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 14U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
path = tunnel1 - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
tunnel2 = tb_tunnel_alloc_dma ( NULL , nhi , port , 9 , 2 , 9 , 2 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel2 ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , tunnel2 - > npaths , ( size_t ) 2 ) ;
path = tunnel2 - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 14U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
path = tunnel2 - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
tunnel3 = tb_tunnel_alloc_dma ( NULL , nhi , port , 10 , 3 , 10 , 3 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NULL ( test , tunnel3 ) ;
2021-04-28 19:04:02 +03:00
/*
* Release the first DMA tunnel . That should make 14 buffers
* available for the next tunnel .
*/
tb_tunnel_free ( tunnel1 ) ;
tunnel3 = tb_tunnel_alloc_dma ( NULL , nhi , port , 10 , 3 , 10 , 3 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , tunnel3 ) ;
2021-04-28 19:04:02 +03:00
path = tunnel3 - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 14U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
path = tunnel3 - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
tb_tunnel_free ( tunnel3 ) ;
tb_tunnel_free ( tunnel2 ) ;
}
2021-09-06 22:27:03 +03:00
static struct tb_tunnel * TB_TEST_PCIE_TUNNEL ( struct kunit * test ,
struct tb_switch * host , struct tb_switch * dev )
2021-04-28 19:04:02 +03:00
{
2021-09-06 22:27:03 +03:00
struct tb_port * up , * down ;
struct tb_tunnel * pcie_tunnel ;
2021-04-28 19:04:02 +03:00
struct tb_path * path ;
down = & host - > ports [ 8 ] ;
up = & dev - > ports [ 9 ] ;
pcie_tunnel = tb_tunnel_alloc_pci ( NULL , up , down ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , pcie_tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , pcie_tunnel - > npaths , ( size_t ) 2 ) ;
path = pcie_tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 32U ) ;
path = pcie_tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 64U ) ;
2021-09-06 22:27:03 +03:00
return pcie_tunnel ;
}
static struct tb_tunnel * TB_TEST_DP_TUNNEL1 ( struct kunit * test ,
struct tb_switch * host , struct tb_switch * dev )
{
struct tb_port * in , * out ;
struct tb_tunnel * dp_tunnel1 ;
struct tb_path * path ;
2021-04-28 19:04:02 +03:00
in = & host - > ports [ 5 ] ;
out = & dev - > ports [ 13 ] ;
2022-04-01 17:24:28 +03:00
dp_tunnel1 = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dp_tunnel1 ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , dp_tunnel1 - > npaths , ( size_t ) 3 ) ;
path = dp_tunnel1 - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 12U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 18U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 0U ) ;
path = dp_tunnel1 - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 1U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
path = dp_tunnel1 - > paths [ 2 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 1U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
2021-09-06 22:27:03 +03:00
return dp_tunnel1 ;
}
static struct tb_tunnel * TB_TEST_DP_TUNNEL2 ( struct kunit * test ,
struct tb_switch * host , struct tb_switch * dev )
{
struct tb_port * in , * out ;
struct tb_tunnel * dp_tunnel2 ;
struct tb_path * path ;
2021-04-28 19:04:02 +03:00
in = & host - > ports [ 6 ] ;
out = & dev - > ports [ 14 ] ;
2022-04-01 17:24:28 +03:00
dp_tunnel2 = tb_tunnel_alloc_dp ( NULL , in , out , 1 , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dp_tunnel2 ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , dp_tunnel2 - > npaths , ( size_t ) 3 ) ;
path = dp_tunnel2 - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 12U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 18U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 0U ) ;
path = dp_tunnel2 - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 1U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
path = dp_tunnel2 - > paths [ 2 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 1U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
2021-09-06 22:27:03 +03:00
return dp_tunnel2 ;
}
static struct tb_tunnel * TB_TEST_USB3_TUNNEL ( struct kunit * test ,
struct tb_switch * host , struct tb_switch * dev )
{
struct tb_port * up , * down ;
struct tb_tunnel * usb3_tunnel ;
struct tb_path * path ;
2021-04-28 19:04:02 +03:00
down = & host - > ports [ 12 ] ;
up = & dev - > ports [ 16 ] ;
usb3_tunnel = tb_tunnel_alloc_usb3 ( NULL , up , down , 0 , 0 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , usb3_tunnel ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , usb3_tunnel - > npaths , ( size_t ) 2 ) ;
path = usb3_tunnel - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
path = usb3_tunnel - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 7U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 32U ) ;
2021-09-06 22:27:03 +03:00
return usb3_tunnel ;
}
static struct tb_tunnel * TB_TEST_DMA_TUNNEL1 ( struct kunit * test ,
struct tb_switch * host , struct tb_switch * dev )
{
struct tb_port * nhi , * port ;
struct tb_tunnel * dma_tunnel1 ;
struct tb_path * path ;
2021-04-28 19:04:02 +03:00
nhi = & host - > ports [ 7 ] ;
port = & dev - > ports [ 3 ] ;
dma_tunnel1 = tb_tunnel_alloc_dma ( NULL , nhi , port , 8 , 1 , 8 , 1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dma_tunnel1 ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , dma_tunnel1 - > npaths , ( size_t ) 2 ) ;
path = dma_tunnel1 - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 14U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
path = dma_tunnel1 - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 14U ) ;
2021-09-06 22:27:03 +03:00
return dma_tunnel1 ;
}
static struct tb_tunnel * TB_TEST_DMA_TUNNEL2 ( struct kunit * test ,
struct tb_switch * host , struct tb_switch * dev )
{
struct tb_port * nhi , * port ;
struct tb_tunnel * dma_tunnel2 ;
struct tb_path * path ;
nhi = & host - > ports [ 7 ] ;
port = & dev - > ports [ 3 ] ;
2021-04-28 19:04:02 +03:00
dma_tunnel2 = tb_tunnel_alloc_dma ( NULL , nhi , port , 9 , 2 , 9 , 2 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dma_tunnel2 ) ;
2021-04-28 19:04:02 +03:00
KUNIT_ASSERT_EQ ( test , dma_tunnel2 - > npaths , ( size_t ) 2 ) ;
path = dma_tunnel2 - > paths [ 0 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 14U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
path = dma_tunnel2 - > paths [ 1 ] ;
KUNIT_ASSERT_EQ ( test , path - > path_length , 2 ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 0 ] . initial_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . nfc_credits , 0U ) ;
KUNIT_EXPECT_EQ ( test , path - > hops [ 1 ] . initial_credits , 1U ) ;
2021-09-06 22:27:03 +03:00
return dma_tunnel2 ;
}
static void tb_test_credit_alloc_all ( struct kunit * test )
{
struct tb_tunnel * pcie_tunnel , * dp_tunnel1 , * dp_tunnel2 , * usb3_tunnel ;
struct tb_tunnel * dma_tunnel1 , * dma_tunnel2 ;
struct tb_switch * host , * dev ;
/*
* Create PCIe , 2 x DP , USB 3. x and two DMA tunnels from host to
* device . Expectation is that all these can be established with
* the default credit allocation found in Intel hardware .
*/
host = alloc_host_usb4 ( test ) ;
dev = alloc_dev_usb4 ( test , host , 0x1 , true ) ;
pcie_tunnel = TB_TEST_PCIE_TUNNEL ( test , host , dev ) ;
dp_tunnel1 = TB_TEST_DP_TUNNEL1 ( test , host , dev ) ;
dp_tunnel2 = TB_TEST_DP_TUNNEL2 ( test , host , dev ) ;
usb3_tunnel = TB_TEST_USB3_TUNNEL ( test , host , dev ) ;
dma_tunnel1 = TB_TEST_DMA_TUNNEL1 ( test , host , dev ) ;
dma_tunnel2 = TB_TEST_DMA_TUNNEL2 ( test , host , dev ) ;
2021-04-28 19:04:02 +03:00
tb_tunnel_free ( dma_tunnel2 ) ;
tb_tunnel_free ( dma_tunnel1 ) ;
tb_tunnel_free ( usb3_tunnel ) ;
tb_tunnel_free ( dp_tunnel2 ) ;
tb_tunnel_free ( dp_tunnel1 ) ;
tb_tunnel_free ( pcie_tunnel ) ;
}
2020-05-04 17:00:38 +03:00
static const u32 root_directory [ ] = {
0x55584401 , /* "UXD" v1 */
0x00000018 , /* Root directory length */
0x76656e64 , /* "vend" */
0x6f726964 , /* "orid" */
0x76000001 , /* "v" R 1 */
0x00000a27 , /* Immediate value, ! Vendor ID */
0x76656e64 , /* "vend" */
0x6f726964 , /* "orid" */
0x74000003 , /* "t" R 3 */
0x0000001a , /* Text leaf offset, (“Apple Inc.”) */
0x64657669 , /* "devi" */
0x63656964 , /* "ceid" */
0x76000001 , /* "v" R 1 */
0x0000000a , /* Immediate value, ! Device ID */
0x64657669 , /* "devi" */
0x63656964 , /* "ceid" */
0x74000003 , /* "t" R 3 */
0x0000001d , /* Text leaf offset, (“Macintosh”) */
0x64657669 , /* "devi" */
0x63657276 , /* "cerv" */
0x76000001 , /* "v" R 1 */
0x80000100 , /* Immediate value, Device Revision */
0x6e657477 , /* "netw" */
0x6f726b00 , /* "ork" */
0x44000014 , /* "D" R 20 */
0x00000021 , /* Directory data offset, (Network Directory) */
0x4170706c , /* "Appl" */
0x6520496e , /* "e In" */
0x632e0000 , /* "c." ! */
0x4d616369 , /* "Maci" */
0x6e746f73 , /* "ntos" */
0x68000000 , /* "h" */
0x00000000 , /* padding */
0xca8961c6 , /* Directory UUID, Network Directory */
0x9541ce1c , /* Directory UUID, Network Directory */
0x5949b8bd , /* Directory UUID, Network Directory */
0x4f5a5f2e , /* Directory UUID, Network Directory */
0x70727463 , /* "prtc" */
0x69640000 , /* "id" */
0x76000001 , /* "v" R 1 */
0x00000001 , /* Immediate value, Network Protocol ID */
0x70727463 , /* "prtc" */
0x76657273 , /* "vers" */
0x76000001 , /* "v" R 1 */
0x00000001 , /* Immediate value, Network Protocol Version */
0x70727463 , /* "prtc" */
0x72657673 , /* "revs" */
0x76000001 , /* "v" R 1 */
0x00000001 , /* Immediate value, Network Protocol Revision */
0x70727463 , /* "prtc" */
0x73746e73 , /* "stns" */
0x76000001 , /* "v" R 1 */
0x00000000 , /* Immediate value, Network Protocol Settings */
} ;
static const uuid_t network_dir_uuid =
UUID_INIT ( 0xc66189ca , 0x1cce , 0x4195 ,
0xbd , 0xb8 , 0x49 , 0x59 , 0x2e , 0x5f , 0x5a , 0x4f ) ;
static void tb_test_property_parse ( struct kunit * test )
{
struct tb_property_dir * dir , * network_dir ;
struct tb_property * p ;
dir = tb_property_parse_dir ( root_directory , ARRAY_SIZE ( root_directory ) ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dir ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( dir , " foo " , TB_PROPERTY_TYPE_TEXT ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NULL ( test , p ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( dir , " vendorid " , TB_PROPERTY_TYPE_TEXT ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2020-05-04 17:00:38 +03:00
KUNIT_EXPECT_STREQ ( test , p - > value . text , " Apple Inc. " ) ;
p = tb_property_find ( dir , " vendorid " , TB_PROPERTY_TYPE_VALUE ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , p - > value . immediate , 0xa27 ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( dir , " deviceid " , TB_PROPERTY_TYPE_TEXT ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2020-05-04 17:00:38 +03:00
KUNIT_EXPECT_STREQ ( test , p - > value . text , " Macintosh " ) ;
p = tb_property_find ( dir , " deviceid " , TB_PROPERTY_TYPE_VALUE ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , p - > value . immediate , 0xa ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( dir , " missing " , TB_PROPERTY_TYPE_DIRECTORY ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NULL ( test , p ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( dir , " network " , TB_PROPERTY_TYPE_DIRECTORY ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2020-05-04 17:00:38 +03:00
network_dir = p - > value . dir ;
KUNIT_EXPECT_TRUE ( test , uuid_equal ( network_dir - > uuid , & network_dir_uuid ) ) ;
p = tb_property_find ( network_dir , " prtcid " , TB_PROPERTY_TYPE_VALUE ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , p - > value . immediate , 0x1 ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( network_dir , " prtcvers " , TB_PROPERTY_TYPE_VALUE ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , p - > value . immediate , 0x1 ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( network_dir , " prtcrevs " , TB_PROPERTY_TYPE_VALUE ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , p - > value . immediate , 0x1 ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( network_dir , " prtcstns " , TB_PROPERTY_TYPE_VALUE ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p ) ;
2021-05-13 22:32:01 +03:00
KUNIT_EXPECT_EQ ( test , p - > value . immediate , 0x0 ) ;
2020-05-04 17:00:38 +03:00
p = tb_property_find ( network_dir , " deviceid " , TB_PROPERTY_TYPE_VALUE ) ;
KUNIT_EXPECT_TRUE ( test , ! p ) ;
p = tb_property_find ( network_dir , " deviceid " , TB_PROPERTY_TYPE_TEXT ) ;
KUNIT_EXPECT_TRUE ( test , ! p ) ;
tb_property_free_dir ( dir ) ;
}
static void tb_test_property_format ( struct kunit * test )
{
struct tb_property_dir * dir ;
ssize_t block_len ;
u32 * block ;
int ret , i ;
dir = tb_property_parse_dir ( root_directory , ARRAY_SIZE ( root_directory ) ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dir ) ;
2020-05-04 17:00:38 +03:00
ret = tb_property_format_dir ( dir , NULL , 0 ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , ret , ARRAY_SIZE ( root_directory ) ) ;
2020-05-04 17:00:38 +03:00
block_len = ret ;
block = kunit_kzalloc ( test , block_len * sizeof ( u32 ) , GFP_KERNEL ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , block ) ;
2020-05-04 17:00:38 +03:00
ret = tb_property_format_dir ( dir , block , block_len ) ;
KUNIT_EXPECT_EQ ( test , ret , 0 ) ;
for ( i = 0 ; i < ARRAY_SIZE ( root_directory ) ; i + + )
KUNIT_EXPECT_EQ ( test , root_directory [ i ] , block [ i ] ) ;
tb_property_free_dir ( dir ) ;
}
static void compare_dirs ( struct kunit * test , struct tb_property_dir * d1 ,
struct tb_property_dir * d2 )
{
struct tb_property * p1 , * p2 , * tmp ;
int n1 , n2 , i ;
if ( d1 - > uuid ) {
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , d2 - > uuid ) ;
2020-05-04 17:00:38 +03:00
KUNIT_ASSERT_TRUE ( test , uuid_equal ( d1 - > uuid , d2 - > uuid ) ) ;
} else {
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NULL ( test , d2 - > uuid ) ;
2020-05-04 17:00:38 +03:00
}
n1 = 0 ;
tb_property_for_each ( d1 , tmp )
n1 + + ;
KUNIT_ASSERT_NE ( test , n1 , 0 ) ;
n2 = 0 ;
tb_property_for_each ( d2 , tmp )
n2 + + ;
KUNIT_ASSERT_NE ( test , n2 , 0 ) ;
KUNIT_ASSERT_EQ ( test , n1 , n2 ) ;
p1 = NULL ;
p2 = NULL ;
for ( i = 0 ; i < n1 ; i + + ) {
p1 = tb_property_get_next ( d1 , p1 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p1 ) ;
2020-05-04 17:00:38 +03:00
p2 = tb_property_get_next ( d2 , p2 ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p2 ) ;
2020-05-04 17:00:38 +03:00
KUNIT_ASSERT_STREQ ( test , & p1 - > key [ 0 ] , & p2 - > key [ 0 ] ) ;
KUNIT_ASSERT_EQ ( test , p1 - > type , p2 - > type ) ;
KUNIT_ASSERT_EQ ( test , p1 - > length , p2 - > length ) ;
switch ( p1 - > type ) {
case TB_PROPERTY_TYPE_DIRECTORY :
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p1 - > value . dir ) ;
KUNIT_ASSERT_NOT_NULL ( test , p2 - > value . dir ) ;
2020-05-04 17:00:38 +03:00
compare_dirs ( test , p1 - > value . dir , p2 - > value . dir ) ;
break ;
case TB_PROPERTY_TYPE_DATA :
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p1 - > value . data ) ;
KUNIT_ASSERT_NOT_NULL ( test , p2 - > value . data ) ;
2020-05-04 17:00:38 +03:00
KUNIT_ASSERT_TRUE ( test ,
! memcmp ( p1 - > value . data , p2 - > value . data ,
p1 - > length * 4 )
) ;
break ;
case TB_PROPERTY_TYPE_TEXT :
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , p1 - > value . text ) ;
KUNIT_ASSERT_NOT_NULL ( test , p2 - > value . text ) ;
2020-05-04 17:00:38 +03:00
KUNIT_ASSERT_STREQ ( test , p1 - > value . text , p2 - > value . text ) ;
break ;
case TB_PROPERTY_TYPE_VALUE :
KUNIT_ASSERT_EQ ( test , p1 - > value . immediate ,
p2 - > value . immediate ) ;
break ;
default :
KUNIT_FAIL ( test , " unexpected property type " ) ;
break ;
}
}
}
static void tb_test_property_copy ( struct kunit * test )
{
struct tb_property_dir * src , * dst ;
u32 * block ;
int ret , i ;
src = tb_property_parse_dir ( root_directory , ARRAY_SIZE ( root_directory ) ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , src ) ;
2020-05-04 17:00:38 +03:00
dst = tb_property_copy_dir ( src ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , dst ) ;
2020-05-04 17:00:38 +03:00
/* Compare the structures */
compare_dirs ( test , src , dst ) ;
/* Compare the resulting property block */
ret = tb_property_format_dir ( dst , NULL , 0 ) ;
2021-05-13 22:32:01 +03:00
KUNIT_ASSERT_EQ ( test , ret , ARRAY_SIZE ( root_directory ) ) ;
2020-05-04 17:00:38 +03:00
block = kunit_kzalloc ( test , sizeof ( root_directory ) , GFP_KERNEL ) ;
2022-02-11 19:42:43 +03:00
KUNIT_ASSERT_NOT_NULL ( test , block ) ;
2020-05-04 17:00:38 +03:00
ret = tb_property_format_dir ( dst , block , ARRAY_SIZE ( root_directory ) ) ;
KUNIT_EXPECT_TRUE ( test , ! ret ) ;
for ( i = 0 ; i < ARRAY_SIZE ( root_directory ) ; i + + )
KUNIT_EXPECT_EQ ( test , root_directory [ i ] , block [ i ] ) ;
tb_property_free_dir ( dst ) ;
tb_property_free_dir ( src ) ;
}
2020-04-29 16:38:39 +03:00
static struct kunit_case tb_test_cases [ ] = {
KUNIT_CASE ( tb_test_path_basic ) ,
KUNIT_CASE ( tb_test_path_not_connected_walk ) ,
KUNIT_CASE ( tb_test_path_single_hop_walk ) ,
KUNIT_CASE ( tb_test_path_daisy_chain_walk ) ,
KUNIT_CASE ( tb_test_path_simple_tree_walk ) ,
KUNIT_CASE ( tb_test_path_complex_tree_walk ) ,
KUNIT_CASE ( tb_test_path_max_length_walk ) ,
KUNIT_CASE ( tb_test_path_not_connected ) ,
KUNIT_CASE ( tb_test_path_not_bonded_lane0 ) ,
KUNIT_CASE ( tb_test_path_not_bonded_lane1 ) ,
KUNIT_CASE ( tb_test_path_not_bonded_lane1_chain ) ,
KUNIT_CASE ( tb_test_path_not_bonded_lane1_chain_reverse ) ,
KUNIT_CASE ( tb_test_path_mixed_chain ) ,
KUNIT_CASE ( tb_test_path_mixed_chain_reverse ) ,
2020-05-04 17:10:40 +03:00
KUNIT_CASE ( tb_test_tunnel_pcie ) ,
KUNIT_CASE ( tb_test_tunnel_dp ) ,
KUNIT_CASE ( tb_test_tunnel_dp_chain ) ,
KUNIT_CASE ( tb_test_tunnel_dp_tree ) ,
KUNIT_CASE ( tb_test_tunnel_dp_max_length ) ,
2022-02-14 15:09:50 +03:00
KUNIT_CASE ( tb_test_tunnel_3dp ) ,
2020-05-04 17:10:40 +03:00
KUNIT_CASE ( tb_test_tunnel_port_on_path ) ,
KUNIT_CASE ( tb_test_tunnel_usb3 ) ,
2021-01-08 17:32:19 +03:00
KUNIT_CASE ( tb_test_tunnel_dma ) ,
KUNIT_CASE ( tb_test_tunnel_dma_rx ) ,
KUNIT_CASE ( tb_test_tunnel_dma_tx ) ,
KUNIT_CASE ( tb_test_tunnel_dma_chain ) ,
KUNIT_CASE ( tb_test_tunnel_dma_match ) ,
2021-04-28 19:04:02 +03:00
KUNIT_CASE ( tb_test_credit_alloc_legacy_not_bonded ) ,
KUNIT_CASE ( tb_test_credit_alloc_legacy_bonded ) ,
KUNIT_CASE ( tb_test_credit_alloc_pcie ) ,
2022-05-09 23:49:04 +03:00
KUNIT_CASE ( tb_test_credit_alloc_without_dp ) ,
2021-04-28 19:04:02 +03:00
KUNIT_CASE ( tb_test_credit_alloc_dp ) ,
KUNIT_CASE ( tb_test_credit_alloc_usb3 ) ,
KUNIT_CASE ( tb_test_credit_alloc_dma ) ,
KUNIT_CASE ( tb_test_credit_alloc_dma_multiple ) ,
KUNIT_CASE ( tb_test_credit_alloc_all ) ,
2020-05-04 17:00:38 +03:00
KUNIT_CASE ( tb_test_property_parse ) ,
KUNIT_CASE ( tb_test_property_format ) ,
KUNIT_CASE ( tb_test_property_copy ) ,
2020-04-29 16:38:39 +03:00
{ }
} ;
static struct kunit_suite tb_test_suite = {
. name = " thunderbolt " ,
. test_cases = tb_test_cases ,
} ;
2020-08-24 12:46:52 +03:00
2022-07-09 06:19:59 +03:00
kunit_test_suite ( tb_test_suite ) ;