The later versions of the driver > 4.3.15 all exhibit this behavior and
are extremely broken.
Jeff
On Wed, Nov 20, 2002 at 08:01:16PM +0100, Robert Olsson wrote:
>
>
> Two fixes the NAPI branch of e1000.
>
>
> 1) e1000_irq_disable was used to disable irqs which called synchronize_irq
> which in turn caused a solid hang on SMP systems.
>
> 2) Interrupt acking patch previously sent by DaveM.
>
> Cheers.
> --ro
>
>
>
> --- linux/drivers/net/e1000.vanilla/e1000.h 2002-11-13 12:54:49.000000000 +0100
> +++ linux/drivers/net/e1000/e1000.h 2002-11-20 15:00:14.000000000 +0100
> @@ -181,6 +181,10 @@
> uint32_t tx_abs_int_delay;
> int max_data_per_txd;
>
> +#ifdef CONFIG_E1000_NAPI
> + uint32_t icr_pending;
> +#endif
> +
> /* RX */
> struct e1000_desc_ring rx_ring;
> uint64_t hw_csum_err;
> --- linux/drivers/net/e1000.vanilla/e1000_main.c 2002-11-13 12:54:49.000000000 +0100
> +++ linux/drivers/net/e1000/e1000_main.c 2002-11-20 17:37:55.000000000 +0100
> @@ -1896,15 +1896,29 @@
> {
> struct net_device *netdev = data;
> struct e1000_adapter *adapter = netdev->priv;
> + uint32_t icr;
> + int i = E1000_MAX_INTR;
> +
>
> #ifdef CONFIG_E1000_NAPI
> - if (netif_rx_schedule_prep(netdev)) {
> - e1000_irq_disable(adapter);
> + icr = E1000_READ_REG(&adapter->hw, ICR);
> + if (icr && netif_rx_schedule_prep(netdev)) {
> +
> + /* Disable interrupts */
> + atomic_inc(&adapter->irq_sem);
> + E1000_WRITE_REG(&adapter->hw, IMC, ~0);
> +
> + /* E1000_WRITE_FLUSH(&adapter->hw);
> + * E1000_READ below syncs it --ro
> + */
> +
> __netif_rx_schedule(netdev);
> +
> + adapter->icr_pending = icr;
> + while (i-- && (icr = E1000_READ_REG(&adapter->hw, ICR)) != 0)
> + adapter->icr_pending |= icr;
> }
> #else
> - uint32_t icr;
> - int i = E1000_MAX_INTR;
>
> while(i && (icr = E1000_READ_REG(&adapter->hw, ICR))) {
>
> @@ -1930,7 +1944,15 @@
> int i = E1000_MAX_INTR;
> int hasReceived = 0;
>
> - while(i && (icr = E1000_READ_REG(&adapter->hw, ICR))) {
> + while(i) {
> + if (adapter->icr_pending) {
> + icr = adapter->icr_pending;
> + adapter->icr_pending = 0;
> + } else
> + icr = E1000_READ_REG(&adapter->hw, ICR);
> + if (!icr)
> + break;
> +
> if (icr & E1000_ICR_RXT0)
> hasReceived = 1;
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/