Merge branch 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6
[pandora-kernel.git] / drivers / net / wireless / mwifiex / cmdevt.c
index 3a8fe1e..b5352af 100644 (file)
 static void
 mwifiex_init_cmd_node(struct mwifiex_private *priv,
                      struct cmd_ctrl_node *cmd_node,
-                     u32 cmd_oid, void *wait_queue, void *data_buf)
+                     u32 cmd_oid, void *data_buf)
 {
        cmd_node->priv = priv;
        cmd_node->cmd_oid = cmd_oid;
-       cmd_node->wq_buf = wait_queue;
+       cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required;
+       priv->adapter->cmd_wait_q_required = false;
        cmd_node->data_buf = data_buf;
        cmd_node->cmd_skb = cmd_node->skb;
 }
@@ -86,39 +87,13 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
 {
        cmd_node->cmd_oid = 0;
        cmd_node->cmd_flag = 0;
-       cmd_node->wq_buf = NULL;
        cmd_node->data_buf = NULL;
+       cmd_node->wait_q_enabled = false;
 
        if (cmd_node->resp_skb) {
-               mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0);
+               dev_kfree_skb_any(cmd_node->resp_skb);
                cmd_node->resp_skb = NULL;
        }
-
-       return;
-}
-
-/*
- * This function returns a command node from the pending queue which
- * matches the given IOCTL request.
- */
-static struct cmd_ctrl_node *
-mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter,
-                             struct mwifiex_wait_queue *wait_queue)
-{
-       unsigned long flags;
-       struct cmd_ctrl_node *cmd_node;
-
-       spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
-       list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
-               if (cmd_node->wq_buf == wait_queue) {
-                       spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
-                                              flags);
-                       return cmd_node;
-               }
-       }
-       spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
-
-       return NULL;
 }
 
 /*
@@ -129,13 +104,11 @@ mwifiex_get_pending_ioctl_cmd(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;
 }
@@ -153,9 +126,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
 {
 
        struct mwifiex_adapter *adapter = priv->adapter;
-       int ret = 0;
+       int ret;
        struct host_cmd_ds_command *host_cmd;
-       struct mwifiex_wait_queue *wait_queue = NULL;
        uint16_t cmd_code;
        uint16_t cmd_size;
        struct timeval tstamp;
@@ -165,15 +137,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
                return -1;
 
        host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
-       if (cmd_node->wq_buf)
-               wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
 
        /* Sanity test */
        if (host_cmd == NULL || host_cmd->size == 0) {
                dev_err(adapter->dev, "DNLD_CMD: host_cmd is null"
                        " or cmd size is 0, not sending\n");
-               if (wait_queue)
-                       wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL;
+               if (cmd_node->wait_q_enabled)
+                       adapter->cmd_wait_q.status = -1;
                mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
                return -1;
        }
@@ -206,10 +176,12 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
                                             cmd_node->cmd_skb->data,
                                             cmd_node->cmd_skb->len, NULL);
 
+       skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
+
        if (ret == -1) {
                dev_err(adapter->dev, "DNLD_CMD: host to card failed\n");
-               if (wait_queue)
-                       wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL;
+               if (cmd_node->wait_q_enabled)
+                       adapter->cmd_wait_q.status = -1;
                mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
 
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
@@ -248,25 +220,24 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
  */
 static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
 {
-       int ret = 0;
-       u16 cmd_len = 0;
+       int ret;
        struct mwifiex_private *priv;
-       struct mwifiex_opt_sleep_confirm_buffer *sleep_cfm_buf =
-                               (struct mwifiex_opt_sleep_confirm_buffer *)
+       struct mwifiex_opt_sleep_confirm *sleep_cfm_buf =
+                               (struct mwifiex_opt_sleep_confirm *)
                                adapter->sleep_cfm->data;
-       cmd_len = sizeof(struct mwifiex_opt_sleep_confirm);
        priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 
-       sleep_cfm_buf->ps_cfm_sleep.seq_num =
+       sleep_cfm_buf->seq_num =
                cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
                                        (adapter->seq_num, priv->bss_num,
                                         priv->bss_type)));
        adapter->seq_num++;
 
