Ok, here is the new version of the firmware version detection patch.
I hope it's in a better shape now.
Martin
--- ../../linux-2.6.17/drivers/base/firmware_class.c 2006-06-18
03:49:35.000000000 +0200
+++ drivers/base/firmware_class.c 2006-07-06 23:13:29.000000000 +0200
@@ -15,6 +15,8 @@
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
#include <asm/semaphore.h>
#include <linux/firmware.h>
@@ -48,6 +50,32 @@
struct timer_list timeout;
};
+u32 firmware_version(const struct firmware *fw, struct firmware_files *elmnt)
+{
+ struct scatterlist sg;
+ struct crypto_tfm *tfm;
+ char sig[16];
+
+ tfm = crypto_alloc_tfm("md5", 0);
+ if (tfm == NULL)
+ return 0;
+
+ sg_init_one(&sg, fw->data, fw->size);
+
+ crypto_digest_init(tfm);
+ crypto_digest_update(tfm, &sg, 1);
+ crypto_digest_final(tfm, sig);
+ crypto_free_tfm(tfm);
+
+ while (elmnt->version) {
+ if (memcmp(sig, elmnt->signature, sizeof(sig)) == 0)
+ return elmnt->version;
+ elmnt++;
+ }
+
+ return 0;
+}
+
static void
fw_load_abort(struct firmware_priv *fw_priv)
{
@@ -605,6 +633,7 @@
module_init(firmware_class_init);
module_exit(firmware_class_exit);
+EXPORT_SYMBOL(firmware_version);
EXPORT_SYMBOL(release_firmware);
EXPORT_SYMBOL(request_firmware);
EXPORT_SYMBOL(request_firmware_nowait);
--- ../../linux-2.6.17/include/linux/firmware.h 2006-06-18 03:49:35.000000000
+0200
+++ include/linux/firmware.h 2006-07-06 23:33:33.000000000 +0200
@@ -10,7 +10,12 @@
size_t size;
u8 *data;
};
+struct firmware_files {
+ u8 signature[16];
+ u32 version;
+};
struct device;
+u32 firmware_version(const struct firmware *fw, struct firmware_files *elmnt);
int request_firmware(const struct firmware **fw, const char *name,
struct device *device);
int request_firmware_nowait(
--- ../../linux-2.6.17/drivers/base/Kconfig 2006-06-18 03:49:35.000000000
+0200
+++ drivers/base/Kconfig 2006-07-06 23:19:06.000000000 +0200
@@ -20,6 +20,7 @@
config FW_LOADER
tristate "Userspace firmware loading support"
+ depends on CRYPTO_MD5
select HOTPLUG
---help---
This option is provided for the case where no in-kernel-tree modules
--- ../../linux-2.6.17/drivers/net/wireless/bcm43xx/bcm43xx_main.c
2006-06-18 03:49:35.000000000 +0200
+++ drivers/net/wireless/bcm43xx/bcm43xx_main.c 2006-07-06 23:16:43.000000000
+0200
@@ -148,6 +148,22 @@
};
MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl);
+static struct firmware_files ucode_version_tbl[] = {
+ { { 0xed, 0x55, 0x26, 0xf9, 0x2e, 0xcb, 0x8f, 0x76, 0x90, 0x34, 0xa0,
+ 0xf1, 0x67, 0x33, 0x00, 0x5f }, FW_VERSION(3, 130, 20, 0) },
+ { { 0x65, 0x1e, 0x4f, 0xc1, 0x92, 0xb6, 0xae, 0x16, 0xb2, 0xf6, 0x39,
+ 0x56, 0xc5, 0x66, 0x8d, 0xbd }, FW_VERSION(4, 10, 40, 0) },
+ {},
+};
+
+static struct firmware_files pcm_version_tbl[] = {
+ { { 0x2d, 0x0f, 0xd4, 0x02, 0x88, 0x9d, 0xf1, 0xd1, 0xf6, 0xb3, 0xdd,
+ 0x8b, 0x4d, 0x37, 0xcc, 0x9a }, FW_VERSION(3, 30, 15, 0) },
+ { { 0xff, 0x29, 0xcd, 0x07, 0x56, 0x75, 0xa5, 0x44, 0xbd, 0xc5, 0xd5,
+ 0xae, 0x95, 0x3d, 0x96, 0x4a }, FW_VERSION(3, 90, 7, 0) },
+ {},
+};
+
static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
{
u32 status;
@@ -1930,6 +1946,7 @@
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
u8 rev = bcm->current_core->rev;
+ u32 ver = 0;
int err = 0;
int nr;
char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
@@ -1945,6 +1962,18 @@
buf);
goto error;
}
+
+ ver = firmware_version(bcm->ucode, ucode_version_tbl);
+ if (ver != 0) {
+ printk(KERN_INFO PFX "UCODE: %s version %i.%i.%i.%i\n",
+ buf,
+ (ver & 0xFF000000) >> 24,
+ (ver & 0x00FF0000) >> 16,
+ (ver & 0x0000FF00) >> 8,
+ (ver & 0x000000FF));
+ } else
+ printk(KERN_INFO PFX "UCODE: %s detection failure.\n",
+ buf);
}
if (!bcm->pcm) {
@@ -1959,6 +1988,18 @@
buf);
goto error;
}
+
+ ver = firmware_version(bcm->pcm, pcm_version_tbl);
+ if (ver != 0) {
+ printk(KERN_INFO PFX "PCM: %s version %i.%i.%i.%i\n",
+ buf,
+ (ver & 0xFF000000) >> 24,
+ (ver & 0x00FF0000) >> 16,
+ (ver & 0x0000FF00) >> 8,
+ (ver & 0x000000FF));
+ } else
+ printk(KERN_INFO PFX "PCM: %s detection failure.\n",
+ buf);
}
if (!bcm->initvals0) {
--- ../../linux-2.6.17/drivers/net/wireless/bcm43xx/bcm43xx.h 2006-06-18
03:49:35.000000000 +0200
+++ drivers/net/wireless/bcm43xx/bcm43xx.h 2006-07-06 23:24:35.000000000
+0200
@@ -345,6 +345,8 @@
BCM43xx_SEC_ALGO_TKIP,
};
+#define FW_VERSION(a, b, c, d) (((a)<<24) | ((b)<<16) | ((c)<<8) | (d))
+
#ifdef assert
# undef assert
#endif