Skip to content

Commit 6503df3

Browse files
committed
firewire: core: add common macro to serialize/deserialize isochronous packet header
The packet for Asynchronous Streaming Packet includes the same header fields as the isochronous packet has. It is helpful to have some helper functions to serialize/deserialize them. This commit adds such helper functions with their test. Link: https://lore.kernel.org/r/20240428071347.409202-8-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
1 parent c5deb01 commit 6503df3

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

drivers/firewire/packet-header-definitions.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,70 @@ static inline void async_header_set_extended_tcode(u32 header[ASYNC_HEADER_QUADL
165165
header[3] |= (((u32)extended_tcode) << ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT) & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK;
166166
}
167167

168+
#define ISOC_HEADER_DATA_LENGTH_SHIFT 16
169+
#define ISOC_HEADER_DATA_LENGTH_MASK 0xffff0000
170+
#define ISOC_HEADER_TAG_SHIFT 14
171+
#define ISOC_HEADER_TAG_MASK 0x0000c000
172+
#define ISOC_HEADER_CHANNEL_SHIFT 8
173+
#define ISOC_HEADER_CHANNEL_MASK 0x00003f00
174+
#define ISOC_HEADER_TCODE_SHIFT 4
175+
#define ISOC_HEADER_TCODE_MASK 0x000000f0
176+
#define ISOC_HEADER_SY_SHIFT 0
177+
#define ISOC_HEADER_SY_MASK 0x0000000f
178+
179+
static inline unsigned int isoc_header_get_data_length(u32 header)
180+
{
181+
return (header & ISOC_HEADER_DATA_LENGTH_MASK) >> ISOC_HEADER_DATA_LENGTH_SHIFT;
182+
}
183+
184+
static inline unsigned int isoc_header_get_tag(u32 header)
185+
{
186+
return (header & ISOC_HEADER_TAG_MASK) >> ISOC_HEADER_TAG_SHIFT;
187+
}
188+
189+
static inline unsigned int isoc_header_get_channel(u32 header)
190+
{
191+
return (header & ISOC_HEADER_CHANNEL_MASK) >> ISOC_HEADER_CHANNEL_SHIFT;
192+
}
193+
194+
static inline unsigned int isoc_header_get_tcode(u32 header)
195+
{
196+
return (header & ISOC_HEADER_TCODE_MASK) >> ISOC_HEADER_TCODE_SHIFT;
197+
}
198+
199+
static inline unsigned int isoc_header_get_sy(u32 header)
200+
{
201+
return (header & ISOC_HEADER_SY_MASK) >> ISOC_HEADER_SY_SHIFT;
202+
}
203+
204+
static inline void isoc_header_set_data_length(u32 *header, unsigned int data_length)
205+
{
206+
*header &= ~ISOC_HEADER_DATA_LENGTH_MASK;
207+
*header |= (((u32)data_length) << ISOC_HEADER_DATA_LENGTH_SHIFT) & ISOC_HEADER_DATA_LENGTH_MASK;
208+
}
209+
210+
static inline void isoc_header_set_tag(u32 *header, unsigned int tag)
211+
{
212+
*header &= ~ISOC_HEADER_TAG_MASK;
213+
*header |= (((u32)tag) << ISOC_HEADER_TAG_SHIFT) & ISOC_HEADER_TAG_MASK;
214+
}
215+
216+
static inline void isoc_header_set_channel(u32 *header, unsigned int channel)
217+
{
218+
*header &= ~ISOC_HEADER_CHANNEL_MASK;
219+
*header |= (((u32)channel) << ISOC_HEADER_CHANNEL_SHIFT) & ISOC_HEADER_CHANNEL_MASK;
220+
}
221+
222+
static inline void isoc_header_set_tcode(u32 *header, unsigned int tcode)
223+
{
224+
*header &= ~ISOC_HEADER_TCODE_MASK;
225+
*header |= (((u32)tcode) << ISOC_HEADER_TCODE_SHIFT) & ISOC_HEADER_TCODE_MASK;
226+
}
227+
228+
static inline void isoc_header_set_sy(u32 *header, unsigned int sy)
229+
{
230+
*header &= ~ISOC_HEADER_SY_MASK;
231+
*header |= (((u32)sy) << ISOC_HEADER_SY_SHIFT) & ISOC_HEADER_SY_MASK;
232+
}
233+
168234
#endif // _FIREWIRE_PACKET_HEADER_DEFINITIONS_H

drivers/firewire/packet-serdes-test.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,26 @@ static void deserialize_async_header_block_response(const u32 header[ASYNC_HEADE
167167
*extended_tcode = async_header_get_extended_tcode(header);
168168
}
169169

170+
static void serialize_isoc_header(u32 *header, unsigned int data_length, unsigned int tag,
171+
unsigned int channel, unsigned int tcode, unsigned int sy)
172+
{
173+
isoc_header_set_data_length(header, data_length);
174+
isoc_header_set_tag(header, tag);
175+
isoc_header_set_channel(header, channel);
176+
isoc_header_set_tcode(header, tcode);
177+
isoc_header_set_sy(header, sy);
178+
}
179+
180+
static void deserialize_isoc_header(u32 header, unsigned int *data_length, unsigned int *tag,
181+
unsigned int *channel, unsigned int *tcode, unsigned int *sy)
182+
{
183+
*data_length = isoc_header_get_data_length(header);
184+
*tag = isoc_header_get_tag(header);
185+
*channel = isoc_header_get_channel(header);
186+
*tcode = isoc_header_get_tcode(header);
187+
*sy = isoc_header_get_sy(header);
188+
}
189+
170190
static void test_async_header_write_quadlet_request(struct kunit *test)
171191
{
172192
static const u32 expected[ASYNC_HEADER_QUADLET_COUNT] = {
@@ -515,6 +535,29 @@ static void test_async_header_lock_response(struct kunit *test)
515535
KUNIT_EXPECT_MEMEQ(test, header, expected, sizeof(expected));
516536
}
517537

538+
static void test_isoc_header(struct kunit *test)
539+
{
540+
const u32 expected = 0x00d08dec;
541+
u32 header = 0;
542+
543+
unsigned int data_length;
544+
unsigned int tag;
545+
unsigned int channel;
546+
unsigned int tcode;
547+
unsigned int sy;
548+
549+
deserialize_isoc_header(expected, &data_length, &tag, &channel, &tcode, &sy);
550+
551+
KUNIT_EXPECT_EQ(test, 0xd0, data_length);
552+
KUNIT_EXPECT_EQ(test, 0x02, tag);
553+
KUNIT_EXPECT_EQ(test, 0x0d, channel);
554+
KUNIT_EXPECT_EQ(test, 0x0e, tcode);
555+
KUNIT_EXPECT_EQ(test, 0x0c, sy);
556+
557+
serialize_isoc_header(&header, data_length, tag, channel, tcode, sy);
558+
559+
KUNIT_EXPECT_EQ(test, header, expected);
560+
}
518561

519562
static struct kunit_case packet_serdes_test_cases[] = {
520563
KUNIT_CASE(test_async_header_write_quadlet_request),
@@ -526,6 +569,7 @@ static struct kunit_case packet_serdes_test_cases[] = {
526569
KUNIT_CASE(test_async_header_read_block_response),
527570
KUNIT_CASE(test_async_header_lock_request),
528571
KUNIT_CASE(test_async_header_lock_response),
572+
KUNIT_CASE(test_isoc_header),
529573
{}
530574
};
531575

0 commit comments

Comments
 (0)