diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/devices.c b/target/linux/ar71xx/files/arch/mips/ar71xx/devices.c
index 088d27a346bf1be88941a8c14d96985099315a0f..74d9495c30b782ae748ac027b9287d3b46134fbf 100644
--- a/target/linux/ar71xx/files/arch/mips/ar71xx/devices.c
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/devices.c
@@ -589,6 +589,8 @@ void __init ar71xx_add_device_eth(unsigned int id)
 		pdata->set_pll =  id ? ar724x_set_pll_ge1
 				     : ar724x_set_pll_ge0;
 		pdata->is_ar724x = 1;
+		if (ar71xx_soc == AR71XX_SOC_AR7240)
+			pdata->is_ar7240 = 1;
 
 		if (!pdata->fifo_cfg1)
 			pdata->fifo_cfg1 = 0x0010ffff;
diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/platform.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/platform.h
index b0eb22840cb4020f42cfcb46c33b8ef74ce98396..0d9b5d2345508c9e0891139f7b144bb60d863f4d 100644
--- a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/platform.h
+++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/platform.h
@@ -29,6 +29,7 @@ struct ag71xx_platform_data {
 
 	u8		has_gbit:1;
 	u8		is_ar91xx:1;
+	u8		is_ar7240:1;
 	u8		is_ar724x:1;
 	u8		has_ar8216:1;
 	u8		has_ar7240_switch:1;
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
index d5cc46c42a02dd1cc94dab98429cb5ef8c193690..0222cab7975485699ab688ca5b1e7ab313b41706 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
@@ -236,6 +236,10 @@ static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
 #define AG71XX_REG_INT_ENABLE	0x0198
 #define AG71XX_REG_INT_STATUS	0x019c
 
+#define AG71XX_REG_FIFO_DEPTH	0x01a8
+#define AG71XX_REG_RX_SM	0x01b0
+#define AG71XX_REG_TX_SM	0x01b4
+
 #define MAC_CFG1_TXE		BIT(0)	/* Tx Enable */
 #define MAC_CFG1_STX		BIT(1)	/* Synchronize Tx Enable */
 #define MAC_CFG1_RXE		BIT(2)	/* Rx Enable */
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
index ee76c9a03d46b3818ad7b249afc223164ef671a7..c541933cec53b638798d878b2df20c78e9dda833 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
@@ -805,9 +805,33 @@ static void ag71xx_restart_work_func(struct work_struct *work)
 	ag71xx_open(ag->dev);
 }
 
+static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp)
+{
+	u32 rx_sm, tx_sm, rx_fd;
+
+	if (likely(time_before(jiffies, timestamp + HZ/10)))
+		return false;
+
+	if (!netif_carrier_ok(ag->dev))
+		return false;
+
+	rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM);
+	if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6)
+		return true;
+
+	tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM);
+	rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH);
+	if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) &&
+	    ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0)
+		return true;
+
+	return false;
+}
+
 static int ag71xx_tx_packets(struct ag71xx *ag)
 {
 	struct ag71xx_ring *ring = &ag->tx_ring;
+	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
 	int sent;
 
 	DBG("%s: processing TX ring\n", ag->dev->name);
@@ -818,8 +842,12 @@ static int ag71xx_tx_packets(struct ag71xx *ag)
 		struct ag71xx_desc *desc = ring->buf[i].desc;
 		struct sk_buff *skb = ring->buf[i].skb;
 
-		if (!ag71xx_desc_empty(desc))
+		if (!ag71xx_desc_empty(desc)) {
+			if (pdata->is_ar7240 &&
+			    ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp))
+				schedule_work(&ag->restart_work);
 			break;
+		}
 
 		ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);