aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-23 03:31:06 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-23 03:31:06 -0500
commit51c24aaacaea90c8e87f1dec75a2ac7622b593f8 (patch)
tree9f54936c87764bef75e97395cb56b7d1e0df24c6 /drivers/net/e1000
parent4276e47e2d1c85a2477caf0d22b91c4f2377fba8 (diff)
parent6be325719b3e54624397e413efd4b33a997e55a3 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'drivers/net/e1000')
-rw-r--r--drivers/net/e1000/e1000.h2
-rw-r--r--drivers/net/e1000/e1000_main.c23
2 files changed, 18 insertions, 7 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 2a567df3ea71..e8932db7ee77 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -326,6 +326,8 @@ struct e1000_adapter {
326 /* for ioport free */ 326 /* for ioport free */
327 int bars; 327 int bars;
328 int need_ioport; 328 int need_ioport;
329
330 bool discarding;
329}; 331};
330 332
331enum e1000_state_t { 333enum e1000_state_t {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 9ec7480be1d8..87f575ca427d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2802,13 +2802,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
2802dma_error: 2802dma_error:
2803 dev_err(&pdev->dev, "TX DMA map failed\n"); 2803 dev_err(&pdev->dev, "TX DMA map failed\n");
2804 buffer_info->dma = 0; 2804 buffer_info->dma = 0;
2805 count--; 2805 if (count)
2806
2807 while (count >= 0) {
2808 count--; 2806 count--;
2809 i--; 2807
2810 if (i < 0) 2808 while (count--) {
2809 if (i==0)
2811 i += tx_ring->count; 2810 i += tx_ring->count;
2811 i--;
2812 buffer_info = &tx_ring->buffer_info[i]; 2812 buffer_info = &tx_ring->buffer_info[i];
2813 e1000_unmap_and_free_tx_resource(adapter, buffer_info); 2813 e1000_unmap_and_free_tx_resource(adapter, buffer_info);
2814 } 2814 }
@@ -3850,13 +3850,22 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
3850 3850
3851 length = le16_to_cpu(rx_desc->length); 3851 length = le16_to_cpu(rx_desc->length);
3852 /* !EOP means multiple descriptors were used to store a single 3852 /* !EOP means multiple descriptors were used to store a single
3853 * packet, also make sure the frame isn't just CRC only */ 3853 * packet, if thats the case we need to toss it. In fact, we
3854 if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) { 3854 * to toss every packet with the EOP bit clear and the next
3855 * frame that _does_ have the EOP bit set, as it is by
3856 * definition only a frame fragment
3857 */
3858 if (unlikely(!(status & E1000_RXD_STAT_EOP)))
3859 adapter->discarding = true;
3860
3861 if (adapter->discarding) {
3855 /* All receives must fit into a single buffer */ 3862 /* All receives must fit into a single buffer */
3856 E1000_DBG("%s: Receive packet consumed multiple" 3863 E1000_DBG("%s: Receive packet consumed multiple"
3857 " buffers\n", netdev->name); 3864 " buffers\n", netdev->name);
3858 /* recycle */ 3865 /* recycle */
3859 buffer_info->skb = skb; 3866 buffer_info->skb = skb;
3867 if (status & E1000_RXD_STAT_EOP)
3868 adapter->discarding = false;
3860 goto next_desc; 3869 goto next_desc;
3861 } 3870 }
3862 3871