mt7603: change hang detection code to detect any tx queue hang

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2016-03-04 20:18:36 +01:00
parent f466a62489
commit f34b842df6
4 changed files with 19 additions and 29 deletions
+2 -2
View File
@@ -137,8 +137,8 @@ struct mt7603_dev {
u8 beacon_mask;
u8 beacon_check;
u8 tx_check;
u8 txrx_check;
u8 tx_hang_check;
u8 tx_dma_check;
u8 rx_dma_check;
u8 rx_pse_check;
+1 -1
View File
@@ -114,7 +114,7 @@ mt7603_tx_tasklet(unsigned long data)
struct mt7603_dev *dev = (struct mt7603_dev *) data;
int i;
dev->tx_check = 0;
dev->tx_dma_check = 0;
for (i = MT_TXQ_MCU; i >= 0; i--)
mt76_queue_tx_cleanup(dev, i, false);
+15 -25
View File
@@ -919,6 +919,9 @@ void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
return;
}
if (q - dev->mt76.q_tx < 4)
dev->tx_hang_check = 0;
/* will be freed by tx status handling codepath */
if (skb->prev) {
spin_lock_bh(&dev->status_lock);
@@ -1066,40 +1069,27 @@ static bool mt7603_tx_dma_busy(struct mt7603_dev *dev)
return (val & BIT(8)) && (val & 0xf) != 0xf;
}
static bool mt7603_tx_rx_dma_busy(struct mt7603_dev *dev)
static bool mt7603_tx_hang(struct mt7603_dev *dev)
{
struct mt76_queue *q;
u32 dma_idx, prev_dma_idx, val;
u32 dma_idx, prev_dma_idx;
int i;
for (i = 0; i < 4; i++) {
q = &dev->mt76.q_tx[i];
if (!q->queued)
continue;
prev_dma_idx = dev->tx_dma_idx[i];
dev->tx_dma_idx[i] = dma_idx = ioread32(&q->regs->dma_idx);
if (dma_idx != prev_dma_idx ||
dma_idx == ioread32(&q->regs->cpu_idx))
continue;
val = mt76_rr(dev, MT_FC_RSV_COUNT_0);
if (MT76_GET(MT_FC_RSV_COUNT_0_P0, val) > 0xa0)
break;
}
if (i == 4)
return false;
q = &dev->mt76.q_rx[0];
prev_dma_idx = dev->rx_dma_idx;
dev->rx_dma_idx = dma_idx = ioread32(&q->regs->dma_idx);
if (dma_idx != prev_dma_idx)
return false;
if (dma_idx == ioread32(&q->regs->cpu_idx))
return false;
val = mt76_rr(dev, MT_FC_SP2_Q0Q1);
return MT76_GET(MT_FC_SP2_Q0Q1_SRC_COUNT_Q0, val) > 0x20;
return i < 4;
}
static bool mt7603_rx_pse_busy(struct mt7603_dev *dev)
@@ -1158,15 +1148,15 @@ void mt7603_mac_work(struct work_struct *work)
mutex_lock(&dev->mutex);
if (WARN_ON_ONCE(mt7603_watchdog_check(dev, &dev->tx_check,
if (WARN_ON_ONCE(mt7603_watchdog_check(dev, &dev->tx_dma_check,
RESET_CAUSE_TX_BUSY,
mt7603_tx_dma_busy)) ||
WARN_ON_ONCE(mt7603_watchdog_check(dev, &dev->rx_dma_check,
RESET_CAUSE_RX_BUSY,
mt7603_rx_dma_busy)) ||
WARN_ON_ONCE(mt7603_watchdog_check(dev, &dev->txrx_check,
WARN_ON_ONCE(mt7603_watchdog_check(dev, &dev->tx_hang_check,
RESET_CAUSE_TX_HANG,
mt7603_tx_rx_dma_busy)) ||
mt7603_tx_hang)) ||
WARN_ON_ONCE(mt7603_watchdog_check(dev, &dev->rx_pse_check,
RESET_CAUSE_RX_PSE_BUSY,
mt7603_rx_pse_busy)) ||
@@ -1174,8 +1164,8 @@ void mt7603_mac_work(struct work_struct *work)
RESET_CAUSE_BEACON_STUCK,
NULL))) {
dev->beacon_check = 0;
dev->tx_check = 0;
dev->txrx_check = 0;
dev->tx_dma_check = 0;
dev->tx_hang_check = 0;
dev->rx_dma_check = 0;
dev->rx_pse_check = 0;
dev->rx_dma_idx = ~0;
+1 -1
View File
@@ -112,7 +112,7 @@ mt7603_mcu_msg_send(struct mt7603_dev *dev, struct sk_buff *skb, int cmd, int qu
skb = mt7603_mcu_get_response(dev, expires);
if (!skb) {
printk("MCU message %d (seq %d) timed out\n", cmd, seq);
dev->tx_check = MT7603_WATCHDOG_TIMEOUT;
dev->tx_dma_check = MT7603_WATCHDOG_TIMEOUT;
ret = -ETIMEDOUT;
break;
}