X-Git-Url: http://git.ozo.com/?p=openwrt-10.03%2F.git;a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Fdrivers%2Fnet%2Fag71xx%2Fag71xx_main.c;h=4a86bb974b8fccd11ec2bf190c328063185fa325;hp=70cf87612438d946c36bc24fe32e9ec8a1170cde;hb=8c252c022d47bb218a812e03b659618e2364bd8f;hpb=a28281edd2dbdc3c57fdbb173cd2316b9a1fcf76 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 70cf87612..4a86bb974 100644 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c +++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c @@ -796,13 +796,43 @@ static void ag71xx_restart_work_func(struct work_struct *work) { struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); + if (ag71xx_get_pdata(ag)->is_ar724x) { + ag->link = 0; + ag71xx_link_adjust(ag); + return; + } + ag71xx_stop(ag->dev); 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); @@ -813,8 +843,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);