]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/rtlwifi/pci.c
Merge tag 'wireless-drivers-next-for-davem-2015-02-07' of git://git.kernel.org/pub...
[karo-tx-linux.git] / drivers / net / wireless / rtlwifi / pci.c
index c70efb9a6e78ccf22170bb8bbfe0abe89be695ef..ec456f0d972eb583f4f2bbfda84472680b2513f0 100644 (file)
@@ -578,6 +578,13 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
                else
                        entry = (u8 *)(&ring->desc[ring->idx]);
 
+               if (rtlpriv->cfg->ops->get_available_desc &&
+                   rtlpriv->cfg->ops->get_available_desc(hw, prio) <= 1) {
+                       RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_DMESG,
+                                "no available desc!\n");
+                       return;
+               }
+
                if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx))
                        return;
                ring->idx = (ring->idx + 1) % ring->entries;
@@ -641,10 +648,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
 
                ieee80211_tx_status_irqsafe(hw, skb);
 
-               if ((ring->entries - skb_queue_len(&ring->queue))
-                               == 2) {
+               if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) {
 
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
                                 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n",
                                 prio, ring->idx,
                                 skb_queue_len(&ring->queue));
@@ -793,7 +799,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                        rx_remained_cnt =
                                rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw,
                                                                      hw_queue);
-                       if (rx_remained_cnt < 1)
+                       if (rx_remained_cnt == 0)
                                return;
 
                } else {        /* rx descriptor */
@@ -848,18 +854,18 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                        else
                                skb_reserve(skb, stats.rx_drvinfo_size +
                                            stats.rx_bufshift);
-
                } else {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
                                 "skb->end - skb->tail = %d, len is %d\n",
                                 skb->end - skb->tail, len);
-                       break;
+                       dev_kfree_skb_any(skb);
+                       goto new_trx_end;
                }
                /* handle command packet here */
                if (rtlpriv->cfg->ops->rx_command_packet &&
                    rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) {
                                dev_kfree_skb_any(skb);
-                               goto end;
+                               goto new_trx_end;
                }
 
                /*
@@ -909,6 +915,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                } else {
                        dev_kfree_skb_any(skb);
                }
+new_trx_end:
                if (rtlpriv->use_new_trx_flow) {
                        rtlpci->rx_ring[hw_queue].next_rx_rp += 1;
                        rtlpci->rx_ring[hw_queue].next_rx_rp %=
@@ -924,7 +931,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                        rtlpriv->enter_ps = false;
                        schedule_work(&rtlpriv->works.lps_change_work);
                }
-end:
                skb = new_skb;
 no_new:
                if (rtlpriv->use_new_trx_flow) {
@@ -1688,6 +1694,15 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
                }
        }
 
+       if (rtlpriv->cfg->ops->get_available_desc &&
+           rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                                "get_available_desc fail\n");
+                       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
+                                              flags);
+                       return skb->len;
+       }
+
        if (ieee80211_is_data_qos(fc)) {
                tid = rtl_get_tid(skb);
                if (sta) {