diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index db04795dfc..93f8417a4c 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -227,6 +227,9 @@ struct cpsw_priv {
 	struct cpsw_slave		*slaves;
 	struct phy_device		*phydev;
 	struct mii_dev			*bus;
+
+	u32				mdio_link;
+	u32				phy_mask;
 };
 
 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
@@ -598,10 +601,21 @@ static int cpsw_update_link(struct cpsw_priv *priv)
 
 	for_each_slave(slave, priv)
 		cpsw_slave_update_link(slave, priv, &link);
-
+	priv->mdio_link = readl(&mdio_regs->link);
 	return link;
 }
 
+static int cpsw_check_link(struct cpsw_priv *priv)
+{
+	u32 link = 0;
+
+	link = __raw_readl(&mdio_regs->link) & priv->phy_mask;
+	if ((link) && (link == priv->mdio_link))
+		return 1;
+
+	return cpsw_update_link(priv);
+}
+
 static inline u32  cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
 {
 	if (priv->host_port == 0)
@@ -631,6 +645,8 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
 	cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);
 
 	cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port);
+
+	priv->phy_mask |= 1 << slave->data->phy_id;
 }
 
 static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
@@ -862,7 +878,7 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length)
 	int len;
 	int timeout = CPDMA_TIMEOUT;
 
-	if (!cpsw_update_link(priv))
+	if (!cpsw_check_link(priv))
 		return -EIO;
 
 	flush_dcache_range((unsigned long)packet,