mirror of
https://github.com/openwrt/openwrt.git
synced 2026-05-05 22:25:44 +04:00
d62ecd6c07
Refresh patches 6.12 for airoha and econet Fixes:122135b964("airoha: an7581: add support for kernel 6.12") Fixes:73d0f92460("kernel: Add new platform EcoNet MIPS") Signed-off-by: Leo Barsky <leobrsky@proton.me> Link: https://github.com/openwrt/openwrt/pull/20073 Signed-off-by: Robert Marko <robimarko@gmail.com>
293 lines
9.3 KiB
Diff
293 lines
9.3 KiB
Diff
From 9439db26d3ee4a897e5cd108864172531f31ce07 Mon Sep 17 00:00:00 2001
|
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Date: Fri, 18 Apr 2025 12:40:49 +0200
|
|
Subject: [PATCH 1/2] net: airoha: Introduce airoha_irq_bank struct
|
|
|
|
EN7581 ethernet SoC supports 4 programmable IRQ lines each one composed
|
|
by 4 IRQ configuration registers. Add airoha_irq_bank struct as a
|
|
container for independent IRQ lines info (e.g. IRQ number, enabled source
|
|
interrupts, ecc). This is a preliminary patch to support multiple IRQ lines
|
|
in airoha_eth driver.
|
|
|
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Link: https://patch.msgid.link/20250418-airoha-eth-multi-irq-v1-1-1ab0083ca3c1@kernel.org
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
---
|
|
drivers/net/ethernet/airoha/airoha_eth.c | 106 ++++++++++++++--------
|
|
drivers/net/ethernet/airoha/airoha_eth.h | 13 ++-
|
|
drivers/net/ethernet/airoha/airoha_regs.h | 11 ++-
|
|
3 files changed, 86 insertions(+), 44 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
|
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
|
@@ -34,37 +34,40 @@ u32 airoha_rmw(void __iomem *base, u32 o
|
|
return val;
|
|
}
|
|
|
|
-static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index,
|
|
- u32 clear, u32 set)
|
|
+static void airoha_qdma_set_irqmask(struct airoha_irq_bank *irq_bank,
|
|
+ int index, u32 clear, u32 set)
|
|
{
|
|
+ struct airoha_qdma *qdma = irq_bank->qdma;
|
|
+ int bank = irq_bank - &qdma->irq_banks[0];
|
|
unsigned long flags;
|
|
|
|
- if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask)))
|
|
+ if (WARN_ON_ONCE(index >= ARRAY_SIZE(irq_bank->irqmask)))
|
|
return;
|
|
|
|
- spin_lock_irqsave(&qdma->irq_lock, flags);
|
|
+ spin_lock_irqsave(&irq_bank->irq_lock, flags);
|
|
|
|
- qdma->irqmask[index] &= ~clear;
|
|
- qdma->irqmask[index] |= set;
|
|
- airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]);
|
|
+ irq_bank->irqmask[index] &= ~clear;
|
|
+ irq_bank->irqmask[index] |= set;
|
|
+ airoha_qdma_wr(qdma, REG_INT_ENABLE(bank, index),
|
|
+ irq_bank->irqmask[index]);
|
|
/* Read irq_enable register in order to guarantee the update above
|
|
* completes in the spinlock critical section.
|
|
*/
|
|
- airoha_qdma_rr(qdma, REG_INT_ENABLE(index));
|
|
+ airoha_qdma_rr(qdma, REG_INT_ENABLE(bank, index));
|
|
|
|
- spin_unlock_irqrestore(&qdma->irq_lock, flags);
|
|
+ spin_unlock_irqrestore(&irq_bank->irq_lock, flags);
|
|
}
|
|
|
|
-static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index,
|
|
- u32 mask)
|
|
+static void airoha_qdma_irq_enable(struct airoha_irq_bank *irq_bank,
|
|
+ int index, u32 mask)
|
|
{
|
|
- airoha_qdma_set_irqmask(qdma, index, 0, mask);
|
|
+ airoha_qdma_set_irqmask(irq_bank, index, 0, mask);
|
|
}
|
|
|
|
-static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index,
|
|
- u32 mask)
|
|
+static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,
|
|
+ int index, u32 mask)
|
|
{
|
|
- airoha_qdma_set_irqmask(qdma, index, mask, 0);
|
|
+ airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
|
|
}
|
|
|
|
static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
|
|
@@ -732,6 +735,7 @@ free_frag:
|
|
static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
|
|
{
|
|
struct airoha_queue *q = container_of(napi, struct airoha_queue, napi);
|
|
+ struct airoha_irq_bank *irq_bank = &q->qdma->irq_banks[0];
|
|
int cur, done = 0;
|
|
|
|
do {
|
|
@@ -740,7 +744,7 @@ static int airoha_qdma_rx_napi_poll(stru
|
|
} while (cur && done < budget);
|
|
|
|
if (done < budget && napi_complete(napi))
|
|
- airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1,
|
|
+ airoha_qdma_irq_enable(irq_bank, QDMA_INT_REG_IDX1,
|
|
RX_DONE_INT_MASK);
|
|
|
|
return done;
|
|
@@ -944,7 +948,7 @@ unlock:
|
|
}
|
|
|
|
if (done < budget && napi_complete(napi))
|
|
- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0,
|
|
+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0,
|
|
TX_DONE_INT_MASK(id));
|
|
|
|
return done;
|
|
@@ -1175,13 +1179,16 @@ static int airoha_qdma_hw_init(struct ai
|
|
int i;
|
|
|
|
/* clear pending irqs */
|
|
- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++)
|
|
+ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks[0].irqmask); i++)
|
|
airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff);
|
|
|
|
/* setup irqs */
|
|
- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
|
|
- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK);
|
|
- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
|
|
+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0,
|
|
+ INT_IDX0_MASK);
|
|
+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX1,
|
|
+ INT_IDX1_MASK);
|
|
+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX4,
|
|
+ INT_IDX4_MASK);
|
|
|
|
/* setup irq binding */
|
|
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
|
@@ -1226,13 +1233,14 @@ static int airoha_qdma_hw_init(struct ai
|
|
|
|
static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
|
|
{
|
|
- struct airoha_qdma *qdma = dev_instance;
|
|
- u32 intr[ARRAY_SIZE(qdma->irqmask)];
|
|
+ struct airoha_irq_bank *irq_bank = dev_instance;
|
|
+ struct airoha_qdma *qdma = irq_bank->qdma;
|
|
+ u32 intr[ARRAY_SIZE(irq_bank->irqmask)];
|
|
int i;
|
|
|
|
- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) {
|
|
+ for (i = 0; i < ARRAY_SIZE(intr); i++) {
|
|
intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i));
|
|
- intr[i] &= qdma->irqmask[i];
|
|
+ intr[i] &= irq_bank->irqmask[i];
|
|
airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
|
|
}
|
|
|
|
@@ -1240,7 +1248,7 @@ static irqreturn_t airoha_irq_handler(in
|
|
return IRQ_NONE;
|
|
|
|
if (intr[1] & RX_DONE_INT_MASK) {
|
|
- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1,
|
|
+ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX1,
|
|
RX_DONE_INT_MASK);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
|
@@ -1257,7 +1265,7 @@ static irqreturn_t airoha_irq_handler(in
|
|
if (!(intr[0] & TX_DONE_INT_MASK(i)))
|
|
continue;
|
|
|
|
- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0,
|
|
+ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX0,
|
|
TX_DONE_INT_MASK(i));
|
|
napi_schedule(&qdma->q_tx_irq[i].napi);
|
|
}
|
|
@@ -1266,6 +1274,39 @@ static irqreturn_t airoha_irq_handler(in
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
+static int airoha_qdma_init_irq_banks(struct platform_device *pdev,
|
|
+ struct airoha_qdma *qdma)
|
|
+{
|
|
+ struct airoha_eth *eth = qdma->eth;
|
|
+ int i, id = qdma - ð->qdma[0];
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) {
|
|
+ struct airoha_irq_bank *irq_bank = &qdma->irq_banks[i];
|
|
+ int err, irq_index = 4 * id + i;
|
|
+ const char *name;
|
|
+
|
|
+ spin_lock_init(&irq_bank->irq_lock);
|
|
+ irq_bank->qdma = qdma;
|
|
+
|
|
+ irq_bank->irq = platform_get_irq(pdev, irq_index);
|
|
+ if (irq_bank->irq < 0)
|
|
+ return irq_bank->irq;
|
|
+
|
|
+ name = devm_kasprintf(eth->dev, GFP_KERNEL,
|
|
+ KBUILD_MODNAME ".%d", irq_index);
|
|
+ if (!name)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ err = devm_request_irq(eth->dev, irq_bank->irq,
|
|
+ airoha_irq_handler, IRQF_SHARED, name,
|
|
+ irq_bank);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int airoha_qdma_init(struct platform_device *pdev,
|
|
struct airoha_eth *eth,
|
|
struct airoha_qdma *qdma)
|
|
@@ -1273,9 +1314,7 @@ static int airoha_qdma_init(struct platf
|
|
int err, id = qdma - ð->qdma[0];
|
|
const char *res;
|
|
|
|
- spin_lock_init(&qdma->irq_lock);
|
|
qdma->eth = eth;
|
|
-
|
|
res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id);
|
|
if (!res)
|
|
return -ENOMEM;
|
|
@@ -1285,12 +1324,7 @@ static int airoha_qdma_init(struct platf
|
|
return dev_err_probe(eth->dev, PTR_ERR(qdma->regs),
|
|
"failed to iomap qdma%d regs\n", id);
|
|
|
|
- qdma->irq = platform_get_irq(pdev, 4 * id);
|
|
- if (qdma->irq < 0)
|
|
- return qdma->irq;
|
|
-
|
|
- err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler,
|
|
- IRQF_SHARED, KBUILD_MODNAME, qdma);
|
|
+ err = airoha_qdma_init_irq_banks(pdev, qdma);
|
|
if (err)
|
|
return err;
|
|
|
|
@@ -2781,7 +2815,7 @@ static int airoha_alloc_gdm_port(struct
|
|
dev->features |= dev->hw_features;
|
|
dev->vlan_features = dev->hw_features;
|
|
dev->dev.of_node = np;
|
|
- dev->irq = qdma->irq;
|
|
+ dev->irq = qdma->irq_banks[0].irq;
|
|
SET_NETDEV_DEV(dev, eth->dev);
|
|
|
|
/* reserve hw queues for HTB offloading */
|
|
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
|
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
|
@@ -17,6 +17,7 @@
|
|
|
|
#define AIROHA_MAX_NUM_GDM_PORTS 4
|
|
#define AIROHA_MAX_NUM_QDMA 2
|
|
+#define AIROHA_MAX_NUM_IRQ_BANKS 1
|
|
#define AIROHA_MAX_DSA_PORTS 7
|
|
#define AIROHA_MAX_NUM_RSTS 3
|
|
#define AIROHA_MAX_NUM_XSI_RSTS 5
|
|
@@ -452,17 +453,23 @@ struct airoha_flow_table_entry {
|
|
unsigned long cookie;
|
|
};
|
|
|
|
-struct airoha_qdma {
|
|
- struct airoha_eth *eth;
|
|
- void __iomem *regs;
|
|
+struct airoha_irq_bank {
|
|
+ struct airoha_qdma *qdma;
|
|
|
|
/* protect concurrent irqmask accesses */
|
|
spinlock_t irq_lock;
|
|
u32 irqmask[QDMA_INT_REG_MAX];
|
|
int irq;
|
|
+};
|
|
+
|
|
+struct airoha_qdma {
|
|
+ struct airoha_eth *eth;
|
|
+ void __iomem *regs;
|
|
|
|
atomic_t users;
|
|
|
|
+ struct airoha_irq_bank irq_banks[AIROHA_MAX_NUM_IRQ_BANKS];
|
|
+
|
|
struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
|
|
|
|
struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
|
|
--- a/drivers/net/ethernet/airoha/airoha_regs.h
|
|
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
|
|
@@ -423,11 +423,12 @@
|
|
((_n) == 2) ? 0x0720 : \
|
|
((_n) == 1) ? 0x0024 : 0x0020)
|
|
|
|
-#define REG_INT_ENABLE(_n) \
|
|
- (((_n) == 4) ? 0x0750 : \
|
|
- ((_n) == 3) ? 0x0744 : \
|
|
- ((_n) == 2) ? 0x0740 : \
|
|
- ((_n) == 1) ? 0x002c : 0x0028)
|
|
+#define REG_INT_ENABLE(_b, _n) \
|
|
+ (((_n) == 4) ? 0x0750 + ((_b) << 5) : \
|
|
+ ((_n) == 3) ? 0x0744 + ((_b) << 5) : \
|
|
+ ((_n) == 2) ? 0x0740 + ((_b) << 5) : \
|
|
+ ((_n) == 1) ? 0x002c + ((_b) << 3) : \
|
|
+ 0x0028 + ((_b) << 3))
|
|
|
|
/* QDMA_CSR_INT_ENABLE1 */
|
|
#define RX15_COHERENT_INT_MASK BIT(31)
|