Commit 598daa4d authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: mt7663s: fix possible quota leak in mt7663s_refill_sched_quota

Look just at reported quota since the hw sporadically reports mcu tx
quota without setting WHIER_TX_DONE_INT_EN bit
Tested-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent e98e6df6
...@@ -19,21 +19,40 @@ ...@@ -19,21 +19,40 @@
#include "sdio.h" #include "sdio.h"
#include "mac.h" #include "mac.h"
static void mt7663s_refill_sched_quota(struct mt76_dev *dev, u32 *data) static int mt7663s_refill_sched_quota(struct mt76_dev *dev, u32 *data)
{ {
u32 ple_ac_data_quota[] = {
FIELD_GET(TXQ_CNT_L, data[4]), /* VO */
FIELD_GET(TXQ_CNT_H, data[3]), /* VI */
FIELD_GET(TXQ_CNT_L, data[3]), /* BE */
FIELD_GET(TXQ_CNT_H, data[2]), /* BK */
};
u32 pse_ac_data_quota[] = {
FIELD_GET(TXQ_CNT_H, data[1]), /* VO */
FIELD_GET(TXQ_CNT_L, data[1]), /* VI */
FIELD_GET(TXQ_CNT_H, data[0]), /* BE */
FIELD_GET(TXQ_CNT_L, data[0]), /* BK */
};
u32 pse_mcu_quota = FIELD_GET(TXQ_CNT_L, data[2]);
u32 pse_data_quota = 0, ple_data_quota = 0;
struct mt76_sdio *sdio = &dev->sdio; struct mt76_sdio *sdio = &dev->sdio;
int i;
for (i = 0; i < ARRAY_SIZE(pse_ac_data_quota); i++) {
pse_data_quota += pse_ac_data_quota[i];
ple_data_quota += ple_ac_data_quota[i];
}
if (!pse_data_quota && !ple_data_quota && !pse_mcu_quota)
return 0;
mutex_lock(&sdio->sched.lock); mutex_lock(&sdio->sched.lock);
sdio->sched.pse_data_quota += FIELD_GET(TXQ_CNT_L, data[0]) + /* BK */ sdio->sched.pse_mcu_quota += pse_mcu_quota;
FIELD_GET(TXQ_CNT_H, data[0]) + /* BE */ sdio->sched.pse_data_quota += pse_data_quota;
FIELD_GET(TXQ_CNT_L, data[1]) + /* VI */ sdio->sched.ple_data_quota += ple_data_quota;
FIELD_GET(TXQ_CNT_H, data[1]); /* VO */
sdio->sched.ple_data_quota += FIELD_GET(TXQ_CNT_H, data[2]) + /* BK */
FIELD_GET(TXQ_CNT_L, data[3]) + /* BE */
FIELD_GET(TXQ_CNT_H, data[3]) + /* VI */
FIELD_GET(TXQ_CNT_L, data[4]); /* VO */
sdio->sched.pse_mcu_quota += FIELD_GET(TXQ_CNT_L, data[2]);
mutex_unlock(&sdio->sched.lock); mutex_unlock(&sdio->sched.lock);
return pse_data_quota + ple_data_quota + pse_mcu_quota;
} }
static struct sk_buff *mt7663s_build_rx_skb(void *data, int data_len, static struct sk_buff *mt7663s_build_rx_skb(void *data, int data_len,
...@@ -259,10 +278,8 @@ void mt7663s_rx_work(struct work_struct *work) ...@@ -259,10 +278,8 @@ void mt7663s_rx_work(struct work_struct *work)
} }
} }
if (intr->isr & WHIER_TX_DONE_INT_EN) { if (mt7663s_refill_sched_quota(dev, intr->tx.wtqcr))
mt7663s_refill_sched_quota(dev, intr->tx.wtqcr);
queue_work(sdio->txrx_wq, &sdio->tx.xmit_work); queue_work(sdio->txrx_wq, &sdio->tx.xmit_work);
}
if (nframes) { if (nframes) {
queue_work(sdio->txrx_wq, &sdio->rx.recv_work); queue_work(sdio->txrx_wq, &sdio->rx.recv_work);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment