1
0
Fork 0

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: Kristian Hoegsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (fixed Kconfig)
hifive-unleashed-5.1
Kristian Høgsberg 2007-05-07 20:33:31 -04:00 committed by Stefan Richter
parent 3e7cbae7c6
commit e175569c46
4 changed files with 17 additions and 27 deletions

View File

@ -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

View File

@ -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++) { length = (*block >> 16) & 0xff;
data = *buffer++; for (i = 0; i < length; i++)
for (shift = 28; shift >= 0; shift -= 4 ) { be32_block[i] = cpu_to_be32(block[i + 1]);
sum = ((crc >> 12) ^ (data >> shift)) & 0xf; *block |= crc_itu_t(0, (u8 *) be32_block, length * 4);
crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
}
crc &= 0xffff;
}
return crc; 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)
* 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;

View File

@ -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

View File

@ -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 */