}
 }
 
+static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)
+{
+       if (!slave->phy)
+               return;
+       phy_stop(slave->phy);
+       phy_disconnect(slave->phy);
+       slave->phy = NULL;
+}
+
 static int cpsw_ndo_open(struct net_device *ndev)
 {
        struct cpsw_priv *priv = netdev_priv(ndev);
                        struct sk_buff *skb;
 
                        ret = -ENOMEM;
-                       skb = netdev_alloc_skb_ip_align(priv->ndev,
-                                                       priv->rx_packet_max);
+                       skb = __netdev_alloc_skb_ip_align(priv->ndev,
+                                       priv->rx_packet_max, GFP_KERNEL);
                        if (!skb)
-                               break;
+                               goto err_cleanup;
                        ret = cpdma_chan_submit(priv->rxch, skb, skb->data,
                                        skb_tailroom(skb), 0, GFP_KERNEL);
-                       if (WARN_ON(ret < 0))
-                               break;
+                       if (ret < 0) {
+                               kfree_skb(skb);
+                               goto err_cleanup;
+                       }
                }
                /* continue even if we didn't manage to submit all
                 * receive descs
        if (priv->data.dual_emac)
                priv->slaves[priv->emac_port].open_stat = true;
        return 0;
-}
 
-static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)
-{
-       if (!slave->phy)
-               return;
-       phy_stop(slave->phy);
-       phy_disconnect(slave->phy);
-       slave->phy = NULL;
+err_cleanup:
+       cpdma_ctlr_stop(priv->dma);
+       for_each_slave(priv, cpsw_slave_stop, priv);
+       pm_runtime_put_sync(&priv->pdev->dev);
+       netif_carrier_off(priv->ndev);
+       return ret;
 }
 
 static int cpsw_ndo_stop(struct net_device *ndev)