Commit 1519e57f authored by Francois Romieu's avatar Francois Romieu

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: default avatarFrancois Romieu <romieu@fr.zoreil.com>
Cc: Ivan Vecera <ivecera@redhat.com>
Cc: Hayes <hayeswang@realtek.com>
parent b5ba6d12
...@@ -973,7 +973,8 @@ static void __rtl8169_check_link_status(struct net_device *dev, ...@@ -973,7 +973,8 @@ static void __rtl8169_check_link_status(struct net_device *dev,
if (pm) if (pm)
pm_request_resume(&tp->pci_dev->dev); pm_request_resume(&tp->pci_dev->dev);
netif_carrier_on(dev); netif_carrier_on(dev);
netif_info(tp, ifup, dev, "link up\n"); if (net_ratelimit())
netif_info(tp, ifup, dev, "link up\n");
} else { } else {
netif_carrier_off(dev); netif_carrier_off(dev);
netif_info(tp, ifdown, dev, "link down\n"); netif_info(tp, ifdown, dev, "link down\n");
...@@ -4640,13 +4641,24 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) ...@@ -4640,13 +4641,24 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
break; break;
} }
/* Work around for rx fifo overflow */ if (unlikely(status & RxFIFOOver)) {
if (unlikely(status & RxFIFOOver) && switch (tp->mac_version) {
(tp->mac_version == RTL_GIGA_MAC_VER_11 || /* Work around for rx fifo overflow */
tp->mac_version == RTL_GIGA_MAC_VER_22)) { case RTL_GIGA_MAC_VER_11:
netif_stop_queue(dev); case RTL_GIGA_MAC_VER_22:
rtl8169_tx_timeout(dev); case RTL_GIGA_MAC_VER_26:
break; netif_stop_queue(dev);
rtl8169_tx_timeout(dev);
goto done;
/* Experimental science. Pktgen proof. */
case RTL_GIGA_MAC_VER_12:
case RTL_GIGA_MAC_VER_25:
if (status == RxFIFOOver)
goto done;
break;
default:
break;
}
} }
if (unlikely(status & SYSErr)) { if (unlikely(status & SYSErr)) {
...@@ -4682,7 +4694,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) ...@@ -4682,7 +4694,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
(status & RxFIFOOver) ? (status | RxOverflow) : status); (status & RxFIFOOver) ? (status | RxOverflow) : status);
status = RTL_R16(IntrStatus); status = RTL_R16(IntrStatus);
} }
done:
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
......
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