mirror of https://gitee.com/openkylin/linux.git
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: c156633f13
("Renesas Ethernet AVB driver proper")
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5e6038b88a
commit
5718458b09
|
@ -911,31 +911,20 @@ static int ravb_poll(struct napi_struct *napi, int budget)
|
|||
int q = napi - priv->napi;
|
||||
int mask = BIT(q);
|
||||
int quota = budget;
|
||||
u32 ris0, tis;
|
||||
|
||||
for (;;) {
|
||||
tis = ravb_read(ndev, TIS);
|
||||
ris0 = ravb_read(ndev, RIS0);
|
||||
if (!((ris0 & mask) || (tis & mask)))
|
||||
break;
|
||||
/* Processing RX Descriptor Ring */
|
||||
/* Clear RX interrupt */
|
||||
ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0);
|
||||
if (ravb_rx(ndev, "a, q))
|
||||
goto out;
|
||||
|
||||
/* Processing RX Descriptor Ring */
|
||||
if (ris0 & mask) {
|
||||
/* Clear RX interrupt */
|
||||
ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0);
|
||||
if (ravb_rx(ndev, "a, q))
|
||||
goto out;
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
/* Processing RX Descriptor Ring */
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue