can: Unify droping of invalid tx skbs and netdev stats
[safe/jmp/linux-2.6] / drivers / net / ucc_geth.c
index 0f8c99e..96bdc0b 100644 (file)
@@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode)
 
 static void ugeth_quiesce(struct ucc_geth_private *ugeth)
 {
-       /* Wait for and prevent any further xmits. */
+       /* Prevent any further xmits, plus detach the device. */
+       netif_device_detach(ugeth->ndev);
+
+       /* Wait for any current xmits to finish. */
        netif_tx_disable(ugeth->ndev);
 
        /* Disable the interrupt to avoid NAPI rescheduling. */
@@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth)
 {
        napi_enable(&ugeth->napi);
        enable_irq(ugeth->ug_info->uf_info.irq);
-       netif_tx_wake_all_queues(ugeth->ndev);
+       netif_device_attach(ugeth->ndev);
 }
 
 /* Called every time the controller might need to be made
@@ -1648,25 +1651,28 @@ static void adjust_link(struct net_device *dev)
                        ugeth->oldspeed = phydev->speed;
                }
 
-               /*
-                * To change the MAC configuration we need to disable the
-                * controller. To do so, we have to either grab ugeth->lock,
-                * which is a bad idea since 'graceful stop' commands might
-                * take quite a while, or we can quiesce driver's activity.
-                */
-               ugeth_quiesce(ugeth);
-               ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
-
-               out_be32(&ug_regs->maccfg2, tempval);
-               out_be32(&uf_regs->upsmr, upsmr);
-
-               ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
-               ugeth_activate(ugeth);
-
                if (!ugeth->oldlink) {
                        new_state = 1;
                        ugeth->oldlink = 1;
                }
+
+               if (new_state) {
+                       /*
+                        * To change the MAC configuration we need to disable
+                        * the controller. To do so, we have to either grab
+                        * ugeth->lock, which is a bad idea since 'graceful
+                        * stop' commands might take quite a while, or we can
+                        * quiesce driver's activity.
+                        */
+                       ugeth_quiesce(ugeth);
+                       ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
+
+                       out_be32(&ug_regs->maccfg2, tempval);
+                       out_be32(&uf_regs->upsmr, upsmr);
+
+                       ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+                       ugeth_activate(ugeth);
+               }
        } else if (ugeth->oldlink) {
                        new_state = 1;
                        ugeth->oldlink = 0;
@@ -3601,6 +3607,7 @@ static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state)
        if (!netif_running(ndev))
                return 0;
 
+       netif_device_detach(ndev);
        napi_disable(&ugeth->napi);
 
        /*
@@ -3659,7 +3666,7 @@ static int ucc_geth_resume(struct of_device *ofdev)
        phy_start(ugeth->phydev);
 
        napi_enable(&ugeth->napi);
-       netif_start_queue(ndev);
+       netif_device_attach(ndev);
 
        return 0;
 }