Commit 6ef2d665 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: mt7663s: split mt7663s_tx_update_sched in mt7663s_tx_{pick,update}_quota

In order to not update the available quota in case of a tx error, split
mt7663s_tx_update_sched in mt7663s_tx_{pick,update}_quota routines
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 8bf71ab6
...@@ -119,52 +119,57 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, ...@@ -119,52 +119,57 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
return i; return i;
} }
static int mt7663s_tx_update_sched(struct mt76_dev *dev, static int mt7663s_tx_pick_quota(struct mt76_dev *dev, enum mt76_txq_id qid,
struct mt76_queue_entry *e, int buf_sz, int *pse_size, int *ple_size)
bool mcu)
{ {
struct mt76_sdio *sdio = &dev->sdio; struct mt76_sdio *sdio = &dev->sdio;
int size, ret = -EBUSY; int pse_sz;
if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state)) if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state))
return 0; return 0;
size = DIV_ROUND_UP(e->buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ); pse_sz = DIV_ROUND_UP(buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ);
if (mcu) { if (qid == MT_TXQ_MCU) {
mutex_lock(&sdio->sched.lock); if (sdio->sched.pse_mcu_quota < *pse_size + pse_sz)
if (sdio->sched.pse_mcu_quota > size) { return -EBUSY;
sdio->sched.pse_mcu_quota -= size; } else {
ret = 0; if (sdio->sched.pse_data_quota < *pse_size + pse_sz ||
} sdio->sched.ple_data_quota < *ple_size)
mutex_unlock(&sdio->sched.lock); return -EBUSY;
return ret; *ple_size = *ple_size + 1;
} }
*pse_size = *pse_size + pse_sz;
return 0;
}
static void mt7663s_tx_update_quota(struct mt76_sdio *sdio, enum mt76_txq_id qid,
int pse_size, int ple_size)
{
mutex_lock(&sdio->sched.lock); mutex_lock(&sdio->sched.lock);
if (sdio->sched.pse_data_quota > size && if (qid == MT_TXQ_MCU) {
sdio->sched.ple_data_quota > 0) { sdio->sched.pse_mcu_quota -= pse_size;
sdio->sched.pse_data_quota -= size; } else {
sdio->sched.ple_data_quota--; sdio->sched.pse_data_quota -= pse_size;
ret = 0; sdio->sched.ple_data_quota -= ple_size;
} }
mutex_unlock(&sdio->sched.lock); mutex_unlock(&sdio->sched.lock);
return ret;
} }
static int mt7663s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q) static int mt7663s_tx_run_queue(struct mt76_dev *dev, enum mt76_txq_id qid)
{ {
bool mcu = q == dev->q_tx[MT_TXQ_MCU]; int nframes = 0, pse_sz = 0, ple_sz = 0;
struct mt76_queue *q = dev->q_tx[qid];
struct mt76_sdio *sdio = &dev->sdio; struct mt76_sdio *sdio = &dev->sdio;
int nframes = 0;
while (q->first != q->head) { while (q->first != q->head) {
struct mt76_queue_entry *e = &q->entry[q->first]; struct mt76_queue_entry *e = &q->entry[q->first];
int err, len = e->skb->len; int err, len = e->skb->len;
if (mt7663s_tx_update_sched(dev, e, mcu)) if (mt7663s_tx_pick_quota(dev, qid, e->buf_sz, &pse_sz,
&ple_sz))
break; break;
if (len > sdio->func->cur_blksize) if (len > sdio->func->cur_blksize)
...@@ -184,6 +189,7 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q) ...@@ -184,6 +189,7 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q)
q->first = (q->first + 1) % q->ndesc; q->first = (q->first + 1) % q->ndesc;
nframes++; nframes++;
} }
mt7663s_tx_update_quota(sdio, qid, pse_sz, ple_sz);
return nframes; return nframes;
} }
...@@ -198,7 +204,7 @@ void mt7663s_tx_work(struct work_struct *work) ...@@ -198,7 +204,7 @@ void mt7663s_tx_work(struct work_struct *work)
for (i = 0; i < MT_TXQ_MCU_WA; i++) { for (i = 0; i < MT_TXQ_MCU_WA; i++) {
int ret; int ret;
ret = mt7663s_tx_run_queue(dev, dev->q_tx[i]); ret = mt7663s_tx_run_queue(dev, i);
if (ret < 0) if (ret < 0)
break; break;
......
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