diff options
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/main.c')
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/main.c | 66 |
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); } |