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;
 
                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));
                        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 */
                        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;
                }
 
                /*
                } 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 %=
                        rtlpriv->enter_ps = false;
                        schedule_work(&rtlpriv->works.lps_change_work);
                }
-end:
                if (rtlpriv->use_new_trx_flow) {
                        _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc,
                                                 rxring_idx,
                }
        }
 
+       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) {
 
        return desc_address;
 }
 
+u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u16 point_diff = 0;
+       u16 current_tx_read_point = 0, current_tx_write_point = 0;
+       u32 tmp_4byte;
+
+       tmp_4byte = rtl_read_dword(rtlpriv,
+                                  get_desc_addr_fr_q_idx(q_idx));
+       current_tx_read_point = (u16)((tmp_4byte >> 16) & 0x0fff);
+       current_tx_write_point = (u16)((tmp_4byte) & 0x0fff);
+
+       point_diff = calc_fifo_space(current_tx_read_point,
+                                    current_tx_write_point);
+
+       rtlpci->tx_ring[q_idx].avl_desc = point_diff;
+       return point_diff;
+}
+
 void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw,
                                 u8 *tx_bd_desc, u8 *desc, u8 queue_index,
                                 struct sk_buff *skb, dma_addr_t addr)