|
@@ -666,7 +666,8 @@ tx_status_ok:
|
|
}
|
|
}
|
|
|
|
|
|
static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
|
|
static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
|
|
- u8 *entry, int rxring_idx, int desc_idx)
|
|
|
|
|
|
+ struct sk_buff *new_skb, u8 *entry,
|
|
|
|
+ int rxring_idx, int desc_idx)
|
|
{
|
|
{
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
|
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
|
@@ -674,11 +675,15 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
|
|
u8 tmp_one = 1;
|
|
u8 tmp_one = 1;
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
|
|
|
|
|
|
+ if (likely(new_skb)) {
|
|
|
|
+ skb = new_skb;
|
|
|
|
+ goto remap;
|
|
|
|
+ }
|
|
skb = dev_alloc_skb(rtlpci->rxbuffersize);
|
|
skb = dev_alloc_skb(rtlpci->rxbuffersize);
|
|
if (!skb)
|
|
if (!skb)
|
|
return 0;
|
|
return 0;
|
|
- rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
|
|
|
|
|
|
|
|
|
|
+remap:
|
|
/* just set skb->cb to mapping addr for pci_unmap_single use */
|
|
/* just set skb->cb to mapping addr for pci_unmap_single use */
|
|
*((dma_addr_t *)skb->cb) =
|
|
*((dma_addr_t *)skb->cb) =
|
|
pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
|
|
pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
|
|
@@ -686,6 +691,7 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
|
|
bufferaddress = *((dma_addr_t *)skb->cb);
|
|
bufferaddress = *((dma_addr_t *)skb->cb);
|
|
if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
|
|
if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
|
|
return 0;
|
|
return 0;
|
|
|
|
+ rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
|
|
rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
|
|
HW_DESC_RX_PREPARE,
|
|
HW_DESC_RX_PREPARE,
|
|
@@ -781,6 +787,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
|
/*rx pkt */
|
|
/*rx pkt */
|
|
struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[
|
|
struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[
|
|
rtlpci->rx_ring[rxring_idx].idx];
|
|
rtlpci->rx_ring[rxring_idx].idx];
|
|
|
|
+ struct sk_buff *new_skb;
|
|
|
|
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
rx_remained_cnt =
|
|
rx_remained_cnt =
|
|
@@ -807,6 +814,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
|
pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb),
|
|
pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb),
|
|
rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
|
|
rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
|
|
|
|
|
|
|
|
+ /* get a new skb - if fail, old one will be reused */
|
|
|
|
+ new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
|
|
|
|
+ if (unlikely(!new_skb)) {
|
|
|
|
+ pr_err("Allocation of new skb failed in %s\n",
|
|
|
|
+ __func__);
|
|
|
|
+ goto no_new;
|
|
|
|
+ }
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
buffer_desc =
|
|
buffer_desc =
|
|
&rtlpci->rx_ring[rxring_idx].buffer_desc
|
|
&rtlpci->rx_ring[rxring_idx].buffer_desc
|
|
@@ -911,14 +925,16 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
|
schedule_work(&rtlpriv->works.lps_change_work);
|
|
schedule_work(&rtlpriv->works.lps_change_work);
|
|
}
|
|
}
|
|
end:
|
|
end:
|
|
|
|
+ skb = new_skb;
|
|
|
|
+no_new:
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
if (rtlpriv->use_new_trx_flow) {
|
|
- _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc,
|
|
|
|
|
|
+ _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc,
|
|
rxring_idx,
|
|
rxring_idx,
|
|
- rtlpci->rx_ring[rxring_idx].idx);
|
|
|
|
|
|
+ rtlpci->rx_ring[rxring_idx].idx);
|
|
} else {
|
|
} else {
|
|
- _rtl_pci_init_one_rxdesc(hw, (u8 *)pdesc, rxring_idx,
|
|
|
|
|
|
+ _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc,
|
|
|
|
+ rxring_idx,
|
|
rtlpci->rx_ring[rxring_idx].idx);
|
|
rtlpci->rx_ring[rxring_idx].idx);
|
|
-
|
|
|
|
if (rtlpci->rx_ring[rxring_idx].idx ==
|
|
if (rtlpci->rx_ring[rxring_idx].idx ==
|
|
rtlpci->rxringcount - 1)
|
|
rtlpci->rxringcount - 1)
|
|
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc,
|
|
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc,
|
|
@@ -1307,7 +1323,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
|
|
rtlpci->rx_ring[rxring_idx].idx = 0;
|
|
rtlpci->rx_ring[rxring_idx].idx = 0;
|
|
for (i = 0; i < rtlpci->rxringcount; i++) {
|
|
for (i = 0; i < rtlpci->rxringcount; i++) {
|
|
entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i];
|
|
entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i];
|
|
- if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry,
|
|
|
|
|
|
+ if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
|
|
rxring_idx, i))
|
|
rxring_idx, i))
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
@@ -1332,7 +1348,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
|
|
|
|
|
|
for (i = 0; i < rtlpci->rxringcount; i++) {
|
|
for (i = 0; i < rtlpci->rxringcount; i++) {
|
|
entry = &rtlpci->rx_ring[rxring_idx].desc[i];
|
|
entry = &rtlpci->rx_ring[rxring_idx].desc[i];
|
|
- if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry,
|
|
|
|
|
|
+ if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
|
|
rxring_idx, i))
|
|
rxring_idx, i))
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|