summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo@kernel.org>2021-10-19 07:11:41 +0800
committerFelix Fietkau <nbd@nbd.name>2021-10-20 10:36:58 +0200
commit3ad0850934179103e7c4ba8574139543b1109bbf (patch)
tree67daf692fd89bf93a92c2bfd70f30a0815d5be7e /drivers/net/wireless/mediatek/mt76
parent764dee47e2c1ed828c8a51cbf58f89b5e3ded11b (diff)
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: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h12
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio.c23
-rw-r--r--drivers/net/wireless/mediatek/mt76/sdio.h10
-rw-r--r--drivers/net/wireless/mediatek/mt76/sdio_txrx.c18
5 files changed, 51 insertions, 15 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 8dc4bbaca15d..a3fc0c920f46 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -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 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index 77bd59813d47..6ff6d5800918 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -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 */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index 14108e3fadda..8d23dd4d5457 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -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;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.h b/drivers/net/wireless/mediatek/mt76/sdio.h
index 03877d89e152..dfcba5e3786c 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.h
+++ b/drivers/net/wireless/mediatek/mt76/sdio.h
@@ -102,14 +102,14 @@
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
diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
index ceb3dc0613d6..f94de48ebadc 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
@@ -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;
}