aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-02-03 09:48:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:28 -0500
commit9404ef34e4747228717d6e22ce3827ed366ccf41 (patch)
tree90f4a51af46519e42dcd638a3344ee664db539ec
parentadfdbb79c06154cd3cc7b5983106ace324aa3b02 (diff)
rt2x00: Driver requiring firmware should select crc algo
The driver should select what CRC algorithm is required when performing a checksum on the firmware. rt61pci & rt73usb require crc-itu-t rt2800pci & rt2800usb require crc-ccitt Legacy 2800pci/usb driver uses crc-itu-t + bit order reversion, but that is just inefficient especially since the end result is the same as a different algorithm which is also available as library. ;) Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c41
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c3
6 files changed, 42 insertions, 16 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index da05b1faf60d..28f3e5e94ab6 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -28,6 +28,7 @@ config RT2X00_LIB_USB
28config RT2X00_LIB_FIRMWARE 28config RT2X00_LIB_FIRMWARE
29 boolean 29 boolean
30 depends on RT2X00_LIB 30 depends on RT2X00_LIB
31 select CRC_CCITT
31 select CRC_ITU_T 32 select CRC_ITU_T
32 select FW_LOADER 33 select FW_LOADER
33 34
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 7b67f9666c3b..6a25195816db 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -551,6 +551,8 @@ enum rt2x00_flags {
551 * Driver features 551 * Driver features
552 */ 552 */
553 DRIVER_REQUIRE_FIRMWARE, 553 DRIVER_REQUIRE_FIRMWARE,
554 DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T,
555 DRIVER_REQUIRE_FIRMWARE_CCITT,
554 DRIVER_REQUIRE_BEACON_GUARD, 556 DRIVER_REQUIRE_BEACON_GUARD,
555 DRIVER_REQUIRE_ATIM_QUEUE, 557 DRIVER_REQUIRE_ATIM_QUEUE,
556 558
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 7620427887b6..bc07c56f89b3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1017,11 +1017,9 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
1017 * If this is the first interface which is added, 1017 * If this is the first interface which is added,
1018 * we should load the firmware now. 1018 * we should load the firmware now.
1019 */ 1019 */
1020 if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) { 1020 retval = rt2x00lib_load_firmware(rt2x00dev);
1021 retval = rt2x00lib_load_firmware(rt2x00dev); 1021 if (retval)
1022 if (retval) 1022 return retval;
1023 return retval;
1024 }
1025 1023
1026 /* 1024 /*
1027 * Initialize the device. 1025 * Initialize the device.
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index 442ff8047dce..4f9fe56f4f2e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -23,6 +23,7 @@
23 Abstract: rt2x00 firmware loading routines. 23 Abstract: rt2x00 firmware loading routines.
24 */ 24 */
25 25
26#include <linux/crc-ccitt.h>
26#include <linux/crc-itu-t.h> 27#include <linux/crc-itu-t.h>
27#include <linux/kernel.h> 28#include <linux/kernel.h>
28#include <linux/module.h> 29#include <linux/module.h>
@@ -37,7 +38,6 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
37 char *fw_name; 38 char *fw_name;
38 int retval; 39 int retval;
39 u16 crc; 40 u16 crc;
40 u16 tmp;
41 41
42 /* 42 /*
43 * Read correct firmware from harddisk. 43 * Read correct firmware from harddisk.
@@ -64,17 +64,37 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
64 } 64 }
65 65
66 /* 66 /*
67 * Validate the firmware using 16 bit CRC. 67 * Perform crc validation on the firmware.
68 * The last 2 bytes of the firmware are the CRC 68 * The last 2 bytes in the firmware array are the crc checksum itself,
69 * so substract those 2 bytes from the CRC checksum, 69 * this means that we should never pass those 2 bytes to the crc
70 * and set those 2 bytes to 0 when calculating CRC. 70 * algorithm.
71 */ 71 */
72 tmp = 0; 72 if (test_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags)) {
73 crc = crc_itu_t(0, fw->data, fw->size - 2); 73 /*
74 crc = crc_itu_t(crc, (u8 *)&tmp, 2); 74 * Use the crc itu-t algorithm.
75 * Use 0 for the last 2 bytes to complete the checksum.
76 */
77 crc = crc_itu_t(0, fw->data, fw->size - 2);
78 crc = crc_itu_t_byte(crc, 0);
79 crc = crc_itu_t_byte(crc, 0);
80 } else if (test_bit(DRIVER_REQUIRE_FIRMWARE_CCITT, &rt2x00dev->flags)) {
81 /*
82 * Use the crc ccitt algorithm.
83 * This will return the same value as the legacy driver which
84 * used bit ordering reversion on the both the firmware bytes
85 * before input input as well as on the final output.
86 * Obviously using crc ccitt directly is much more efficient.
87 */
88 crc = crc_ccitt(~0, fw->data, fw->size - 2);
89 } else {
90 ERROR(rt2x00dev, "No checksum algorithm selected "
91 "for firmware validation.\n");
92 retval = -ENOENT;
93 goto exit;
94 }
75 95
76 if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { 96 if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) {
77 ERROR(rt2x00dev, "Firmware CRC error.\n"); 97 ERROR(rt2x00dev, "Firmware checksum error.\n");
78 retval = -ENOENT; 98 retval = -ENOENT;
79 goto exit; 99 goto exit;
80 } 100 }
@@ -96,6 +116,9 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
96{ 116{
97 int retval; 117 int retval;
98 118
119 if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags))
120 return 0;
121
99 if (!rt2x00dev->fw) { 122 if (!rt2x00dev->fw) {
100 retval = rt2x00lib_request_firmware(rt2x00dev); 123 retval = rt2x00lib_request_firmware(rt2x00dev);
101 if (retval) 124 if (retval)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 5e08541958cc..b5ab771bbac2 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2258,9 +2258,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
2258 rt61pci_probe_hw_mode(rt2x00dev); 2258 rt61pci_probe_hw_mode(rt2x00dev);
2259 2259
2260 /* 2260 /*
2261 * This device requires firmware 2261 * This device requires firmware.
2262 */ 2262 */
2263 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); 2263 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
2264 __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags);
2264 2265
2265 /* 2266 /*
2266 * Set the rssi offset. 2267 * Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4e6466b13af1..8ebf3fed9815 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1849,9 +1849,10 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
1849 rt73usb_probe_hw_mode(rt2x00dev); 1849 rt73usb_probe_hw_mode(rt2x00dev);
1850 1850
1851 /* 1851 /*
1852 * This device requires firmware 1852 * This device requires firmware.
1853 */ 1853 */
1854 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); 1854 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
1855 __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags);
1855 1856
1856 /* 1857 /*
1857 * Set the rssi offset. 1858 * Set the rssi offset.