diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2010-08-16 19:16:58 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-24 16:28:15 -0400 |
commit | d7eb50c0f7cb5d3ebb7bea8c681a6dfda3819a3b (patch) | |
tree | b7b03ffbae065955211cced45027672d520442d1 | |
parent | b9c066597fdf38b126d2e0434d0ce18d22bbf401 (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/wireless/p54/eeprom.c | 21 |
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 | |||
682 | good_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, |