2023-07-18 16:03:02 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* KUnit test for the FPGA Bridge
*
* Copyright ( C ) 2023 Red Hat , Inc .
*
* Author : Marco Pagani < marpagan @ redhat . com >
*/
2024-03-29 20:48:47 +03:00
# include <kunit/device.h>
2023-07-18 16:03:02 +03:00
# include <kunit/test.h>
# include <linux/fpga/fpga-bridge.h>
# include <linux/module.h>
# include <linux/types.h>
struct bridge_stats {
bool enable ;
} ;
struct bridge_ctx {
struct fpga_bridge * bridge ;
2024-03-29 20:48:47 +03:00
struct device * dev ;
2023-07-18 16:03:02 +03:00
struct bridge_stats stats ;
} ;
static int op_enable_set ( struct fpga_bridge * bridge , bool enable )
{
struct bridge_stats * stats = bridge - > priv ;
stats - > enable = enable ;
return 0 ;
}
/*
* Fake FPGA bridge that implements only the enable_set op to track
* the state .
*/
static const struct fpga_bridge_ops fake_bridge_ops = {
. enable_set = op_enable_set ,
} ;
/**
* register_test_bridge ( ) - Register a fake FPGA bridge for testing .
* @ test : KUnit test context object .
2024-03-29 20:48:47 +03:00
* @ dev_name : name of the kunit device to be registered
2023-07-18 16:03:02 +03:00
*
* Return : Context of the newly registered FPGA bridge .
*/
2024-03-29 20:48:47 +03:00
static struct bridge_ctx * register_test_bridge ( struct kunit * test , const char * dev_name )
2023-07-18 16:03:02 +03:00
{
struct bridge_ctx * ctx ;
ctx = kunit_kzalloc ( test , sizeof ( * ctx ) , GFP_KERNEL ) ;
KUNIT_ASSERT_NOT_ERR_OR_NULL ( test , ctx ) ;
2024-03-29 20:48:47 +03:00
ctx - > dev = kunit_device_register ( test , dev_name ) ;
KUNIT_ASSERT_NOT_ERR_OR_NULL ( test , ctx - > dev ) ;
2023-07-18 16:03:02 +03:00
2024-03-29 20:48:47 +03:00
ctx - > bridge = fpga_bridge_register ( ctx - > dev , " Fake FPGA bridge " , & fake_bridge_ops ,
2023-07-18 16:03:02 +03:00
& ctx - > stats ) ;
KUNIT_ASSERT_FALSE ( test , IS_ERR_OR_NULL ( ctx - > bridge ) ) ;
return ctx ;
}
2024-03-29 20:48:47 +03:00
static void unregister_test_bridge ( struct kunit * test , struct bridge_ctx * ctx )
2023-07-18 16:03:02 +03:00
{
fpga_bridge_unregister ( ctx - > bridge ) ;
2024-03-29 20:48:47 +03:00
kunit_device_unregister ( test , ctx - > dev ) ;
2023-07-18 16:03:02 +03:00
}
static void fpga_bridge_test_get ( struct kunit * test )
{
struct bridge_ctx * ctx = test - > priv ;
struct fpga_bridge * bridge ;
2024-03-29 20:48:47 +03:00
bridge = fpga_bridge_get ( ctx - > dev , NULL ) ;
2023-07-18 16:03:02 +03:00
KUNIT_EXPECT_PTR_EQ ( test , bridge , ctx - > bridge ) ;
2024-03-29 20:48:47 +03:00
bridge = fpga_bridge_get ( ctx - > dev , NULL ) ;
2023-07-18 16:03:02 +03:00
KUNIT_EXPECT_EQ ( test , PTR_ERR ( bridge ) , - EBUSY ) ;
fpga_bridge_put ( ctx - > bridge ) ;
}
static void fpga_bridge_test_toggle ( struct kunit * test )
{
struct bridge_ctx * ctx = test - > priv ;
int ret ;
ret = fpga_bridge_disable ( ctx - > bridge ) ;
KUNIT_EXPECT_EQ ( test , ret , 0 ) ;
KUNIT_EXPECT_FALSE ( test , ctx - > stats . enable ) ;
ret = fpga_bridge_enable ( ctx - > bridge ) ;
KUNIT_EXPECT_EQ ( test , ret , 0 ) ;
KUNIT_EXPECT_TRUE ( test , ctx - > stats . enable ) ;
}
/* Test the functions for getting and controlling a list of bridges */
static void fpga_bridge_test_get_put_list ( struct kunit * test )
{
struct list_head bridge_list ;
struct bridge_ctx * ctx_0 , * ctx_1 ;
int ret ;
ctx_0 = test - > priv ;
2024-03-29 20:48:47 +03:00
ctx_1 = register_test_bridge ( test , " fpga-bridge-test-dev-1 " ) ;
2023-07-18 16:03:02 +03:00
INIT_LIST_HEAD ( & bridge_list ) ;
/* Get bridge 0 and add it to the list */
2024-03-29 20:48:47 +03:00
ret = fpga_bridge_get_to_list ( ctx_0 - > dev , NULL , & bridge_list ) ;
2023-07-18 16:03:02 +03:00
KUNIT_EXPECT_EQ ( test , ret , 0 ) ;
KUNIT_EXPECT_PTR_EQ ( test , ctx_0 - > bridge ,
list_first_entry_or_null ( & bridge_list , struct fpga_bridge , node ) ) ;
/* Get bridge 1 and add it to the list */
2024-03-29 20:48:47 +03:00
ret = fpga_bridge_get_to_list ( ctx_1 - > dev , NULL , & bridge_list ) ;
2023-07-18 16:03:02 +03:00
KUNIT_EXPECT_EQ ( test , ret , 0 ) ;
KUNIT_EXPECT_PTR_EQ ( test , ctx_1 - > bridge ,
list_first_entry_or_null ( & bridge_list , struct fpga_bridge , node ) ) ;
/* Disable an then enable both bridges from the list */
ret = fpga_bridges_disable ( & bridge_list ) ;
KUNIT_EXPECT_EQ ( test , ret , 0 ) ;
KUNIT_EXPECT_FALSE ( test , ctx_0 - > stats . enable ) ;
KUNIT_EXPECT_FALSE ( test , ctx_1 - > stats . enable ) ;
ret = fpga_bridges_enable ( & bridge_list ) ;
KUNIT_EXPECT_EQ ( test , ret , 0 ) ;
KUNIT_EXPECT_TRUE ( test , ctx_0 - > stats . enable ) ;
KUNIT_EXPECT_TRUE ( test , ctx_1 - > stats . enable ) ;
/* Put and remove both bridges from the list */
fpga_bridges_put ( & bridge_list ) ;
KUNIT_EXPECT_TRUE ( test , list_empty ( & bridge_list ) ) ;
2024-03-29 20:48:47 +03:00
unregister_test_bridge ( test , ctx_1 ) ;
2023-07-18 16:03:02 +03:00
}
static int fpga_bridge_test_init ( struct kunit * test )
{
2024-03-29 20:48:47 +03:00
test - > priv = register_test_bridge ( test , " fpga-bridge-test-dev-0 " ) ;
2023-07-18 16:03:02 +03:00
return 0 ;
}
static void fpga_bridge_test_exit ( struct kunit * test )
{
2024-03-29 20:48:47 +03:00
unregister_test_bridge ( test , test - > priv ) ;
2023-07-18 16:03:02 +03:00
}
static struct kunit_case fpga_bridge_test_cases [ ] = {
KUNIT_CASE ( fpga_bridge_test_get ) ,
KUNIT_CASE ( fpga_bridge_test_toggle ) ,
KUNIT_CASE ( fpga_bridge_test_get_put_list ) ,
{ }
} ;
static struct kunit_suite fpga_bridge_suite = {
. name = " fpga_bridge " ,
. init = fpga_bridge_test_init ,
. exit = fpga_bridge_test_exit ,
. test_cases = fpga_bridge_test_cases ,
} ;
kunit_test_suite ( fpga_bridge_suite ) ;
MODULE_LICENSE ( " GPL " ) ;