xref: /linux/drivers/firewire/packet-header-definitions.h (revision 93d4e8bb3f137e8037a65ea96f175f81c25c50e5)
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 #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 
234 #endif // _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
235