|
|
@@ -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));
|
|
|
@@ -786,7 +792,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 */
|
|
|
@@ -834,18 +840,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;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -895,6 +901,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 %=
|
|
|
@@ -910,7 +917,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
|
|
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,
|
|
|
@@ -1672,6 +1678,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) {
|