#else
static bool ixgb_clean_rx_irq(struct ixgb_adapter *);
#endif
-static void ixgb_alloc_rx_buffers(struct ixgb_adapter *);
+static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int);
static void ixgb_tx_timeout(struct net_device *dev);
static void ixgb_tx_timeout_task(struct work_struct *work);
ixgb_configure_tx(adapter);
ixgb_setup_rctl(adapter);
ixgb_configure_rx(adapter);
- ixgb_alloc_rx_buffers(adapter);
+ ixgb_alloc_rx_buffers(adapter, IXGB_DESC_UNUSED(&adapter->rx_ring));
/* disable interrupts and get the hardware into a known state */
IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
u32 length;
unsigned int i, j;
+ int cleaned_count = 0;
bool cleaned = false;
i = rx_ring->next_to_clean;
buffer_info = &rx_ring->buffer_info[i];
while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
- struct sk_buff *skb, *next_skb;
+ struct sk_buff *skb;
u8 status;
#ifdef CONFIG_IXGB_NAPI
skb = buffer_info->skb;
buffer_info->skb = NULL;
- prefetch(skb->data);
+ prefetch(skb->data - NET_IP_ALIGN);
if (++i == rx_ring->count) i = 0;
next_rxd = IXGB_RX_DESC(*rx_ring, i);
prefetch(next2_buffer);
next_buffer = &rx_ring->buffer_info[i];
- next_skb = next_buffer->skb;
- prefetch(next_skb);
cleaned = true;
+ cleaned_count++;
pci_unmap_single(pdev,
buffer_info->dma,
buffer_info->length,
PCI_DMA_FROMDEVICE);
+ buffer_info->dma = 0;
length = le16_to_cpu(rx_desc->length);
+ rx_desc->length = 0;
if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) {
/* clean up descriptor, might be written over by hw */
rx_desc->status = 0;
+ /* return some buffers to hardware, one at a time is too slow */
+ if (unlikely(cleaned_count >= IXGB_RX_BUFFER_WRITE)) {
+ ixgb_alloc_rx_buffers(adapter, cleaned_count);
+ cleaned_count = 0;
+ }
+
/* use prefetched values */
rx_desc = next_rxd;
buffer_info = next_buffer;
rx_ring->next_to_clean = i;
- ixgb_alloc_rx_buffers(adapter);
+ cleaned_count = IXGB_DESC_UNUSED(rx_ring);
+ if (cleaned_count)
+ ixgb_alloc_rx_buffers(adapter, cleaned_count);
return cleaned;
}
**/
static void
-ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
+ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count)
{
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
/* leave three descriptors unused */
- while (--cleancount > 2) {
+ while (--cleancount > 2 && cleaned_count--) {
/* recycle! its good for you */
skb = buffer_info->skb;
if (skb) {