Commit 5718458b authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by David S. Miller

net: renesas: ravb: Fix a stuck issue when a lot of frames are received

When a lot of frames were received in the short term, the driver
caused a stuck of receiving until a new frame was received. For example,
the following command from other device could cause this issue.

    $ sudo ping -f -l 1000 -c 1000 <this driver's ipaddress>

The previous code always cleared the interrupt flag of RX but checks
the interrupt flags in ravb_poll(). So, ravb_poll() could not call
ravb_rx() in the next time until a new RX frame was received if
ravb_rx() returned true. To fix the issue, always calls ravb_rx()
regardless the interrupt flags condition.

Fixes: c156633f ("Renesas Ethernet AVB driver proper")
Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5e6038b8
...@@ -911,31 +911,20 @@ static int ravb_poll(struct napi_struct *napi, int budget) ...@@ -911,31 +911,20 @@ static int ravb_poll(struct napi_struct *napi, int budget)
int q = napi - priv->napi; int q = napi - priv->napi;
int mask = BIT(q); int mask = BIT(q);
int quota = budget; int quota = budget;
u32 ris0, tis;
for (;;) { /* Processing RX Descriptor Ring */
tis = ravb_read(ndev, TIS); /* Clear RX interrupt */
ris0 = ravb_read(ndev, RIS0); ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0);
if (!((ris0 & mask) || (tis & mask))) if (ravb_rx(ndev, &quota, q))
break; goto out;
/* Processing RX Descriptor Ring */ /* Processing RX Descriptor Ring */
if (ris0 & mask) { spin_lock_irqsave(&priv->lock, flags);
/* Clear RX interrupt */ /* Clear TX interrupt */
ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0); ravb_write(ndev, ~(mask | TIS_RESERVED), TIS);
if (ravb_rx(ndev, &quota, q)) ravb_tx_free(ndev, q, true);
goto out; netif_wake_subqueue(ndev, q);
} spin_unlock_irqrestore(&priv->lock, flags);
/* Processing TX Descriptor Ring */
if (tis & mask) {
spin_lock_irqsave(&priv->lock, flags);
/* Clear TX interrupt */
ravb_write(ndev, ~(mask | TIS_RESERVED), TIS);
ravb_tx_free(ndev, q, true);
netif_wake_subqueue(ndev, q);
spin_unlock_irqrestore(&priv->lock, flags);
}
}
napi_complete(napi); napi_complete(napi);
......
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