[PATCH] libertas: Fix sd8686 firmware reload
Daniel Drake
dsd at laptop.org
Sun Oct 10 05:53:50 EDT 2010
From: Paul Fox <pgf at laptop.org>
The firmware presence check is not fully reliable. Broaden the check
to see if the firmware is running.
The module can now be unloaded/reloaded successfully.
Based on the implementation from libertas_tf.
Signed-off-by: Daniel Drake <dsd at laptop.org>
---
drivers/net/wireless/libertas/if_sdio.c | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 87b6349..d6b834a 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -704,28 +704,43 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
lbs_deb_enter(LBS_DEB_SDIO);
+ /*
+ * Disable interrupts
+ */
+ sdio_claim_host(card->func);
+ sdio_writeb(card->func, 0x00, IF_SDIO_H_INT_MASK, &ret);
+ sdio_release_host(card->func);
+
sdio_claim_host(card->func);
scratch = if_sdio_read_scratch(card, &ret);
sdio_release_host(card->func);
+ lbs_deb_sdio("firmware status = %#x\n", scratch);
+ lbs_deb_sdio("scratch ret = %d\n", ret);
+
if (ret)
goto out;
- lbs_deb_sdio("firmware status = %#x\n", scratch);
-
if (scratch == IF_SDIO_FIRMWARE_OK) {
lbs_deb_sdio("firmware already loaded\n");
goto success;
+ } else if ((card->model == IF_SDIO_MODEL_8686) && (scratch > 0)) {
+ lbs_deb_sdio("firmware may be running\n");
+ goto success;
}
ret = if_sdio_prog_helper(card);
if (ret)
goto out;
+ lbs_deb_sdio("Helper firmware loaded\n");
+
ret = if_sdio_prog_real(card);
if (ret)
goto out;
+ lbs_deb_sdio("Firmware loaded\n");
+
success:
sdio_claim_host(card->func);
sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
@@ -1083,8 +1098,6 @@ static int if_sdio_probe(struct sdio_func *func,
priv->exit_deep_sleep = if_sdio_exit_deep_sleep;
priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup;
- priv->fw_ready = 1;
-
sdio_claim_host(func);
/*
@@ -1105,6 +1118,8 @@ static int if_sdio_probe(struct sdio_func *func,
if (ret)
goto reclaim;
+ priv->fw_ready = 1;
+
/*
* FUNC_INIT is required for SD8688 WLAN/BT multiple functions
*/
--
1.7.2.3
More information about the libertas-dev
mailing list