]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mwifiex: fix race condition causing tx timeout
authorCathy Luo <cluo@marvell.com>
Tue, 20 Sep 2016 15:19:03 +0000 (20:49 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 26 Sep 2016 17:39:42 +0000 (20:39 +0300)
It's been observed that in a corner case mwifiex_usb_tx_complete()
gets called before we exit from mwifiex_usb_host_to_card() after
submitting the urb. 'data_sent' flag remains set in this case. It
blocks further Tx packets and triggers watchdog timeout.

The problem is fixed by setting data_sent and port_block flag at
correct place.

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

index e8283dc1f0882b99af69797218aee601f7cea21d..8fd51e42ea5e5a1b4d9165b21df1e584b7442515 100644 (file)
@@ -897,6 +897,13 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
        else
                atomic_inc(&port->tx_data_urb_pending);
 
+       if (ep != card->tx_cmd_ep &&
+           atomic_read(&port->tx_data_urb_pending) ==
+                                       MWIFIEX_TX_DATA_URB) {
+               port->block_status = true;
+               adapter->data_sent = mwifiex_usb_data_sent(adapter);
+       }
+
        if (usb_submit_urb(tx_urb, GFP_ATOMIC)) {
                mwifiex_dbg(adapter, ERROR,
                            "%s: usb_submit_urb failed\n", __func__);
@@ -905,6 +912,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
                } else {
                        atomic_dec(&port->tx_data_urb_pending);
                        port->block_status = false;
+                       adapter->data_sent = false;
                        if (port->tx_data_ix)
                                port->tx_data_ix--;
                        else
@@ -916,9 +924,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
                if (ep != card->tx_cmd_ep &&
                    atomic_read(&port->tx_data_urb_pending) ==
                                                        MWIFIEX_TX_DATA_URB) {
-                       port->block_status = true;
-                       ret = -ENOSR;
-                       goto done;
+                       return -ENOSR;
                }
        }