aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/if_sdio.c
diff options
context:
space:
mode:
authorBing Zhao <bzhao@marvell.com>2009-05-21 11:32:34 -0700
committerJohn W. Linville <linville@tuxdriver.com>2009-05-22 14:06:02 -0400
commit2c7e57981f24e9f8b732ecf1c01e16111d21b7a5 (patch)
treed62ba6cc2f8d5449a8eabcaec2fb40c4f91033d8 /drivers/net/wireless/libertas/if_sdio.c
parentbb9f8692f5043efef0dcef048cdd1db68299c2cb (diff)
downloadkernel_samsung_smdk4412-2c7e57981f24e9f8b732ecf1c01e16111d21b7a5.zip
kernel_samsung_smdk4412-2c7e57981f24e9f8b732ecf1c01e16111d21b7a5.tar.gz
kernel_samsung_smdk4412-2c7e57981f24e9f8b732ecf1c01e16111d21b7a5.tar.bz2
libertas: read SD8688 firmware status from new register
The scratch pad register is used to store firmware status after firmware is downloaded and initialized. After firmware status is verified OK, the same register is used to store RX packet length. Hence the firmware status code is no longer valid afterwards. SD8688 firmware introduces a new register for firmware status which will never be overwritten. Also add scratch_reg variable to if_sdio_card structure and initialize it based on the model of the card during probe. Signed-off-by: Bing Zhao <bzhao@marvell.com> Acked-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/if_sdio.c')
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 478d766..a7e3fc1 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -100,6 +100,7 @@ struct if_sdio_card {
int model;
unsigned long ioport;
+ unsigned int scratch_reg;
const char *helper;
const char *firmware;
@@ -119,19 +120,21 @@ struct if_sdio_card {
/* I/O */
/********************************************************************/
+/*
+ * For SD8385/SD8686, this function reads firmware status after
+ * the image is downloaded, or reads RX packet length when
+ * interrupt (with IF_SDIO_H_INT_UPLD bit set) is received.
+ * For SD8688, this function reads firmware status only.
+ */
static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
{
- int ret, reg;
+ int ret;
u16 scratch;
- if (card->model == IF_SDIO_MODEL_8385)
- reg = IF_SDIO_SCRATCH_OLD;
- else
- reg = IF_SDIO_SCRATCH;
-
- scratch = sdio_readb(card->func, reg, &ret);
+ scratch = sdio_readb(card->func, card->scratch_reg, &ret);
if (!ret)
- scratch |= sdio_readb(card->func, reg + 1, &ret) << 8;
+ scratch |= sdio_readb(card->func, card->scratch_reg + 1,
+ &ret) << 8;
if (err)
*err = ret;
@@ -706,6 +709,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
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;
@@ -893,6 +898,20 @@ static int if_sdio_probe(struct sdio_func *func,
card->func = func;
card->model = model;
+
+ switch (card->model) {
+ case IF_SDIO_MODEL_8385:
+ card->scratch_reg = IF_SDIO_SCRATCH_OLD;
+ break;
+ case IF_SDIO_MODEL_8686:
+ card->scratch_reg = IF_SDIO_SCRATCH;
+ break;
+ case IF_SDIO_MODEL_8688:
+ default: /* for newer chipsets */
+ card->scratch_reg = IF_SDIO_FW_STATUS;
+ break;
+ }
+
spin_lock_init(&card->lock);
card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);