#include "sdio.h"
#include "mac.h"
-static void mt7663s_refill_sched_quota(struct mt7615_dev *dev, u32 *data)
+static void mt7663s_refill_sched_quota(struct mt76_dev *dev, u32 *data)
{
- struct mt76_sdio *sdio = &dev->mt76.sdio;
+ struct mt76_sdio *sdio = &dev->sdio;
mutex_lock(&sdio->sched.lock);
sdio->sched.pse_data_quota += FIELD_GET(TXQ_CNT_L, data[0]) + /* BK */
return skb;
}
-static int mt7663s_rx_run_queue(struct mt7615_dev *dev, enum mt76_rxq_id qid,
+static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
struct mt76s_intr *intr)
{
- struct mt76_queue *q = &dev->mt76.q_rx[qid];
- struct mt76_sdio *sdio = &dev->mt76.sdio;
+ struct mt76_queue *q = &dev->q_rx[qid];
+ struct mt76_sdio *sdio = &dev->sdio;
int len = 0, err, i, order;
struct page *page;
u8 *buf;
buf = page_address(page);
+ sdio_claim_host(sdio->func);
err = sdio_readsb(sdio->func, buf, MCR_WRDR(qid), len);
+ sdio_release_host(sdio->func);
+
if (err < 0) {
- dev_err(dev->mt76.dev, "sdio read data failed:%d\n", err);
+ dev_err(dev->dev, "sdio read data failed:%d\n", err);
__free_pages(page, order);
return err;
}
q->queued += i;
spin_unlock_bh(&q->lock);
- return err;
+ return i;
}
static int mt7663s_tx_update_sched(struct mt76_dev *dev,
wake_up_process(sdio->kthread);
}
-void mt7663s_sdio_irq(struct sdio_func *func)
+void mt7663s_rx_work(struct work_struct *work)
{
- struct mt7615_dev *dev = sdio_get_drvdata(func);
- struct mt76_sdio *sdio = &dev->mt76.sdio;
+ struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, rx_work);
+ struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
struct mt76s_intr intr;
+ int nframes = 0, ret;
/* disable interrupt */
- sdio_writel(func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, 0);
+ sdio_claim_host(sdio->func);
+ sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, 0);
+ sdio_readsb(sdio->func, &intr, MCR_WHISR, sizeof(struct mt76s_intr));
+ sdio_release_host(sdio->func);
- do {
- sdio_readsb(func, &intr, MCR_WHISR, sizeof(struct mt76s_intr));
- trace_dev_irq(&dev->mt76, intr.isr, 0);
+ trace_dev_irq(dev, intr.isr, 0);
- if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.phy.state))
- goto out;
-
- if (intr.isr & WHIER_RX0_DONE_INT_EN) {
- mt7663s_rx_run_queue(dev, 0, &intr);
+ if (intr.isr & WHIER_RX0_DONE_INT_EN) {
+ ret = mt7663s_rx_run_queue(dev, 0, &intr);
+ if (ret > 0) {
wake_up_process(sdio->kthread);
+ nframes += ret;
}
+ }
- if (intr.isr & WHIER_RX1_DONE_INT_EN) {
- mt7663s_rx_run_queue(dev, 1, &intr);
+ if (intr.isr & WHIER_RX1_DONE_INT_EN) {
+ ret = mt7663s_rx_run_queue(dev, 1, &intr);
+ if (ret > 0) {
wake_up_process(sdio->kthread);
+ nframes += ret;
}
+ }
+
+ if (intr.isr & WHIER_TX_DONE_INT_EN) {
+ mt7663s_refill_sched_quota(dev, intr.tx.wtqcr);
+ queue_work(sdio->txrx_wq, &sdio->tx_work);
+ }
+
+ if (nframes) {
+ queue_work(sdio->txrx_wq, &sdio->rx_work);
+ return;
+ }
- if (intr.isr & WHIER_TX_DONE_INT_EN) {
- mt7663s_refill_sched_quota(dev, intr.tx.wtqcr);
- queue_work(sdio->txrx_wq, &sdio->tx_work);
- wake_up_process(sdio->kthread);
- }
- } while (intr.isr);
-out:
/* enable interrupt */
- sdio_writel(func, WHLPCR_INT_EN_SET, MCR_WHLPCR, 0);
+ sdio_claim_host(sdio->func);
+ sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, 0);
+ sdio_release_host(sdio->func);
+}
+
+void mt7663s_sdio_irq(struct sdio_func *func)
+{
+ struct mt7615_dev *dev = sdio_get_drvdata(func);
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+
+ if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.phy.state))
+ return;
+
+ queue_work(sdio->txrx_wq, &sdio->rx_work);
}