Skip to content

Commit 9338976

Browse files
committed
firewire: core: add helper function to handle port status from self ID sequence and its KUnit test
The self ID sequence delivers the information about the state of port. This commit adds some enumerations to express the state of port, and some helper functions to handle the state. It adds a KUnit test for them, too. Link: https://lore.kernel.org/r/20240605235155.116468-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
1 parent 7bd10e0 commit 9338976

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

drivers/firewire/phy-packet-definitions.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#define SELF_ID_EXTENDED_SEQUENCE_MASK 0x00700000
1616
#define SELF_ID_EXTENDED_SEQUENCE_SHIFT 20
1717

18+
#define SELF_ID_PORT_STATUS_MASK 0x3
19+
1820
#define SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT 4
1921

2022
static inline bool phy_packet_self_id_get_extended(u32 quadlet)
@@ -75,4 +77,45 @@ static inline const u32 *self_id_sequence_enumerator_next(
7577
return self_id_sequence;
7678
}
7779

80+
enum phy_packet_self_id_port_status {
81+
PHY_PACKET_SELF_ID_PORT_STATUS_NONE = 0,
82+
PHY_PACKET_SELF_ID_PORT_STATUS_NCONN = 1,
83+
PHY_PACKET_SELF_ID_PORT_STATUS_PARENT = 2,
84+
PHY_PACKET_SELF_ID_PORT_STATUS_CHILD = 3,
85+
};
86+
87+
static inline unsigned int self_id_sequence_get_port_capacity(unsigned int quadlet_count)
88+
{
89+
return quadlet_count * 8 - 5;
90+
}
91+
92+
static inline enum phy_packet_self_id_port_status self_id_sequence_get_port_status(
93+
const u32 *self_id_sequence, unsigned int quadlet_count, unsigned int port_index)
94+
{
95+
unsigned int index, shift;
96+
97+
index = (port_index + 5) / 8;
98+
shift = 16 - ((port_index + 5) % 8) * 2;
99+
100+
if (index < quadlet_count && index < SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT)
101+
return (self_id_sequence[index] >> shift) & SELF_ID_PORT_STATUS_MASK;
102+
103+
return PHY_PACKET_SELF_ID_PORT_STATUS_NONE;
104+
}
105+
106+
static inline void self_id_sequence_set_port_status(u32 *self_id_sequence, unsigned int quadlet_count,
107+
unsigned int port_index,
108+
enum phy_packet_self_id_port_status status)
109+
{
110+
unsigned int index, shift;
111+
112+
index = (port_index + 5) / 8;
113+
shift = 16 - ((port_index + 5) % 8) * 2;
114+
115+
if (index < quadlet_count) {
116+
self_id_sequence[index] &= ~(SELF_ID_PORT_STATUS_MASK << shift);
117+
self_id_sequence[index] |= status << shift;
118+
}
119+
}
120+
78121
#endif // _FIREWIRE_PHY_PACKET_DEFINITIONS_H

drivers/firewire/self-id-sequence-helper-test.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,82 @@ static void test_self_id_sequence_enumerator_invalid(struct kunit *test)
6363
KUNIT_EXPECT_EQ(test, PTR_ERR(entry), -EPROTO);
6464
}
6565

66+
static void test_self_id_sequence_get_port_status(struct kunit *test)
67+
{
68+
static const u32 expected[] = {
69+
0x000000e5,
70+
0x00839e79,
71+
0x0091e79d,
72+
0x00a279e4,
73+
};
74+
u32 quadlets [] = {
75+
0x00000001,
76+
0x00800001,
77+
0x00900001,
78+
0x00a00000,
79+
};
80+
enum phy_packet_self_id_port_status port_status[28];
81+
unsigned int port_capacity;
82+
unsigned int port_index;
83+
84+
KUNIT_ASSERT_EQ(test, ARRAY_SIZE(expected), ARRAY_SIZE(quadlets));
85+
86+
// With an extra port.
87+
port_capacity = self_id_sequence_get_port_capacity(ARRAY_SIZE(expected)) + 1;
88+
KUNIT_ASSERT_EQ(test, port_capacity, ARRAY_SIZE(port_status));
89+
90+
for (port_index = 0; port_index < port_capacity; ++port_index) {
91+
port_status[port_index] =
92+
self_id_sequence_get_port_status(expected, ARRAY_SIZE(expected), port_index);
93+
self_id_sequence_set_port_status(quadlets, ARRAY_SIZE(quadlets), port_index,
94+
port_status[port_index]);
95+
}
96+
97+
// Self ID zero.
98+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[0]);
99+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[1]);
100+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[2]);
101+
102+
// Self ID one.
103+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[3]);
104+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[4]);
105+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[5]);
106+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[6]);
107+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[7]);
108+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[8]);
109+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[9]);
110+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[10]);
111+
112+
// Self ID two.
113+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[11]);
114+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[12]);
115+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[13]);
116+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[14]);
117+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[15]);
118+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[16]);
119+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[17]);
120+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[18]);
121+
122+
// Self ID three.
123+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[19]);
124+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[20]);
125+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[21]);
126+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[22]);
127+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[23]);
128+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[24]);
129+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[25]);
130+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[26]);
131+
132+
// Our of order.
133+
KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[27]);
134+
135+
KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
136+
}
137+
66138
static struct kunit_case self_id_sequence_helper_test_cases[] = {
67139
KUNIT_CASE(test_self_id_sequence_enumerator_valid),
68140
KUNIT_CASE(test_self_id_sequence_enumerator_invalid),
141+
KUNIT_CASE(test_self_id_sequence_get_port_status),
69142
{}
70143
};
71144

0 commit comments

Comments
 (0)