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 ;
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 ;
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 ;
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 ;
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 ;
}
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 ;
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 ;
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 ;
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 ;
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 ;
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 ;
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 ;
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 ;
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 ;
}
if ( bonded ) {
/* Bonding is used */
port - > bonded = true ;
port - > dual_link_port - > bonded = true ;
upstream_port - > bonded = true ;
upstream_port - > dual_link_port - > bonded = true ;
}
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 ;
}
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
i + + ;
}
KUNIT_EXPECT_EQ ( test , i , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
i + + ;
}
KUNIT_EXPECT_EQ ( test , i , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
i + + ;
}
KUNIT_EXPECT_EQ ( test , i , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
i + + ;
}
KUNIT_EXPECT_EQ ( test , i , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
i + + ;
}
KUNIT_EXPECT_EQ ( test , i , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) p - > config . type ,
test_data [ i ] . type ) ;
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 " ) ;
KUNIT_ASSERT_TRUE ( test , path = = NULL ) ;
path = tb_path_alloc ( NULL , down , 8 , up , 8 , 1 , " PCIe Down " ) ;
KUNIT_ASSERT_TRUE ( test , path = = NULL ) ;
}
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 " ) ;
KUNIT_ASSERT_TRUE ( test , path ! = NULL ) ;
KUNIT_ASSERT_EQ ( test , path - > path_length , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
}
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 " ) ;
KUNIT_ASSERT_TRUE ( test , path ! = NULL ) ;
KUNIT_ASSERT_EQ ( test , path - > path_length , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
}
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 " ) ;
KUNIT_ASSERT_TRUE ( test , path ! = NULL ) ;
KUNIT_ASSERT_EQ ( test , path - > path_length , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
}
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 " ) ;
KUNIT_ASSERT_TRUE ( test , path ! = NULL ) ;
KUNIT_ASSERT_EQ ( test , path - > path_length , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
}
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 " ) ;
KUNIT_ASSERT_TRUE ( test , path ! = NULL ) ;
KUNIT_ASSERT_EQ ( test , path - > path_length , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
}
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 " ) ;
KUNIT_ASSERT_TRUE ( test , path ! = NULL ) ;
KUNIT_ASSERT_EQ ( test , path - > path_length , ( int ) ARRAY_SIZE ( test_data ) ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) in_port - > config . type ,
test_data [ i ] . in_type ) ;
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 ) ;
KUNIT_EXPECT_EQ ( test , ( enum tb_port_type ) out_port - > config . type ,
test_data [ i ] . out_type ) ;
}
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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel1 ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel1 - > type , ( enum tb_tunnel_type ) TB_TUNNEL_PCI ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > dst_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel1 - > npaths , ( size_t ) 2 ) ;
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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel2 ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel2 - > type , ( enum tb_tunnel_type ) TB_TUNNEL_PCI ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > dst_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel2 - > npaths , ( size_t ) 2 ) ;
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 ] ;
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DP ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 3 ) ;
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 ] ;
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DP ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 3 ) ;
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 ] ;
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DP ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 3 ) ;
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 ] ;
tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DP ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , in ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , out ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 3 ) ;
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 ) ;
}
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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel1 ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel1 - > type , ( enum tb_tunnel_type ) TB_TUNNEL_USB3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel1 - > dst_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel1 - > npaths , ( size_t ) 2 ) ;
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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel2 ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel2 - > type , ( enum tb_tunnel_type ) TB_TUNNEL_USB3 ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > src_port , down ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel2 - > dst_port , up ) ;
KUNIT_ASSERT_EQ ( test , tunnel2 - > npaths , ( size_t ) 2 ) ;
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 ] ;
dp_tunnel = tb_tunnel_alloc_dp ( NULL , in , out , 0 , 0 ) ;
KUNIT_ASSERT_TRUE ( test , dp_tunnel ! = NULL ) ;
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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DMA ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
/* 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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DMA ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 1 ) ;
/* 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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DMA ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 1 ) ;
/* 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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , tunnel - > type , ( enum tb_tunnel_type ) TB_TUNNEL_DMA ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > src_port , nhi ) ;
KUNIT_EXPECT_PTR_EQ ( test , tunnel - > dst_port , port ) ;
KUNIT_ASSERT_EQ ( test , tunnel - > npaths , ( size_t ) 2 ) ;
/* 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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
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 ) ;
KUNIT_ASSERT_TRUE ( test , tunnel ! = NULL ) ;
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 ) ;
}
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 ) ) ;
KUNIT_ASSERT_TRUE ( test , dir ! = NULL ) ;
p = tb_property_find ( dir , " foo " , TB_PROPERTY_TYPE_TEXT ) ;
KUNIT_ASSERT_TRUE ( test , ! p ) ;
p = tb_property_find ( dir , " vendorid " , TB_PROPERTY_TYPE_TEXT ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_STREQ ( test , p - > value . text , " Apple Inc. " ) ;
p = tb_property_find ( dir , " vendorid " , TB_PROPERTY_TYPE_VALUE ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , p - > value . immediate , ( u32 ) 0xa27 ) ;
p = tb_property_find ( dir , " deviceid " , TB_PROPERTY_TYPE_TEXT ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_STREQ ( test , p - > value . text , " Macintosh " ) ;
p = tb_property_find ( dir , " deviceid " , TB_PROPERTY_TYPE_VALUE ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , p - > value . immediate , ( u32 ) 0xa ) ;
p = tb_property_find ( dir , " missing " , TB_PROPERTY_TYPE_DIRECTORY ) ;
KUNIT_ASSERT_TRUE ( test , ! p ) ;
p = tb_property_find ( dir , " network " , TB_PROPERTY_TYPE_DIRECTORY ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
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 ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , p - > value . immediate , ( u32 ) 0x1 ) ;
p = tb_property_find ( network_dir , " prtcvers " , TB_PROPERTY_TYPE_VALUE ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , p - > value . immediate , ( u32 ) 0x1 ) ;
p = tb_property_find ( network_dir , " prtcrevs " , TB_PROPERTY_TYPE_VALUE ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , p - > value . immediate , ( u32 ) 0x1 ) ;
p = tb_property_find ( network_dir , " prtcstns " , TB_PROPERTY_TYPE_VALUE ) ;
KUNIT_ASSERT_TRUE ( test , p ! = NULL ) ;
KUNIT_EXPECT_EQ ( test , p - > value . immediate , ( u32 ) 0x0 ) ;
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 ) ) ;
KUNIT_ASSERT_TRUE ( test , dir ! = NULL ) ;
ret = tb_property_format_dir ( dir , NULL , 0 ) ;
KUNIT_ASSERT_EQ ( test , ret , ( int ) ARRAY_SIZE ( root_directory ) ) ;
block_len = ret ;
block = kunit_kzalloc ( test , block_len * sizeof ( u32 ) , GFP_KERNEL ) ;
KUNIT_ASSERT_TRUE ( test , block ! = NULL ) ;
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 ) {
KUNIT_ASSERT_TRUE ( test , d2 - > uuid ! = NULL ) ;
KUNIT_ASSERT_TRUE ( test , uuid_equal ( d1 - > uuid , d2 - > uuid ) ) ;
} else {
KUNIT_ASSERT_TRUE ( test , d2 - > uuid = = NULL ) ;
}
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 ) ;
KUNIT_ASSERT_TRUE ( test , p1 ! = NULL ) ;
p2 = tb_property_get_next ( d2 , p2 ) ;
KUNIT_ASSERT_TRUE ( test , p2 ! = NULL ) ;
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 :
KUNIT_ASSERT_TRUE ( test , p1 - > value . dir ! = NULL ) ;
KUNIT_ASSERT_TRUE ( test , p2 - > value . dir ! = NULL ) ;
compare_dirs ( test , p1 - > value . dir , p2 - > value . dir ) ;
break ;
case TB_PROPERTY_TYPE_DATA :
KUNIT_ASSERT_TRUE ( test , p1 - > value . data ! = NULL ) ;
KUNIT_ASSERT_TRUE ( test , p2 - > value . data ! = NULL ) ;
KUNIT_ASSERT_TRUE ( test ,
! memcmp ( p1 - > value . data , p2 - > value . data ,
p1 - > length * 4 )
) ;
break ;
case TB_PROPERTY_TYPE_TEXT :
KUNIT_ASSERT_TRUE ( test , p1 - > value . text ! = NULL ) ;
KUNIT_ASSERT_TRUE ( test , p2 - > value . text ! = NULL ) ;
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 ) ) ;
KUNIT_ASSERT_TRUE ( test , src ! = NULL ) ;
dst = tb_property_copy_dir ( src ) ;
KUNIT_ASSERT_TRUE ( test , dst ! = NULL ) ;
/* Compare the structures */
compare_dirs ( test , src , dst ) ;
/* Compare the resulting property block */
ret = tb_property_format_dir ( dst , NULL , 0 ) ;
KUNIT_ASSERT_EQ ( test , ret , ( int ) ARRAY_SIZE ( root_directory ) ) ;
block = kunit_kzalloc ( test , sizeof ( root_directory ) , GFP_KERNEL ) ;
KUNIT_ASSERT_TRUE ( test , block ! = NULL ) ;
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 ) ,
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 ) ,
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
static struct kunit_suite * tb_test_suites [ ] = { & tb_test_suite , NULL } ;
int tb_test_init ( void )
{
return __kunit_test_suites_init ( tb_test_suites ) ;
}
void tb_test_exit ( void )
{
return __kunit_test_suites_exit ( tb_test_suites ) ;
}