mt76: sdio: introduce parse_irq callback
authorLorenzo Bianconi <lorenzo@kernel.org>
Mon, 18 Oct 2021 23:11:41 +0000 (07:11 +0800)
committerFelix Fietkau <nbd@nbd.name>
Wed, 20 Oct 2021 08:36:58 +0000 (10:36 +0200)
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: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
drivers/net/wireless/mediatek/mt76/sdio.h
drivers/net/wireless/mediatek/mt76/sdio_txrx.c

index 8dc4bbaca15de5e6f5e5f43bc2e253d0260af0d0..a3fc0c920f46cb9a686e0a06fd6b601b6bcad35b 100644 (file)
@@ -29,6 +29,7 @@
 struct mt76_dev;
 struct mt76_phy;
 struct mt76_wcid;
+struct mt76s_intr;
 
 struct mt76_reg_pair {
        u32 reg;
@@ -512,6 +513,8 @@ struct mt76_sdio {
                int pse_mcu_quota;
                int deficit;
        } sched;
+
+       int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr);
 };
 
 struct mt76_mmio {
index 77bd59813d477bf1e491a8d49e62e4bca80744ce..6ff6d580091882ce74e8de8d378dc391eff2d9b9 100644 (file)
@@ -107,6 +107,18 @@ struct mt7615_wtbl_rate_desc {
        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 mt76_wcid wcid; /* must be first */
 
index 14108e3fadda9eb4c1fefb88c93e516e3dfb5927..8d23dd4d54570bf61316185a682b77000ca588d0 100644 (file)
@@ -50,6 +50,26 @@ static void mt7663s_init_work(struct work_struct *work)
        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,
                         const struct sdio_device_id *id)
 {
@@ -108,8 +128,9 @@ static int mt7663s_probe(struct sdio_func *func,
                    (mt76_rr(dev, MT_HW_REV) & 0xff);
        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,
-                                           sizeof(struct mt76s_intr),
+                                           sizeof(struct mt7663s_intr),
                                            GFP_KERNEL);
        if (!mdev->sdio.intr_data) {
                ret = -ENOMEM;
index 03877d89e152050b262d7683b4b36ab394fe5572..dfcba5e3786c78f18a00ce1544cde24bc06e7839 100644 (file)
 
 struct mt76s_intr {
        u32 isr;
+       u32 *rec_mb;
        struct {
-               u32 wtqcr[8];
+               u32 *wtqcr;
        } tx;
        struct {
-               u16 num[2];
-               u16 len[2][16];
+               u16 *len[2];
+               u16 *num;
        } rx;
-       u32 rec_mb[2];
-} __packed;
+};
 
 #endif
index ceb3dc0613d63776119cf089081d6d669883f668..f94de48ebadc1b26320fd351c3e154fd4246264c 100644 (file)
@@ -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)
 {
        struct mt76_sdio *sdio = &dev->sdio;
-       struct mt76s_intr *intr = sdio->intr_data;
+       struct mt76s_intr intr;
        int nframes = 0, ret;
 
-       ret = sdio_readsb(sdio->func, intr, MCR_WHISR, sizeof(*intr));
-       if (ret < 0)
+       ret = sdio->parse_irq(dev, &intr);
+       if (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) {
-               ret = mt76s_rx_run_queue(dev, 0, intr);
+       if (intr.isr & WHIER_RX0_DONE_INT_EN) {
+               ret = mt76s_rx_run_queue(dev, 0, &intr);
                if (ret > 0) {
                        mt76_worker_schedule(&sdio->net_worker);
                        nframes += ret;
                }
        }
 
-       if (intr->isr & WHIER_RX1_DONE_INT_EN) {
-               ret = mt76s_rx_run_queue(dev, 1, intr);
+       if (intr.isr & WHIER_RX1_DONE_INT_EN) {
+               ret = mt76s_rx_run_queue(dev, 1, &intr);
                if (ret > 0) {
                        mt76_worker_schedule(&sdio->net_worker);
                        nframes += ret;
                }
        }
 
-       nframes += !!mt76s_refill_sched_quota(dev, intr->tx.wtqcr);
+       nframes += !!mt76s_refill_sched_quota(dev, intr.tx.wtqcr);
 
        return nframes;
 }