summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/marvell/mwifiex/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/main.c')
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index b62e03d11c2e..dd87b9ff64c3 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -17,6 +17,8 @@
* this warranty disclaimer.
*/
+#include <linux/suspend.h>
+
#include "main.h"
#include "wmm.h"
#include "cfg80211.h"
@@ -147,7 +149,6 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
kfree(adapter->regd);
- vfree(adapter->chan_stats);
kfree(adapter);
return 0;
}
@@ -511,7 +512,7 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
* - Download the correct firmware to card
* - Issue the init commands to firmware
*/
-static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
+static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context)
{
int ret;
char fmt[64];
@@ -594,7 +595,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
rtnl_lock();
/* Create station interface by default */
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", NET_NAME_ENUM,
- NL80211_IFTYPE_STATION, NULL, NULL);
+ NL80211_IFTYPE_STATION, NULL);
if (IS_ERR(wdev)) {
mwifiex_dbg(adapter, ERROR,
"cannot create default STA interface\n");
@@ -604,7 +605,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
if (driver_mode & MWIFIEX_DRIVER_MODE_UAP) {
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", NET_NAME_ENUM,
- NL80211_IFTYPE_AP, NULL, NULL);
+ NL80211_IFTYPE_AP, NULL);
if (IS_ERR(wdev)) {
mwifiex_dbg(adapter, ERROR,
"cannot create AP interface\n");
@@ -615,8 +616,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
if (driver_mode & MWIFIEX_DRIVER_MODE_P2P) {
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", NET_NAME_ENUM,
- NL80211_IFTYPE_P2P_CLIENT, NULL,
- NULL);
+ NL80211_IFTYPE_P2P_CLIENT, NULL);
if (IS_ERR(wdev)) {
mwifiex_dbg(adapter, ERROR,
"cannot create p2p client interface\n");
@@ -631,6 +631,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
goto done;
err_add_intf:
+ vfree(adapter->chan_stats);
wiphy_unregister(adapter->wiphy);
wiphy_free(adapter->wiphy);
err_init_fw:
@@ -664,11 +665,18 @@ done:
mwifiex_free_adapter(adapter);
/* Tell all current and future waiters we're finished */
complete_all(fw_done);
- return;
+
+ return init_failed ? -EIO : 0;
+}
+
+static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
+{
+ _mwifiex_fw_dpc(firmware, context);
}
/*
- * This function initializes the hardware and gets firmware.
+ * This function gets the firmware and (if called asynchronously) kicks off the
+ * HW init when done.
*/
static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter,
bool req_fw_nowait)
@@ -691,20 +699,15 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter,
ret = request_firmware_nowait(THIS_MODULE, 1, adapter->fw_name,
adapter->dev, GFP_KERNEL, adapter,
mwifiex_fw_dpc);
- if (ret < 0)
- mwifiex_dbg(adapter, ERROR,
- "request_firmware_nowait error %d\n", ret);
} else {
ret = request_firmware(&adapter->firmware,
adapter->fw_name,
adapter->dev);
- if (ret < 0)
- mwifiex_dbg(adapter, ERROR,
- "request_firmware error %d\n", ret);
- else
- mwifiex_fw_dpc(adapter->firmware, (void *)adapter);
}
+ if (ret < 0)
+ mwifiex_dbg(adapter, ERROR, "request_firmware%s error %d\n",
+ req_fw_nowait ? "_nowait" : "", ret);
return ret;
}
@@ -745,7 +748,7 @@ mwifiex_close(struct net_device *dev)
mwifiex_dbg(priv->adapter, INFO,
"aborting bgscan on ndo_stop\n");
mwifiex_stop_bg_scan(priv);
- cfg80211_sched_scan_stopped(priv->wdev.wiphy);
+ cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
}
return 0;
@@ -1413,6 +1416,7 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
rtnl_unlock();
}
+ vfree(adapter->chan_stats);
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
exit_return:
@@ -1426,6 +1430,8 @@ EXPORT_SYMBOL_GPL(mwifiex_shutdown_sw);
int
mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
{
+ int ret;
+
mwifiex_init_lock_list(adapter);
if (adapter->if_ops.up_dev)
adapter->if_ops.up_dev(adapter);
@@ -1435,6 +1441,7 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
init_waitqueue_head(&adapter->init_wait_q);
adapter->is_suspended = false;
adapter->hs_activated = false;
+ adapter->is_cmd_timedout = 0;
init_waitqueue_head(&adapter->hs_activate_wait_q);
init_waitqueue_head(&adapter->cmd_wait_q.wait);
adapter->cmd_wait_q.status = 0;
@@ -1472,9 +1479,15 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
"%s: firmware init failed\n", __func__);
goto err_init_fw;
}
+
+ /* _mwifiex_fw_dpc() does its own cleanup */
+ ret = _mwifiex_fw_dpc(adapter->firmware, adapter);
+ if (ret) {
+ pr_err("Failed to bring up adapter: %d\n", ret);
+ return ret;
+ }
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
- complete_all(adapter->fw_done);
return 0;
err_init_fw:
@@ -1502,14 +1515,13 @@ static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
{
struct mwifiex_adapter *adapter = priv;
- if (adapter->irq_wakeup >= 0) {
- dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
- adapter->wake_by_wifi = true;
- disable_irq_nosync(irq);
- }
+ dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
+ adapter->wake_by_wifi = true;
+ disable_irq_nosync(irq);
/* Notify PM core we are wakeup source */
pm_wakeup_event(adapter->dev, 0);
+ pm_system_wakeup();
return IRQ_HANDLED;
}
@@ -1714,6 +1726,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter)
mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
rtnl_unlock();
}
+ vfree(adapter->chan_stats);
wiphy_unregister(adapter->wiphy);
wiphy_free(adapter->wiphy);
@@ -1742,7 +1755,7 @@ void _mwifiex_dbg(const struct mwifiex_adapter *adapter, int mask,
struct va_format vaf;
va_list args;
- if (!adapter->dev || !(adapter->debug_mask & mask))
+ if (!(adapter->debug_mask & mask))
return;
va_start(args, fmt);
@@ -1750,7 +1763,10 @@ void _mwifiex_dbg(const struct mwifiex_adapter *adapter, int mask,
vaf.fmt = fmt;
vaf.va = &args;
- dev_info(adapter->dev, "%pV", &vaf);
+ if (adapter->dev)
+ dev_info(adapter->dev, "%pV", &vaf);
+ else
+ pr_info("%pV", &vaf);
va_end(args);
}