mwifiex: cleanup ioctl wait queue and abstraction layer

1) remove mwifiex_alloc_fill_wait_queue() and
mwifiex_request_ioctl()
2) avoid dynamic allocation of wait queue
3) remove unnecessary mwifiex_error_code macros that
were used mainly by the wait queue status code
4) remove some abstraction functions
5) split mwifiex_prepare_cmd() to mwifiex_send_cmd_async()
and mwifiex_send_sync() to handle asynchronous and
synchronous commands respectively

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 8676480..bb6fecd 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -36,11 +36,12 @@
 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,8 +87,8 @@
 {
 	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);
@@ -98,30 +99,6 @@
 }
 
 /*
- * 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;
-}
-
-/*
  * This function sends a host command to the firmware.
  *
  * The function copies the host command into the driver command
@@ -155,7 +132,6 @@
 	struct mwifiex_adapter *adapter = priv->adapter;
 	int ret = 0;
 	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 +141,13 @@
 		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;
 	}
@@ -210,8 +184,8 @@
 
 	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);
@@ -437,7 +411,31 @@
 }
 
 /*
- * 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
@@ -447,9 +445,8 @@
  *      - 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;
 	struct mwifiex_adapter *adapter = priv->adapter;
@@ -487,7 +484,7 @@
 	}
 
 	/* 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");
@@ -537,18 +534,13 @@
 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)
 		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);
 
@@ -694,7 +686,6 @@
 	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;
 
@@ -708,10 +699,6 @@
 		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;
@@ -766,8 +753,8 @@
 
 	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);
@@ -783,8 +770,7 @@
 			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 */
@@ -799,10 +785,10 @@
 	}
 
 	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);
@@ -826,7 +812,6 @@
 	struct mwifiex_adapter *adapter =
 		(struct mwifiex_adapter *) function_context;
 	struct cmd_ctrl_node *cmd_node = NULL;
-	struct mwifiex_wait_queue *wait_queue = NULL;
 	struct timeval tstamp;
 
 	adapter->num_cmd_timeout++;
@@ -836,10 +821,8 @@
 		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 =
@@ -903,18 +886,15 @@
 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;
 	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);
@@ -923,12 +903,10 @@
 		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);
@@ -942,7 +920,7 @@
 		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);
 	}
@@ -964,8 +942,7 @@
  * 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;
@@ -974,45 +951,33 @@
 	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);
@@ -1022,8 +987,8 @@
 		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);
+	adapter->cmd_wait_q.status = -1;
+	mwifiex_complete_cmd(adapter);
 
 	return;
 }