Commit 86c3d59f authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Jeff Garzik

[PATCH] e1000: fix receive breakage

in attempting to not send the "prefetch" patch, we broke the receive code,
this patch fixes that issue.
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarJohn Ronciak <john.ronciak@intel.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 73629bbc
...@@ -88,8 +88,6 @@ ...@@ -88,8 +88,6 @@
* sessions are active and log a message * sessions are active and log a message
* 6.2.2 7/21/05 * 6.2.2 7/21/05
* o used fixed size descriptors for all MTU sizes, reduces memory load * o used fixed size descriptors for all MTU sizes, reduces memory load
* 6.2.1 7/21/05
* o Performance tweaks, including copybreak and prefetch
* 6.1.2 4/13/05 * 6.1.2 4/13/05
* o Fixed ethtool diagnostics * o Fixed ethtool diagnostics
* o Enabled flow control to take default eeprom settings * o Enabled flow control to take default eeprom settings
...@@ -3615,8 +3613,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, ...@@ -3615,8 +3613,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct e1000_rx_desc *rx_desc; struct e1000_rx_desc *rx_desc, *next_rxd;
struct e1000_buffer *buffer_info; struct e1000_buffer *buffer_info, *next_buffer;
unsigned long flags; unsigned long flags;
uint32_t length; uint32_t length;
uint8_t last_byte; uint8_t last_byte;
...@@ -3629,7 +3627,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, ...@@ -3629,7 +3627,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
buffer_info = &rx_ring->buffer_info[i]; buffer_info = &rx_ring->buffer_info[i];
while (rx_desc->status & E1000_RXD_STAT_DD) { while (rx_desc->status & E1000_RXD_STAT_DD) {
struct sk_buff *skb; struct sk_buff *skb, *next_skb;
u8 status; u8 status;
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
if (*work_done >= work_to_do) if (*work_done >= work_to_do)
...@@ -3638,6 +3636,13 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, ...@@ -3638,6 +3636,13 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
#endif #endif
status = rx_desc->status; status = rx_desc->status;
skb = buffer_info->skb; skb = buffer_info->skb;
buffer_info->skb = NULL;
if (++i == rx_ring->count) i = 0;
next_rxd = E1000_RX_DESC(*rx_ring, i);
next_buffer = &rx_ring->buffer_info[i];
next_skb = next_buffer->skb;
cleaned = TRUE; cleaned = TRUE;
cleaned_count++; cleaned_count++;
pci_unmap_single(pdev, pci_unmap_single(pdev,
...@@ -3769,6 +3774,8 @@ next_desc: ...@@ -3769,6 +3774,8 @@ next_desc:
cleaned_count = 0; cleaned_count = 0;
} }
rx_desc = next_rxd;
buffer_info = next_buffer;
} }
rx_ring->next_to_clean = i; rx_ring->next_to_clean = i;
...@@ -3794,13 +3801,13 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, ...@@ -3794,13 +3801,13 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring) struct e1000_rx_ring *rx_ring)
#endif #endif
{ {
union e1000_rx_desc_packet_split *rx_desc; union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct e1000_buffer *buffer_info; struct e1000_buffer *buffer_info, *next_buffer;
struct e1000_ps_page *ps_page; struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma; struct e1000_ps_page_dma *ps_page_dma;
struct sk_buff *skb; struct sk_buff *skb, *next_skb;
unsigned int i, j; unsigned int i, j;
uint32_t length, staterr; uint32_t length, staterr;
int cleaned_count = 0; int cleaned_count = 0;
...@@ -3809,9 +3816,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, ...@@ -3809,9 +3816,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
i = rx_ring->next_to_clean; i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC_PS(*rx_ring, i); rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.middle.status_error); staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
buffer_info = &rx_ring->buffer_info[i];
while (staterr & E1000_RXD_STAT_DD) { while (staterr & E1000_RXD_STAT_DD) {
buffer_info = &rx_ring->buffer_info[i];
ps_page = &rx_ring->ps_page[i]; ps_page = &rx_ring->ps_page[i];
ps_page_dma = &rx_ring->ps_page_dma[i]; ps_page_dma = &rx_ring->ps_page_dma[i];
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
...@@ -3819,14 +3826,19 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, ...@@ -3819,14 +3826,19 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
break; break;
(*work_done)++; (*work_done)++;
#endif #endif
skb = buffer_info->skb;
if (++i == rx_ring->count) i = 0;
next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
next_buffer = &rx_ring->buffer_info[i];
next_skb = next_buffer->skb;
cleaned = TRUE; cleaned = TRUE;
cleaned_count++; cleaned_count++;
pci_unmap_single(pdev, buffer_info->dma, pci_unmap_single(pdev, buffer_info->dma,
buffer_info->length, buffer_info->length,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
skb = buffer_info->skb;
if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) { if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
E1000_DBG("%s: Packet Split buffers didn't pick up" E1000_DBG("%s: Packet Split buffers didn't pick up"
" the full packet\n", netdev->name); " the full packet\n", netdev->name);
...@@ -3908,6 +3920,9 @@ next_desc: ...@@ -3908,6 +3920,9 @@ next_desc:
cleaned_count = 0; cleaned_count = 0;
} }
rx_desc = next_rxd;
buffer_info = next_buffer;
staterr = le32_to_cpu(rx_desc->wb.middle.status_error); staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
} }
rx_ring->next_to_clean = i; rx_ring->next_to_clean = i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment