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 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 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 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 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 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 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 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 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 78 static inline u32 async_header_get_quadlet_data(const u32 header[ASYNC_HEADER_QUADLET_COUNT]) 79 { 80 return header[3]; 81 } 82 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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