aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2010-08-16 19:16:58 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-24 16:28:15 -0400
commitd7eb50c0f7cb5d3ebb7bea8c681a6dfda3819a3b (patch)
treeb7b03ffbae065955211cced45027672d520442d1
parentb9c066597fdf38b126d2e0434d0ce18d22bbf401 (diff)
p54: improve eeprom parser
Like other vendors, p54* devices have a checksum for the EEPROM descriptor data. This patch enhances the parser code to generate and verify the data fields, before initializing the radio-chip on the card. Note: If you have to bootstrap an alternative EEPROM image for your device and you don't know how to generate a valid crc ccitt checksum, you should take a look at: http://git.kernel.org/?p=linux/kernel/git/chr/p54tools.git The "checksum" utility loads a binary p54 EEPROM blob (use the -f switch, to skip the check) and applies the correct crc automatically. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/p54/Kconfig1
-rw-r--r--drivers/net/wireless/p54/eeprom.c21
2 files changed, 19 insertions, 3 deletions
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
index b0342a520bf1..60a930e45a8b 100644
--- a/drivers/net/wireless/p54/Kconfig
+++ b/drivers/net/wireless/p54/Kconfig
@@ -2,6 +2,7 @@ config P54_COMMON
2 tristate "Softmac Prism54 support" 2 tristate "Softmac Prism54 support"
3 depends on MAC80211 && EXPERIMENTAL 3 depends on MAC80211 && EXPERIMENTAL
4 select FW_LOADER 4 select FW_LOADER
5 select CRC_CCITT
5 ---help--- 6 ---help---
6 This is common code for isl38xx/stlc45xx based modules. 7 This is common code for isl38xx/stlc45xx based modules.
7 This module does nothing by itself - the USB/PCI/SPI front-ends 8 This module does nothing by itself - the USB/PCI/SPI front-ends
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index d687cb7f2a59..32d3f99b0844 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24 24
25#include <net/mac80211.h> 25#include <net/mac80211.h>
26#include <linux/crc-ccitt.h>
26 27
27#include "p54.h" 28#include "p54.h"
28#include "eeprom.h" 29#include "eeprom.h"
@@ -540,6 +541,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
540 int err; 541 int err;
541 u8 *end = (u8 *)eeprom + len; 542 u8 *end = (u8 *)eeprom + len;
542 u16 synth = 0; 543 u16 synth = 0;
544 u16 crc16 = ~0;
543 545
544 wrap = (struct eeprom_pda_wrap *) eeprom; 546 wrap = (struct eeprom_pda_wrap *) eeprom;
545 entry = (void *)wrap->data + le16_to_cpu(wrap->len); 547 entry = (void *)wrap->data + le16_to_cpu(wrap->len);
@@ -655,16 +657,29 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
655 } 657 }
656 break; 658 break;
657 case PDR_END: 659 case PDR_END:
658 /* make it overrun */ 660 crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
659 entry_len = len; 661 if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
662 wiphy_err(dev->wiphy, "eeprom failed checksum "
663 "test!\n");
664 err = -ENOMSG;
665 goto err;
666 } else {
667 goto good_eeprom;
668 }
660 break; 669 break;
661 default: 670 default:
662 break; 671 break;
663 } 672 }
664 673
665 entry = (void *)entry + (entry_len + 1)*2; 674 crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
675 entry = (void *)entry + (entry_len + 1) * 2;
666 } 676 }
667 677
678 wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
679 err = -ENODATA;
680 goto err;
681
682good_eeprom:
668 if (!synth || !priv->iq_autocal || !priv->output_limit || 683 if (!synth || !priv->iq_autocal || !priv->output_limit ||
669 !priv->curve_data) { 684 !priv->curve_data) {
670 wiphy_err(dev->wiphy, 685 wiphy_err(dev->wiphy,