diff options
author | David Kilroy <kilroyd@googlemail.com> | 2008-11-22 05:37:25 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-26 09:47:45 -0500 |
commit | 7473431297761fa644a128a497b91e299676f501 (patch) | |
tree | fc89508d4230af445849e1d6ce7e1e95caf68db8 /drivers | |
parent | cb71d9bafb37adab50ddce53bb119a84b4966c06 (diff) |
orinoco: Separate fw caching from download
This refactorring will make it easier to share logic with Symbol
firmware.
Signed-off by: David Kilroy <kilroyd@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/orinoco/orinoco.c | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c index 7ec038ac1c36..492f419d18f4 100644 --- a/drivers/net/wireless/orinoco/orinoco.c +++ b/drivers/net/wireless/orinoco/orinoco.c | |||
@@ -431,9 +431,9 @@ struct fw_info { | |||
431 | }; | 431 | }; |
432 | 432 | ||
433 | const static struct fw_info orinoco_fw[] = { | 433 | const static struct fw_info orinoco_fw[] = { |
434 | { "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 }, | 434 | { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 }, |
435 | { "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 }, | 435 | { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 }, |
436 | { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 512 } | 436 | { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 } |
437 | }; | 437 | }; |
438 | 438 | ||
439 | /* Structure used to access fields in FW | 439 | /* Structure used to access fields in FW |
@@ -487,18 +487,17 @@ orinoco_dl_firmware(struct orinoco_private *priv, | |||
487 | if (err) | 487 | if (err) |
488 | goto free; | 488 | goto free; |
489 | 489 | ||
490 | if (priv->cached_fw) | 490 | if (!priv->cached_fw) { |
491 | fw_entry = priv->cached_fw; | ||
492 | else { | ||
493 | err = request_firmware(&fw_entry, firmware, priv->dev); | 491 | err = request_firmware(&fw_entry, firmware, priv->dev); |
492 | |||
494 | if (err) { | 493 | if (err) { |
495 | printk(KERN_ERR "%s: Cannot find firmware %s\n", | 494 | printk(KERN_ERR "%s: Cannot find firmware %s\n", |
496 | dev->name, firmware); | 495 | dev->name, firmware); |
497 | err = -ENOENT; | 496 | err = -ENOENT; |
498 | goto free; | 497 | goto free; |
499 | } | 498 | } |
500 | priv->cached_fw = fw_entry; | 499 | } else |
501 | } | 500 | fw_entry = priv->cached_fw; |
502 | 501 | ||
503 | hdr = (const struct orinoco_fw_header *) fw_entry->data; | 502 | hdr = (const struct orinoco_fw_header *) fw_entry->data; |
504 | 503 | ||
@@ -540,11 +539,9 @@ orinoco_dl_firmware(struct orinoco_private *priv, | |||
540 | dev->name, hermes_present(hw)); | 539 | dev->name, hermes_present(hw)); |
541 | 540 | ||
542 | abort: | 541 | abort: |
543 | /* In case of error, assume firmware was bogus and release it */ | 542 | /* If we requested the firmware, release it. */ |
544 | if (err) { | 543 | if (!priv->cached_fw) |
545 | priv->cached_fw = NULL; | ||
546 | release_firmware(fw_entry); | 544 | release_firmware(fw_entry); |
547 | } | ||
548 | 545 | ||
549 | free: | 546 | free: |
550 | kfree(pda); | 547 | kfree(pda); |
@@ -708,6 +705,30 @@ static int orinoco_download(struct orinoco_private *priv) | |||
708 | return err; | 705 | return err; |
709 | } | 706 | } |
710 | 707 | ||
708 | static void orinoco_cache_fw(struct orinoco_private *priv, int ap) | ||
709 | { | ||
710 | const struct firmware *fw_entry = NULL; | ||
711 | const char *fw; | ||
712 | |||
713 | if (ap) | ||
714 | fw = orinoco_fw[priv->firmware_type].ap_fw; | ||
715 | else | ||
716 | fw = orinoco_fw[priv->firmware_type].sta_fw; | ||
717 | |||
718 | if (fw) { | ||
719 | if (request_firmware(&fw_entry, fw, priv->dev) == 0) | ||
720 | priv->cached_fw = fw_entry; | ||
721 | } | ||
722 | } | ||
723 | |||
724 | static void orinoco_uncache_fw(struct orinoco_private *priv) | ||
725 | { | ||
726 | if (priv->cached_fw) | ||
727 | release_firmware(priv->cached_fw); | ||
728 | |||
729 | priv->cached_fw = NULL; | ||
730 | } | ||
731 | |||
711 | /********************************************************************/ | 732 | /********************************************************************/ |
712 | /* Device methods */ | 733 | /* Device methods */ |
713 | /********************************************************************/ | 734 | /********************************************************************/ |
@@ -3304,6 +3325,8 @@ static int orinoco_init(struct net_device *dev) | |||
3304 | } | 3325 | } |
3305 | 3326 | ||
3306 | if (priv->do_fw_download) { | 3327 | if (priv->do_fw_download) { |
3328 | orinoco_cache_fw(priv, 0); | ||
3329 | |||
3307 | err = orinoco_download(priv); | 3330 | err = orinoco_download(priv); |
3308 | if (err) | 3331 | if (err) |
3309 | priv->do_fw_download = 0; | 3332 | priv->do_fw_download = 0; |
@@ -3553,9 +3576,9 @@ void free_orinocodev(struct net_device *dev) | |||
3553 | * when we call tasklet_kill it will run one final time, | 3576 | * when we call tasklet_kill it will run one final time, |
3554 | * emptying the list */ | 3577 | * emptying the list */ |
3555 | tasklet_kill(&priv->rx_tasklet); | 3578 | tasklet_kill(&priv->rx_tasklet); |
3556 | if (priv->cached_fw) | 3579 | |
3557 | release_firmware(priv->cached_fw); | 3580 | orinoco_uncache_fw(priv); |
3558 | priv->cached_fw = NULL; | 3581 | |
3559 | priv->wpa_ie_len = 0; | 3582 | priv->wpa_ie_len = 0; |
3560 | kfree(priv->wpa_ie); | 3583 | kfree(priv->wpa_ie); |
3561 | orinoco_mic_free(priv); | 3584 | orinoco_mic_free(priv); |