aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorMichael Buesch <mbuesch@freenet.de>2006-02-01 16:09:52 -0500
committerJohn W. Linville <linville@tuxdriver.com>2006-03-27 11:18:27 -0500
commita4a600d3e17f450666a9086465122103e96140d7 (patch)
tree3b76a9ff5ba2c0dc217b21b330930246ea758614 /drivers/net/wireless
parent65f3f19120cf32233f537562e69893b88727b634 (diff)
[PATCH] bcm43xx: Add more initvals sanity checks and error out, if one sanity check fails.
Signed-off-by: Michael Buesch <mbuesch@freenet.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index cfb0f0a485a7..521777f56a3d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2229,9 +2229,9 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
2229 return IRQ_HANDLED; 2229 return IRQ_HANDLED;
2230} 2230}
2231 2231
2232static void bcm43xx_release_firmware(struct bcm43xx_private *bcm) 2232static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
2233{ 2233{
2234 if (bcm->firmware_norelease) 2234 if (bcm->firmware_norelease && !force)
2235 return; /* Suspending or controller reset. */ 2235 return; /* Suspending or controller reset. */
2236 release_firmware(bcm->ucode); 2236 release_firmware(bcm->ucode);
2237 bcm->ucode = NULL; 2237 bcm->ucode = NULL;
@@ -2361,7 +2361,7 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
2361out: 2361out:
2362 return err; 2362 return err;
2363error: 2363error:
2364 bcm43xx_release_firmware(bcm); 2364 bcm43xx_release_firmware(bcm, 1);
2365 goto out; 2365 goto out;
2366err_noinitval: 2366err_noinitval:
2367 printk(KERN_ERR PFX "Error: No InitVals available!\n"); 2367 printk(KERN_ERR PFX "Error: No InitVals available!\n");
@@ -2409,9 +2409,9 @@ static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2409#endif 2409#endif
2410} 2410}
2411 2411
2412static void bcm43xx_write_initvals(struct bcm43xx_private *bcm, 2412static int bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2413 const struct bcm43xx_initval *data, 2413 const struct bcm43xx_initval *data,
2414 const unsigned int len) 2414 const unsigned int len)
2415{ 2415{
2416 u16 offset, size; 2416 u16 offset, size;
2417 u32 value; 2417 u32 value;
@@ -2422,35 +2422,54 @@ static void bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2422 size = be16_to_cpu(data[i].size); 2422 size = be16_to_cpu(data[i].size);
2423 value = be32_to_cpu(data[i].value); 2423 value = be32_to_cpu(data[i].value);
2424 2424
2425 if (size == 2) 2425 if (unlikely(offset >= 0x1000))
2426 bcm43xx_write16(bcm, offset, value); 2426 goto err_format;
2427 else if (size == 4) 2427 if (size == 2) {
2428 if (unlikely(value & 0xFFFF0000))
2429 goto err_format;
2430 bcm43xx_write16(bcm, offset, (u16)value);
2431 } else if (size == 4) {
2428 bcm43xx_write32(bcm, offset, value); 2432 bcm43xx_write32(bcm, offset, value);
2429 else 2433 } else
2430 printk(KERN_ERR PFX "InitVals fileformat error.\n"); 2434 goto err_format;
2431 } 2435 }
2436
2437 return 0;
2438
2439err_format:
2440 printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
2441 "Please fix your bcm43xx firmware files.\n");
2442 return -EPROTO;
2432} 2443}
2433 2444
2434static void bcm43xx_upload_initvals(struct bcm43xx_private *bcm) 2445static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2435{ 2446{
2447 int err;
2448
2436#ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT 2449#ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2437 bcm43xx_mmioprint_enable(bcm); 2450 bcm43xx_mmioprint_enable(bcm);
2438#else 2451#else
2439 bcm43xx_mmioprint_disable(bcm); 2452 bcm43xx_mmioprint_disable(bcm);
2440#endif 2453#endif
2441 2454
2442 bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data, 2455 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data,
2443 bcm->initvals0->size / sizeof(struct bcm43xx_initval)); 2456 bcm->initvals0->size / sizeof(struct bcm43xx_initval));
2457 if (err)
2458 goto out;
2444 if (bcm->initvals1) { 2459 if (bcm->initvals1) {
2445 bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data, 2460 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data,
2446 bcm->initvals1->size / sizeof(struct bcm43xx_initval)); 2461 bcm->initvals1->size / sizeof(struct bcm43xx_initval));
2462 if (err)
2463 goto out;
2447 } 2464 }
2448 2465
2466out:
2449#ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT 2467#ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2450 bcm43xx_mmioprint_disable(bcm); 2468 bcm43xx_mmioprint_disable(bcm);
2451#else 2469#else
2452 bcm43xx_mmioprint_enable(bcm); 2470 bcm43xx_mmioprint_enable(bcm);
2453#endif 2471#endif
2472 return err;
2454} 2473}
2455 2474
2456static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) 2475static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
@@ -2683,7 +2702,7 @@ static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2683 bcm43xx_leds_exit(bcm); 2702 bcm43xx_leds_exit(bcm);
2684 bcm43xx_gpio_cleanup(bcm); 2703 bcm43xx_gpio_cleanup(bcm);
2685 free_irq(bcm->irq, bcm); 2704 free_irq(bcm->irq, bcm);
2686 bcm43xx_release_firmware(bcm); 2705 bcm43xx_release_firmware(bcm, 0);
2687} 2706}
2688 2707
2689/* Initialize the chip 2708/* Initialize the chip
@@ -2708,13 +2727,15 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2708 2727
2709 err = bcm43xx_initialize_irq(bcm); 2728 err = bcm43xx_initialize_irq(bcm);
2710 if (err) 2729 if (err)
2711 goto out; 2730 goto err_release_fw;
2712 2731
2713 err = bcm43xx_gpio_init(bcm); 2732 err = bcm43xx_gpio_init(bcm);
2714 if (err) 2733 if (err)
2715 goto err_free_irq; 2734 goto err_free_irq;
2716 2735
2717 bcm43xx_upload_initvals(bcm); 2736 err = bcm43xx_upload_initvals(bcm);
2737 if (err)
2738 goto err_gpio_cleanup;
2718 bcm43xx_radio_turn_on(bcm); 2739 bcm43xx_radio_turn_on(bcm);
2719 2740
2720 if (modparam_noleds) 2741 if (modparam_noleds)
@@ -2813,9 +2834,12 @@ out:
2813 2834
2814err_radio_off: 2835err_radio_off:
2815 bcm43xx_radio_turn_off(bcm); 2836 bcm43xx_radio_turn_off(bcm);
2837err_gpio_cleanup:
2816 bcm43xx_gpio_cleanup(bcm); 2838 bcm43xx_gpio_cleanup(bcm);
2817err_free_irq: 2839err_free_irq:
2818 free_irq(bcm->irq, bcm); 2840 free_irq(bcm->irq, bcm);
2841err_release_fw:
2842 bcm43xx_release_firmware(bcm, 1);
2819 goto out; 2843 goto out;
2820} 2844}
2821 2845