mwifiex: fix command timeout problem seen in stress tests
authorXinming Hu <huxm@marvell.com>
Wed, 28 Sep 2016 12:48:27 +0000 (18:18 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 9 Nov 2016 01:33:27 +0000 (03:33 +0200)
It is observed that if single tid 6 packet comes among with massive tid 0
packets, tid 6 packet may stay in it's queue and will never be
transmited. This is because wmm.highest_queued_prio will be set to 2
during transmission of tid 0 packets As a result, main work thread
keeps on looping without serving that packet. In this case, if command
has downloaded to firmware, driver doesn't process it's response causing
command timeout.

This patch will reset highest_queued_prio if packets exist in data
queue, and try to find a ra_list for current private.

Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/marvell/mwifiex/main.h
drivers/net/wireless/marvell/mwifiex/wmm.c

index 26df28f4bfb290a36f30c33097f10a3bf12257a4..d61fe3a721183764223aa9dca3b565dbaad0bedc 100644 (file)
@@ -315,6 +315,7 @@ struct mwifiex_tid_tbl {
 #define WMM_HIGHEST_PRIORITY           7
 #define HIGH_PRIO_TID                          7
 #define LOW_PRIO_TID                           0
+#define NO_PKT_PRIO_TID                                -1
 #define MWIFIEX_WMM_DRV_DELAY_MAX 510
 
 struct mwifiex_wmm_desc {
index 1ff3a87d5784a92f4b4dbd6eb287d3599255c9ca..28c2f6fae3e644d0787f8a1f9117e7e867f04e2b 100644 (file)
@@ -1105,6 +1105,7 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
                                    &adapter->bss_prio_tbl[j].bss_prio_head,
                                    list) {
 
+try_again:
                        priv_tmp = adapter->bss_prio_tbl[j].bss_prio_cur->priv;
 
                        if (((priv_tmp->bss_mode != NL80211_IFTYPE_ADHOC) &&
@@ -1140,8 +1141,18 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
                                                       ra_list_spinlock,
                                                       flags_ra);
                        }
-               }
 
+                       if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) != 0) {
+                               atomic_set(&priv_tmp->wmm.highest_queued_prio,
+                                          HIGH_PRIO_TID);
+                               /* Iterate current private once more, since
+                                * there still exist packets in data queue
+                                */
+                               goto try_again;
+                       } else
+                               atomic_set(&priv_tmp->wmm.highest_queued_prio,
+                                          NO_PKT_PRIO_TID);
+               }
        }
 
        return NULL;