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  #include <linux/types.h>
11  
12  #define ASYNC_HEADER_QUADLET_COUNT		4
13  
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
36  
async_header_get_destination(const u32 header[ASYNC_HEADER_QUADLET_COUNT])37  static inline unsigned int async_header_get_destination(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
38  {
39  	return (header[0] & ASYNC_HEADER_Q0_DESTINATION_MASK) >> ASYNC_HEADER_Q0_DESTINATION_SHIFT;
40  }
41  
async_header_get_tlabel(const u32 header[ASYNC_HEADER_QUADLET_COUNT])42  static inline unsigned int async_header_get_tlabel(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
43  {
44  	return (header[0] & ASYNC_HEADER_Q0_TLABEL_MASK) >> ASYNC_HEADER_Q0_TLABEL_SHIFT;
45  }
46  
async_header_get_retry(const u32 header[ASYNC_HEADER_QUADLET_COUNT])47  static inline unsigned int async_header_get_retry(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
48  {
49  	return (header[0] & ASYNC_HEADER_Q0_RETRY_MASK) >> ASYNC_HEADER_Q0_RETRY_SHIFT;
50  }
51  
async_header_get_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])52  static inline unsigned int async_header_get_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
53  {
54  	return (header[0] & ASYNC_HEADER_Q0_TCODE_MASK) >> ASYNC_HEADER_Q0_TCODE_SHIFT;
55  }
56  
async_header_get_priority(const u32 header[ASYNC_HEADER_QUADLET_COUNT])57  static inline unsigned int async_header_get_priority(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
58  {
59  	return (header[0] & ASYNC_HEADER_Q0_PRIORITY_MASK) >> ASYNC_HEADER_Q0_PRIORITY_SHIFT;
60  }
61  
async_header_get_source(const u32 header[ASYNC_HEADER_QUADLET_COUNT])62  static inline unsigned int async_header_get_source(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
63  {
64  	return (header[1] & ASYNC_HEADER_Q1_SOURCE_MASK) >> ASYNC_HEADER_Q1_SOURCE_SHIFT;
65  }
66  
async_header_get_rcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])67  static inline unsigned int async_header_get_rcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
68  {
69  	return (header[1] & ASYNC_HEADER_Q1_RCODE_MASK) >> ASYNC_HEADER_Q1_RCODE_SHIFT;
70  }
71  
async_header_get_offset(const u32 header[ASYNC_HEADER_QUADLET_COUNT])72  static inline u64 async_header_get_offset(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
73  {
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]);
76  }
77  
async_header_get_quadlet_data(const u32 header[ASYNC_HEADER_QUADLET_COUNT])78  static inline u32 async_header_get_quadlet_data(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
79  {
80  	return header[3];
81  }
82  
async_header_get_data_length(const u32 header[ASYNC_HEADER_QUADLET_COUNT])83  static inline unsigned int async_header_get_data_length(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
84  {
85  	return (header[3] & ASYNC_HEADER_Q3_DATA_LENGTH_MASK) >> ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT;
86  }
87  
async_header_get_extended_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])88  static inline unsigned int async_header_get_extended_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
89  {
90  	return (header[3] & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK) >> ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT;
91  }
92  
async_header_set_destination(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int destination)93  static inline void async_header_set_destination(u32 header[ASYNC_HEADER_QUADLET_COUNT],
94  						unsigned int destination)
95  {
96  	header[0] &= ~ASYNC_HEADER_Q0_DESTINATION_MASK;
97  	header[0] |= (((u32)destination) << ASYNC_HEADER_Q0_DESTINATION_SHIFT) & ASYNC_HEADER_Q0_DESTINATION_MASK;
98  }
99  
async_header_set_tlabel(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int tlabel)100  static inline void async_header_set_tlabel(u32 header[ASYNC_HEADER_QUADLET_COUNT],
101  					   unsigned int tlabel)
102  {
103  	header[0] &= ~ASYNC_HEADER_Q0_TLABEL_MASK;
104  	header[0] |= (((u32)tlabel) << ASYNC_HEADER_Q0_TLABEL_SHIFT) & ASYNC_HEADER_Q0_TLABEL_MASK;
105  }
106  
async_header_set_retry(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int retry)107  static inline void async_header_set_retry(u32 header[ASYNC_HEADER_QUADLET_COUNT],
108  					  unsigned int retry)
109  {
110  	header[0] &= ~ASYNC_HEADER_Q0_RETRY_MASK;
111  	header[0] |= (((u32)retry) << ASYNC_HEADER_Q0_RETRY_SHIFT) & ASYNC_HEADER_Q0_RETRY_MASK;
112  }
113  
async_header_set_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int tcode)114  static inline void async_header_set_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
115  					  unsigned int tcode)
116  {
117  	header[0] &= ~ASYNC_HEADER_Q0_TCODE_MASK;
118  	header[0] |= (((u32)tcode) << ASYNC_HEADER_Q0_TCODE_SHIFT) & ASYNC_HEADER_Q0_TCODE_MASK;
119  }
120  
async_header_set_priority(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int priority)121  static inline void async_header_set_priority(u32 header[ASYNC_HEADER_QUADLET_COUNT],
122  					     unsigned int priority)
123  {
124  	header[0] &= ~ASYNC_HEADER_Q0_PRIORITY_MASK;
125  	header[0] |= (((u32)priority) << ASYNC_HEADER_Q0_PRIORITY_SHIFT) & ASYNC_HEADER_Q0_PRIORITY_MASK;
126  }
127  
128  
async_header_set_source(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int source)129  static inline void async_header_set_source(u32 header[ASYNC_HEADER_QUADLET_COUNT],
130  					   unsigned int source)
131  {
132  	header[1] &= ~ASYNC_HEADER_Q1_SOURCE_MASK;
133  	header[1] |= (((u32)source) << ASYNC_HEADER_Q1_SOURCE_SHIFT) & ASYNC_HEADER_Q1_SOURCE_MASK;
134  }
135  
async_header_set_rcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int rcode)136  static inline void async_header_set_rcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
137  					  unsigned int rcode)
138  {
139  	header[1] &= ~ASYNC_HEADER_Q1_RCODE_MASK;
140  	header[1] |= (((u32)rcode) << ASYNC_HEADER_Q1_RCODE_SHIFT) & ASYNC_HEADER_Q1_RCODE_MASK;
141  }
142  
async_header_set_offset(u32 header[ASYNC_HEADER_QUADLET_COUNT],u64 offset)143  static inline void async_header_set_offset(u32 header[ASYNC_HEADER_QUADLET_COUNT], u64 offset)
144  {
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);
149  }
150  
async_header_set_quadlet_data(u32 header[ASYNC_HEADER_QUADLET_COUNT],u32 quadlet_data)151  static inline void async_header_set_quadlet_data(u32 header[ASYNC_HEADER_QUADLET_COUNT], u32 quadlet_data)
152  {
153  	header[3] = quadlet_data;
154  }
155  
async_header_set_data_length(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int data_length)156  static inline void async_header_set_data_length(u32 header[ASYNC_HEADER_QUADLET_COUNT],
157  						unsigned int data_length)
158  {
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;
161  }
162  
async_header_set_extended_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],unsigned int extended_tcode)163  static inline void async_header_set_extended_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
164  						   unsigned int extended_tcode)
165  {
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;
168  }
169  
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
180  
isoc_header_get_data_length(u32 header)181  static inline unsigned int isoc_header_get_data_length(u32 header)
182  {
183  	return (header & ISOC_HEADER_DATA_LENGTH_MASK) >> ISOC_HEADER_DATA_LENGTH_SHIFT;
184  }
185  
isoc_header_get_tag(u32 header)186  static inline unsigned int isoc_header_get_tag(u32 header)
187  {
188  	return (header & ISOC_HEADER_TAG_MASK) >> ISOC_HEADER_TAG_SHIFT;
189  }
190  
isoc_header_get_channel(u32 header)191  static inline unsigned int isoc_header_get_channel(u32 header)
192  {
193  	return (header & ISOC_HEADER_CHANNEL_MASK) >> ISOC_HEADER_CHANNEL_SHIFT;
194  }
195  
isoc_header_get_tcode(u32 header)196  static inline unsigned int isoc_header_get_tcode(u32 header)
197  {
198  	return (header & ISOC_HEADER_TCODE_MASK) >> ISOC_HEADER_TCODE_SHIFT;
199  }
200  
isoc_header_get_sy(u32 header)201  static inline unsigned int isoc_header_get_sy(u32 header)
202  {
203  	return (header & ISOC_HEADER_SY_MASK) >> ISOC_HEADER_SY_SHIFT;
204  }
205  
isoc_header_set_data_length(u32 * header,unsigned int data_length)206  static inline void isoc_header_set_data_length(u32 *header, unsigned int data_length)
207  {
208  	*header &= ~ISOC_HEADER_DATA_LENGTH_MASK;
209  	*header |= (((u32)data_length) << ISOC_HEADER_DATA_LENGTH_SHIFT) & ISOC_HEADER_DATA_LENGTH_MASK;
210  }
211  
isoc_header_set_tag(u32 * header,unsigned int tag)212  static inline void isoc_header_set_tag(u32 *header, unsigned int tag)
213  {
214  	*header &= ~ISOC_HEADER_TAG_MASK;
215  	*header |= (((u32)tag) << ISOC_HEADER_TAG_SHIFT) & ISOC_HEADER_TAG_MASK;
216  }
217  
isoc_header_set_channel(u32 * header,unsigned int channel)218  static inline void isoc_header_set_channel(u32 *header, unsigned int channel)
219  {
220  	*header &= ~ISOC_HEADER_CHANNEL_MASK;
221  	*header |= (((u32)channel) << ISOC_HEADER_CHANNEL_SHIFT) & ISOC_HEADER_CHANNEL_MASK;
222  }
223  
isoc_header_set_tcode(u32 * header,unsigned int tcode)224  static inline void isoc_header_set_tcode(u32 *header, unsigned int tcode)
225  {
226  	*header &= ~ISOC_HEADER_TCODE_MASK;
227  	*header |= (((u32)tcode) << ISOC_HEADER_TCODE_SHIFT) & ISOC_HEADER_TCODE_MASK;
228  }
229  
isoc_header_set_sy(u32 * header,unsigned int sy)230  static inline void isoc_header_set_sy(u32 *header, unsigned int sy)
231  {
232  	*header &= ~ISOC_HEADER_SY_MASK;
233  	*header |= (((u32)sy) << ISOC_HEADER_SY_SHIFT) & ISOC_HEADER_SY_MASK;
234  }
235  
236  #endif // _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
237