Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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/20240606235133.231543-2-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

+134
+79
drivers/firewire/packet-serdes-test.c
··· 248 248 *has_more_packets = phy_packet_self_id_get_more_packets(quadlet); 249 249 } 250 250 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 + 251 274 static void test_async_header_write_quadlet_request(struct kunit *test) 252 275 { 253 276 static const u32 expected[ASYNC_HEADER_QUADLET_COUNT] = { ··· 834 811 KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected)); 835 812 } 836 813 814 + static void test_phy_packet_phy_config_force_root_node(struct kunit *test) 815 + { 816 + const u32 expected = 0x02800000; 817 + u32 quadlet = 0; 818 + 819 + unsigned int packet_identifier; 820 + unsigned int root_id; 821 + bool has_force_root_node; 822 + bool has_gap_count_optimization; 823 + unsigned int gap_count; 824 + 825 + deserialize_phy_packet_phy_config(expected, &packet_identifier, &root_id, 826 + &has_force_root_node, &has_gap_count_optimization, 827 + &gap_count); 828 + 829 + KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG, packet_identifier); 830 + KUNIT_EXPECT_EQ(test, 0x02, root_id); 831 + KUNIT_EXPECT_TRUE(test, has_force_root_node); 832 + KUNIT_EXPECT_FALSE(test, has_gap_count_optimization); 833 + KUNIT_EXPECT_EQ(test, 0, gap_count); 834 + 835 + serialize_phy_packet_phy_config(&quadlet, packet_identifier, root_id, has_force_root_node, 836 + has_gap_count_optimization, gap_count); 837 + 838 + KUNIT_EXPECT_EQ(test, quadlet, expected); 839 + } 840 + 841 + static void test_phy_packet_phy_config_gap_count_optimization(struct kunit *test) 842 + { 843 + const u32 expected = 0x034f0000; 844 + u32 quadlet = 0; 845 + 846 + unsigned int packet_identifier; 847 + unsigned int root_id; 848 + bool has_force_root_node; 849 + bool has_gap_count_optimization; 850 + unsigned int gap_count; 851 + 852 + deserialize_phy_packet_phy_config(expected, &packet_identifier, &root_id, 853 + &has_force_root_node, &has_gap_count_optimization, 854 + &gap_count); 855 + 856 + KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG, packet_identifier); 857 + KUNIT_EXPECT_EQ(test, 0x03, root_id); 858 + KUNIT_EXPECT_FALSE(test, has_force_root_node); 859 + KUNIT_EXPECT_TRUE(test, has_gap_count_optimization); 860 + KUNIT_EXPECT_EQ(test, 0x0f, gap_count); 861 + 862 + serialize_phy_packet_phy_config(&quadlet, packet_identifier, root_id, has_force_root_node, 863 + has_gap_count_optimization, gap_count); 864 + 865 + KUNIT_EXPECT_EQ(test, quadlet, expected); 866 + } 867 + 837 868 static struct kunit_case packet_serdes_test_cases[] = { 838 869 KUNIT_CASE(test_async_header_write_quadlet_request), 839 870 KUNIT_CASE(test_async_header_write_block_request), ··· 902 825 KUNIT_CASE(test_phy_packet_self_id_zero_case0), 903 826 KUNIT_CASE(test_phy_packet_self_id_zero_case1), 904 827 KUNIT_CASE(test_phy_packet_self_id_zero_and_one), 828 + KUNIT_CASE(test_phy_packet_phy_config_force_root_node), 829 + KUNIT_CASE(test_phy_packet_phy_config_gap_count_optimization), 905 830 {} 906 831 }; 907 832
+55
drivers/firewire/phy-packet-definitions.h
··· 21 21 *quadlet |= (packet_identifier << PACKET_IDENTIFIER_SHIFT) & PACKET_IDENTIFIER_MASK; 22 22 } 23 23 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 + 24 79 #define PHY_PACKET_PACKET_IDENTIFIER_SELF_ID 2 25 80 26 81 #define SELF_ID_PHY_ID_MASK 0x3f000000