diff options
author | Zhu Yi <yi.zhu@intel.com> | 2009-10-23 13:42:32 -0700 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-27 16:50:03 -0400 |
commit | 7300515d1095aa11731866da7c9b000f2edb4626 (patch) | |
tree | 1b01fe8ba04d476169f2da66951807b67f647091 /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | 71c55d90f9733abdf5e4e0bc24f71e189cefeea6 (diff) | |
download | lwn-7300515d1095aa11731866da7c9b000f2edb4626.tar.gz lwn-7300515d1095aa11731866da7c9b000f2edb4626.zip |
iwlwifi: reuse page for notification packets
For notification packets and SKBs that fail to rx correctly, add
them back into the rx_free list so that the pages can be reused
later. This avoids allocating new rx pages unnecessarily.
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0d3886505205..ea1b9315f17c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -769,7 +769,7 @@ void iwl_rx_handle(struct iwl_priv *priv) IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); /* calculate total frames need to be restock after handling RX */ - total_empty = r - priv->rxq.write_actual; + total_empty = r - rxq->write_actual; if (total_empty < 0) total_empty += RX_QUEUE_SIZE; @@ -841,25 +841,28 @@ void iwl_rx_handle(struct iwl_priv *priv) IWL_WARN(priv, "Claim null rxb?\n"); } - /* For now we just don't re-use anything. We can tweak this - * later to try and re-use notification packets and SKBs that - * fail to Rx correctly */ + /* Reuse the page if possible. For notification packets and + * SKBs that fail to Rx correctly, add them back into the + * rx_free list for reuse later. */ + spin_lock_irqsave(&rxq->lock, flags); if (rxb->page != NULL) { - priv->alloc_rxb_page--; - __free_pages(rxb->page, priv->hw_params.rx_page_order); - rxb->page = NULL; - } + rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, + 0, PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } else + list_add_tail(&rxb->list, &rxq->rx_used); - spin_lock_irqsave(&rxq->lock, flags); - list_add_tail(&rxb->list, &priv->rxq.rx_used); spin_unlock_irqrestore(&rxq->lock, flags); + i = (i + 1) & RX_QUEUE_MASK; /* If there are a lot of unused frames, * restock the Rx queue so ucode wont assert. */ if (fill_rx) { count++; if (count >= 8) { - priv->rxq.read = i; + rxq->read = i; iwl_rx_replenish_now(priv); count = 0; } @@ -867,7 +870,7 @@ void iwl_rx_handle(struct iwl_priv *priv) } /* Backtrack one entry */ - priv->rxq.read = i; + rxq->read = i; if (fill_rx) iwl_rx_replenish_now(priv); else |