+       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 +
-                                            INTF_HEADER_LEN, NULL);
+                                            adapter->sleep_cfm->len, NULL);
+       skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
 
        if (ret == -1) {
                dev_err(adapter->dev, "SLEEP_CFM: failed\n");
@@ -275,14 +246,14 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
        }
        if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
                        == MWIFIEX_BSS_ROLE_STA) {
-               if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl)
+               if (!sleep_cfm_buf->resp_ctrl)
                        /* Response is not needed for sleep
                           confirm command */
                        adapter->ps_state = PS_STATE_SLEEP;
                else
                        adapter->ps_state = PS_STATE_SLEEP_CFM;
 
-               if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl
+               if (!sleep_cfm_buf->resp_ctrl
                                && (adapter->is_hs_configured
                                        && !adapter->sleep_period.period)) {
                        adapter->pm_wakeup_card_req = true;
@@ -318,7 +289,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
        if (!cmd_array) {
                dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
                                __func__);
-               return -1;
+               return -ENOMEM;
        }
 
        adapter->cmd_pool = cmd_array;
@@ -366,7 +337,7 @@ int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
                }
                if (!cmd_array[i].resp_skb)
                        continue;
-               mwifiex_recv_complete(adapter, cmd_array[i].resp_skb, 0);
+               dev_kfree_skb_any(cmd_array[i].resp_skb);
        }
        /* Release struct cmd_ctrl_node */
        if (adapter->cmd_pool) {
@@ -390,13 +361,13 @@ int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
  */
 int mwifiex_process_event(struct mwifiex_adapter *adapter)
 {
-       int ret = 0;
+       int ret;
        struct mwifiex_private *priv =
                mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
        struct sk_buff *skb = adapter->event_skb;
        u32 eventcause = adapter->event_cause;
        struct timeval tstamp;
-       struct mwifiex_rxinfo *rx_info = NULL;
+       struct mwifiex_rxinfo *rx_info;
 
        /* Save the last event to debug log */
        adapter->dbg.last_event_index =
@@ -429,13 +400,37 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
        adapter->event_cause = 0;
        adapter->event_skb = NULL;
 
-       mwifiex_recv_complete(adapter, skb, 0);
+       dev_kfree_skb_any(skb);
 
        return ret;
 }
 
 /*
- * This function prepares a command before sending it to the firmware.
+ * This function is used to send synchronous command to the firmware.
+ *
+ * it allocates a wait queue for the command and wait for the command
+ * response.
+ */
+int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
+                         u16 cmd_action, u32 cmd_oid, void *data_buf)
+{
+       int ret = 0;
+       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);
+       if (!ret)
+               ret = mwifiex_wait_queue_complete(adapter);
+
+       return ret;
+}
+
+
+/*
+ * This function prepares a command and asynchronously send it to the firmware.
  *
  * Preparation includes -
  *      - Sanity tests to make sure the card is still present or the FW
@@ -445,14 +440,13 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
  *      - Fill up the non-default parameters and buffer pointers
  *      - Add the command to pending queue
  */
-int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
-                       u16 cmd_action, u32 cmd_oid,
-                       void *wait_queue, void *data_buf)
+int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
+                          u16 cmd_action, u32 cmd_oid, void *data_buf)
 {
-       int ret = 0;
+       int ret;
        struct mwifiex_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *cmd_node = NULL;
-       struct host_cmd_ds_command *cmd_ptr = NULL;
+       struct cmd_ctrl_node *cmd_node;
+       struct host_cmd_ds_command *cmd_ptr;
 
        if (!adapter) {
                pr_err("PREP_CMD: adapter is NULL\n");
@@ -485,7 +479,7 @@ int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
        }
 
        /* Initialize the command node */
-       mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf);
+       mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf);
 
        if (!cmd_node->cmd_skb) {
                dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
@@ -535,18 +529,13 @@ void
 mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
                             struct cmd_ctrl_node *cmd_node)
 {
-       struct mwifiex_wait_queue *wait_queue = NULL;
        unsigned long flags;
 
-       if (cmd_node == NULL)
+       if (!cmd_node)
                return;
-       if (cmd_node->wq_buf) {
-               wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
-               if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR)
-                       mwifiex_ioctl_complete(adapter, wait_queue, -1);
-               else
-                       mwifiex_ioctl_complete(adapter, wait_queue, 0);
-       }
+
+       if (cmd_node->wait_q_enabled)
+               mwifiex_complete_cmd(adapter);
        /* Clean the node */
        mwifiex_clean_cmd_node(adapter, cmd_node);
 
