diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 296fd00a5129..e5685dc317a8 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -684,18 +684,40 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) | |||
684 | 684 | ||
685 | lbs_deb_enter(LBS_DEB_SDIO); | 685 | lbs_deb_enter(LBS_DEB_SDIO); |
686 | 686 | ||
687 | /* | ||
688 | * Disable interrupts | ||
689 | */ | ||
690 | sdio_claim_host(card->func); | ||
691 | sdio_writeb(card->func, 0x00, IF_SDIO_H_INT_MASK, &ret); | ||
692 | sdio_release_host(card->func); | ||
693 | |||
687 | sdio_claim_host(card->func); | 694 | sdio_claim_host(card->func); |
688 | scratch = if_sdio_read_scratch(card, &ret); | 695 | scratch = if_sdio_read_scratch(card, &ret); |
689 | sdio_release_host(card->func); | 696 | sdio_release_host(card->func); |
690 | 697 | ||
698 | lbs_deb_sdio("firmware status = %#x\n", scratch); | ||
699 | lbs_deb_sdio("scratch ret = %d\n", ret); | ||
700 | |||
691 | if (ret) | 701 | if (ret) |
692 | goto out; | 702 | goto out; |
693 | 703 | ||
694 | lbs_deb_sdio("firmware status = %#x\n", scratch); | ||
695 | 704 | ||
705 | /* | ||
706 | * The manual clearly describes that FEDC is the right code to use | ||
707 | * to detect firmware presence, but for SD8686 it is not that simple. | ||
708 | * Scratch is also used to store the RX packet length, so we lose | ||
709 | * the FEDC value early on. So we use a non-zero check in order | ||
710 | * to validate firmware presence. | ||
711 | * Additionally, the SD8686 in the Gumstix always has the high scratch | ||
712 | * bit set, even when the firmware is not loaded. So we have to | ||
713 | * exclude that from the test. | ||
714 | */ | ||
696 | if (scratch == IF_SDIO_FIRMWARE_OK) { | 715 | if (scratch == IF_SDIO_FIRMWARE_OK) { |
697 | lbs_deb_sdio("firmware already loaded\n"); | 716 | lbs_deb_sdio("firmware already loaded\n"); |
698 | goto success; | 717 | goto success; |
718 | } else if ((card->model == MODEL_8686) && (scratch & 0x7fff)) { | ||
719 | lbs_deb_sdio("firmware may be running\n"); | ||
720 | goto success; | ||
699 | } | 721 | } |
700 | 722 | ||
701 | ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, | 723 | ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, |
@@ -709,10 +731,14 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) | |||
709 | if (ret) | 731 | if (ret) |
710 | goto out; | 732 | goto out; |
711 | 733 | ||
734 | lbs_deb_sdio("Helper firmware loaded\n"); | ||
735 | |||
712 | ret = if_sdio_prog_real(card, mainfw); | 736 | ret = if_sdio_prog_real(card, mainfw); |
713 | if (ret) | 737 | if (ret) |
714 | goto out; | 738 | goto out; |
715 | 739 | ||
740 | lbs_deb_sdio("Firmware loaded\n"); | ||
741 | |||
716 | success: | 742 | success: |
717 | sdio_claim_host(card->func); | 743 | sdio_claim_host(card->func); |
718 | sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE); | 744 | sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE); |
@@ -1042,8 +1068,6 @@ static int if_sdio_probe(struct sdio_func *func, | |||
1042 | priv->exit_deep_sleep = if_sdio_exit_deep_sleep; | 1068 | priv->exit_deep_sleep = if_sdio_exit_deep_sleep; |
1043 | priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; | 1069 | priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; |
1044 | 1070 | ||
1045 | priv->fw_ready = 1; | ||
1046 | |||
1047 | sdio_claim_host(func); | 1071 | sdio_claim_host(func); |
1048 | 1072 | ||
1049 | /* | 1073 | /* |
@@ -1064,6 +1088,8 @@ static int if_sdio_probe(struct sdio_func *func, | |||
1064 | if (ret) | 1088 | if (ret) |
1065 | goto reclaim; | 1089 | goto reclaim; |
1066 | 1090 | ||
1091 | priv->fw_ready = 1; | ||
1092 | |||
1067 | /* | 1093 | /* |
1068 | * FUNC_INIT is required for SD8688 WLAN/BT multiple functions | 1094 | * FUNC_INIT is required for SD8688 WLAN/BT multiple functions |
1069 | */ | 1095 | */ |