diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2011-02-03 06:02:36 -0500 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2011-02-04 04:38:10 -0500 |
commit | 1519e57fe81c14bb8fa4855579f19264d1ef63b4 (patch) | |
tree | 4a0323c2060dcc31ae3e75b98c665f49476c1368 /drivers/net/r8169.c | |
parent | b5ba6d12bdac21bc0620a5089e0f24e362645efd (diff) |
r8169: RxFIFO overflow oddities with 8168 chipsets.
Some experiment-based action to prevent my 8168 chipsets locking-up hard
in the irq handler under load (pktgen ~1Mpps). Apparently a reset is not
always mandatory (is it at all ?).
- RTL_GIGA_MAC_VER_12
- RTL_GIGA_MAC_VER_25
Missed ~55% packets. Note:
- this is an old SiS 965L motherboard
- the 8168 chipset emits (lots of) control frames towards the sender
- RTL_GIGA_MAC_VER_26
The chipset does not go into a frenzy of mac control pause when it
crashes yet but it can still be crashed. It needs more work.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Ivan Vecera <ivecera@redhat.com>
Cc: Hayes <hayeswang@realtek.com>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 9ab3b43c7d04..40dabe2b3dae 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -973,7 +973,8 @@ static void __rtl8169_check_link_status(struct net_device *dev, | |||
973 | if (pm) | 973 | if (pm) |
974 | pm_request_resume(&tp->pci_dev->dev); | 974 | pm_request_resume(&tp->pci_dev->dev); |
975 | netif_carrier_on(dev); | 975 | netif_carrier_on(dev); |
976 | netif_info(tp, ifup, dev, "link up\n"); | 976 | if (net_ratelimit()) |
977 | netif_info(tp, ifup, dev, "link up\n"); | ||
977 | } else { | 978 | } else { |
978 | netif_carrier_off(dev); | 979 | netif_carrier_off(dev); |
979 | netif_info(tp, ifdown, dev, "link down\n"); | 980 | netif_info(tp, ifdown, dev, "link down\n"); |
@@ -4640,13 +4641,24 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
4640 | break; | 4641 | break; |
4641 | } | 4642 | } |
4642 | 4643 | ||
4643 | /* Work around for rx fifo overflow */ | 4644 | if (unlikely(status & RxFIFOOver)) { |
4644 | if (unlikely(status & RxFIFOOver) && | 4645 | switch (tp->mac_version) { |
4645 | (tp->mac_version == RTL_GIGA_MAC_VER_11 || | 4646 | /* Work around for rx fifo overflow */ |
4646 | tp->mac_version == RTL_GIGA_MAC_VER_22)) { | 4647 | case RTL_GIGA_MAC_VER_11: |
4647 | netif_stop_queue(dev); | 4648 | case RTL_GIGA_MAC_VER_22: |
4648 | rtl8169_tx_timeout(dev); | 4649 | case RTL_GIGA_MAC_VER_26: |
4649 | break; | 4650 | netif_stop_queue(dev); |
4651 | rtl8169_tx_timeout(dev); | ||
4652 | goto done; | ||
4653 | /* Experimental science. Pktgen proof. */ | ||
4654 | case RTL_GIGA_MAC_VER_12: | ||
4655 | case RTL_GIGA_MAC_VER_25: | ||
4656 | if (status == RxFIFOOver) | ||
4657 | goto done; | ||
4658 | break; | ||
4659 | default: | ||
4660 | break; | ||
4661 | } | ||
4650 | } | 4662 | } |
4651 | 4663 | ||
4652 | if (unlikely(status & SYSErr)) { | 4664 | if (unlikely(status & SYSErr)) { |
@@ -4682,7 +4694,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
4682 | (status & RxFIFOOver) ? (status | RxOverflow) : status); | 4694 | (status & RxFIFOOver) ? (status | RxOverflow) : status); |
4683 | status = RTL_R16(IntrStatus); | 4695 | status = RTL_R16(IntrStatus); |
4684 | } | 4696 | } |
4685 | 4697 | done: | |
4686 | return IRQ_RETVAL(handled); | 4698 | return IRQ_RETVAL(handled); |
4687 | } | 4699 | } |
4688 | 4700 | ||