summaryrefslogtreecommitdiff
path: root/drivers/firewire/packet-header-definitions.h
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2024-04-28 10:13:39 +0300
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>2024-05-06 05:06:04 +0300
commit75527d8d9e5ec374b9b0d70c712fec78b4bb693f (patch)
treeb1dbf190244b595df5a60792665c210b094dc1b4 /drivers/firewire/packet-header-definitions.h
parente41b2c1532d6d43945a59e7d844a258b5a82f307 (diff)
downloadlinux-75527d8d9e5ec374b9b0d70c712fec78b4bb693f.tar.xz
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/20240428071347.409202-2-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Diffstat (limited to 'drivers/firewire/packet-header-definitions.h')
-rw-r--r--drivers/firewire/packet-header-definitions.h168
1 files changed, 168 insertions, 0 deletions
diff --git a/drivers/firewire/packet-header-definitions.h b/drivers/firewire/packet-header-definitions.h
new file mode 100644
index 000000000000..83e550427706
--- /dev/null
+++ b/drivers/firewire/packet-header-definitions.h
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+// packet-header-definitions.h - The definitions of header fields for IEEE 1394 packet.
+//
+// Copyright (c) 2024 Takashi Sakamoto
+
+#ifndef _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
+#define _FIREWIRE_PACKET_HEADER_DEFINITIONS_H
+
+#define ASYNC_HEADER_QUADLET_COUNT 4
+
+#define ASYNC_HEADER_Q0_DESTINATION_SHIFT 16
+#define ASYNC_HEADER_Q0_DESTINATION_MASK 0xffff0000
+#define ASYNC_HEADER_Q0_TLABEL_SHIFT 10
+#define ASYNC_HEADER_Q0_TLABEL_MASK 0x0000fc00
+#define ASYNC_HEADER_Q0_RETRY_SHIFT 8
+#define ASYNC_HEADER_Q0_RETRY_MASK 0x00000300
+#define ASYNC_HEADER_Q0_TCODE_SHIFT 4
+#define ASYNC_HEADER_Q0_TCODE_MASK 0x000000f0
+#define ASYNC_HEADER_Q0_PRIORITY_SHIFT 0
+#define ASYNC_HEADER_Q0_PRIORITY_MASK 0x0000000f
+#define ASYNC_HEADER_Q1_SOURCE_SHIFT 16
+#define ASYNC_HEADER_Q1_SOURCE_MASK 0xffff0000
+#define ASYNC_HEADER_Q1_RCODE_SHIFT 12
+#define ASYNC_HEADER_Q1_RCODE_MASK 0x0000f000
+#define ASYNC_HEADER_Q1_RCODE_SHIFT 12
+#define ASYNC_HEADER_Q1_RCODE_MASK 0x0000f000
+#define ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT 0
+#define ASYNC_HEADER_Q1_OFFSET_HIGH_MASK 0x0000ffff
+#define ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT 16
+#define ASYNC_HEADER_Q3_DATA_LENGTH_MASK 0xffff0000
+#define ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT 0
+#define ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK 0x0000ffff
+
+static inline unsigned int async_header_get_destination(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[0] & ASYNC_HEADER_Q0_DESTINATION_MASK) >> ASYNC_HEADER_Q0_DESTINATION_SHIFT;
+}
+
+static inline unsigned int async_header_get_tlabel(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[0] & ASYNC_HEADER_Q0_TLABEL_MASK) >> ASYNC_HEADER_Q0_TLABEL_SHIFT;
+}
+
+static inline unsigned int async_header_get_retry(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[0] & ASYNC_HEADER_Q0_RETRY_MASK) >> ASYNC_HEADER_Q0_RETRY_SHIFT;
+}
+
+static inline unsigned int async_header_get_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[0] & ASYNC_HEADER_Q0_TCODE_MASK) >> ASYNC_HEADER_Q0_TCODE_SHIFT;
+}
+
+static inline unsigned int async_header_get_priority(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[0] & ASYNC_HEADER_Q0_PRIORITY_MASK) >> ASYNC_HEADER_Q0_PRIORITY_SHIFT;
+}
+
+static inline unsigned int async_header_get_source(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[1] & ASYNC_HEADER_Q1_SOURCE_MASK) >> ASYNC_HEADER_Q1_SOURCE_SHIFT;
+}
+
+static inline unsigned int async_header_get_rcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[1] & ASYNC_HEADER_Q1_RCODE_MASK) >> ASYNC_HEADER_Q1_RCODE_SHIFT;
+}
+
+static inline u64 async_header_get_offset(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ u32 hi = (header[1] & ASYNC_HEADER_Q1_OFFSET_HIGH_MASK) >> ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT;
+ return (((u64)hi) << 32) | ((u64)header[2]);
+}
+
+static inline u32 async_header_get_quadlet_data(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return header[3];
+}
+
+static inline unsigned int async_header_get_data_length(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[3] & ASYNC_HEADER_Q3_DATA_LENGTH_MASK) >> ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT;
+}
+
+static inline unsigned int async_header_get_extended_tcode(const u32 header[ASYNC_HEADER_QUADLET_COUNT])
+{
+ return (header[3] & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK) >> ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT;
+}
+
+static inline void async_header_set_destination(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int destination)
+{
+ header[0] &= ~ASYNC_HEADER_Q0_DESTINATION_MASK;
+ header[0] |= (((u32)destination) << ASYNC_HEADER_Q0_DESTINATION_SHIFT) & ASYNC_HEADER_Q0_DESTINATION_MASK;
+}
+
+static inline void async_header_set_tlabel(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int tlabel)
+{
+ header[0] &= ~ASYNC_HEADER_Q0_TLABEL_MASK;
+ header[0] |= (((u32)tlabel) << ASYNC_HEADER_Q0_TLABEL_SHIFT) & ASYNC_HEADER_Q0_TLABEL_MASK;
+}
+
+static inline void async_header_set_retry(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int retry)
+{
+ header[0] &= ~ASYNC_HEADER_Q0_RETRY_MASK;
+ header[0] |= (((u32)retry) << ASYNC_HEADER_Q0_RETRY_SHIFT) & ASYNC_HEADER_Q0_RETRY_MASK;
+}
+
+static inline void async_header_set_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int tcode)
+{
+ header[0] &= ~ASYNC_HEADER_Q0_TCODE_MASK;
+ header[0] |= (((u32)tcode) << ASYNC_HEADER_Q0_TCODE_SHIFT) & ASYNC_HEADER_Q0_TCODE_MASK;
+}
+
+static inline void async_header_set_priority(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int priority)
+{
+ header[0] &= ~ASYNC_HEADER_Q0_PRIORITY_MASK;
+ header[0] |= (((u32)priority) << ASYNC_HEADER_Q0_PRIORITY_SHIFT) & ASYNC_HEADER_Q0_PRIORITY_MASK;
+}
+
+
+static inline void async_header_set_source(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int source)
+{
+ header[1] &= ~ASYNC_HEADER_Q1_SOURCE_MASK;
+ header[1] |= (((u32)source) << ASYNC_HEADER_Q1_SOURCE_SHIFT) & ASYNC_HEADER_Q1_SOURCE_MASK;
+}
+
+static inline void async_header_set_rcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int rcode)
+{
+ header[1] &= ~ASYNC_HEADER_Q1_RCODE_MASK;
+ header[1] |= (((u32)rcode) << ASYNC_HEADER_Q1_RCODE_SHIFT) & ASYNC_HEADER_Q1_RCODE_MASK;
+}
+
+static inline void async_header_set_offset(u32 header[ASYNC_HEADER_QUADLET_COUNT], u64 offset)
+{
+ u32 hi = (u32)(offset >> 32);
+ header[1] &= ~ASYNC_HEADER_Q1_OFFSET_HIGH_MASK;
+ header[1] |= (hi << ASYNC_HEADER_Q1_OFFSET_HIGH_SHIFT) & ASYNC_HEADER_Q1_OFFSET_HIGH_MASK;
+ header[2] = (u32)(offset & 0x00000000ffffffff);
+}
+
+static inline void async_header_set_quadlet_data(u32 header[ASYNC_HEADER_QUADLET_COUNT], u32 quadlet_data)
+{
+ header[3] = quadlet_data;
+}
+
+static inline void async_header_set_data_length(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int data_length)
+{
+ header[3] &= ~ASYNC_HEADER_Q3_DATA_LENGTH_MASK;
+ header[3] |= (((u32)data_length) << ASYNC_HEADER_Q3_DATA_LENGTH_SHIFT) & ASYNC_HEADER_Q3_DATA_LENGTH_MASK;
+}
+
+static inline void async_header_set_extended_tcode(u32 header[ASYNC_HEADER_QUADLET_COUNT],
+ unsigned int extended_tcode)
+{
+ header[3] &= ~ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK;
+ header[3] |= (((u32)extended_tcode) << ASYNC_HEADER_Q3_EXTENDED_TCODE_SHIFT) & ASYNC_HEADER_Q3_EXTENDED_TCODE_MASK;
+}
+
+#endif // _FIREWIRE_PACKET_HEADER_DEFINITIONS_H