summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/marvell/mwifiex/sdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/sdio.c')
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sdio.c78
1 files changed, 51 insertions, 27 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index a24bd40dd41a..f039d6f19183 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -21,7 +21,7 @@
static void mwifiex_sdio_work(struct work_struct *work);
-static struct mwifiex_if_ops sdio_ops;
+static const struct mwifiex_if_ops sdio_ops;
static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
.start_rd_port = 1,
@@ -331,6 +331,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = false,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -346,6 +348,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -361,6 +365,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -376,6 +382,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
.can_dump_fw = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
@@ -392,6 +400,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
.fw_dump_enh = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
@@ -408,6 +418,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
.fw_dump_enh = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = true,
+ .host_mlme = true,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
@@ -425,6 +437,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
.fw_dump_enh = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = true,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
@@ -440,6 +454,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
.can_dump_fw = false,
.can_auto_tdls = true,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
@@ -456,6 +472,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
.fw_dump_enh = true,
.can_auto_tdls = true,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
@@ -471,6 +489,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
+ .host_mlme = false,
};
static struct memory_type_mapping generic_mem_type_map[] = {
@@ -563,6 +583,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
card->fw_dump_enh = data->fw_dump_enh;
card->can_auto_tdls = data->can_auto_tdls;
card->can_ext_scan = data->can_ext_scan;
+ card->fw_ready_extra_delay = data->fw_ready_extra_delay;
+ card->host_mlme = data->host_mlme;
INIT_WORK(&card->work, mwifiex_sdio_work);
}
@@ -766,8 +788,9 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
u32 poll_num)
{
+ struct sdio_mmc_card *card = adapter->card;
int ret = 0;
- u16 firmware_stat;
+ u16 firmware_stat = 0;
u32 tries;
for (tries = 0; tries < poll_num; tries++) {
@@ -783,6 +806,13 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
ret = -1;
}
+ if (card->fw_ready_extra_delay &&
+ firmware_stat == FIRMWARE_READY_SDIO)
+ /* firmware might pretend to be ready, when it's not.
+ * Wait a little bit more as a workaround.
+ */
+ msleep(100);
+
return ret;
}
@@ -960,7 +990,6 @@ static struct sdio_driver mwifiex_sdio = {
.probe = mwifiex_sdio_probe,
.remove = mwifiex_sdio_remove,
.drv = {
- .owner = THIS_MODULE,
.coredump = mwifiex_sdio_coredump,
.pm = &mwifiex_sdio_pm_ops,
}
@@ -1083,17 +1112,17 @@ cont:
"info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);
/* Set Host interrupt reset to read to clear */
- if (!mwifiex_read_reg(adapter, card->reg->host_int_rsr_reg, &reg))
- mwifiex_write_reg(adapter, card->reg->host_int_rsr_reg,
- reg | card->reg->sdio_int_mask);
- else
+ if (mwifiex_read_reg(adapter, card->reg->host_int_rsr_reg, &reg))
+ return -1;
+ if (mwifiex_write_reg(adapter, card->reg->host_int_rsr_reg,
+ reg | card->reg->sdio_int_mask))
return -1;
/* Dnld/Upld ready set to auto reset */
- if (!mwifiex_read_reg(adapter, card->reg->card_misc_cfg_reg, &reg))
- mwifiex_write_reg(adapter, card->reg->card_misc_cfg_reg,
- reg | AUTO_RE_ENABLE_INT);
- else
+ if (mwifiex_read_reg(adapter, card->reg->card_misc_cfg_reg, &reg))
+ return -1;
+ if (mwifiex_write_reg(adapter, card->reg->card_misc_cfg_reg,
+ reg | AUTO_RE_ENABLE_INT))
return -1;
return 0;
@@ -1556,7 +1585,7 @@ done:
}
/*
- * This function decode sdio aggreation pkt.
+ * This function decodes sdio aggregation pkt.
*
* Based on the data block size and pkt_len,
* skb data will be decoded to few packets.
@@ -2266,7 +2295,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
card->mpa_tx.buf_len, mport);
- /* Save the last multi port tx aggreagation info to debug log */
+ /* Save the last multi port tx aggregation info to debug log. */
index = adapter->dbg.last_sdio_mp_index;
index = (index + 1) % MWIFIEX_DBG_SDIO_MP_NUM;
adapter->dbg.last_sdio_mp_index = index;
@@ -2493,6 +2522,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
}
+ adapter->host_mlme_enabled = card->host_mlme;
+
return 0;
}
@@ -2525,7 +2556,8 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
mwifiex_read_reg(adapter, card->reg->host_int_status_reg, &sdio_ireg);
/* Get SDIO ioport */
- mwifiex_init_sdio_ioport(adapter);
+ if (mwifiex_init_sdio_ioport(adapter))
+ return -EIO;
/* Initialize SDIO variables in card */
card->mp_rd_bitmap = 0;
@@ -2554,20 +2586,11 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
if (!card->mp_regs)
return -ENOMEM;
- /* Allocate skb pointer buffers */
- card->mpa_rx.skb_arr = kcalloc(card->mp_agg_pkt_limit, sizeof(void *),
- GFP_KERNEL);
- if (!card->mpa_rx.skb_arr) {
- kfree(card->mp_regs);
- return -ENOMEM;
- }
-
card->mpa_rx.len_arr = kcalloc(card->mp_agg_pkt_limit,
sizeof(*card->mpa_rx.len_arr),
GFP_KERNEL);
if (!card->mpa_rx.len_arr) {
kfree(card->mp_regs);
- kfree(card->mpa_rx.skb_arr);
return -ENOMEM;
}
@@ -2622,7 +2645,6 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
cancel_work_sync(&card->work);
kfree(card->mp_regs);
- kfree(card->mpa_rx.skb_arr);
kfree(card->mpa_rx.len_arr);
kfree(card->mpa_tx.buf);
kfree(card->mpa_rx.buf);
@@ -3141,10 +3163,11 @@ static void mwifiex_sdio_up_dev(struct mwifiex_adapter *adapter)
*/
mwifiex_read_reg(adapter, card->reg->host_int_status_reg, &sdio_ireg);
- mwifiex_init_sdio_ioport(adapter);
+ if (mwifiex_init_sdio_ioport(adapter))
+ dev_err(&card->func->dev, "error enabling SDIO port\n");
}
-static struct mwifiex_if_ops sdio_ops = {
+static const struct mwifiex_if_ops sdio_ops = {
.init_if = mwifiex_init_sdio,
.cleanup_if = mwifiex_cleanup_sdio,
.check_fw_status = mwifiex_check_fw_status,
@@ -3172,7 +3195,7 @@ static struct mwifiex_if_ops sdio_ops = {
.up_dev = mwifiex_sdio_up_dev,
};
-module_driver(mwifiex_sdio, sdio_register_driver, sdio_unregister_driver);
+module_sdio_driver(mwifiex_sdio);
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
@@ -3181,6 +3204,7 @@ MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME);
MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME);
MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME);
+MODULE_FIRMWARE(SD8801_DEFAULT_FW_NAME);
MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME);
MODULE_FIRMWARE(SD8887_DEFAULT_FW_NAME);
MODULE_FIRMWARE(SD8977_DEFAULT_FW_NAME);