diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00firmware.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00firmware.c | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index 236025f8b90..fbae2799e3e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2007 rt2x00 SourceForge Project + Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> + Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> <http://rt2x00.serialmonkey.com> This program is free software; you can redistribute it and/or modify @@ -13,9 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* @@ -23,12 +22,6 @@ Abstract: rt2x00 firmware loading routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00lib" - -#include <linux/crc-itu-t.h> #include <linux/kernel.h> #include <linux/module.h> @@ -41,52 +34,54 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) const struct firmware *fw; char *fw_name; int retval; - u16 crc; - u16 tmp; /* * Read correct firmware from harddisk. */ fw_name = rt2x00dev->ops->lib->get_firmware_name(rt2x00dev); if (!fw_name) { - ERROR(rt2x00dev, - "Invalid firmware filename.\n" - "Please file bug report to %s.\n", DRV_PROJECT); + rt2x00_err(rt2x00dev, + "Invalid firmware filename\n" + "Please file bug report to %s\n", DRV_PROJECT); return -EINVAL; } - INFO(rt2x00dev, "Loading firmware file '%s'.\n", fw_name); + rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name); retval = request_firmware(&fw, fw_name, device); if (retval) { - ERROR(rt2x00dev, "Failed to request Firmware.\n"); + rt2x00_err(rt2x00dev, "Failed to request Firmware\n"); return retval; } if (!fw || !fw->size || !fw->data) { - ERROR(rt2x00dev, "Failed to read Firmware.\n"); + rt2x00_err(rt2x00dev, "Failed to read Firmware\n"); + release_firmware(fw); return -ENOENT; } - /* - * Validate the firmware using 16 bit CRC. - * The last 2 bytes of the firmware are the CRC - * so substract those 2 bytes from the CRC checksum, - * and set those 2 bytes to 0 when calculating CRC. - */ - tmp = 0; - crc = crc_itu_t(0, fw->data, fw->size - 2); - crc = crc_itu_t(crc, (u8 *)&tmp, 2); - - if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { - ERROR(rt2x00dev, "Firmware CRC error.\n"); - retval = -ENOENT; + rt2x00_info(rt2x00dev, "Firmware detected - version: %d.%d\n", + fw->data[fw->size - 4], fw->data[fw->size - 3]); + snprintf(rt2x00dev->hw->wiphy->fw_version, + sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d", + fw->data[fw->size - 4], fw->data[fw->size - 3]); + + retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size); + switch (retval) { + case FW_OK: + break; + case FW_BAD_CRC: + rt2x00_err(rt2x00dev, "Firmware checksum error\n"); + goto exit; + case FW_BAD_LENGTH: + rt2x00_err(rt2x00dev, "Invalid firmware file length (len=%zu)\n", + fw->size); + goto exit; + case FW_BAD_VERSION: + rt2x00_err(rt2x00dev, "Current firmware does not support detected chipset\n"); goto exit; } - INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", - fw->data[fw->size - 4], fw->data[fw->size - 3]); - rt2x00dev->fw = fw; return 0; @@ -94,13 +89,16 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) exit: release_firmware(fw); - return retval; + return -ENOENT; } int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) { int retval; + if (!test_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags)) + return 0; + if (!rt2x00dev->fw) { retval = rt2x00lib_request_firmware(rt2x00dev); if (retval) @@ -113,6 +111,14 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) retval = rt2x00dev->ops->lib->load_firmware(rt2x00dev, rt2x00dev->fw->data, rt2x00dev->fw->size); + + /* + * When the firmware is uploaded to the hardware the LED + * association status might have been triggered, for correct + * LED handling it should now be reset. + */ + rt2x00leds_led_assoc(rt2x00dev, false); + return retval; } @@ -121,4 +127,3 @@ void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev) release_firmware(rt2x00dev->fw); rt2x00dev->fw = NULL; } - |
