aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2012-08-03 21:06:04 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-08-06 15:12:50 -0400
commitbdd37bed619b2445b2a04f398a7fe34b1e416172 (patch)
tree4e364ca35c6a701923a84da3cbbc67fcbb84ba1d /drivers/net/wireless
parentb7525dbd075414ab2dc3742bacdc386f0f1223b2 (diff)
mwifiex: improve scan delay logic during Tx traffic
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>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/mwifiex/init.c103
-rw-r--r--drivers/net/wireless/mwifiex/main.c3
-rw-r--r--drivers/net/wireless/mwifiex/main.h3
3 files changed, 64 insertions, 45 deletions
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 21fdc6c02775..81fc8ed0e976 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -64,60 +64,72 @@ static void scan_delay_timer_fn(unsigned long data)
64 struct cmd_ctrl_node *cmd_node, *tmp_node; 64 struct cmd_ctrl_node *cmd_node, *tmp_node;
65 unsigned long flags; 65 unsigned long flags;
66 66
67 if (!mwifiex_wmm_lists_empty(adapter)) { 67 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
68 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { 68 /*
69 * Abort scan operation by cancelling all pending scan
70 * commands
71 */
72 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
73 list_for_each_entry_safe(cmd_node, tmp_node,
74 &adapter->scan_pending_q, list) {
75 list_del(&cmd_node->list);
76 cmd_node->wait_q_enabled = false;
77 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
78 }
79 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
80
81 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
82 adapter->scan_processing = false;
83 adapter->scan_delay_cnt = 0;
84 adapter->empty_tx_q_cnt = 0;
85 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
86
87 if (priv->user_scan_cfg) {
88 dev_dbg(priv->adapter->dev,
89 "info: %s: scan aborted\n", __func__);
90 cfg80211_scan_done(priv->scan_request, 1);
91 priv->scan_request = NULL;
92 kfree(priv->user_scan_cfg);
93 priv->user_scan_cfg = NULL;
94 }
95 goto done;
96 }
97
98 if (!atomic_read(&priv->adapter->is_tx_received)) {
99 adapter->empty_tx_q_cnt++;
100 if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) {
69 /* 101 /*
70 * Abort scan operation by cancelling all pending scan 102 * No Tx traffic for 200msec. Get scan command from
71 * command 103 * scan pending queue and put to cmd pending queue to
104 * resume scan operation
72 */ 105 */
106 adapter->scan_delay_cnt = 0;
107 adapter->empty_tx_q_cnt = 0;
73 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 108 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
74 list_for_each_entry_safe(cmd_node, tmp_node, 109 cmd_node = list_first_entry(&adapter->scan_pending_q,
75 &adapter->scan_pending_q, 110 struct cmd_ctrl_node, list);
76 list) { 111 list_del(&cmd_node->list);
77 list_del(&cmd_node->list);
78 cmd_node->wait_q_enabled = false;
79 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
80 }
81 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 112 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
82 flags); 113 flags);
83 114
84 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 115 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
85 adapter->scan_processing = false; 116 true);
86 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, 117 goto done;
87 flags);
88
89 if (priv->user_scan_cfg) {
90 dev_dbg(priv->adapter->dev,
91 "info: %s: scan aborted\n", __func__);
92 cfg80211_scan_done(priv->scan_request, 1);
93 priv->scan_request = NULL;
94 kfree(priv->user_scan_cfg);
95 priv->user_scan_cfg = NULL;
96 }
97 } else {
98 /*
99 * Tx data queue is still not empty, delay scan
100 * operation further by 20msec.
101 */
102 mod_timer(&priv->scan_delay_timer, jiffies +
103 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
104 adapter->scan_delay_cnt++;
105 } 118 }
106 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
107 } else { 119 } else {
108 /* 120 adapter->empty_tx_q_cnt = 0;
109 * Tx data queue is empty. Get scan command from scan_pending_q
110 * and put to cmd_pending_q to resume scan operation
111 */
112 adapter->scan_delay_cnt = 0;
113 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
114 cmd_node = list_first_entry(&adapter->scan_pending_q,
115 struct cmd_ctrl_node, list);
116 list_del(&cmd_node->list);
117 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
118
119 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
120 } 121 }
122
123 /* Delay scan operation further by 20msec */
124 mod_timer(&priv->scan_delay_timer, jiffies +
125 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
126 adapter->scan_delay_cnt++;
127
128done:
129 if (atomic_read(&priv->adapter->is_tx_received))
130 atomic_set(&priv->adapter->is_tx_received, false);
131
132 return;
121} 133}
122 134
123/* 135/*
@@ -345,6 +357,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
345 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 357 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
346 adapter->arp_filter_size = 0; 358 adapter->arp_filter_size = 0;
347 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; 359 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
360 adapter->empty_tx_q_cnt = 0;
348} 361}
349 362
350/* 363/*
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 46803621d015..cb1155286e0f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -520,6 +520,9 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
520 mwifiex_wmm_add_buf_txqueue(priv, skb); 520 mwifiex_wmm_add_buf_txqueue(priv, skb);
521 atomic_inc(&priv->adapter->tx_pending); 521 atomic_inc(&priv->adapter->tx_pending);
522 522
523 if (priv->adapter->scan_delay_cnt)
524 atomic_set(&priv->adapter->is_tx_received, true);
525
523 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { 526 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
524 mwifiex_set_trans_start(dev); 527 mwifiex_set_trans_start(dev);
525 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); 528 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e7c2a82fd610..16f046a556b5 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -88,6 +88,7 @@ enum {
88#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) 88#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)
89 89
90#define MWIFIEX_MAX_SCAN_DELAY_CNT 50 90#define MWIFIEX_MAX_SCAN_DELAY_CNT 50
91#define MWIFIEX_MAX_EMPTY_TX_Q_CNT 10
91#define MWIFIEX_SCAN_DELAY_MSEC 20 92#define MWIFIEX_SCAN_DELAY_MSEC 20
92 93
93#define RSN_GTK_OUI_OFFSET 2 94#define RSN_GTK_OUI_OFFSET 2
@@ -690,6 +691,8 @@ struct mwifiex_adapter {
690 u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; 691 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
691 u16 max_mgmt_ie_index; 692 u16 max_mgmt_ie_index;
692 u8 scan_delay_cnt; 693 u8 scan_delay_cnt;
694 u8 empty_tx_q_cnt;
695 atomic_t is_tx_received;
693}; 696};
694 697
695int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 698int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);