diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/cmdevt.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/cmdevt.c | 83 |
1 files changed, 41 insertions, 42 deletions
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 677e60b..90ffc76 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -40,8 +40,12 @@ mwifiex_init_cmd_node(struct mwifiex_private *priv, { cmd_node->priv = priv; cmd_node->cmd_oid = cmd_oid; - cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; - priv->adapter->cmd_wait_q_required = false; + if (priv->adapter->cmd_wait_q_required) { + cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; + priv->adapter->cmd_wait_q_required = false; + cmd_node->cmd_wait_q_woken = false; + cmd_node->condition = &cmd_node->cmd_wait_q_woken; + } cmd_node->data_buf = data_buf; cmd_node->cmd_skb = cmd_node->skb; } @@ -90,8 +94,11 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, cmd_node->data_buf = NULL; cmd_node->wait_q_enabled = false; + if (cmd_node->cmd_skb) + skb_trim(cmd_node->cmd_skb, 0); + if (cmd_node->resp_skb) { - dev_kfree_skb_any(cmd_node->resp_skb); + adapter->if_ops.cmdrsp_complete(adapter, cmd_node->resp_skb); cmd_node->resp_skb = NULL; } } @@ -104,13 +111,11 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, * main thread. */ static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) + struct host_cmd_ds_command *cmd, + struct mwifiex_ds_misc_cmd *pcmd_ptr) { - struct mwifiex_ds_misc_cmd *pcmd_ptr = - (struct mwifiex_ds_misc_cmd *) data_buf; - /* Copy the HOST command to command buffer */ - memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len); + memcpy(cmd, pcmd_ptr->cmd, pcmd_ptr->len); dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len); return 0; } @@ -175,8 +180,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, - cmd_node->cmd_skb->data, - cmd_node->cmd_skb->len, NULL); + cmd_node->cmd_skb, NULL); skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN); @@ -237,8 +241,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) skb_push(adapter->sleep_cfm, INTF_HEADER_LEN); ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, - adapter->sleep_cfm->data, - adapter->sleep_cfm->len, NULL); + adapter->sleep_cfm, NULL); skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN); if (ret == -1) { @@ -401,8 +404,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) adapter->event_cause = 0; adapter->event_skb = NULL; - - dev_kfree_skb_any(skb); + adapter->if_ops.event_complete(adapter, skb); return ret; } @@ -420,7 +422,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, struct mwifiex_adapter *adapter = priv->adapter; adapter->cmd_wait_q_required = true; - adapter->cmd_wait_q.condition = false; ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, data_buf); @@ -513,10 +514,12 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, } /* Send command */ - if (cmd_no == HostCmd_CMD_802_11_SCAN) + if (cmd_no == HostCmd_CMD_802_11_SCAN) { mwifiex_queue_scan_cmd(priv, cmd_node); - else + } else { + adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + } return ret; } @@ -537,7 +540,7 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, return; if (cmd_node->wait_q_enabled) - mwifiex_complete_cmd(adapter); + mwifiex_complete_cmd(adapter, cmd_node); /* Clean the node */ mwifiex_clean_cmd_node(adapter, cmd_node); @@ -707,15 +710,14 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { /* Copy original response back to response buffer */ - struct mwifiex_ds_misc_cmd *hostcmd = NULL; + struct mwifiex_ds_misc_cmd *hostcmd; uint16_t size = le16_to_cpu(resp->size); dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size); size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER); if (adapter->curr_cmd->data_buf) { - hostcmd = (struct mwifiex_ds_misc_cmd *) - adapter->curr_cmd->data_buf; + hostcmd = adapter->curr_cmd->data_buf; hostcmd->len = size; - memcpy(hostcmd->cmd, (void *) resp, size); + memcpy(hostcmd->cmd, resp, size); } } orig_cmdresp_no = le16_to_cpu(resp->command); @@ -814,9 +816,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; - if (cmd_node->wait_q_enabled) - adapter->cmd_wait_q.status = -ETIMEDOUT; - if (cmd_node) { adapter->dbg.timeout_cmd_id = adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; @@ -861,6 +860,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context) dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", adapter->ps_mode, adapter->ps_state); + + if (cmd_node->wait_q_enabled) { + adapter->cmd_wait_q.status = -ETIMEDOUT; + wake_up_interruptible(&adapter->cmd_wait_q.wait); + mwifiex_cancel_pending_ioctl(adapter); + /* reset cmd_sent flag to unblock new commands */ + adapter->cmd_sent = false; + } } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); @@ -885,7 +892,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) adapter->curr_cmd->wait_q_enabled = false; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); adapter->cmd_wait_q.status = -1; - mwifiex_complete_cmd(adapter); + mwifiex_complete_cmd(adapter, adapter->curr_cmd); } /* Cancel all pending command */ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); @@ -896,7 +903,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) if (cmd_node->wait_q_enabled) { adapter->cmd_wait_q.status = -1; - mwifiex_complete_cmd(adapter); + mwifiex_complete_cmd(adapter, cmd_node); cmd_node->wait_q_enabled = false; } mwifiex_insert_cmd_to_free_q(adapter, cmd_node); @@ -937,7 +944,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; unsigned long cmd_flags; - unsigned long cmd_pending_q_flags; unsigned long scan_pending_q_flags; uint16_t cancel_scan_cmd = false; @@ -947,12 +953,9 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) cmd_node = adapter->curr_cmd; cmd_node->wait_q_enabled = false; cmd_node->cmd_flag |= CMD_F_CANCELED; - spin_lock_irqsave(&adapter->cmd_pending_q_lock, - cmd_pending_q_flags); - list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, - cmd_pending_q_flags); mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + mwifiex_complete_cmd(adapter, adapter->curr_cmd); + adapter->curr_cmd = NULL; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } @@ -979,7 +982,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } adapter->cmd_wait_q.status = -1; - mwifiex_complete_cmd(adapter); } /* @@ -1156,7 +1158,7 @@ EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp); int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, uint16_t ps_bitmap, - void *data_buf) + struct mwifiex_ds_auto_ds *auto_ds) { struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh = &cmd->params.psmode_enh; @@ -1219,9 +1221,8 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, sizeof(struct mwifiex_ie_types_header)); cmd_size += sizeof(*auto_ds_tlv); tlv += sizeof(*auto_ds_tlv); - if (data_buf) - idletime = ((struct mwifiex_ds_auto_ds *) - data_buf)->idle_time; + if (auto_ds) + idletime = auto_ds->idle_time; dev_dbg(priv->adapter->dev, "cmd: PS Command: Enter Auto Deep Sleep\n"); auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); @@ -1240,7 +1241,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, */ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_pm_cfg *pm_cfg) { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_ps_mode_enh *ps_mode = @@ -1283,10 +1284,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap); - if (data_buf) { + if (pm_cfg) { /* This section is for get power save mode */ - struct mwifiex_ds_pm_cfg *pm_cfg = - (struct mwifiex_ds_pm_cfg *)data_buf; if (ps_bitmap & BITMAP_STA_PS) pm_cfg->param.ps_mode = 1; else |