mwifiex: more_task flag for main_process
authorShengzhen Li <szli@marvell.com>
Wed, 11 Feb 2015 17:42:24 +0000 (23:12 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 27 Feb 2015 08:08:40 +0000 (10:08 +0200)
This patch handles a corner case where TX packet would remain in
driver queue till next packet comes in.
Here is sequence:
1. TX packet is queued via hard_start_xmit and main_work is queued
2. SDIO interrupt comes in which directly call mwifiex_main_process.
This starts executing main superloop.
3. Now work from step1 is scheduled but at first check itself it sees
mwifiex_processing is set and exits.
4. Now if superloop from step2 has passed TX processing part of superloop
this packet would remain in queue until next packet/command/SDIO interrupt
arrives and queues main_work.

This patch fixes this corner case by defining more_task flag which is set when
mwifiex_processing is found to be true. At end of superloop we again check if
more_task flag is set and if set, execute superloop again.

Signed-off-by: Shengzhen Li <szli@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h

index 7e74b4fccddd56e67eb8b28453553e4083eec895..74488aba92bdec159df217c47ae08c990161e847 100644 (file)
@@ -190,14 +190,16 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
 
        /* Check if already processing */
        if (adapter->mwifiex_processing) {
+               adapter->more_task_flag = true;
                spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
                goto exit_main_proc;
        } else {
                adapter->mwifiex_processing = true;
-               spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
        }
 process_start:
        do {
+               adapter->more_task_flag = false;
+               spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
                if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
                    (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
                        break;
@@ -238,6 +240,7 @@ process_start:
                        adapter->pm_wakeup_fw_try = true;
                        mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
                        adapter->if_ops.wakeup(adapter);
+                       spin_lock_irqsave(&adapter->main_proc_lock, flags);
                        continue;
                }
 
@@ -295,8 +298,10 @@ process_start:
                if ((adapter->ps_state == PS_STATE_SLEEP) ||
                    (adapter->ps_state == PS_STATE_PRE_SLEEP) ||
                    (adapter->ps_state == PS_STATE_SLEEP_CFM) ||
-                   adapter->tx_lock_flag)
+                   adapter->tx_lock_flag){
+                       spin_lock_irqsave(&adapter->main_proc_lock, flags);
                        continue;
+               }
 
                if (!adapter->cmd_sent && !adapter->curr_cmd) {
                        if (mwifiex_exec_next_cmd(adapter) == -1) {
@@ -330,15 +335,12 @@ process_start:
                        }
                        break;
                }
+               spin_lock_irqsave(&adapter->main_proc_lock, flags);
        } while (true);
 
        spin_lock_irqsave(&adapter->main_proc_lock, flags);
-       if (!adapter->delay_main_work &&
-           (adapter->int_status || IS_CARD_RX_RCVD(adapter))) {
-               spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+       if (adapter->more_task_flag)
                goto process_start;
-       }
-
        adapter->mwifiex_processing = false;
        spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
 
index f0a6af179af03ba2ba2497c6a296f5f450b18463..2089a30840435acce5ec41209da78242da869cf2 100644 (file)
@@ -774,6 +774,7 @@ struct mwifiex_adapter {
        /* spin lock for main process */
        spinlock_t main_proc_lock;
        u32 mwifiex_processing;
+       u8 more_task_flag;
        u16 tx_buf_size;
        u16 curr_tx_buf_size;
        u32 ioport;