mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
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>
This commit is contained in:
parent
c5deb01849
commit
6503df3612
@ -165,4 +165,70 @@ static inline void async_header_set_extended_tcode(u32 header[ASYNC_HEADER_QUADL
|
||||
header[3] |= (((u32)extended_tcode) << ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT) & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK;
|
||||
}
|
||||
|
||||
#define ISOC_HEADER_DATA_LENGTH_SHIFT 16
|
||||
#define ISOC_HEADER_DATA_LENGTH_MASK 0xffff0000
|
||||
#define ISOC_HEADER_TAG_SHIFT 14
|
||||
#define ISOC_HEADER_TAG_MASK 0x0000c000
|
||||
#define ISOC_HEADER_CHANNEL_SHIFT 8
|
||||
#define ISOC_HEADER_CHANNEL_MASK 0x00003f00
|
||||
#define ISOC_HEADER_TCODE_SHIFT 4
|
||||
#define ISOC_HEADER_TCODE_MASK 0x000000f0
|
||||
#define ISOC_HEADER_SY_SHIFT 0
|
||||
#define ISOC_HEADER_SY_MASK 0x0000000f
|
||||
|
||||
static inline unsigned int isoc_header_get_data_length(u32 header)
|
||||
{
|
||||
return (header & ISOC_HEADER_DATA_LENGTH_MASK) >> ISOC_HEADER_DATA_LENGTH_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned int isoc_header_get_tag(u32 header)
|
||||
{
|
||||
return (header & ISOC_HEADER_TAG_MASK) >> ISOC_HEADER_TAG_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned int isoc_header_get_channel(u32 header)
|
||||
{
|
||||
return (header & ISOC_HEADER_CHANNEL_MASK) >> ISOC_HEADER_CHANNEL_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned int isoc_header_get_tcode(u32 header)
|
||||
{
|
||||
return (header & ISOC_HEADER_TCODE_MASK) >> ISOC_HEADER_TCODE_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned int isoc_header_get_sy(u32 header)
|
||||
{
|
||||
return (header & ISOC_HEADER_SY_MASK) >> ISOC_HEADER_SY_SHIFT;
|
||||
}
|
||||
|
||||
static inline void isoc_header_set_data_length(u32 *header, unsigned int data_length)
|
||||
{
|
||||
*header &= ~ISOC_HEADER_DATA_LENGTH_MASK;
|
||||
*header |= (((u32)data_length) << ISOC_HEADER_DATA_LENGTH_SHIFT) & ISOC_HEADER_DATA_LENGTH_MASK;
|
||||
}
|
||||
|
||||
static inline void isoc_header_set_tag(u32 *header, unsigned int tag)
|
||||
{
|
||||
*header &= ~ISOC_HEADER_TAG_MASK;
|
||||
*header |= (((u32)tag) << ISOC_HEADER_TAG_SHIFT) & ISOC_HEADER_TAG_MASK;
|
||||
}
|
||||
|
||||
static inline void isoc_header_set_channel(u32 *header, unsigned int channel)
|
||||
{
|
||||
*header &= ~ISOC_HEADER_CHANNEL_MASK;
|
||||
*header |= (((u32)channel) << ISOC_HEADER_CHANNEL_SHIFT) & ISOC_HEADER_CHANNEL_MASK;
|
||||
}
|
||||
|
||||
static inline void isoc_header_set_tcode(u32 *header, unsigned int tcode)
|
||||
{
|
||||
*header &= ~ISOC_HEADER_TCODE_MASK;
|
||||
*header |= (((u32)tcode) << ISOC_HEADER_TCODE_SHIFT) & ISOC_HEADER_TCODE_MASK;
|
||||
}
|
||||
|
||||
static inline void isoc_header_set_sy(u32 *header, unsigned int sy)
|
||||
{
|
||||
*header &= ~ISOC_HEADER_SY_MASK;
|
||||
*header |= (((u32)sy) << ISOC_HEADER_SY_SHIFT) & ISOC_HEADER_SY_MASK;
|
||||
}
|
||||
|
||||
#endif // _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
|
||||
|
@ -167,6 +167,26 @@ static void deserialize_async_header_block_response(const u32 header[ASYNC_HEADE
|
||||
*extended_tcode = async_header_get_extended_tcode(header);
|
||||
}
|
||||
|
||||
static void serialize_isoc_header(u32 *header, unsigned int data_length, unsigned int tag,
|
||||
unsigned int channel, unsigned int tcode, unsigned int sy)
|
||||
{
|
||||
isoc_header_set_data_length(header, data_length);
|
||||
isoc_header_set_tag(header, tag);
|
||||
isoc_header_set_channel(header, channel);
|
||||
isoc_header_set_tcode(header, tcode);
|
||||
isoc_header_set_sy(header, sy);
|
||||
}
|
||||
|
||||
static void deserialize_isoc_header(u32 header, unsigned int *data_length, unsigned int *tag,
|
||||
unsigned int *channel, unsigned int *tcode, unsigned int *sy)
|
||||
{
|
||||
*data_length = isoc_header_get_data_length(header);
|
||||
*tag = isoc_header_get_tag(header);
|
||||
*channel = isoc_header_get_channel(header);
|
||||
*tcode = isoc_header_get_tcode(header);
|
||||
*sy = isoc_header_get_sy(header);
|
||||
}
|
||||
|
||||
static void test_async_header_write_quadlet_request(struct kunit *test)
|
||||
{
|
||||
static const u32 expected[ASYNC_HEADER_QUADLET_COUNT] = {
|
||||
@ -515,6 +535,29 @@ static void test_async_header_lock_response(struct kunit *test)
|
||||
KUNIT_EXPECT_MEMEQ(test, header, expected, sizeof(expected));
|
||||
}
|
||||
|
||||
static void test_isoc_header(struct kunit *test)
|
||||
{
|
||||
const u32 expected = 0x00d08dec;
|
||||
u32 header = 0;
|
||||
|
||||
unsigned int data_length;
|
||||
unsigned int tag;
|
||||
unsigned int channel;
|
||||
unsigned int tcode;
|
||||
unsigned int sy;
|
||||
|
||||
deserialize_isoc_header(expected, &data_length, &tag, &channel, &tcode, &sy);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, 0xd0, data_length);
|
||||
KUNIT_EXPECT_EQ(test, 0x02, tag);
|
||||
KUNIT_EXPECT_EQ(test, 0x0d, channel);
|
||||
KUNIT_EXPECT_EQ(test, 0x0e, tcode);
|
||||
KUNIT_EXPECT_EQ(test, 0x0c, sy);
|
||||
|
||||
serialize_isoc_header(&header, data_length, tag, channel, tcode, sy);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, header, expected);
|
||||
}
|
||||
|
||||
static struct kunit_case packet_serdes_test_cases[] = {
|
||||
KUNIT_CASE(test_async_header_write_quadlet_request),
|
||||
@ -526,6 +569,7 @@ static struct kunit_case packet_serdes_test_cases[] = {
|
||||
KUNIT_CASE(test_async_header_read_block_response),
|
||||
KUNIT_CASE(test_async_header_lock_request),
|
||||
KUNIT_CASE(test_async_header_lock_response),
|
||||
KUNIT_CASE(test_isoc_header),
|
||||
{}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user