]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
mwifiex: improve scan delay logic during Tx traffic
authorAmitkumar Karwar <akarwar@marvell.com>
Sat, 4 Aug 2012 01:06:04 +0000 (18:06 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 6 Aug 2012 19:12:50 +0000 (15:12 -0400)
Earlier scan command was postponed by 20msec multiple times to give
preference to Tx traffic until we find empty wmm queue.

There is a corner case in which wmm queue becomes empty immediately
after processing the packet(before 20msec) and there may be next
packet coming after some time. In this case we should not resume scan
operation.

We will use new flag to check Tx traffic and resume scan operation
only if there is no traffic for 200msec.

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>
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h

index 21fdc6c02775b4f9b119afbab1de01420062c28f..81fc8ed0e9764e57824c0a6352b1f42db5b22220 100644 (file)
@@ -64,60 +64,72 @@ static void scan_delay_timer_fn(unsigned long data)
        struct cmd_ctrl_node *cmd_node, *tmp_node;
        unsigned long flags;
 
-       if (!mwifiex_wmm_lists_empty(adapter)) {
-               if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
+       if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
+               /*
+                * Abort scan operation by cancelling all pending scan
+                * commands
+                */
+               spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+               list_for_each_entry_safe(cmd_node, tmp_node,
+                                        &adapter->scan_pending_q, list) {
+                       list_del(&cmd_node->list);
+                       cmd_node->wait_q_enabled = false;
+                       mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+               }
+               spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+               spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+               adapter->scan_processing = false;
+               adapter->scan_delay_cnt = 0;
+               adapter->empty_tx_q_cnt = 0;
+               spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+               if (priv->user_scan_cfg) {
+                       dev_dbg(priv->adapter->dev,
+                               "info: %s: scan aborted\n", __func__);
+                       cfg80211_scan_done(priv->scan_request, 1);
+                       priv->scan_request = NULL;
+                       kfree(priv->user_scan_cfg);
+                       priv->user_scan_cfg = NULL;
+               }
+               goto done;
+       }
+
+       if (!atomic_read(&priv->adapter->is_tx_received)) {
+               adapter->empty_tx_q_cnt++;
+               if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) {
                        /*
-                        * Abort scan operation by cancelling all pending scan
-                        * command
+                        * No Tx traffic for 200msec. Get scan command from
+                        * scan pending queue and put to cmd pending queue to
+                        * resume scan operation
                         */
+                       adapter->scan_delay_cnt = 0;
+                       adapter->empty_tx_q_cnt = 0;
                        spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-                       list_for_each_entry_safe(cmd_node, tmp_node,
-                                                &adapter->scan_pending_q,
-                                                list) {
-                               list_del(&cmd_node->list);
-                               cmd_node->wait_q_enabled = false;
-                               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-                       }
+                       cmd_node = list_first_entry(&adapter->scan_pending_q,
+                                                   struct cmd_ctrl_node, list);
+                       list_del(&cmd_node->list);
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
 
-                       spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
-                       adapter->scan_processing = false;
-                       spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock,
-                                              flags);
-
-                       if (priv->user_scan_cfg) {
-                               dev_dbg(priv->adapter->dev,
-                                       "info: %s: scan aborted\n", __func__);
-                               cfg80211_scan_done(priv->scan_request, 1);
-                               priv->scan_request = NULL;
-                               kfree(priv->user_scan_cfg);
-                               priv->user_scan_cfg = NULL;
-                       }
-               } else {
-                       /*
-                        * Tx data queue is still not empty, delay scan
-                        * operation further by 20msec.
-                        */
-                       mod_timer(&priv->scan_delay_timer, jiffies +
-                                 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
-                       adapter->scan_delay_cnt++;
+                       mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
+                                                       true);
+                       goto done;
                }
-               queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
        } else {
-               /*
-                * Tx data queue is empty. Get scan command from scan_pending_q
-                * and put to cmd_pending_q to resume scan operation
-                */
-               adapter->scan_delay_cnt = 0;
-               spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-               cmd_node = list_first_entry(&adapter->scan_pending_q,
-                                           struct cmd_ctrl_node, list);
-               list_del(&cmd_node->list);
-               spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
-
-               mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
+               adapter->empty_tx_q_cnt = 0;
        }
+
+       /* Delay scan operation further by 20msec */
+       mod_timer(&priv->scan_delay_timer, jiffies +
+                 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
+       adapter->scan_delay_cnt++;
+
+done:
+       if (atomic_read(&priv->adapter->is_tx_received))
+               atomic_set(&priv->adapter->is_tx_received, false);
+
+       return;
 }
 
 /*
@@ -345,6 +357,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
        memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
        adapter->arp_filter_size = 0;
        adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
+       adapter->empty_tx_q_cnt = 0;
 }
 
 /*
index 46803621d01511dad87b91b59ef2b6fb8a38a9ef..cb1155286e0fb65ace438688de95938039144367 100644 (file)
@@ -520,6 +520,9 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        mwifiex_wmm_add_buf_txqueue(priv, skb);
        atomic_inc(&priv->adapter->tx_pending);
 
+       if (priv->adapter->scan_delay_cnt)
+               atomic_set(&priv->adapter->is_tx_received, true);
+
        if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
                mwifiex_set_trans_start(dev);
                mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
index e7c2a82fd6106481d63d7beb9df0388d1a0798c2..16f046a556b5468ab9729ebf471c0108d1b66206 100644 (file)
@@ -88,6 +88,7 @@ enum {
 #define MWIFIEX_MAX_TOTAL_SCAN_TIME    (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)
 
 #define MWIFIEX_MAX_SCAN_DELAY_CNT                     50
+#define MWIFIEX_MAX_EMPTY_TX_Q_CNT                     10
 #define MWIFIEX_SCAN_DELAY_MSEC                                20
 
 #define RSN_GTK_OUI_OFFSET                             2
@@ -690,6 +691,8 @@ struct mwifiex_adapter {
        u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
        u16 max_mgmt_ie_index;
        u8 scan_delay_cnt;
+       u8 empty_tx_q_cnt;
+       atomic_t is_tx_received;
 };
 
 int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);