Skip to content

Commit baf9d20

Browse files
committed
firewire: core: add common inline functions to serialize/deserialize self ID packet
Within FireWire subsystem, the serializations and deserializations of phy packet are implemented in several parts. They includes some redundancies. This commit adds a series of helper functions for the serializations and deserializations of self ID packet with a Kunit test suite. Link: https://lore.kernel.org/r/20240605235155.116468-8-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
1 parent a16931a commit baf9d20

2 files changed

Lines changed: 381 additions & 0 deletions

File tree

drivers/firewire/packet-serdes-test.c

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/firewire-constants.h>
1111

1212
#include "packet-header-definitions.h"
13+
#include "phy-packet-definitions.h"
1314

1415
static void serialize_async_header_common(u32 header[ASYNC_HEADER_QUADLET_COUNT],
1516
unsigned int dst_id, unsigned int tlabel,
@@ -187,6 +188,66 @@ static void deserialize_isoc_header(u32 header, unsigned int *data_length, unsig
187188
*sy = isoc_header_get_sy(header);
188189
}
189190

191+
static void serialize_phy_packet_self_id_zero(u32 *quadlet, unsigned int packet_identifier,
192+
unsigned int phy_id, bool extended,
193+
bool link_is_active, unsigned int gap_count,
194+
unsigned int scode, bool is_contender,
195+
unsigned int power_class, bool is_initiated_reset,
196+
bool has_more_packets)
197+
{
198+
phy_packet_set_packet_identifier(quadlet, packet_identifier);
199+
phy_packet_self_id_set_phy_id(quadlet, phy_id);
200+
phy_packet_self_id_set_extended(quadlet, extended);
201+
phy_packet_self_id_zero_set_link_active(quadlet, link_is_active);
202+
phy_packet_self_id_zero_set_gap_count(quadlet, gap_count);
203+
phy_packet_self_id_zero_set_scode(quadlet, scode);
204+
phy_packet_self_id_zero_set_contender(quadlet, is_contender);
205+
phy_packet_self_id_zero_set_power_class(quadlet, power_class);
206+
phy_packet_self_id_zero_set_initiated_reset(quadlet, is_initiated_reset);
207+
phy_packet_self_id_set_more_packets(quadlet, has_more_packets);
208+
}
209+
210+
static void deserialize_phy_packet_self_id_zero(u32 quadlet, unsigned int *packet_identifier,
211+
unsigned int *phy_id, bool *extended,
212+
bool *link_is_active, unsigned int *gap_count,
213+
unsigned int *scode, bool *is_contender,
214+
unsigned int *power_class,
215+
bool *is_initiated_reset, bool *has_more_packets)
216+
{
217+
*packet_identifier = phy_packet_get_packet_identifier(quadlet);
218+
*phy_id = phy_packet_self_id_get_phy_id(quadlet);
219+
*extended = phy_packet_self_id_get_extended(quadlet);
220+
*link_is_active = phy_packet_self_id_zero_get_link_active(quadlet);
221+
*gap_count = phy_packet_self_id_zero_get_gap_count(quadlet);
222+
*scode = phy_packet_self_id_zero_get_scode(quadlet);
223+
*is_contender = phy_packet_self_id_zero_get_contender(quadlet);
224+
*power_class = phy_packet_self_id_zero_get_power_class(quadlet);
225+
*is_initiated_reset = phy_packet_self_id_zero_get_initiated_reset(quadlet);
226+
*has_more_packets = phy_packet_self_id_get_more_packets(quadlet);
227+
}
228+
229+
static void serialize_phy_packet_self_id_extended(u32 *quadlet, unsigned int packet_identifier,
230+
unsigned int phy_id, bool extended,
231+
unsigned int sequence, bool has_more_packets)
232+
{
233+
phy_packet_set_packet_identifier(quadlet, packet_identifier);
234+
phy_packet_self_id_set_phy_id(quadlet, phy_id);
235+
phy_packet_self_id_set_extended(quadlet, extended);
236+
phy_packet_self_id_extended_set_sequence(quadlet, sequence);
237+
phy_packet_self_id_set_more_packets(quadlet, has_more_packets);
238+
}
239+
240+
static void deserialize_phy_packet_self_id_extended(u32 quadlet, unsigned int *packet_identifier,
241+
unsigned int *phy_id, bool *extended,
242+
unsigned int *sequence, bool *has_more_packets)
243+
{
244+
*packet_identifier = phy_packet_get_packet_identifier(quadlet);
245+
*phy_id = phy_packet_self_id_get_phy_id(quadlet);
246+
*extended = phy_packet_self_id_get_extended(quadlet);
247+
*sequence = phy_packet_self_id_extended_get_sequence(quadlet);
248+
*has_more_packets = phy_packet_self_id_get_more_packets(quadlet);
249+
}
250+
190251
static void test_async_header_write_quadlet_request(struct kunit *test)
191252
{
192253
static const u32 expected[ASYNC_HEADER_QUADLET_COUNT] = {
@@ -559,6 +620,197 @@ static void test_isoc_header(struct kunit *test)
559620
KUNIT_EXPECT_EQ(test, header, expected);
560621
}
561622

623+
static void test_phy_packet_self_id_zero_case0(struct kunit *test)
624+
{
625+
// TSB41AB1/2 with 1 port.
626+
const u32 expected[] = {0x80458c80};
627+
u32 quadlets[] = {0};
628+
629+
unsigned int packet_identifier;
630+
unsigned int phy_id;
631+
bool extended;
632+
bool link_is_active;
633+
unsigned int gap_count;
634+
unsigned int scode;
635+
bool is_contender;
636+
unsigned int power_class;
637+
enum phy_packet_self_id_port_status port_status[3];
638+
bool is_initiated_reset;
639+
bool has_more_packets;
640+
unsigned int port_index;
641+
642+
deserialize_phy_packet_self_id_zero(expected[0], &packet_identifier, &phy_id, &extended,
643+
&link_is_active, &gap_count, &scode, &is_contender,
644+
&power_class, &is_initiated_reset, &has_more_packets);
645+
646+
KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
647+
KUNIT_EXPECT_EQ(test, 0, phy_id);
648+
KUNIT_EXPECT_FALSE(test, extended);
649+
KUNIT_EXPECT_TRUE(test, link_is_active);
650+
KUNIT_EXPECT_EQ(test, 0x05, gap_count);
651+
KUNIT_EXPECT_EQ(test, SCODE_400, scode);
652+
KUNIT_EXPECT_TRUE(test, is_contender);
653+
KUNIT_EXPECT_EQ(test, 0x4, power_class);
654+
KUNIT_EXPECT_FALSE(test, is_initiated_reset);
655+
KUNIT_EXPECT_FALSE(test, has_more_packets);
656+
657+
serialize_phy_packet_self_id_zero(quadlets, packet_identifier, phy_id, extended,
658+
link_is_active, gap_count, scode, is_contender,
659+
power_class, is_initiated_reset, has_more_packets);
660+
661+
for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
662+
port_status[port_index] =
663+
self_id_sequence_get_port_status(expected, ARRAY_SIZE(expected), port_index);
664+
}
665+
666+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[0]);
667+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[1]);
668+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[2]);
669+
670+
for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
671+
self_id_sequence_set_port_status(quadlets, ARRAY_SIZE(quadlets), port_index,
672+
port_status[port_index]);
673+
}
674+
675+
KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
676+
}
677+
678+
static void test_phy_packet_self_id_zero_case1(struct kunit *test)
679+
{
680+
// XIO2213 and TSB81BA3E with 3 ports.
681+
const u32 expected[] = {0x817fcc5e};
682+
u32 quadlets[] = {0};
683+
684+
unsigned int packet_identifier;
685+
unsigned int phy_id;
686+
bool extended;
687+
bool link_is_active;
688+
unsigned int gap_count;
689+
unsigned int scode;
690+
bool is_contender;
691+
unsigned int power_class;
692+
enum phy_packet_self_id_port_status port_status[3];
693+
bool is_initiated_reset;
694+
bool has_more_packets;
695+
unsigned int port_index;
696+
697+
deserialize_phy_packet_self_id_zero(expected[0], &packet_identifier, &phy_id, &extended,
698+
&link_is_active, &gap_count, &scode, &is_contender,
699+
&power_class, &is_initiated_reset, &has_more_packets);
700+
701+
KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
702+
KUNIT_EXPECT_EQ(test, 1, phy_id);
703+
KUNIT_EXPECT_FALSE(test, extended);
704+
KUNIT_EXPECT_TRUE(test, link_is_active);
705+
KUNIT_EXPECT_EQ(test, 0x3f, gap_count);
706+
KUNIT_EXPECT_EQ(test, SCODE_800, scode);
707+
KUNIT_EXPECT_TRUE(test, is_contender);
708+
KUNIT_EXPECT_EQ(test, 0x4, power_class);
709+
KUNIT_EXPECT_TRUE(test, is_initiated_reset);
710+
KUNIT_EXPECT_FALSE(test, has_more_packets);
711+
712+
serialize_phy_packet_self_id_zero(quadlets, packet_identifier, phy_id, extended,
713+
link_is_active, gap_count, scode, is_contender,
714+
power_class, is_initiated_reset, has_more_packets);
715+
716+
for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
717+
port_status[port_index] =
718+
self_id_sequence_get_port_status(expected, ARRAY_SIZE(expected), port_index);
719+
}
720+
721+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[0]);
722+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[1]);
723+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[2]);
724+
725+
for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
726+
self_id_sequence_set_port_status(quadlets, ARRAY_SIZE(quadlets), port_index,
727+
port_status[port_index]);
728+
}
729+
730+
KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
731+
}
732+
733+
static void test_phy_packet_self_id_zero_and_one(struct kunit *test)
734+
{
735+
// TSB41LV06A with 6 ports.
736+
const u32 expected[] = {
737+
0x803f8459,
738+
0x80815000,
739+
};
740+
u32 quadlets[] = {0, 0};
741+
742+
unsigned int packet_identifier;
743+
unsigned int phy_id;
744+
bool extended;
745+
bool link_is_active;
746+
unsigned int gap_count;
747+
unsigned int scode;
748+
bool is_contender;
749+
unsigned int power_class;
750+
enum phy_packet_self_id_port_status port_status[11];
751+
bool is_initiated_reset;
752+
bool has_more_packets;
753+
754+
unsigned int sequence;
755+
unsigned int port_index;
756+
757+
deserialize_phy_packet_self_id_zero(expected[0], &packet_identifier, &phy_id, &extended,
758+
&link_is_active, &gap_count, &scode, &is_contender,
759+
&power_class, &is_initiated_reset, &has_more_packets);
760+
761+
KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
762+
KUNIT_EXPECT_EQ(test, 0, phy_id);
763+
KUNIT_EXPECT_FALSE(test, extended);
764+
KUNIT_EXPECT_FALSE(test, link_is_active);
765+
KUNIT_EXPECT_EQ(test, 0x3f, gap_count);
766+
KUNIT_EXPECT_EQ(test, SCODE_400, scode);
767+
KUNIT_EXPECT_FALSE(test, is_contender);
768+
KUNIT_EXPECT_EQ(test, 0x4, power_class);
769+
KUNIT_EXPECT_FALSE(test, is_initiated_reset);
770+
KUNIT_EXPECT_TRUE(test, has_more_packets);
771+
772+
serialize_phy_packet_self_id_zero(quadlets, packet_identifier, phy_id, extended,
773+
link_is_active, gap_count, scode, is_contender,
774+
power_class, is_initiated_reset, has_more_packets);
775+
776+
deserialize_phy_packet_self_id_extended(expected[1], &packet_identifier, &phy_id, &extended,
777+
&sequence, &has_more_packets);
778+
779+
KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
780+
KUNIT_EXPECT_EQ(test, 0, phy_id);
781+
KUNIT_EXPECT_TRUE(test, extended);
782+
KUNIT_EXPECT_EQ(test, 0, sequence);
783+
KUNIT_EXPECT_FALSE(test, has_more_packets);
784+
785+
serialize_phy_packet_self_id_extended(&quadlets[1], packet_identifier, phy_id, extended,
786+
sequence, has_more_packets);
787+
788+
789+
for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
790+
port_status[port_index] =
791+
self_id_sequence_get_port_status(expected, ARRAY_SIZE(expected), port_index);
792+
}
793+
794+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[0]);
795+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[1]);
796+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[2]);
797+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[3]);
798+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[4]);
799+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[5]);
800+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[6]);
801+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[7]);
802+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[8]);
803+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[9]);
804+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[10]);
805+
806+
for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
807+
self_id_sequence_set_port_status(quadlets, ARRAY_SIZE(quadlets), port_index,
808+
port_status[port_index]);
809+
}
810+
811+
KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
812+
}
813+
562814
static struct kunit_case packet_serdes_test_cases[] = {
563815
KUNIT_CASE(test_async_header_write_quadlet_request),
564816
KUNIT_CASE(test_async_header_write_block_request),
@@ -570,6 +822,9 @@ static struct kunit_case packet_serdes_test_cases[] = {
570822
KUNIT_CASE(test_async_header_lock_request),
571823
KUNIT_CASE(test_async_header_lock_response),
572824
KUNIT_CASE(test_isoc_header),
825+
KUNIT_CASE(test_phy_packet_self_id_zero_case0),
826+
KUNIT_CASE(test_phy_packet_self_id_zero_case1),
827+
KUNIT_CASE(test_phy_packet_self_id_zero_and_one),
573828
{}
574829
};
575830

0 commit comments

Comments
 (0)