@@ -554,8 +543,6 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
        spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
        list_add_tail(&cmd_node->list, &adapter->cmd_free_q);
        spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
-
-       return;
 }
 
 /*
@@ -600,8 +587,6 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
        spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
 
        dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command);
-
-       return;
 }
 
 /*
@@ -617,8 +602,8 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
  */
 int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
 {
-       struct mwifiex_private *priv = NULL;
-       struct cmd_ctrl_node *cmd_node = NULL;
+       struct mwifiex_private *priv;
+       struct cmd_ctrl_node *cmd_node;
        int ret = 0;
        struct host_cmd_ds_command *host_cmd;
        unsigned long cmd_flags;
@@ -685,14 +670,13 @@ int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
  */
 int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 {
-       struct host_cmd_ds_command *resp = NULL;
+       struct host_cmd_ds_command *resp;
        struct mwifiex_private *priv =
                mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
        int ret = 0;
        uint16_t orig_cmdresp_no;
        uint16_t cmdresp_no;
        uint16_t cmdresp_result;
-       struct mwifiex_wait_queue *wait_queue = NULL;
        struct timeval tstamp;
        unsigned long flags;
 
@@ -706,10 +690,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
                return -1;
        }
 
-       if (adapter->curr_cmd->wq_buf)
-               wait_queue = (struct mwifiex_wait_queue *)
-                               adapter->curr_cmd->wq_buf;
-
        adapter->num_cmd_timeout = 0;
 
        resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
@@ -725,15 +705,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);
@@ -764,8 +743,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 
        if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
                dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
-               if (wait_queue)
-                       wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP;
+               if (adapter->curr_cmd->wait_q_enabled)
+                       adapter->cmd_wait_q.status = -1;
 
                mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
@@ -781,8 +760,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
                        ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
        } else {
                /* handle response */
-               ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp,
-                                                 wait_queue);
+               ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp);
        }
 
        /* Check init command response */
@@ -797,10 +775,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
        }
 
        if (adapter->curr_cmd) {
-               if (wait_queue && (!ret))
-                       wait_queue->status = MWIFIEX_ERROR_NO_ERROR;
-               else if (wait_queue && (ret == -1))
-                       wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL;
+               if (adapter->curr_cmd->wait_q_enabled && (!ret))
+                       adapter->cmd_wait_q.status = 0;
+               else if (adapter->curr_cmd->wait_q_enabled && (ret == -1))
+                       adapter->cmd_wait_q.status = -1;
 
                /* Clean up and put current command back to cmd_free_q */
                mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
@@ -823,8 +801,7 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
 {
        struct mwifiex_adapter *adapter =
                (struct mwifiex_adapter *) function_context;
-       struct cmd_ctrl_node *cmd_node = NULL;
-       struct mwifiex_wait_queue *wait_queue = NULL;
+       struct cmd_ctrl_node *cmd_node;
        struct timeval tstamp;
 
        adapter->num_cmd_timeout++;
@@ -834,10 +811,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
                return;
        }
        cmd_node = adapter->curr_cmd;
-       if (cmd_node->wq_buf) {
-               wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
-               wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT;
-       }
+       if (cmd_node->wait_q_enabled)
+               adapter->cmd_wait_q.status = -ETIMEDOUT;
 
        if (cmd_node) {
                adapter->dbg.timeout_cmd_id =
@@ -886,8 +861,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
        }
        if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
                mwifiex_init_fw_complete(adapter);
-
-       return;
 }
 
 /*
@@ -900,19 +873,16 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
 void
 mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
 {
-       struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
-       struct mwifiex_wait_queue *wait_queue = NULL;
+       struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
        unsigned long flags;
 
        /* Cancel current cmd */
