/* * This function frees the adapter structure. * * The freeing operation is done recursively, by canceling all * pending commands, freeing the member buffers previously * allocated (command buffers, scan table buffer, sleep confirm * command buffer), stopping the timers and calling the cleanup * routines for every interface, before the actual adapter * structure is freed. */ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter) { if (!adapter) { pr_err("%s: adapter is NULL\n", __func__); return; } mwifiex_cancel_all_pending_cmd(adapter); /* Free lock variables */ mwifiex_free_lock_list(adapter); /* Free command buffer */ dev_dbg(adapter->dev, "info: free cmd buffer\n"); mwifiex_free_cmd_buffer(adapter); del_timer(&adapter->cmd_timer); dev_dbg(adapter->dev, "info: free scan table\n"); adapter->if_ops.cleanup_if(adapter); if (adapter->sleep_cfm) dev_kfree_skb_any(adapter->sleep_cfm); }
/* * This function performs cleanup for adapter structure. * * The cleanup is done recursively, by canceling all pending * commands, freeing the member buffers previously allocated * (command buffers, scan table buffer, sleep confirm command * buffer), stopping the timers and calling the cleanup routines * for every interface. */ static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) { int idx; if (!adapter) { pr_err("%s: adapter is NULL\n", __func__); return; } mwifiex_cancel_all_pending_cmd(adapter); /* Free lock variables */ mwifiex_free_lock_list(adapter); /* Free command buffer */ dev_dbg(adapter->dev, "info: free cmd buffer\n"); mwifiex_free_cmd_buffer(adapter); for (idx = 0; idx < adapter->num_mem_types; idx++) { struct memory_type_mapping *entry = &adapter->mem_type_mapping_tbl[idx]; if (entry->mem_ptr) { vfree(entry->mem_ptr); entry->mem_ptr = NULL; } entry->mem_size = 0; } if (adapter->sleep_cfm) dev_kfree_skb_any(adapter->sleep_cfm); }
static void wakeup_timer_fn(unsigned long data) { struct mwifiex_adapter *adapter = (struct mwifiex_adapter *)data; mwifiex_dbg(adapter, ERROR, "Firmware wakeup failed\n"); adapter->hw_status = MWIFIEX_HW_STATUS_RESET; mwifiex_cancel_all_pending_cmd(adapter); if (adapter->if_ops.card_reset) adapter->if_ops.card_reset(adapter); }
/* * Sends IOCTL request to cancel the existing Host Sleep configuration. * * This function allocates the IOCTL request buffer, fills it * with requisite parameters and calls the IOCTL handler. */ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) { struct mwifiex_ds_hs_cfg hscfg; struct mwifiex_private *priv; int i; if (disconnect_on_suspend) { for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; if (priv) mwifiex_deauthenticate(priv, NULL); } } if (adapter->hs_activated) { dev_dbg(adapter->dev, "cmd: HS Already activated\n"); return true; } adapter->hs_activate_wait_q_woken = false; memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); hscfg.is_invoke_hostcmd = true; adapter->hs_enabling = true; mwifiex_cancel_all_pending_cmd(adapter); if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, &hscfg)) { dev_err(adapter->dev, "IOCTL request HS enable failed\n"); return false; } if (wait_event_interruptible_timeout(adapter->hs_activate_wait_q, adapter->hs_activate_wait_q_woken, (10 * HZ)) <= 0) { dev_err(adapter->dev, "hs_activate_wait_q terminated\n"); return false; } return true; }
/* * Wait queue completion handler. * * This function waits on a cmd wait queue. It also cancels the pending * request after waking up, in case of errors. */ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_queued) { int status; /* Wait for completion */ status = wait_event_interruptible(adapter->cmd_wait_q.wait, *(cmd_queued->condition)); if (status) { dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status); mwifiex_cancel_all_pending_cmd(adapter); return status; } status = adapter->cmd_wait_q.status; adapter->cmd_wait_q.status = 0; return status; }
/* * This function performs cleanup for adapter structure. * * The cleanup is done recursively, by canceling all pending * commands, freeing the member buffers previously allocated * (command buffers, scan table buffer, sleep confirm command * buffer), stopping the timers and calling the cleanup routines * for every interface. */ static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) { int idx; if (!adapter) { pr_err("%s: adapter is NULL\n", __func__); return; } del_timer(&adapter->wakeup_timer); mwifiex_cancel_all_pending_cmd(adapter); wake_up_interruptible(&adapter->cmd_wait_q.wait); wake_up_interruptible(&adapter->hs_activate_wait_q); /* Free lock variables */ mwifiex_free_lock_list(adapter); /* Free command buffer */ mwifiex_dbg(adapter, INFO, "info: free cmd buffer\n"); mwifiex_free_cmd_buffer(adapter); for (idx = 0; idx < adapter->num_mem_types; idx++) { struct memory_type_mapping *entry = &adapter->mem_type_mapping_tbl[idx]; if (entry->mem_ptr) { vfree(entry->mem_ptr); entry->mem_ptr = NULL; } entry->mem_size = 0; } if (adapter->drv_info_dump) { vfree(adapter->drv_info_dump); adapter->drv_info_dump = NULL; adapter->drv_info_size = 0; } if (adapter->sleep_cfm) dev_kfree_skb_any(adapter->sleep_cfm); }
/* * Wait queue completion handler. * * This function waits on a cmd wait queue. It also cancels the pending * request after waking up, in case of errors. */ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_queued) { int status; /* Wait for completion */ status = wait_event_interruptible_timeout(adapter->cmd_wait_q.wait, *(cmd_queued->condition), (12 * HZ)); if (status <= 0) { if (status == 0) status = -ETIMEDOUT; mwifiex_dbg(adapter, ERROR, "cmd_wait_q terminated: %d\n", status); mwifiex_cancel_all_pending_cmd(adapter); return status; } status = adapter->cmd_wait_q.status; adapter->cmd_wait_q.status = 0; return status; }
/* * Sends IOCTL request to cancel the existing Host Sleep configuration. * * This function allocates the IOCTL request buffer, fills it * with requisite parameters and calls the IOCTL handler. */ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) { struct mwifiex_ds_hs_cfg hscfg; struct mwifiex_private *priv; int i; if (disconnect_on_suspend) { for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; if (priv) mwifiex_deauthenticate(priv, NULL); } } priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); if (priv && priv->sched_scanning) { #ifdef CONFIG_PM if (priv->wdev.wiphy->wowlan_config && !priv->wdev.wiphy->wowlan_config->nd_config) { #endif mwifiex_dbg(adapter, CMD, "aborting bgscan!\n"); mwifiex_stop_bg_scan(priv); cfg80211_sched_scan_stopped(priv->wdev.wiphy); #ifdef CONFIG_PM } #endif } if (adapter->hs_activated) { mwifiex_dbg(adapter, CMD, "cmd: HS Already activated\n"); return true; } adapter->hs_activate_wait_q_woken = false; memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); hscfg.is_invoke_hostcmd = true; adapter->hs_enabling = true; mwifiex_cancel_all_pending_cmd(adapter); if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, &hscfg)) { mwifiex_dbg(adapter, ERROR, "IOCTL request HS enable failed\n"); return false; } if (wait_event_interruptible_timeout(adapter->hs_activate_wait_q, adapter->hs_activate_wait_q_woken, (10 * HZ)) <= 0) { mwifiex_dbg(adapter, ERROR, "hs_activate_wait_q terminated\n"); return false; } return true; }