@@ -1600,8 +1600,10 @@
struct gfar_private *priv = netdev_priv(dev);
struct gfar __iomem *regs = NULL;
u32 tempval;
- int i;
-
+ u32 reset_value = DMACTRL_GRS;
+ u32 event_value = IEVENT_GRSC;
+ int i = 0;
+
for (i = 0; i < priv->num_grps; i++) {
regs = priv->gfargrp[i].regs;
/* Mask all interrupts */
@@ -1612,22 +1614,32 @@
}
regs = priv->gfargrp[0].regs;
+
+ if (!((gfar_read(®s->tctrl) & TCTRL_RFCPAUSE) == TCTRL_RFCPAUSE))
+ {
+ reset_value |= DMACTRL_GTS;
+ event_value |= IEVENT_GTSC;
+
+ }
+
/* Stop the DMA, and wait for it to stop */
tempval = gfar_read(®s->dmactrl);
- if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) !=
- (DMACTRL_GRS | DMACTRL_GTS)) {
+ if ((tempval & reset_value) != reset_value) {
int ret;
- tempval |= (DMACTRL_GRS | DMACTRL_GTS);
+ tempval |= reset_value;
gfar_write(®s->dmactrl, tempval);
do {
- ret = spin_event_timeout(((gfar_read(®s->ievent) &
- (IEVENT_GRSC | IEVENT_GTSC)) ==
- (IEVENT_GRSC | IEVENT_GTSC)), 1000000, 0);
+
+ ret = spin_event_timeout(((gfar_read(®s->ievent) & event_value) == event_value), 1000000, 0);
+
if (!ret && !(gfar_read(®s->ievent) & IEVENT_GRSC))
+ {
ret = __gfar_is_rx_idle(priv);
+ }
} while (!ret);
+
}
}
@@ -1668,9 +1682,10 @@
lock_rx_qs(priv);
gfar_halt(dev);
-
+
unlock_rx_qs(priv);
unlock_tx_qs(priv);
+
local_irq_restore(flags);
/* Free the IRQs */
@@ -2424,22 +2439,32 @@
struct gfar_private *priv = container_of(work, struct gfar_private,
reset_task);
struct net_device *dev = priv->ndev;
-
if (dev->flags & IFF_UP) {
netif_tx_stop_all_queues(dev);
stop_gfar(dev);
startup_gfar(dev);
netif_tx_start_all_queues(dev);
}
-
netif_tx_schedule_all(dev);
}
static void gfar_timeout(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
+ struct gfar __iomem *regs = NULL;
- dev->stats.tx_errors++;
+ regs = priv->gfargrp[0].regs;
+
+ if ((gfar_read(®s->tctrl) & TCTRL_RFCPAUSE) == TCTRL_RFCPAUSE)
+ {
+ printk(KERN_DEBUG "PAUSE FRAME RECEIVED\n");
+ dev->stats.tx_dropped++;
+ }
+ else
+ {
+ dev->stats.tx_errors++;
+ }
+
schedule_work(&priv->reset_task);
}