-       if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) {
-               wait_queue =
-                       (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf;
+       if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
-               adapter->curr_cmd->wq_buf = NULL;
+               adapter->curr_cmd->wait_q_enabled = false;
                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
-               wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL;
-               mwifiex_ioctl_complete(adapter, wait_queue, -1);
+               adapter->cmd_wait_q.status = -1;
+               mwifiex_complete_cmd(adapter);
        }
        /* Cancel all pending command */
        spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
@@ -921,12 +891,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
                list_del(&cmd_node->list);
                spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
 
-               if (cmd_node->wq_buf) {
-                       wait_queue =
-                               (struct mwifiex_wait_queue *) cmd_node->wq_buf;
-                       wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL;
-                       mwifiex_ioctl_complete(adapter, wait_queue, -1);
-                       cmd_node->wq_buf = NULL;
+               if (cmd_node->wait_q_enabled) {
+                       adapter->cmd_wait_q.status = -1;
+                       mwifiex_complete_cmd(adapter);
+                       cmd_node->wait_q_enabled = false;
                }
                mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
                spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
@@ -940,7 +908,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
                list_del(&cmd_node->list);
                spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
 
-               cmd_node->wq_buf = NULL;
+               cmd_node->wait_q_enabled = false;
                mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
                spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
        }
@@ -962,8 +930,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
  * are cancelled.
  */
 void
-mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
-                            struct mwifiex_wait_queue *wait_queue)
+mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
 {
        struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
        unsigned long cmd_flags;
@@ -972,45 +939,33 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
        uint16_t cancel_scan_cmd = false;
 
        if ((adapter->curr_cmd) &&
-           (adapter->curr_cmd->wq_buf == wait_queue)) {
+            (adapter->curr_cmd->wait_q_enabled)) {
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
                cmd_node = adapter->curr_cmd;
-               cmd_node->wq_buf = NULL;
+               cmd_node->wait_q_enabled = false;
                cmd_node->cmd_flag |= CMD_F_CANCELED;
-               spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
-       }
-
-       spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
-       while (1) {
-               cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue);
-               if (!cmd_node)
-                       break;
-
                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);
-
-               cmd_node->wq_buf = NULL;
                mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+               spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
        }
-       spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+
        /* Cancel all pending scan command */
        spin_lock_irqsave(&adapter->scan_pending_q_lock,
                          scan_pending_q_flags);
        list_for_each_entry_safe(cmd_node, tmp_node,
                                 &adapter->scan_pending_q, list) {
-               if (cmd_node->wq_buf == wait_queue) {
-                       list_del(&cmd_node->list);
-                       spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
-                                              scan_pending_q_flags);
-                       cmd_node->wq_buf = NULL;
-                       mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-                       spin_lock_irqsave(&adapter->scan_pending_q_lock,
-                                         scan_pending_q_flags);
-                       cancel_scan_cmd = true;
-               }
+               list_del(&cmd_node->list);
+               spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+                                      scan_pending_q_flags);
+               cmd_node->wait_q_enabled = false;
+               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+               spin_lock_irqsave(&adapter->scan_pending_q_lock,
+                                 scan_pending_q_flags);
+               cancel_scan_cmd = true;
        }
        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                               scan_pending_q_flags);
@@ -1020,10 +975,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
                adapter->scan_processing = false;
                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
        }
