Skip to content

Commit 75527d8

Browse files
committed
firewire: core: add common inline functions to serialize/deserialize asynchronous packet header
In both core and 1394 OHCI driver, some hard-coded values and macros are used to serialize/deserialize the header of asynchronous packets. It is inconvenient to reuse them. This commit adds some helper inline functions with their tests for the purpose. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Sakamoto <[email protected]>
1 parent e41b2c1 commit 75527d8

File tree

5 files changed

+726
-0
lines changed

5 files changed

+726
-0
lines changed

drivers/firewire/.kunitconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ CONFIG_PCI=y
33
CONFIG_FIREWIRE=y
44
CONFIG_FIREWIRE_KUNIT_UAPI_TEST=y
55
CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=y
6+
CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST=y

drivers/firewire/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ config FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST
5050
For more information on KUnit and unit tests in general, refer
5151
to the KUnit documentation in Documentation/dev-tools/kunit/.
5252

53+
config FIREWIRE_KUNIT_PACKET_SERDES_TEST
54+
tristate "KUnit tests for packet serialization/deserialization" if !KUNIT_ALL_TESTS
55+
depends on FIREWIRE && KUNIT
56+
default KUNIT_ALL_TESTS
57+
help
58+
This builds the KUnit tests for packet serialization and
59+
deserialization.
60+
61+
KUnit tests run during boot and output the results to the debug
62+
log in TAP format (https://testanything.org/). Only useful for
63+
kernel devs running KUnit test harness and are not for inclusion
64+
into a production build.
65+
66+
For more information on KUnit and unit tests in general, refer
67+
to the KUnit documentation in Documentation/dev-tools/kunit/.
68+
5369
config FIREWIRE_OHCI
5470
tristate "OHCI-1394 controllers"
5571
depends on PCI && FIREWIRE && MMU

drivers/firewire/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@ obj-$(CONFIG_FIREWIRE_NOSY) += nosy.o
1717
obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o
1818

1919
firewire-uapi-test-objs += uapi-test.o
20+
firewire-packet-serdes-test-objs += packet-serdes-test.o
21+
2022
obj-$(CONFIG_FIREWIRE_KUNIT_UAPI_TEST) += firewire-uapi-test.o
23+
obj-$(CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST) += firewire-packet-serdes-test.o
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
//
3+
// packet-header-definitions.h - The definitions of header fields for IEEE 1394 packet.
4+
//
5+
// Copyright (c) 2024 Takashi Sakamoto
6+
7+
#ifndef _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
8+
#define _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
9+
10+
#define ASYNC_HEADER_QUADLET_COUNT 4
11+
12+
#define ASYNC_HEADER_Q0_DESTINATION_SHIFT 16
13+
#define ASYNC_HEADER_Q0_DESTINATION_MASK 0xffff0000
14+
#define ASYNC_HEADER_Q0_TLABEL_SHIFT 10
15+
#define ASYNC_HEADER_Q0_TLABEL_MASK 0x0000fc00
16+
#define ASYNC_HEADER_Q0_RETRY_SHIFT 8
17+
#define ASYNC_HEADER_Q0_RETRY_MASK 0x00000300
18+
#define ASYNC_HEADER_Q0_TCODE_SHIFT 4
19+
#define ASYNC_HEADER_Q0_TCODE_MASK 0x000000f0
20+
#define ASYNC_HEADER_Q0_PRIORITY_SHIFT 0
21+
#define ASYNC_HEADER_Q0_PRIORITY_MASK 0x0000000f
22+
#define ASYNC_HEADER_Q1_SOURCE_SHIFT 16
23+
#define ASYNC_HEADER_Q1_SOURCE_MASK 0xffff0000
24+
#define ASYNC_HEADER_Q1_RCODE_SHIFT 12
25+
#define ASYNC_HEADER_Q1_RCODE_MASK 0x0000f000
26+
#define ASYNC_HEADER_Q1_RCODE_SHIFT 12
27+
#define ASYNC_HEADER_Q1_RCODE_MASK 0x0000f000
28+
#define ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT 0
29+
#define ASYNC_HEADER_Q1_OFFSET_HIGH_MASK 0x0000ffff
30+
#define ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT 16
31+
#define ASYNC_HEADER_Q3_DATA_LENGTH_MASK 0xffff0000
32+
#define ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT 0
33+
#define ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK 0x0000ffff
34+
35+
static inline unsigned int async_header_get_destination(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
36+
{
37+
return (header[0] & ASYNC_HEADER_Q0_DESTINATION_MASK) >> ASYNC_HEADER_Q0_DESTINATION_SHIFT;
38+
}
39+
40+
static inline unsigned int async_header_get_tlabel(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
41+
{
42+
return (header[0] & ASYNC_HEADER_Q0_TLABEL_MASK) >> ASYNC_HEADER_Q0_TLABEL_SHIFT;
43+
}
44+
45+
static inline unsigned int async_header_get_retry(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
46+
{
47+
return (header[0] & ASYNC_HEADER_Q0_RETRY_MASK) >> ASYNC_HEADER_Q0_RETRY_SHIFT;
48+
}
49+
50+
static inline unsigned int async_header_get_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
51+
{
52+
return (header[0] & ASYNC_HEADER_Q0_TCODE_MASK) >> ASYNC_HEADER_Q0_TCODE_SHIFT;
53+
}
54+
55+
static inline unsigned int async_header_get_priority(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
56+
{
57+
return (header[0] & ASYNC_HEADER_Q0_PRIORITY_MASK) >> ASYNC_HEADER_Q0_PRIORITY_SHIFT;
58+
}
59+
60+
static inline unsigned int async_header_get_source(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
61+
{
62+
return (header[1] & ASYNC_HEADER_Q1_SOURCE_MASK) >> ASYNC_HEADER_Q1_SOURCE_SHIFT;
63+
}
64+
65+
static inline unsigned int async_header_get_rcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
66+
{
67+
return (header[1] & ASYNC_HEADER_Q1_RCODE_MASK) >> ASYNC_HEADER_Q1_RCODE_SHIFT;
68+
}
69+
70+
static inline u64 async_header_get_offset(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
71+
{
72+
u32 hi = (header[1] & ASYNC_HEADER_Q1_OFFSET_HIGH_MASK) >> ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT;
73+
return (((u64)hi) << 32) | ((u64)header[2]);
74+
}
75+
76+
static inline u32 async_header_get_quadlet_data(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
77+
{
78+
return header[3];
79+
}
80+
81+
static inline unsigned int async_header_get_data_length(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
82+
{
83+
return (header[3] & ASYNC_HEADER_Q3_DATA_LENGTH_MASK) >> ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT;
84+
}
85+
86+
static inline unsigned int async_header_get_extended_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
87+
{
88+
return (header[3] & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK) >> ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT;
89+
}
90+
91+
static inline void async_header_set_destination(u32 header[ASYNC_HEADER_QUADLET_COUNT],
92+
unsigned int destination)
93+
{
94+
header[0] &= ~ASYNC_HEADER_Q0_DESTINATION_MASK;
95+
header[0] |= (((u32)destination) << ASYNC_HEADER_Q0_DESTINATION_SHIFT) & ASYNC_HEADER_Q0_DESTINATION_MASK;
96+
}
97+
98+
static inline void async_header_set_tlabel(u32 header[ASYNC_HEADER_QUADLET_COUNT],
99+
unsigned int tlabel)
100+
{
101+
header[0] &= ~ASYNC_HEADER_Q0_TLABEL_MASK;
102+
header[0] |= (((u32)tlabel) << ASYNC_HEADER_Q0_TLABEL_SHIFT) & ASYNC_HEADER_Q0_TLABEL_MASK;
103+
}
104+
105+
static inline void async_header_set_retry(u32 header[ASYNC_HEADER_QUADLET_COUNT],
106+
unsigned int retry)
107+
{
108+
header[0] &= ~ASYNC_HEADER_Q0_RETRY_MASK;
109+
header[0] |= (((u32)retry) << ASYNC_HEADER_Q0_RETRY_SHIFT) & ASYNC_HEADER_Q0_RETRY_MASK;
110+
}
111+
112+
static inline void async_header_set_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
113+
unsigned int tcode)
114+
{
115+
header[0] &= ~ASYNC_HEADER_Q0_TCODE_MASK;
116+
header[0] |= (((u32)tcode) << ASYNC_HEADER_Q0_TCODE_SHIFT) & ASYNC_HEADER_Q0_TCODE_MASK;
117+
}
118+
119+
static inline void async_header_set_priority(u32 header[ASYNC_HEADER_QUADLET_COUNT],
120+
unsigned int priority)
121+
{
122+
header[0] &= ~ASYNC_HEADER_Q0_PRIORITY_MASK;
123+
header[0] |= (((u32)priority) << ASYNC_HEADER_Q0_PRIORITY_SHIFT) & ASYNC_HEADER_Q0_PRIORITY_MASK;
124+
}
125+
126+
127+
static inline void async_header_set_source(u32 header[ASYNC_HEADER_QUADLET_COUNT],
128+
unsigned int source)
129+
{
130+
header[1] &= ~ASYNC_HEADER_Q1_SOURCE_MASK;
131+
header[1] |= (((u32)source) << ASYNC_HEADER_Q1_SOURCE_SHIFT) & ASYNC_HEADER_Q1_SOURCE_MASK;
132+
}
133+
134+
static inline void async_header_set_rcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
135+
unsigned int rcode)
136+
{
137+
header[1] &= ~ASYNC_HEADER_Q1_RCODE_MASK;
138+
header[1] |= (((u32)rcode) << ASYNC_HEADER_Q1_RCODE_SHIFT) & ASYNC_HEADER_Q1_RCODE_MASK;
139+
}
140+
141+
static inline void async_header_set_offset(u32 header[ASYNC_HEADER_QUADLET_COUNT], u64 offset)
142+
{
143+
u32 hi = (u32)(offset >> 32);
144+
header[1] &= ~ASYNC_HEADER_Q1_OFFSET_HIGH_MASK;
145+
header[1] |= (hi << ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT) & ASYNC_HEADER_Q1_OFFSET_HIGH_MASK;
146+
header[2] = (u32)(offset & 0x00000000ffffffff);
147+
}
148+
149+
static inline void async_header_set_quadlet_data(u32 header[ASYNC_HEADER_QUADLET_COUNT], u32 quadlet_data)
150+
{
151+
header[3] = quadlet_data;
152+
}
153+
154+
static inline void async_header_set_data_length(u32 header[ASYNC_HEADER_QUADLET_COUNT],
155+
unsigned int data_length)
156+
{
157+
header[3] &= ~ASYNC_HEADER_Q3_DATA_LENGTH_MASK;
158+
header[3] |= (((u32)data_length) << ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT) & ASYNC_HEADER_Q3_DATA_LENGTH_MASK;
159+
}
160+
161+
static inline void async_header_set_extended_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
162+
unsigned int extended_tcode)
163+
{
164+
header[3] &= ~ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK;
165+
header[3] |= (((u32)extended_tcode) << ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT) & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK;
166+
}
167+
168+
#endif // _FIREWIRE_PACKET_HEADER_DEFINITIONS_H

0 commit comments

Comments
 (0)