Commit e175569c authored by Kristian Høgsberg's avatar Kristian Høgsberg Committed by Stefan Richter

firewire: Use lib/ implementation of CRC ITU-T.

With the CRC ITU-T implementation available in lib/ we can use that instead.

This also fixes a bug in the topology map crc computation.
Signed-off-by: default avatarKristian Hoegsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (fixed Kconfig)
parent 3e7cbae7
...@@ -6,6 +6,7 @@ comment "An alternative FireWire stack is available with EXPERIMENTAL=y" ...@@ -6,6 +6,7 @@ comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
config FIREWIRE config FIREWIRE
tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)" tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)"
depends on EXPERIMENTAL depends on EXPERIMENTAL
select CRC_ITU_T
help help
IEEE 1394 describes a high performance serial bus, which is also IEEE 1394 describes a high performance serial bus, which is also
known as FireWire(tm) or i.Link(tm) and is used for connecting all known as FireWire(tm) or i.Link(tm) and is used for connecting all
......
...@@ -23,31 +23,22 @@ ...@@ -23,31 +23,22 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/crc-itu-t.h>
#include "fw-transaction.h" #include "fw-transaction.h"
#include "fw-topology.h" #include "fw-topology.h"
#include "fw-device.h" #include "fw-device.h"
/* The lib/crc16.c implementation uses the standard (0x8005) int fw_compute_block_crc(u32 *block)
* polynomial, but we need the ITU-T (or CCITT) polynomial (0x1021).
* The implementation below works on an array of host-endian u32
* words, assuming they'll be transmited msb first. */
u16
crc16_itu_t(const u32 *buffer, size_t length)
{ {
int shift, i; __be32 be32_block[256];
u32 data; int i, length;
u16 sum, crc = 0;
for (i = 0; i < length; i++) {
data = *buffer++;
for (shift = 28; shift >= 0; shift -= 4 ) {
sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
}
crc &= 0xffff;
}
return crc; length = (*block >> 16) & 0xff;
for (i = 0; i < length; i++)
be32_block[i] = cpu_to_be32(block[i + 1]);
*block |= crc_itu_t(0, (u8 *) be32_block, length * 4);
return length;
} }
static DECLARE_RWSEM(card_rwsem); static DECLARE_RWSEM(card_rwsem);
...@@ -126,10 +117,8 @@ generate_config_rom (struct fw_card *card, size_t *config_rom_length) ...@@ -126,10 +117,8 @@ generate_config_rom (struct fw_card *card, size_t *config_rom_length)
* assumes that CRC length and info length are identical for * assumes that CRC length and info length are identical for
* the bus info block, which is always the case for this * the bus info block, which is always the case for this
* implementation. */ * implementation. */
for (i = 0; i < j; i += length + 1) { for (i = 0; i < j; i += length + 1)
length = (config_rom[i] >> 16) & 0xff; length = fw_compute_block_crc(config_rom + i);
config_rom[i] |= crc16_itu_t(&config_rom[i + 1], length);
}
*config_rom_length = j; *config_rom_length = j;
......
...@@ -465,14 +465,13 @@ static void ...@@ -465,14 +465,13 @@ static void
update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count) update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count)
{ {
int node_count; int node_count;
u32 crc;
card->topology_map[1]++; card->topology_map[1]++;
node_count = (card->root_node->node_id & 0x3f) + 1; node_count = (card->root_node->node_id & 0x3f) + 1;
card->topology_map[2] = (node_count << 16) | self_id_count; card->topology_map[2] = (node_count << 16) | self_id_count;
crc = crc16_itu_t(card->topology_map + 1, self_id_count + 2); card->topology_map[0] = (self_id_count + 2) << 16;
card->topology_map[0] = ((self_id_count + 2) << 16) | crc;
memcpy(&card->topology_map[3], self_ids, self_id_count * 4); memcpy(&card->topology_map[3], self_ids, self_id_count * 4);
fw_compute_block_crc(card->topology_map);
} }
void void
......
...@@ -88,7 +88,8 @@ fw_node_put(struct fw_node *node) ...@@ -88,7 +88,8 @@ fw_node_put(struct fw_node *node)
void void
fw_destroy_nodes(struct fw_card *card); fw_destroy_nodes(struct fw_card *card);
u16 int
crc16_itu_t(const u32 *buffer, size_t length); fw_compute_block_crc(u32 *block);
#endif /* __fw_topology_h */ #endif /* __fw_topology_h */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment