diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2009-01-27 18:33:47 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-09 15:03:35 -0500 |
commit | 0cbe0064614ace61e08618948f82c6d525e75017 (patch) | |
tree | dc6f68d5da42ab6ada2fab2bd4e5fecfa6f1ed8c /drivers/net/wireless/rt2x00/rt2x00firmware.c | |
parent | a2c9b652a12a550d3d8509e9bae43bac396c5076 (diff) |
rt2x00: Validate firmware in driver
The get_firmware_crc() callback function isn't flexible
enough when dealing with multiple firmware versions.
It might in some cases be possible that the firmware
file contains multiple CRC checksums.
Create the check_firmware() callback function where the driver
has complete freedom in how to validate the firmware.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00firmware.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00firmware.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index 2a7e8bc0016b..d2deea2f2679 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -35,7 +35,6 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
35 | const struct firmware *fw; | 35 | const struct firmware *fw; |
36 | char *fw_name; | 36 | char *fw_name; |
37 | int retval; | 37 | int retval; |
38 | u16 crc; | ||
39 | 38 | ||
40 | /* | 39 | /* |
41 | * Read correct firmware from harddisk. | 40 | * Read correct firmware from harddisk. |
@@ -61,16 +60,26 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
61 | return -ENOENT; | 60 | return -ENOENT; |
62 | } | 61 | } |
63 | 62 | ||
64 | crc = rt2x00dev->ops->lib->get_firmware_crc(fw->data, fw->size); | ||
65 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { | ||
66 | ERROR(rt2x00dev, "Firmware checksum error.\n"); | ||
67 | retval = -ENOENT; | ||
68 | goto exit; | ||
69 | } | ||
70 | |||
71 | INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", | 63 | INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", |
72 | fw->data[fw->size - 4], fw->data[fw->size - 3]); | 64 | fw->data[fw->size - 4], fw->data[fw->size - 3]); |
73 | 65 | ||
66 | retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size); | ||
67 | switch (retval) { | ||
68 | case FW_OK: | ||
69 | break; | ||
70 | case FW_BAD_CRC: | ||
71 | ERROR(rt2x00dev, "Firmware checksum error.\n"); | ||
72 | goto exit; | ||
73 | case FW_BAD_LENGTH: | ||
74 | ERROR(rt2x00dev, | ||
75 | "Invalid firmware file length (len=%zu)\n", fw->size); | ||
76 | goto exit; | ||
77 | case FW_BAD_VERSION: | ||
78 | ERROR(rt2x00dev, | ||
79 | "Current firmware does not support detected chipset.\n"); | ||
80 | goto exit; | ||
81 | }; | ||
82 | |||
74 | rt2x00dev->fw = fw; | 83 | rt2x00dev->fw = fw; |
75 | 84 | ||
76 | return 0; | 85 | return 0; |
@@ -78,7 +87,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
78 | exit: | 87 | exit: |
79 | release_firmware(fw); | 88 | release_firmware(fw); |
80 | 89 | ||
81 | return retval; | 90 | return -ENOENT; |
82 | } | 91 | } |
83 | 92 | ||
84 | int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | 93 | int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) |