|
@@ -1369,29 +1369,25 @@ fec_enet_interrupt(int irq, void *dev_id)
|
|
|
{
|
|
|
struct net_device *ndev = dev_id;
|
|
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
|
|
+ const unsigned napi_mask = FEC_ENET_RXF | FEC_ENET_TXF;
|
|
|
uint int_events;
|
|
|
irqreturn_t ret = IRQ_NONE;
|
|
|
|
|
|
- do {
|
|
|
- int_events = readl(fep->hwp + FEC_IEVENT);
|
|
|
- writel(int_events, fep->hwp + FEC_IEVENT);
|
|
|
+ int_events = readl(fep->hwp + FEC_IEVENT);
|
|
|
+ writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT);
|
|
|
|
|
|
- if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
|
|
|
- ret = IRQ_HANDLED;
|
|
|
+ if (int_events & napi_mask) {
|
|
|
+ ret = IRQ_HANDLED;
|
|
|
|
|
|
- /* Disable the RX interrupt */
|
|
|
- if (napi_schedule_prep(&fep->napi)) {
|
|
|
- writel(FEC_RX_DISABLED_IMASK,
|
|
|
- fep->hwp + FEC_IMASK);
|
|
|
- __napi_schedule(&fep->napi);
|
|
|
- }
|
|
|
- }
|
|
|
+ /* Disable the NAPI interrupts */
|
|
|
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
|
|
|
+ napi_schedule(&fep->napi);
|
|
|
+ }
|
|
|
|
|
|
- if (int_events & FEC_ENET_MII) {
|
|
|
- ret = IRQ_HANDLED;
|
|
|
- complete(&fep->mdio_done);
|
|
|
- }
|
|
|
- } while (int_events);
|
|
|
+ if (int_events & FEC_ENET_MII) {
|
|
|
+ ret = IRQ_HANDLED;
|
|
|
+ complete(&fep->mdio_done);
|
|
|
+ }
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -1399,8 +1395,16 @@ fec_enet_interrupt(int irq, void *dev_id)
|
|
|
static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
|
|
|
{
|
|
|
struct net_device *ndev = napi->dev;
|
|
|
- int pkts = fec_enet_rx(ndev, budget);
|
|
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
|
|
+ int pkts;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Clear any pending transmit or receive interrupts before
|
|
|
+ * processing the rings to avoid racing with the hardware.
|
|
|
+ */
|
|
|
+ writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT);
|
|
|
+
|
|
|
+ pkts = fec_enet_rx(ndev, budget);
|
|
|
|
|
|
fec_enet_tx(ndev);
|
|
|
|