Skip to content

Commit 75d4710

Browse files
committed
firewire: core: add tests for serialization/deserialization of phy config packet
In the protocol of IEEE 1394, phy configuration packet is broadcasted to the bus to configure all PHYs residing on the bus. It includes two purposes; selecting root node and optimizing gap count. This commit adds some helper function to serialize/deserialize the content of phy configuration packet, as well as some KUnit tests for it. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Sakamoto <[email protected]>
1 parent 677ceae commit 75d4710

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

drivers/firewire/packet-serdes-test.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,29 @@ static void deserialize_phy_packet_self_id_extended(u32 quadlet, unsigned int *p
248248
*has_more_packets = phy_packet_self_id_get_more_packets(quadlet);
249249
}
250250

251+
static void serialize_phy_packet_phy_config(u32 *quadlet, unsigned int packet_identifier,
252+
unsigned int root_id, bool has_force_root_node,
253+
bool has_gap_count_optimization, unsigned int gap_count)
254+
{
255+
phy_packet_set_packet_identifier(quadlet, packet_identifier);
256+
phy_packet_phy_config_set_root_id(quadlet, root_id);
257+
phy_packet_phy_config_set_force_root_node(quadlet, has_force_root_node);
258+
phy_packet_phy_config_set_gap_count_optimization(quadlet, has_gap_count_optimization);
259+
phy_packet_phy_config_set_gap_count(quadlet, gap_count);
260+
}
261+
262+
static void deserialize_phy_packet_phy_config(u32 quadlet, unsigned int *packet_identifier,
263+
unsigned int *root_id, bool *has_force_root_node,
264+
bool *has_gap_count_optimization,
265+
unsigned int *gap_count)
266+
{
267+
*packet_identifier = phy_packet_get_packet_identifier(quadlet);
268+
*root_id = phy_packet_phy_config_get_root_id(quadlet);
269+
*has_force_root_node = phy_packet_phy_config_get_force_root_node(quadlet);
270+
*has_gap_count_optimization = phy_packet_phy_config_get_gap_count_optimization(quadlet);
271+
*gap_count = phy_packet_phy_config_get_gap_count(quadlet);
272+
}
273+
251274
static void test_async_header_write_quadlet_request(struct kunit *test)
252275
{
253276
static const u32 expected[ASYNC_HEADER_QUADLET_COUNT] = {
@@ -811,6 +834,60 @@ static void test_phy_packet_self_id_zero_and_one(struct kunit *test)
811834
KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
812835
}
813836

837+
static void test_phy_packet_phy_config_force_root_node(struct kunit *test)
838+
{
839+
const u32 expected = 0x02800000;
840+
u32 quadlet = 0;
841+
842+
unsigned int packet_identifier;
843+
unsigned int root_id;
844+
bool has_force_root_node;
845+
bool has_gap_count_optimization;
846+
unsigned int gap_count;
847+
848+
deserialize_phy_packet_phy_config(expected, &packet_identifier, &root_id,
849+
&has_force_root_node, &has_gap_count_optimization,
850+
&gap_count);
851+
852+
KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG, packet_identifier);
853+
KUNIT_EXPECT_EQ(test, 0x02, root_id);
854+
KUNIT_EXPECT_TRUE(test, has_force_root_node);
855+
KUNIT_EXPECT_FALSE(test, has_gap_count_optimization);
856+
KUNIT_EXPECT_EQ(test, 0, gap_count);
857+
858+
serialize_phy_packet_phy_config(&quadlet, packet_identifier, root_id, has_force_root_node,
859+
has_gap_count_optimization, gap_count);
860+
861+
KUNIT_EXPECT_EQ(test, quadlet, expected);
862+
}
863+
864+
static void test_phy_packet_phy_config_gap_count_optimization(struct kunit *test)
865+
{
866+
const u32 expected = 0x034f0000;
867+
u32 quadlet = 0;
868+
869+
unsigned int packet_identifier;
870+
unsigned int root_id;
871+
bool has_force_root_node;
872+
bool has_gap_count_optimization;
873+
unsigned int gap_count;
874+
875+
deserialize_phy_packet_phy_config(expected, &packet_identifier, &root_id,
876+
&has_force_root_node, &has_gap_count_optimization,
877+
&gap_count);
878+
879+
KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG, packet_identifier);
880+
KUNIT_EXPECT_EQ(test, 0x03, root_id);
881+
KUNIT_EXPECT_FALSE(test, has_force_root_node);
882+
KUNIT_EXPECT_TRUE(test, has_gap_count_optimization);
883+
KUNIT_EXPECT_EQ(test, 0x0f, gap_count);
884+
885+
serialize_phy_packet_phy_config(&quadlet, packet_identifier, root_id, has_force_root_node,
886+
has_gap_count_optimization, gap_count);
887+
888+
KUNIT_EXPECT_EQ(test, quadlet, expected);
889+
}
890+
814891
static struct kunit_case packet_serdes_test_cases[] = {
815892
KUNIT_CASE(test_async_header_write_quadlet_request),
816893
KUNIT_CASE(test_async_header_write_block_request),
@@ -825,6 +902,8 @@ static struct kunit_case packet_serdes_test_cases[] = {
825902
KUNIT_CASE(test_phy_packet_self_id_zero_case0),
826903
KUNIT_CASE(test_phy_packet_self_id_zero_case1),
827904
KUNIT_CASE(test_phy_packet_self_id_zero_and_one),
905+
KUNIT_CASE(test_phy_packet_phy_config_force_root_node),
906+
KUNIT_CASE(test_phy_packet_phy_config_gap_count_optimization),
828907
{}
829908
};
830909

drivers/firewire/phy-packet-definitions.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,61 @@ static inline void phy_packet_set_packet_identifier(u32 *quadlet, unsigned int p
2121
*quadlet |= (packet_identifier << PACKET_IDENTIFIER_SHIFT) & PACKET_IDENTIFIER_MASK;
2222
}
2323

24+
#define PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG 0
25+
26+
#define PHY_CONFIG_ROOT_ID_MASK 0x3f000000
27+
#define PHY_CONFIG_ROOT_ID_SHIFT 24
28+
#define PHY_CONFIG_FORCE_ROOT_NODE_MASK 0x00800000
29+
#define PHY_CONFIG_FORCE_ROOT_NODE_SHIFT 23
30+
#define PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK 0x00400000
31+
#define PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT 22
32+
#define PHY_CONFIG_GAP_COUNT_MASK 0x003f0000
33+
#define PHY_CONFIG_GAP_COUNT_SHIFT 16
34+
35+
static inline unsigned int phy_packet_phy_config_get_root_id(u32 quadlet)
36+
{
37+
return (quadlet & PHY_CONFIG_ROOT_ID_MASK) >> PHY_CONFIG_ROOT_ID_SHIFT;
38+
}
39+
40+
static inline void phy_packet_phy_config_set_root_id(u32 *quadlet, unsigned int root_id)
41+
{
42+
*quadlet &= ~PHY_CONFIG_ROOT_ID_MASK;
43+
*quadlet |= (root_id << PHY_CONFIG_ROOT_ID_SHIFT) & PHY_CONFIG_ROOT_ID_MASK;
44+
}
45+
46+
static inline bool phy_packet_phy_config_get_force_root_node(u32 quadlet)
47+
{
48+
return (quadlet & PHY_CONFIG_FORCE_ROOT_NODE_MASK) >> PHY_CONFIG_FORCE_ROOT_NODE_SHIFT;
49+
}
50+
51+
static inline void phy_packet_phy_config_set_force_root_node(u32 *quadlet, bool has_force_root_node)
52+
{
53+
*quadlet &= ~PHY_CONFIG_FORCE_ROOT_NODE_MASK;
54+
*quadlet |= (has_force_root_node << PHY_CONFIG_FORCE_ROOT_NODE_SHIFT) & PHY_CONFIG_FORCE_ROOT_NODE_MASK;
55+
}
56+
57+
static inline bool phy_packet_phy_config_get_gap_count_optimization(u32 quadlet)
58+
{
59+
return (quadlet & PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK) >> PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT;
60+
}
61+
62+
static inline void phy_packet_phy_config_set_gap_count_optimization(u32 *quadlet, bool has_gap_count_optimization)
63+
{
64+
*quadlet &= ~PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK;
65+
*quadlet |= (has_gap_count_optimization << PHY_CONFIG_GAP_COUNT_OPTIMIZATION_SHIFT) & PHY_CONFIG_GAP_COUNT_OPTIMIZATION_MASK;
66+
}
67+
68+
static inline unsigned int phy_packet_phy_config_get_gap_count(u32 quadlet)
69+
{
70+
return (quadlet & PHY_CONFIG_GAP_COUNT_MASK) >> PHY_CONFIG_GAP_COUNT_SHIFT;
71+
}
72+
73+
static inline void phy_packet_phy_config_set_gap_count(u32 *quadlet, unsigned int gap_count)
74+
{
75+
*quadlet &= ~PHY_CONFIG_GAP_COUNT_MASK;
76+
*quadlet |= (gap_count << PHY_CONFIG_GAP_COUNT_SHIFT) & PHY_CONFIG_GAP_COUNT_MASK;
77+
}
78+
2479
#define PHY_PACKET_PACKET_IDENTIFIER_SELF_ID 2
2580

2681
#define SELF_ID_PHY_ID_MASK 0x3f000000

0 commit comments

Comments
 (0)