CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=y
CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST=y
CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST=y
+CONFIG_FIREWIRE_KUNIT_OHCI_SERDES_TEST=y
To compile this driver as a module, say M here: The module will be
called firewire-ohci.
+config FIREWIRE_KUNIT_OHCI_SERDES_TEST
+ tristate "KUnit tests for serialization/deserialization of data in buffers/registers" if !KUNIT_ALL_TESTS
+ depends on FIREWIRE && KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ This builds the KUnit tests to check serialization and deserialization
+ of data in buffers and registers defined in 1394 OHCI specification.
+
+ KUnit tests run during boot and output the results to the debug
+ log in TAP format (https://testanything.org/). Only useful for
+ kernel devs running KUnit test harness and are not for inclusion
+ into a production build.
+
+ For more information on KUnit and unit tests in general, refer
+ to the KUnit documentation in Documentation/dev-tools/kunit/.
+
config FIREWIRE_SBP2
tristate "Storage devices (SBP-2 protocol)"
depends on FIREWIRE && SCSI
obj-$(CONFIG_FIREWIRE_KUNIT_UAPI_TEST) += uapi-test.o
obj-$(CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST) += packet-serdes-test.o
obj-$(CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST) += self-id-sequence-helper-test.o
+obj-$(CONFIG_FIREWIRE_KUNIT_OHCI_SERDES_TEST) += ohci-serdes-test.o
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+// ohci-serdes-test.c - An application of Kunit to check serialization/deserialization of data in
+// buffers and registers defined in 1394 OHCI specification.
+//
+// Copyright (c) 2024 Takashi Sakamoto
+
+#include <kunit/test.h>
+
+#include "ohci.h"
+
+
+static void test_self_id_count_register_deserialization(struct kunit *test)
+{
+ const u32 expected = 0x803d0594;
+
+ bool is_error = ohci1394_self_id_count_is_error(expected);
+ u8 generation = ohci1394_self_id_count_get_generation(expected);
+ u32 size = ohci1394_self_id_count_get_size(expected);
+
+ KUNIT_EXPECT_TRUE(test, is_error);
+ KUNIT_EXPECT_EQ(test, 0x3d, generation);
+ KUNIT_EXPECT_EQ(test, 0x165, size);
+}
+
+static void test_self_id_receive_buffer_deserialization(struct kunit *test)
+{
+ const u32 buffer[] = {
+ 0x0006f38b,
+ 0x807fcc56,
+ 0x7f8033a9,
+ 0x8145cc5e,
+ 0x7eba33a1,
+ };
+
+ u8 generation = ohci1394_self_id_receive_q0_get_generation(buffer[0]);
+ u16 timestamp = ohci1394_self_id_receive_q0_get_timestamp(buffer[0]);
+
+ KUNIT_EXPECT_EQ(test, 0x6, generation);
+ KUNIT_EXPECT_EQ(test, 0xf38b, timestamp);
+}
+
+static struct kunit_case ohci_serdes_test_cases[] = {
+ KUNIT_CASE(test_self_id_count_register_deserialization),
+ KUNIT_CASE(test_self_id_receive_buffer_deserialization),
+ {}
+};
+
+static struct kunit_suite ohci_serdes_test_suite = {
+ .name = "firewire-ohci-serdes",
+ .test_cases = ohci_serdes_test_cases,
+};
+kunit_test_suite(ohci_serdes_test_suite);
+
+MODULE_DESCRIPTION("FireWire buffers and registers serialization/deserialization unit test suite");
+MODULE_LICENSE("GPL");
#define OHCI1394_phy_tcode 0xe
+// Self-ID DMA.
+
+#define OHCI1394_SelfIDCount_selfIDError_MASK 0x80000000
+#define OHCI1394_SelfIDCount_selfIDError_SHIFT 31
+#define OHCI1394_SelfIDCount_selfIDGeneration_MASK 0x00ff0000
+#define OHCI1394_SelfIDCount_selfIDGeneration_SHIFT 16
+#define OHCI1394_SelfIDCount_selfIDSize_MASK 0x000007fc
+#define OHCI1394_SelfIDCount_selfIDSize_SHIFT 2
+
+static inline bool ohci1394_self_id_count_is_error(u32 value)
+{
+ return !!((value & OHCI1394_SelfIDCount_selfIDError_MASK) >> OHCI1394_SelfIDCount_selfIDError_SHIFT);
+}
+
+static inline u8 ohci1394_self_id_count_get_generation(u32 value)
+{
+ return (value & OHCI1394_SelfIDCount_selfIDGeneration_MASK) >> OHCI1394_SelfIDCount_selfIDGeneration_SHIFT;
+}
+
+// In 1394 OHCI specification, the maximum size of self ID stream is 504 quadlets
+// (= 63 devices * 4 self ID packets * 2 quadlets). The selfIDSize field accommodates it and its
+// additional first quadlet, since the field is 9 bits (0x1ff = 511).
+static inline u32 ohci1394_self_id_count_get_size(u32 value)
+{
+ return (value & OHCI1394_SelfIDCount_selfIDSize_MASK) >> OHCI1394_SelfIDCount_selfIDSize_SHIFT;
+}
+
+#define OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_MASK 0x00ff0000
+#define OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_SHIFT 16
+#define OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_MASK 0x0000ffff
+#define OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_SHIFT 0
+
+static inline u8 ohci1394_self_id_receive_q0_get_generation(u32 quadlet0)
+{
+ return (quadlet0 & OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_MASK) >> OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_SHIFT;
+}
+
+static inline u16 ohci1394_self_id_receive_q0_get_timestamp(u32 quadlet0)
+{
+ return (quadlet0 & OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_MASK) >> OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_SHIFT;
+}
+
#endif /* _FIREWIRE_OHCI_H */