mwifiex: wakeup main thread to handle command queued
authorAmitkumar Karwar <akarwar@marvell.com>
Thu, 28 Jun 2012 02:57:56 +0000 (19:57 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 28 Jun 2012 18:37:48 +0000 (14:37 -0400)
We miss to wakeup main thread after adding command to cmd pending
queue at follwing places. These commands are handled later when
main thread is woken up for handling an interrupt for sleep event
from firmware. This adds worst case delay of 50msec.

1) We don't wakeup main thread when asynchronous command is added
to cmd pending queue. Move queue_work() call from
mwifiex_wait_queue_complete() to mwifiex_send_cmd_async() to wakeup
main thread for sync as well as async commands.

2) Scan operation is triggered due to following reasons
   a) request from user (ex. "iw scan" command)
   b) Scan performed by driver internally.
   In first case main thread is woken up when first scan command is
queued in cmd pending queue (we don't need to wakeup main thread for
subsequent scan commands, because they are queued in scan command
response handler), but it is not done for second case. queue_work()
is moved inside mwifiex_scan_networks() to handle both the cases.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_ioctl.c

index 9c2e08e4b0931d7f948b2b9235b0641ce10be6d1..02d0ee8609fa83cc9a6892db6e3a0939073533f7 100644 (file)
@@ -1422,7 +1422,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
 
                priv->user_scan_cfg->chan_list[i].scan_time = 0;
        }
-       if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg))
+       if (mwifiex_scan_networks(priv, priv->user_scan_cfg))
                return -EFAULT;
 
        if (request->ie && request->ie_len) {
index ea37b887a874ddf892e48ed3746de24b0c1dcb1a..c68adec3cc8b6522678c98582c7781b885193849 100644 (file)
@@ -578,6 +578,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
        } else {
                adapter->cmd_queued = cmd_node;
                mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
+               queue_work(adapter->workqueue, &adapter->main_work);
        }
 
        return ret;
index 0b3b5aa9830dbb4a38fe6887fbc23264ef47648f..7cd95cc99a8530f3746aa26529c91df478e2655e 100644 (file)
@@ -949,8 +949,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
                              struct mwifiex_rate_cfg *rate);
 int mwifiex_request_scan(struct mwifiex_private *priv,
                         struct cfg80211_ssid *req_ssid);
-int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
-                               struct mwifiex_user_scan_cfg *scan_req);
+int mwifiex_scan_networks(struct mwifiex_private *priv,
+                         const struct mwifiex_user_scan_cfg *user_scan_in);
 int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
 
 int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
index efaf26ccd6ba920895141d792d30a1c6fba63114..884ed6377003664488ca6b55ef7a9bc1cc703041 100644 (file)
@@ -1296,8 +1296,8 @@ mwifiex_radio_type_to_band(u8 radio_type)
  * order to send the appropriate scan commands to firmware to populate or
  * update the internal driver scan table.
  */
-static int mwifiex_scan_networks(struct mwifiex_private *priv,
-               const struct mwifiex_user_scan_cfg *user_scan_in)
+int mwifiex_scan_networks(struct mwifiex_private *priv,
+                         const struct mwifiex_user_scan_cfg *user_scan_in)
 {
        int ret = 0;
        struct mwifiex_adapter *adapter = priv->adapter;
@@ -1362,6 +1362,7 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
                        adapter->cmd_queued = cmd_node;
                        mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
                                                        true);
+                       queue_work(adapter->workqueue, &adapter->main_work);
                } else {
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
@@ -1377,26 +1378,6 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
        return ret;
 }
 
-/*
- * Sends IOCTL request to start a scan with user configurations.
- *
- * This function allocates the IOCTL request buffer, fills it
- * with requisite parameters and calls the IOCTL handler.
- *
- * Upon completion, it also generates a wireless event to notify
- * applications.
- */
-int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
-                               struct mwifiex_user_scan_cfg *scan_req)
-{
-       int status;
-
-       status = mwifiex_scan_networks(priv, scan_req);
-       queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
-
-       return status;
-}
-
 /*
  * This function prepares a scan command to be sent to the firmware.
  *
index 106c449477b2924029942b9b3863b312b527d24c..f2fd2423214f1375da61e0449a3fcd94e5cfaeef 100644 (file)
@@ -66,9 +66,6 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
        dev_dbg(adapter->dev, "cmd pending\n");
        atomic_inc(&adapter->cmd_pending);
 
-       /* Status pending, wake up main process */
-       queue_work(adapter->workqueue, &adapter->main_work);
-
        /* Wait for completion */
        wait_event_interruptible(adapter->cmd_wait_q.wait,
                                 *(cmd_queued->condition));