]> www.infradead.org Git - users/willy/xarray.git/commitdiff
firewire: core: add common inline functions to serialize/deserialize self ID packet
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Wed, 5 Jun 2024 23:51:51 +0000 (08:51 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 16 Jun 2024 23:37:03 +0000 (08:37 +0900)
Within FireWire subsystem, the serializations and deserializations of phy
packet are implemented in several parts. They includes some redundancies.

This commit adds a series of helper functions for the serializations and
deserializations of self ID packet with a Kunit test suite.

Link: https://lore.kernel.org/r/20240605235155.116468-8-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
drivers/firewire/packet-serdes-test.c
drivers/firewire/phy-packet-definitions.h

index e83b1fece780eeae4a50d6dbe943085778649e63..c56199e84f91162c45af293615a0b2ceac649e2b 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/firewire-constants.h>
 
 #include "packet-header-definitions.h"
+#include "phy-packet-definitions.h"
 
 static void serialize_async_header_common(u32 header[ASYNC_HEADER_QUADLET_COUNT],
                                          unsigned int dst_id, unsigned int tlabel,
@@ -187,6 +188,66 @@ static void deserialize_isoc_header(u32 header, unsigned int *data_length, unsig
        *sy = isoc_header_get_sy(header);
 }
 
+static void serialize_phy_packet_self_id_zero(u32 *quadlet, unsigned int packet_identifier,
+                                             unsigned int phy_id, bool extended,
+                                             bool link_is_active, unsigned int gap_count,
+                                             unsigned int scode, bool is_contender,
+                                             unsigned int power_class, bool is_initiated_reset,
+                                             bool has_more_packets)
+{
+       phy_packet_set_packet_identifier(quadlet, packet_identifier);
+       phy_packet_self_id_set_phy_id(quadlet, phy_id);
+       phy_packet_self_id_set_extended(quadlet, extended);
+       phy_packet_self_id_zero_set_link_active(quadlet, link_is_active);
+       phy_packet_self_id_zero_set_gap_count(quadlet, gap_count);
+       phy_packet_self_id_zero_set_scode(quadlet, scode);
+       phy_packet_self_id_zero_set_contender(quadlet, is_contender);
+       phy_packet_self_id_zero_set_power_class(quadlet, power_class);
+       phy_packet_self_id_zero_set_initiated_reset(quadlet, is_initiated_reset);
+       phy_packet_self_id_set_more_packets(quadlet, has_more_packets);
+}
+
+static void deserialize_phy_packet_self_id_zero(u32 quadlet, unsigned int *packet_identifier,
+                                               unsigned int *phy_id, bool *extended,
+                                               bool *link_is_active, unsigned int *gap_count,
+                                               unsigned int *scode, bool *is_contender,
+                                               unsigned int *power_class,
+                                               bool *is_initiated_reset, bool *has_more_packets)
+{
+       *packet_identifier = phy_packet_get_packet_identifier(quadlet);
+       *phy_id = phy_packet_self_id_get_phy_id(quadlet);
+       *extended = phy_packet_self_id_get_extended(quadlet);
+       *link_is_active = phy_packet_self_id_zero_get_link_active(quadlet);
+       *gap_count = phy_packet_self_id_zero_get_gap_count(quadlet);
+       *scode = phy_packet_self_id_zero_get_scode(quadlet);
+       *is_contender = phy_packet_self_id_zero_get_contender(quadlet);
+       *power_class = phy_packet_self_id_zero_get_power_class(quadlet);
+       *is_initiated_reset = phy_packet_self_id_zero_get_initiated_reset(quadlet);
+       *has_more_packets = phy_packet_self_id_get_more_packets(quadlet);
+}
+
+static void serialize_phy_packet_self_id_extended(u32 *quadlet, unsigned int packet_identifier,
+                                                 unsigned int phy_id, bool extended,
+                                                 unsigned int sequence, bool has_more_packets)
+{
+       phy_packet_set_packet_identifier(quadlet, packet_identifier);
+       phy_packet_self_id_set_phy_id(quadlet, phy_id);
+       phy_packet_self_id_set_extended(quadlet, extended);
+       phy_packet_self_id_extended_set_sequence(quadlet, sequence);
+       phy_packet_self_id_set_more_packets(quadlet, has_more_packets);
+}
+
+static void deserialize_phy_packet_self_id_extended(u32 quadlet, unsigned int *packet_identifier,
+                                                   unsigned int *phy_id, bool *extended,
+                                                   unsigned int *sequence, bool *has_more_packets)
+{
+       *packet_identifier = phy_packet_get_packet_identifier(quadlet);
+       *phy_id = phy_packet_self_id_get_phy_id(quadlet);
+       *extended = phy_packet_self_id_get_extended(quadlet);
+       *sequence = phy_packet_self_id_extended_get_sequence(quadlet);
+       *has_more_packets = phy_packet_self_id_get_more_packets(quadlet);
+}
+
 static void test_async_header_write_quadlet_request(struct kunit *test)
 {
        static const u32 expected[ASYNC_HEADER_QUADLET_COUNT] = {
@@ -559,6 +620,197 @@ static void test_isoc_header(struct kunit *test)
        KUNIT_EXPECT_EQ(test, header, expected);
 }
 
+static void test_phy_packet_self_id_zero_case0(struct kunit *test)
+{
+       // TSB41AB1/2 with 1 port.
+       const u32 expected[] = {0x80458c80};
+       u32 quadlets[] = {0};
+
+       unsigned int packet_identifier;
+       unsigned int phy_id;
+       bool extended;
+       bool link_is_active;
+       unsigned int gap_count;
+       unsigned int scode;
+       bool is_contender;
+       unsigned int power_class;
+       enum phy_packet_self_id_port_status port_status[3];
+       bool is_initiated_reset;
+       bool has_more_packets;
+       unsigned int port_index;
+
+       deserialize_phy_packet_self_id_zero(expected[0], &packet_identifier, &phy_id, &extended,
+                                           &link_is_active, &gap_count, &scode, &is_contender,
+                                           &power_class, &is_initiated_reset, &has_more_packets);
+
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
+       KUNIT_EXPECT_EQ(test, 0, phy_id);
+       KUNIT_EXPECT_FALSE(test, extended);
+       KUNIT_EXPECT_TRUE(test, link_is_active);
+       KUNIT_EXPECT_EQ(test, 0x05, gap_count);
+       KUNIT_EXPECT_EQ(test, SCODE_400, scode);
+       KUNIT_EXPECT_TRUE(test, is_contender);
+       KUNIT_EXPECT_EQ(test, 0x4, power_class);
+       KUNIT_EXPECT_FALSE(test, is_initiated_reset);
+       KUNIT_EXPECT_FALSE(test, has_more_packets);
+
+       serialize_phy_packet_self_id_zero(quadlets, packet_identifier, phy_id, extended,
+                                         link_is_active, gap_count, scode, is_contender,
+                                         power_class, is_initiated_reset, has_more_packets);
+
+       for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
+               port_status[port_index] =
+                       self_id_sequence_get_port_status(expected, ARRAY_SIZE(expected), port_index);
+       }
+
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[0]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[1]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[2]);
+
+       for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
+               self_id_sequence_set_port_status(quadlets, ARRAY_SIZE(quadlets), port_index,
+                                                port_status[port_index]);
+       }
+
+       KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
+}
+
+static void test_phy_packet_self_id_zero_case1(struct kunit *test)
+{
+       // XIO2213 and TSB81BA3E with 3 ports.
+       const u32 expected[] = {0x817fcc5e};
+       u32 quadlets[] = {0};
+
+       unsigned int packet_identifier;
+       unsigned int phy_id;
+       bool extended;
+       bool link_is_active;
+       unsigned int gap_count;
+       unsigned int scode;
+       bool is_contender;
+       unsigned int power_class;
+       enum phy_packet_self_id_port_status port_status[3];
+       bool is_initiated_reset;
+       bool has_more_packets;
+       unsigned int port_index;
+
+       deserialize_phy_packet_self_id_zero(expected[0], &packet_identifier, &phy_id, &extended,
+                                           &link_is_active, &gap_count, &scode, &is_contender,
+                                           &power_class, &is_initiated_reset, &has_more_packets);
+
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
+       KUNIT_EXPECT_EQ(test, 1, phy_id);
+       KUNIT_EXPECT_FALSE(test, extended);
+       KUNIT_EXPECT_TRUE(test, link_is_active);
+       KUNIT_EXPECT_EQ(test, 0x3f, gap_count);
+       KUNIT_EXPECT_EQ(test, SCODE_800, scode);
+       KUNIT_EXPECT_TRUE(test, is_contender);
+       KUNIT_EXPECT_EQ(test, 0x4, power_class);
+       KUNIT_EXPECT_TRUE(test, is_initiated_reset);
+       KUNIT_EXPECT_FALSE(test, has_more_packets);
+
+       serialize_phy_packet_self_id_zero(quadlets, packet_identifier, phy_id, extended,
+                                         link_is_active, gap_count, scode, is_contender,
+                                         power_class, is_initiated_reset, has_more_packets);
+
+       for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
+               port_status[port_index] =
+                       self_id_sequence_get_port_status(expected, ARRAY_SIZE(expected), port_index);
+       }
+
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[0]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[1]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_CHILD, port_status[2]);
+
+       for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
+               self_id_sequence_set_port_status(quadlets, ARRAY_SIZE(quadlets), port_index,
+                                                port_status[port_index]);
+       }
+
+       KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
+}
+
+static void test_phy_packet_self_id_zero_and_one(struct kunit *test)
+{
+       // TSB41LV06A with 6 ports.
+       const u32 expected[] = {
+               0x803f8459,
+               0x80815000,
+       };
+       u32 quadlets[] = {0, 0};
+
+       unsigned int packet_identifier;
+       unsigned int phy_id;
+       bool extended;
+       bool link_is_active;
+       unsigned int gap_count;
+       unsigned int scode;
+       bool is_contender;
+       unsigned int power_class;
+       enum phy_packet_self_id_port_status port_status[11];
+       bool is_initiated_reset;
+       bool has_more_packets;
+
+       unsigned int sequence;
+       unsigned int port_index;
+
+       deserialize_phy_packet_self_id_zero(expected[0], &packet_identifier, &phy_id, &extended,
+                                           &link_is_active, &gap_count, &scode, &is_contender,
+                                           &power_class, &is_initiated_reset, &has_more_packets);
+
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
+       KUNIT_EXPECT_EQ(test, 0, phy_id);
+       KUNIT_EXPECT_FALSE(test, extended);
+       KUNIT_EXPECT_FALSE(test, link_is_active);
+       KUNIT_EXPECT_EQ(test, 0x3f, gap_count);
+       KUNIT_EXPECT_EQ(test, SCODE_400, scode);
+       KUNIT_EXPECT_FALSE(test, is_contender);
+       KUNIT_EXPECT_EQ(test, 0x4, power_class);
+       KUNIT_EXPECT_FALSE(test, is_initiated_reset);
+       KUNIT_EXPECT_TRUE(test, has_more_packets);
+
+       serialize_phy_packet_self_id_zero(quadlets, packet_identifier, phy_id, extended,
+                                         link_is_active, gap_count, scode, is_contender,
+                                         power_class, is_initiated_reset, has_more_packets);
+
+       deserialize_phy_packet_self_id_extended(expected[1], &packet_identifier, &phy_id, &extended,
+                                               &sequence, &has_more_packets);
+
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_PACKET_IDENTIFIER_SELF_ID, packet_identifier);
+       KUNIT_EXPECT_EQ(test, 0, phy_id);
+       KUNIT_EXPECT_TRUE(test, extended);
+       KUNIT_EXPECT_EQ(test, 0, sequence);
+       KUNIT_EXPECT_FALSE(test, has_more_packets);
+
+       serialize_phy_packet_self_id_extended(&quadlets[1], packet_identifier, phy_id, extended,
+                                             sequence, has_more_packets);
+
+
+       for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
+               port_status[port_index] =
+                       self_id_sequence_get_port_status(expected, ARRAY_SIZE(expected), port_index);
+       }
+
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[0]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[1]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_PARENT, port_status[2]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[3]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[4]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NCONN, port_status[5]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[6]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[7]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[8]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[9]);
+       KUNIT_EXPECT_EQ(test, PHY_PACKET_SELF_ID_PORT_STATUS_NONE, port_status[10]);
+
+       for (port_index = 0; port_index < ARRAY_SIZE(port_status); ++port_index) {
+               self_id_sequence_set_port_status(quadlets, ARRAY_SIZE(quadlets), port_index,
+                                                port_status[port_index]);
+       }
+
+       KUNIT_EXPECT_MEMEQ(test, quadlets, expected, sizeof(expected));
+}
+
 static struct kunit_case packet_serdes_test_cases[] = {
        KUNIT_CASE(test_async_header_write_quadlet_request),
        KUNIT_CASE(test_async_header_write_block_request),
@@ -570,6 +822,9 @@ static struct kunit_case packet_serdes_test_cases[] = {
        KUNIT_CASE(test_async_header_lock_request),
        KUNIT_CASE(test_async_header_lock_response),
        KUNIT_CASE(test_isoc_header),
+       KUNIT_CASE(test_phy_packet_self_id_zero_case0),
+       KUNIT_CASE(test_phy_packet_self_id_zero_case1),
+       KUNIT_CASE(test_phy_packet_self_id_zero_and_one),
        {}
 };
 
index 4ba8b18aa99300c6fe19bf4251f94ae76277c251..8f78494ad371ef9eb8999fcbce6ad0c0b6c7369a 100644 (file)
@@ -7,11 +7,42 @@
 #ifndef _FIREWIRE_PHY_PACKET_DEFINITIONS_H
 #define _FIREWIRE_PHY_PACKET_DEFINITIONS_H
 
+#define PACKET_IDENTIFIER_MASK                         0xc0000000
+#define PACKET_IDENTIFIER_SHIFT                                30
+
+static inline unsigned int phy_packet_get_packet_identifier(u32 quadlet)
+{
+       return (quadlet & PACKET_IDENTIFIER_MASK) >> PACKET_IDENTIFIER_SHIFT;
+}
+
+static inline void phy_packet_set_packet_identifier(u32 *quadlet, unsigned int packet_identifier)
+{
+       *quadlet &= ~PACKET_IDENTIFIER_MASK;
+       *quadlet |= (packet_identifier << PACKET_IDENTIFIER_SHIFT) & PACKET_IDENTIFIER_MASK;
+}
+
+#define PHY_PACKET_PACKET_IDENTIFIER_SELF_ID           2
+
+#define SELF_ID_PHY_ID_MASK                            0x3f000000
+#define SELF_ID_PHY_ID_SHIFT                           24
 #define SELF_ID_EXTENDED_MASK                          0x00800000
 #define SELF_ID_EXTENDED_SHIFT                         23
 #define SELF_ID_MORE_PACKETS_MASK                      0x00000001
 #define SELF_ID_MORE_PACKETS_SHIFT                     0
 
+#define SELF_ID_ZERO_LINK_ACTIVE_MASK                  0x00400000
+#define SELF_ID_ZERO_LINK_ACTIVE_SHIFT                 22
+#define SELF_ID_ZERO_GAP_COUNT_MASK                    0x003f0000
+#define SELF_ID_ZERO_GAP_COUNT_SHIFT                   16
+#define SELF_ID_ZERO_SCODE_MASK                                0x0000c000
+#define SELF_ID_ZERO_SCODE_SHIFT                       14
+#define SELF_ID_ZERO_CONTENDER_MASK                    0x00000800
+#define SELF_ID_ZERO_CONTENDER_SHIFT                   11
+#define SELF_ID_ZERO_POWER_CLASS_MASK                  0x00000700
+#define SELF_ID_ZERO_POWER_CLASS_SHIFT                 8
+#define SELF_ID_ZERO_INITIATED_RESET_MASK              0x00000002
+#define SELF_ID_ZERO_INITIATED_RESET_SHIFT             1
+
 #define SELF_ID_EXTENDED_SEQUENCE_MASK                 0x00700000
 #define SELF_ID_EXTENDED_SEQUENCE_SHIFT                        20
 
 
 #define SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT         4
 
+static inline unsigned int phy_packet_self_id_get_phy_id(u32 quadlet)
+{
+       return (quadlet & SELF_ID_PHY_ID_MASK)  >> SELF_ID_PHY_ID_SHIFT;
+}
+
+static inline void phy_packet_self_id_set_phy_id(u32 *quadlet, unsigned int phy_id)
+{
+       *quadlet &= ~SELF_ID_PHY_ID_MASK;
+       *quadlet |= (phy_id << SELF_ID_PHY_ID_SHIFT) & SELF_ID_PHY_ID_MASK;
+}
+
 static inline bool phy_packet_self_id_get_extended(u32 quadlet)
 {
        return (quadlet & SELF_ID_EXTENDED_MASK) >> SELF_ID_EXTENDED_SHIFT;
 }
 
+static inline void phy_packet_self_id_set_extended(u32 *quadlet, bool extended)
+{
+       *quadlet &= ~SELF_ID_EXTENDED_MASK;
+       *quadlet |= (extended << SELF_ID_EXTENDED_SHIFT) & SELF_ID_EXTENDED_MASK;
+}
+
+static inline bool phy_packet_self_id_zero_get_link_active(u32 quadlet)
+{
+       return (quadlet & SELF_ID_ZERO_LINK_ACTIVE_MASK) >> SELF_ID_ZERO_LINK_ACTIVE_SHIFT;
+}
+
+static inline void phy_packet_self_id_zero_set_link_active(u32 *quadlet, bool is_active)
+{
+       *quadlet &= ~SELF_ID_ZERO_LINK_ACTIVE_MASK;
+       *quadlet |= (is_active << SELF_ID_ZERO_LINK_ACTIVE_SHIFT) & SELF_ID_ZERO_LINK_ACTIVE_MASK;
+}
+
+static inline unsigned int phy_packet_self_id_zero_get_gap_count(u32 quadlet)
+{
+       return (quadlet & SELF_ID_ZERO_GAP_COUNT_MASK) >> SELF_ID_ZERO_GAP_COUNT_SHIFT;
+}
+
+static inline void phy_packet_self_id_zero_set_gap_count(u32 *quadlet, unsigned int gap_count)
+{
+       *quadlet &= ~SELF_ID_ZERO_GAP_COUNT_MASK;
+       *quadlet |= (gap_count << SELF_ID_ZERO_GAP_COUNT_SHIFT) & SELF_ID_ZERO_GAP_COUNT_MASK;
+}
+
+static inline unsigned int phy_packet_self_id_zero_get_scode(u32 quadlet)
+{
+       return (quadlet & SELF_ID_ZERO_SCODE_MASK) >> SELF_ID_ZERO_SCODE_SHIFT;
+}
+
+static inline void phy_packet_self_id_zero_set_scode(u32 *quadlet, unsigned int speed)
+{
+       *quadlet &= ~SELF_ID_ZERO_SCODE_MASK;
+       *quadlet |= (speed << SELF_ID_ZERO_SCODE_SHIFT) & SELF_ID_ZERO_SCODE_MASK;
+}
+
+static inline bool phy_packet_self_id_zero_get_contender(u32 quadlet)
+{
+       return (quadlet & SELF_ID_ZERO_CONTENDER_MASK) >> SELF_ID_ZERO_CONTENDER_SHIFT;
+}
+
+static inline void phy_packet_self_id_zero_set_contender(u32 *quadlet, bool is_contender)
+{
+       *quadlet &= ~SELF_ID_ZERO_CONTENDER_MASK;
+       *quadlet |= (is_contender << SELF_ID_ZERO_CONTENDER_SHIFT) & SELF_ID_ZERO_CONTENDER_MASK;
+}
+
+static inline unsigned int phy_packet_self_id_zero_get_power_class(u32 quadlet)
+{
+       return (quadlet & SELF_ID_ZERO_POWER_CLASS_MASK) >> SELF_ID_ZERO_POWER_CLASS_SHIFT;
+}
+
+static inline void phy_packet_self_id_zero_set_power_class(u32 *quadlet, unsigned int power_class)
+{
+       *quadlet &= ~SELF_ID_ZERO_POWER_CLASS_MASK;
+       *quadlet |= (power_class << SELF_ID_ZERO_POWER_CLASS_SHIFT) & SELF_ID_ZERO_POWER_CLASS_MASK;
+}
+
+static inline bool phy_packet_self_id_zero_get_initiated_reset(u32 quadlet)
+{
+       return (quadlet & SELF_ID_ZERO_INITIATED_RESET_MASK) >> SELF_ID_ZERO_INITIATED_RESET_SHIFT;
+}
+
+static inline void phy_packet_self_id_zero_set_initiated_reset(u32 *quadlet, bool is_initiated_reset)
+{
+       *quadlet &= ~SELF_ID_ZERO_INITIATED_RESET_MASK;
+       *quadlet |= (is_initiated_reset << SELF_ID_ZERO_INITIATED_RESET_SHIFT) & SELF_ID_ZERO_INITIATED_RESET_MASK;
+}
+
 static inline bool phy_packet_self_id_get_more_packets(u32 quadlet)
 {
        return (quadlet & SELF_ID_MORE_PACKETS_MASK) >> SELF_ID_MORE_PACKETS_SHIFT;
 }
 
+static inline void phy_packet_self_id_set_more_packets(u32 *quadlet, bool is_more_packets)
+{
+       *quadlet &= ~SELF_ID_MORE_PACKETS_MASK;
+       *quadlet |= (is_more_packets << SELF_ID_MORE_PACKETS_SHIFT) & SELF_ID_MORE_PACKETS_MASK;
+}
+
 static inline unsigned int phy_packet_self_id_extended_get_sequence(u32 quadlet)
 {
        return (quadlet & SELF_ID_EXTENDED_SEQUENCE_MASK) >> SELF_ID_EXTENDED_SEQUENCE_SHIFT;
 }
 
+static inline void phy_packet_self_id_extended_set_sequence(u32 *quadlet, unsigned int sequence)
+{
+       *quadlet &= ~SELF_ID_EXTENDED_SEQUENCE_MASK;
+       *quadlet |= (sequence << SELF_ID_EXTENDED_SHIFT) & SELF_ID_EXTENDED_SEQUENCE_MASK;
+}
+
 struct self_id_sequence_enumerator {
        const u32 *cursor;
        unsigned int quadlet_count;