1 // SPDX-License-Identifier: GPL-2.0-or-later
3 // packet-header-definitions.h - The definitions of header fields for IEEE 1394 packet.
5 // Copyright (c) 2024 Takashi Sakamoto
7 #ifndef _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
8 #define _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
10 #include <linux/types.h>
12 #define ASYNC_HEADER_QUADLET_COUNT 4
14 #define ASYNC_HEADER_Q0_DESTINATION_SHIFT 16
15 #define ASYNC_HEADER_Q0_DESTINATION_MASK 0xffff0000
16 #define ASYNC_HEADER_Q0_TLABEL_SHIFT 10
17 #define ASYNC_HEADER_Q0_TLABEL_MASK 0x0000fc00
18 #define ASYNC_HEADER_Q0_RETRY_SHIFT 8
19 #define ASYNC_HEADER_Q0_RETRY_MASK 0x00000300
20 #define ASYNC_HEADER_Q0_TCODE_SHIFT 4
21 #define ASYNC_HEADER_Q0_TCODE_MASK 0x000000f0
22 #define ASYNC_HEADER_Q0_PRIORITY_SHIFT 0
23 #define ASYNC_HEADER_Q0_PRIORITY_MASK 0x0000000f
24 #define ASYNC_HEADER_Q1_SOURCE_SHIFT 16
25 #define ASYNC_HEADER_Q1_SOURCE_MASK 0xffff0000
26 #define ASYNC_HEADER_Q1_RCODE_SHIFT 12
27 #define ASYNC_HEADER_Q1_RCODE_MASK 0x0000f000
28 #define ASYNC_HEADER_Q1_RCODE_SHIFT 12
29 #define ASYNC_HEADER_Q1_RCODE_MASK 0x0000f000
30 #define ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT 0
31 #define ASYNC_HEADER_Q1_OFFSET_HIGH_MASK 0x0000ffff
32 #define ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT 16
33 #define ASYNC_HEADER_Q3_DATA_LENGTH_MASK 0xffff0000
34 #define ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT 0
35 #define ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK 0x0000ffff
37 static inline unsigned int async_header_get_destination(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
39 return (header
[0] & ASYNC_HEADER_Q0_DESTINATION_MASK
) >> ASYNC_HEADER_Q0_DESTINATION_SHIFT
;
42 static inline unsigned int async_header_get_tlabel(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
44 return (header
[0] & ASYNC_HEADER_Q0_TLABEL_MASK
) >> ASYNC_HEADER_Q0_TLABEL_SHIFT
;
47 static inline unsigned int async_header_get_retry(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
49 return (header
[0] & ASYNC_HEADER_Q0_RETRY_MASK
) >> ASYNC_HEADER_Q0_RETRY_SHIFT
;
52 static inline unsigned int async_header_get_tcode(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
54 return (header
[0] & ASYNC_HEADER_Q0_TCODE_MASK
) >> ASYNC_HEADER_Q0_TCODE_SHIFT
;
57 static inline unsigned int async_header_get_priority(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
59 return (header
[0] & ASYNC_HEADER_Q0_PRIORITY_MASK
) >> ASYNC_HEADER_Q0_PRIORITY_SHIFT
;
62 static inline unsigned int async_header_get_source(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
64 return (header
[1] & ASYNC_HEADER_Q1_SOURCE_MASK
) >> ASYNC_HEADER_Q1_SOURCE_SHIFT
;
67 static inline unsigned int async_header_get_rcode(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
69 return (header
[1] & ASYNC_HEADER_Q1_RCODE_MASK
) >> ASYNC_HEADER_Q1_RCODE_SHIFT
;
72 static inline u64
async_header_get_offset(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
74 u32 hi
= (header
[1] & ASYNC_HEADER_Q1_OFFSET_HIGH_MASK
) >> ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT
;
75 return (((u64
)hi
) << 32) | ((u64
)header
[2]);
78 static inline u32
async_header_get_quadlet_data(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
83 static inline unsigned int async_header_get_data_length(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
85 return (header
[3] & ASYNC_HEADER_Q3_DATA_LENGTH_MASK
) >> ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT
;
88 static inline unsigned int async_header_get_extended_tcode(const u32 header
[ASYNC_HEADER_QUADLET_COUNT
])
90 return (header
[3] & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK
) >> ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT
;
93 static inline void async_header_set_destination(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
94 unsigned int destination
)
96 header
[0] &= ~ASYNC_HEADER_Q0_DESTINATION_MASK
;
97 header
[0] |= (((u32
)destination
) << ASYNC_HEADER_Q0_DESTINATION_SHIFT
) & ASYNC_HEADER_Q0_DESTINATION_MASK
;
100 static inline void async_header_set_tlabel(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
103 header
[0] &= ~ASYNC_HEADER_Q0_TLABEL_MASK
;
104 header
[0] |= (((u32
)tlabel
) << ASYNC_HEADER_Q0_TLABEL_SHIFT
) & ASYNC_HEADER_Q0_TLABEL_MASK
;
107 static inline void async_header_set_retry(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
110 header
[0] &= ~ASYNC_HEADER_Q0_RETRY_MASK
;
111 header
[0] |= (((u32
)retry
) << ASYNC_HEADER_Q0_RETRY_SHIFT
) & ASYNC_HEADER_Q0_RETRY_MASK
;
114 static inline void async_header_set_tcode(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
117 header
[0] &= ~ASYNC_HEADER_Q0_TCODE_MASK
;
118 header
[0] |= (((u32
)tcode
) << ASYNC_HEADER_Q0_TCODE_SHIFT
) & ASYNC_HEADER_Q0_TCODE_MASK
;
121 static inline void async_header_set_priority(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
122 unsigned int priority
)
124 header
[0] &= ~ASYNC_HEADER_Q0_PRIORITY_MASK
;
125 header
[0] |= (((u32
)priority
) << ASYNC_HEADER_Q0_PRIORITY_SHIFT
) & ASYNC_HEADER_Q0_PRIORITY_MASK
;
129 static inline void async_header_set_source(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
132 header
[1] &= ~ASYNC_HEADER_Q1_SOURCE_MASK
;
133 header
[1] |= (((u32
)source
) << ASYNC_HEADER_Q1_SOURCE_SHIFT
) & ASYNC_HEADER_Q1_SOURCE_MASK
;
136 static inline void async_header_set_rcode(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
139 header
[1] &= ~ASYNC_HEADER_Q1_RCODE_MASK
;
140 header
[1] |= (((u32
)rcode
) << ASYNC_HEADER_Q1_RCODE_SHIFT
) & ASYNC_HEADER_Q1_RCODE_MASK
;
143 static inline void async_header_set_offset(u32 header
[ASYNC_HEADER_QUADLET_COUNT
], u64 offset
)
145 u32 hi
= (u32
)(offset
>> 32);
146 header
[1] &= ~ASYNC_HEADER_Q1_OFFSET_HIGH_MASK
;
147 header
[1] |= (hi
<< ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT
) & ASYNC_HEADER_Q1_OFFSET_HIGH_MASK
;
148 header
[2] = (u32
)(offset
& 0x00000000ffffffff);
151 static inline void async_header_set_quadlet_data(u32 header
[ASYNC_HEADER_QUADLET_COUNT
], u32 quadlet_data
)
153 header
[3] = quadlet_data
;
156 static inline void async_header_set_data_length(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
157 unsigned int data_length
)
159 header
[3] &= ~ASYNC_HEADER_Q3_DATA_LENGTH_MASK
;
160 header
[3] |= (((u32
)data_length
) << ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT
) & ASYNC_HEADER_Q3_DATA_LENGTH_MASK
;
163 static inline void async_header_set_extended_tcode(u32 header
[ASYNC_HEADER_QUADLET_COUNT
],
164 unsigned int extended_tcode
)
166 header
[3] &= ~ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK
;
167 header
[3] |= (((u32
)extended_tcode
) << ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT
) & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK
;
170 #define ISOC_HEADER_DATA_LENGTH_SHIFT 16
171 #define ISOC_HEADER_DATA_LENGTH_MASK 0xffff0000
172 #define ISOC_HEADER_TAG_SHIFT 14
173 #define ISOC_HEADER_TAG_MASK 0x0000c000
174 #define ISOC_HEADER_CHANNEL_SHIFT 8
175 #define ISOC_HEADER_CHANNEL_MASK 0x00003f00
176 #define ISOC_HEADER_TCODE_SHIFT 4
177 #define ISOC_HEADER_TCODE_MASK 0x000000f0
178 #define ISOC_HEADER_SY_SHIFT 0
179 #define ISOC_HEADER_SY_MASK 0x0000000f
181 static inline unsigned int isoc_header_get_data_length(u32 header
)
183 return (header
& ISOC_HEADER_DATA_LENGTH_MASK
) >> ISOC_HEADER_DATA_LENGTH_SHIFT
;
186 static inline unsigned int isoc_header_get_tag(u32 header
)
188 return (header
& ISOC_HEADER_TAG_MASK
) >> ISOC_HEADER_TAG_SHIFT
;
191 static inline unsigned int isoc_header_get_channel(u32 header
)
193 return (header
& ISOC_HEADER_CHANNEL_MASK
) >> ISOC_HEADER_CHANNEL_SHIFT
;
196 static inline unsigned int isoc_header_get_tcode(u32 header
)
198 return (header
& ISOC_HEADER_TCODE_MASK
) >> ISOC_HEADER_TCODE_SHIFT
;
201 static inline unsigned int isoc_header_get_sy(u32 header
)
203 return (header
& ISOC_HEADER_SY_MASK
) >> ISOC_HEADER_SY_SHIFT
;
206 static inline void isoc_header_set_data_length(u32
*header
, unsigned int data_length
)
208 *header
&= ~ISOC_HEADER_DATA_LENGTH_MASK
;
209 *header
|= (((u32
)data_length
) << ISOC_HEADER_DATA_LENGTH_SHIFT
) & ISOC_HEADER_DATA_LENGTH_MASK
;
212 static inline void isoc_header_set_tag(u32
*header
, unsigned int tag
)
214 *header
&= ~ISOC_HEADER_TAG_MASK
;
215 *header
|= (((u32
)tag
) << ISOC_HEADER_TAG_SHIFT
) & ISOC_HEADER_TAG_MASK
;
218 static inline void isoc_header_set_channel(u32
*header
, unsigned int channel
)
220 *header
&= ~ISOC_HEADER_CHANNEL_MASK
;
221 *header
|= (((u32
)channel
) << ISOC_HEADER_CHANNEL_SHIFT
) & ISOC_HEADER_CHANNEL_MASK
;
224 static inline void isoc_header_set_tcode(u32
*header
, unsigned int tcode
)
226 *header
&= ~ISOC_HEADER_TCODE_MASK
;
227 *header
|= (((u32
)tcode
) << ISOC_HEADER_TCODE_SHIFT
) & ISOC_HEADER_TCODE_MASK
;
230 static inline void isoc_header_set_sy(u32
*header
, unsigned int sy
)
232 *header
&= ~ISOC_HEADER_SY_MASK
;
233 *header
|= (((u32
)sy
) << ISOC_HEADER_SY_SHIFT
) & ISOC_HEADER_SY_MASK
;
236 #endif // _FIREWIRE_PACKET_HEADER_DEFINITIONS_H