mt7603: add another tx/rx watchdog check

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2016-02-28 21:14:48 +01:00
parent 1c4c7adfc2
commit 2e6dcc48f1
3 changed files with 69 additions and 10 deletions
+5 -2
View File
@@ -33,7 +33,7 @@
#define MT7603_PRE_TBTT_TIME 5000 /* ms */
#define MT7603_WATCHDOG_TIME 1000 /* ms */
#define MT7603_WATCHDOG_TIME 100 /* ms */
#define MT7603_WATCHDOG_TIMEOUT 10 /* number of checks */
enum {
@@ -124,7 +124,10 @@ struct mt7603_dev {
u8 beacon_mask;
u8 tx_check;
u8 rx_check;
u8 txrx_check;
u16 tx_dma_idx[4];
u16 rx_dma_idx;
struct delayed_work mac_work;
struct tasklet_struct tx_tasklet;
+56 -8
View File
@@ -994,9 +994,6 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
napi_disable(&dev->mt76.napi[0]);
napi_disable(&dev->mt76.napi[1]);
dev->tx_check = 0;
dev->rx_check = 0;
mt7603_beacon_set_timer(dev, -1, 0);
mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_FORCE_TX_EOF);
@@ -1032,6 +1029,42 @@ 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)
{
struct mt76_queue *q;
u32 dma_idx, prev_dma_idx, val;
int i;
for (i = 0; i < 4; i++) {
q = &dev->mt76.q_tx[i];
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;
}
void mt7603_mac_work(struct work_struct *work)
{
struct mt7603_dev *dev = container_of(work, struct mt7603_dev, mac_work.work);
@@ -1041,18 +1074,33 @@ void mt7603_mac_work(struct work_struct *work)
if (mt7603_tx_dma_busy(dev) ||
dev->tx_check >= MT7603_WATCHDOG_TIMEOUT) {
time = MT7603_WATCHDOG_TIME / 10;
if (WARN_ON_ONCE(++dev->tx_check >= MT7603_WATCHDOG_TIMEOUT)) {
mt7603_mac_watchdog_reset(dev);
goto out;
}
if (WARN_ON_ONCE(++dev->tx_check >= MT7603_WATCHDOG_TIMEOUT))
goto reset;
} else {
dev->tx_check = 0;
}
if (mt7603_tx_rx_dma_busy(dev) ||
dev->txrx_check >= MT7603_WATCHDOG_TIMEOUT) {
if (WARN_ON_ONCE(++dev->txrx_check >= MT7603_WATCHDOG_TIMEOUT))
goto reset;
} else {
dev->txrx_check = 0;
}
out:
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
msecs_to_jiffies(time));
mutex_unlock(&dev->mutex);
return;
reset:
dev->tx_check = 0;
dev->txrx_check = 0;
dev->rx_dma_idx = ~0;
memset(dev->tx_dma_idx, 0xff, sizeof(dev->tx_dma_idx));
mt7603_mac_watchdog_reset(dev);
goto out;
}
+8
View File
@@ -115,6 +115,14 @@
#define MT_PSE_FRP_P2_RQ1 GENMASK(11, 9)
#define MT_PSE_FRP_P2_RQ2 GENMASK(14, 12)
#define MT_FC_RSV_COUNT_0 MT_PSE(0x13c)
#define MT_FC_RSV_COUNT_0_P0 GENMASK(11, 0)
#define MT_FC_RSV_COUNT_0_P1 GENMASK(27, 16)
#define MT_FC_SP2_Q0Q1 MT_PSE(0x14c)
#define MT_FC_SP2_Q0Q1_SRC_COUNT_Q0 GENMASK(11, 0)
#define MT_FC_SP2_Q0Q1_SRC_COUNT_Q1 GENMASK(27, 16)
#define MT_WF_PHY_BASE 0x10000
#define MT_WF_PHY_OFFSET 0x1000
#define MT_WF_PHY(ofs) (MT_WF_PHY_BASE + (ofs))