1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-21 12:27:27 +03:00

ar71xx: add some code to detect DMA stuck conditions on ar7240

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27975 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
nbd
2011-08-13 22:30:14 +00:00
parent 5051a6677f
commit db5c8f65ca
4 changed files with 36 additions and 1 deletions

View File

@@ -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);