-       wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL;
-       mwifiex_ioctl_complete(adapter, wait_queue, -1);
-
-       return;
+       adapter->cmd_wait_q.status = -1;
+       mwifiex_complete_cmd(adapter);
 }
 
 /*
@@ -1127,7 +1080,6 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
        adapter->is_hs_configured = false;
        mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
                                   MWIFIEX_BSS_ROLE_ANY), false);
-       return;
 }
 
 /*
@@ -1200,26 +1152,29 @@ 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;
-       u8 *tlv = NULL;
+       u8 *tlv;
        u16 cmd_size = 0;
 
        cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
        if (cmd_action == DIS_AUTO_PS) {
                psmode_enh->action = cpu_to_le16(DIS_AUTO_PS);
                psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
-               cmd->size = cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE);
+               cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
+                               sizeof(psmode_enh->params.ps_bitmap));
        } else if (cmd_action == GET_PS) {
                psmode_enh->action = cpu_to_le16(GET_PS);
                psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
-               cmd->size = cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE);
+               cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
+                               sizeof(psmode_enh->params.ps_bitmap));
        } else if (cmd_action == EN_AUTO_PS) {
                psmode_enh->action = cpu_to_le16(EN_AUTO_PS);
-               psmode_enh->params.auto_ps.ps_bitmap = cpu_to_le16(ps_bitmap);
-               cmd_size = S_DS_GEN + AUTO_PS_FIX_SIZE;
+               psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
+               cmd_size = S_DS_GEN + sizeof(psmode_enh->action) +
+                               sizeof(psmode_enh->params.ps_bitmap);
                tlv = (u8 *) cmd + cmd_size;
                if (ps_bitmap & BITMAP_STA_PS) {
                        struct mwifiex_adapter *adapter = priv->adapter;
@@ -1249,24 +1204,22 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
 
                }
                if (ps_bitmap & BITMAP_AUTO_DS) {
-                       struct mwifiex_ie_types_auto_ds_param *auto_ps_tlv =
+                       struct mwifiex_ie_types_auto_ds_param *auto_ds_tlv =
                                (struct mwifiex_ie_types_auto_ds_param *) tlv;
-                       struct mwifiex_auto_ds_param *auto_ds =
-                               &auto_ps_tlv->param;
                        u16 idletime = 0;
-                       auto_ps_tlv->header.type =
+
+                       auto_ds_tlv->header.type =
                                cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM);
-                       auto_ps_tlv->header.len =
-                               cpu_to_le16(sizeof(*auto_ps_tlv) -
+                       auto_ds_tlv->header.len =
+                               cpu_to_le16(sizeof(*auto_ds_tlv) -
                                        sizeof(struct mwifiex_ie_types_header));
-                       cmd_size += sizeof(*auto_ps_tlv);
-                       tlv += sizeof(*auto_ps_tlv);
-                       if (data_buf)
-                               idletime = ((struct mwifiex_ds_auto_ds *)
-                                            data_buf)->idle_time;
+                       cmd_size += sizeof(*auto_ds_tlv);
+                       tlv += sizeof(*auto_ds_tlv);
+                       if (auto_ds)
+                               idletime = auto_ds->idle_time;
                        dev_dbg(priv->adapter->dev,
                                        "cmd: PS Command: Enter Auto Deep Sleep\n");
-                       auto_ds->deep_sleep_timeout = cpu_to_le16(idletime);
+                       auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime);
                }
                cmd->size = cpu_to_le16(cmd_size);
        }
@@ -1282,7 +1235,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 =
@@ -1290,7 +1243,7 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
        uint16_t action = le16_to_cpu(ps_mode->action);
        uint16_t ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap);
        uint16_t auto_ps_bitmap =
-               le16_to_cpu(ps_mode->params.auto_ps.ps_bitmap);
+               le16_to_cpu(ps_mode->params.ps_bitmap);
 
        dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
                                        __func__, resp->result, action);
@@ -1318,18 +1271,15 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
                        }
                }
        } else if (action == GET_PS) {
-               if (ps_bitmap & (BITMAP_STA_PS | BITMAP_UAP_INACT_PS
-                                                       | BITMAP_UAP_DTIM_PS))
+               if (ps_bitmap & BITMAP_STA_PS)
                        adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
                else
                        adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
 
                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
@@ -1448,12 +1398,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
        }
 
        adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
-       adapter->usr_dot_11n_dev_cap = adapter->hw_dot_11n_dev_cap &
-               DEFAULT_11N_CAP_MASK;
        adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
-       adapter->usr_dev_mcs_support = adapter->hw_dev_mcs_support;
-       mwifiex_show_dot_11n_dev_cap(adapter, adapter->hw_dot_11n_dev_cap);
-       mwifiex_show_dev_mcs_support(adapter, adapter->hw_dev_mcs_support);
 
        if (adapter->if_ops.update_mp_end_port)
                adapter->if_ops.update_mp_end_port(adapter,