Commit 3ad08509 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: sdio: introduce parse_irq callback

Add parse_irq to handle that interrupt status structure is
different between mt7663s and mt7921s.

This is a preliminary patch to introduce mt7921s driver
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 764dee47
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
struct mt76_dev; struct mt76_dev;
struct mt76_phy; struct mt76_phy;
struct mt76_wcid; struct mt76_wcid;
struct mt76s_intr;
struct mt76_reg_pair { struct mt76_reg_pair {
u32 reg; u32 reg;
...@@ -512,6 +513,8 @@ struct mt76_sdio { ...@@ -512,6 +513,8 @@ struct mt76_sdio {
int pse_mcu_quota; int pse_mcu_quota;
int deficit; int deficit;
} sched; } sched;
int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr);
}; };
struct mt76_mmio { struct mt76_mmio {
......
...@@ -107,6 +107,18 @@ struct mt7615_wtbl_rate_desc { ...@@ -107,6 +107,18 @@ struct mt7615_wtbl_rate_desc {
struct mt7615_sta *sta; struct mt7615_sta *sta;
}; };
struct mt7663s_intr {
u32 isr;
struct {
u32 wtqcr[8];
} tx;
struct {
u16 num[2];
u16 len[2][16];
} rx;
u32 rec_mb[2];
} __packed;
struct mt7615_sta { struct mt7615_sta {
struct mt76_wcid wcid; /* must be first */ struct mt76_wcid wcid; /* must be first */
......
...@@ -50,6 +50,26 @@ static void mt7663s_init_work(struct work_struct *work) ...@@ -50,6 +50,26 @@ static void mt7663s_init_work(struct work_struct *work)
mt7615_init_work(dev); mt7615_init_work(dev);
} }
static int mt7663s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)
{
struct mt76_sdio *sdio = &dev->sdio;
struct mt7663s_intr *irq_data = sdio->intr_data;
int i, err;
err = sdio_readsb(sdio->func, irq_data, MCR_WHISR, sizeof(*irq_data));
if (err)
return err;
intr->isr = irq_data->isr;
intr->rec_mb = irq_data->rec_mb;
intr->tx.wtqcr = irq_data->tx.wtqcr;
intr->rx.num = irq_data->rx.num;
for (i = 0; i < 2 ; i++)
intr->rx.len[i] = irq_data->rx.len[i];
return 0;
}
static int mt7663s_probe(struct sdio_func *func, static int mt7663s_probe(struct sdio_func *func,
const struct sdio_device_id *id) const struct sdio_device_id *id)
{ {
...@@ -108,8 +128,9 @@ static int mt7663s_probe(struct sdio_func *func, ...@@ -108,8 +128,9 @@ static int mt7663s_probe(struct sdio_func *func,
(mt76_rr(dev, MT_HW_REV) & 0xff); (mt76_rr(dev, MT_HW_REV) & 0xff);
dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
mdev->sdio.parse_irq = mt7663s_parse_intr;
mdev->sdio.intr_data = devm_kmalloc(mdev->dev, mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
sizeof(struct mt76s_intr), sizeof(struct mt7663s_intr),
GFP_KERNEL); GFP_KERNEL);
if (!mdev->sdio.intr_data) { if (!mdev->sdio.intr_data) {
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -102,14 +102,14 @@ ...@@ -102,14 +102,14 @@
struct mt76s_intr { struct mt76s_intr {
u32 isr; u32 isr;
u32 *rec_mb;
struct { struct {
u32 wtqcr[8]; u32 *wtqcr;
} tx; } tx;
struct { struct {
u16 num[2]; u16 *len[2];
u16 len[2][16]; u16 *num;
} rx; } rx;
u32 rec_mb[2]; };
} __packed;
#endif #endif
...@@ -135,32 +135,32 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, ...@@ -135,32 +135,32 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
static int mt76s_rx_handler(struct mt76_dev *dev) static int mt76s_rx_handler(struct mt76_dev *dev)
{ {
struct mt76_sdio *sdio = &dev->sdio; struct mt76_sdio *sdio = &dev->sdio;
struct mt76s_intr *intr = sdio->intr_data; struct mt76s_intr intr;
int nframes = 0, ret; int nframes = 0, ret;
ret = sdio_readsb(sdio->func, intr, MCR_WHISR, sizeof(*intr)); ret = sdio->parse_irq(dev, &intr);
if (ret < 0) if (ret)
return ret; return ret;
trace_dev_irq(dev, intr->isr, 0); trace_dev_irq(dev, intr.isr, 0);
if (intr->isr & WHIER_RX0_DONE_INT_EN) { if (intr.isr & WHIER_RX0_DONE_INT_EN) {
ret = mt76s_rx_run_queue(dev, 0, intr); ret = mt76s_rx_run_queue(dev, 0, &intr);
if (ret > 0) { if (ret > 0) {
mt76_worker_schedule(&sdio->net_worker); mt76_worker_schedule(&sdio->net_worker);
nframes += ret; nframes += ret;
} }
} }
if (intr->isr & WHIER_RX1_DONE_INT_EN) { if (intr.isr & WHIER_RX1_DONE_INT_EN) {
ret = mt76s_rx_run_queue(dev, 1, intr); ret = mt76s_rx_run_queue(dev, 1, &intr);
if (ret > 0) { if (ret > 0) {
mt76_worker_schedule(&sdio->net_worker); mt76_worker_schedule(&sdio->net_worker);
nframes += ret; nframes += ret;
} }
} }
nframes += !!mt76s_refill_sched_quota(dev, intr->tx.wtqcr); nframes += !!mt76s_refill_sched_quota(dev, intr.tx.wtqcr);
return nframes; return nframes;
} }
......
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