9f05ad4057c7886add6b4c107378f96844ea1773
[openwrt/staging/xback.git] /
1 From 19e47fc2aeda3a657c4f64144ffd6e65f7a66601 Mon Sep 17 00:00:00 2001
2 From: Lorenzo Bianconi <lorenzo@kernel.org>
3 Date: Thu, 1 Aug 2024 16:35:05 +0200
4 Subject: [PATCH 3/8] net: airoha: Move irq_mask in airoha_qdma structure
5
6 QDMA controllers have independent irq lines, so move irqmask in
7 airoha_qdma structure. This is a preliminary patch to support multiple
8 QDMA controllers.
9
10 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
11 Link: https://patch.msgid.link/1c8a06e8be605278a7b2f3cd8ac06e74bf5ebf2b.1722522582.git.lorenzo@kernel.org
12 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
13 ---
14 drivers/net/ethernet/mediatek/airoha_eth.c | 84 +++++++++++-----------
15 1 file changed, 42 insertions(+), 42 deletions(-)
16
17 --- a/drivers/net/ethernet/mediatek/airoha_eth.c
18 +++ b/drivers/net/ethernet/mediatek/airoha_eth.c
19 @@ -786,6 +786,11 @@ struct airoha_hw_stats {
20 struct airoha_qdma {
21 void __iomem *regs;
22
23 + /* protect concurrent irqmask accesses */
24 + spinlock_t irq_lock;
25 + u32 irqmask[QDMA_INT_REG_MAX];
26 + int irq;
27 +
28 struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
29
30 struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
31 @@ -812,11 +817,6 @@ struct airoha_eth {
32 unsigned long state;
33 void __iomem *fe_regs;
34
35 - /* protect concurrent irqmask accesses */
36 - spinlock_t irq_lock;
37 - u32 irqmask[QDMA_INT_REG_MAX];
38 - int irq;
39 -
40 struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
41 struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
42
43 @@ -866,38 +866,37 @@ static u32 airoha_rmw(void __iomem *base
44 #define airoha_qdma_clear(qdma, offset, val) \
45 airoha_rmw((qdma)->regs, (offset), (val), 0)
46
47 -static void airoha_qdma_set_irqmask(struct airoha_eth *eth, int index,
48 +static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index,
49 u32 clear, u32 set)
50 {
51 unsigned long flags;
52
53 - if (WARN_ON_ONCE(index >= ARRAY_SIZE(eth->irqmask)))
54 + if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask)))
55 return;
56
57 - spin_lock_irqsave(&eth->irq_lock, flags);
58 + spin_lock_irqsave(&qdma->irq_lock, flags);
59
60 - eth->irqmask[index] &= ~clear;
61 - eth->irqmask[index] |= set;
62 - airoha_qdma_wr(&eth->qdma[0], REG_INT_ENABLE(index),
63 - eth->irqmask[index]);
64 + qdma->irqmask[index] &= ~clear;
65 + qdma->irqmask[index] |= set;
66 + airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]);
67 /* Read irq_enable register in order to guarantee the update above
68 * completes in the spinlock critical section.
69 */
70 - airoha_qdma_rr(&eth->qdma[0], REG_INT_ENABLE(index));
71 + airoha_qdma_rr(qdma, REG_INT_ENABLE(index));
72
73 - spin_unlock_irqrestore(&eth->irq_lock, flags);
74 + spin_unlock_irqrestore(&qdma->irq_lock, flags);
75 }
76
77 -static void airoha_qdma_irq_enable(struct airoha_eth *eth, int index,
78 +static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index,
79 u32 mask)
80 {
81 - airoha_qdma_set_irqmask(eth, index, 0, mask);
82 + airoha_qdma_set_irqmask(qdma, index, 0, mask);
83 }
84
85 -static void airoha_qdma_irq_disable(struct airoha_eth *eth, int index,
86 +static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index,
87 u32 mask)
88 {
89 - airoha_qdma_set_irqmask(eth, index, mask, 0);
90 + airoha_qdma_set_irqmask(qdma, index, mask, 0);
91 }
92
93 static void airoha_set_macaddr(struct airoha_eth *eth, const u8 *addr)
94 @@ -1522,7 +1521,7 @@ static int airoha_qdma_rx_process(struct
95 static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
96 {
97 struct airoha_queue *q = container_of(napi, struct airoha_queue, napi);
98 - struct airoha_eth *eth = q->eth;
99 + struct airoha_qdma *qdma = &q->eth->qdma[0];
100 int cur, done = 0;
101
102 do {
103 @@ -1531,7 +1530,7 @@ static int airoha_qdma_rx_napi_poll(stru
104 } while (cur && done < budget);
105
106 if (done < budget && napi_complete(napi))
107 - airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX1,
108 + airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1,
109 RX_DONE_INT_MASK);
110
111 return done;
112 @@ -1719,7 +1718,7 @@ static int airoha_qdma_tx_napi_poll(stru
113 }
114
115 if (done < budget && napi_complete(napi))
116 - airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0,
117 + airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0,
118 TX_DONE_INT_MASK(id));
119
120 return done;
121 @@ -1928,13 +1927,13 @@ static int airoha_qdma_hw_init(struct ai
122 int i;
123
124 /* clear pending irqs */
125 - for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++)
126 + for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++)
127 airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff);
128
129 /* setup irqs */
130 - airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
131 - airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX1, INT_IDX1_MASK);
132 - airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
133 + airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
134 + airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK);
135 + airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
136
137 /* setup irq binding */
138 for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
139 @@ -1980,14 +1979,13 @@ static int airoha_qdma_hw_init(struct ai
140 static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
141 {
142 struct airoha_eth *eth = dev_instance;
143 - u32 intr[ARRAY_SIZE(eth->irqmask)];
144 - struct airoha_qdma *qdma;
145 + struct airoha_qdma *qdma = &eth->qdma[0];
146 + u32 intr[ARRAY_SIZE(qdma->irqmask)];
147 int i;
148
149 - qdma = &eth->qdma[0];
150 - for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++) {
151 + for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) {
152 intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i));
153 - intr[i] &= eth->irqmask[i];
154 + intr[i] &= qdma->irqmask[i];
155 airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
156 }
157
158 @@ -1995,7 +1993,7 @@ static irqreturn_t airoha_irq_handler(in
159 return IRQ_NONE;
160
161 if (intr[1] & RX_DONE_INT_MASK) {
162 - airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX1,
163 + airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1,
164 RX_DONE_INT_MASK);
165
166 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
167 @@ -2015,7 +2013,7 @@ static irqreturn_t airoha_irq_handler(in
168 if (!(intr[0] & TX_DONE_INT_MASK(i)))
169 continue;
170
171 - airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX0,
172 + airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0,
173 TX_DONE_INT_MASK(i));
174
175 status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(i));
176 @@ -2030,12 +2028,18 @@ static irqreturn_t airoha_irq_handler(in
177 return IRQ_HANDLED;
178 }
179
180 -static int airoha_qdma_init(struct airoha_eth *eth)
181 +static int airoha_qdma_init(struct platform_device *pdev,
182 + struct airoha_eth *eth)
183 {
184 struct airoha_qdma *qdma = &eth->qdma[0];
185 int err;
186
187 - err = devm_request_irq(eth->dev, eth->irq, airoha_irq_handler,
188 + spin_lock_init(&qdma->irq_lock);
189 + qdma->irq = platform_get_irq(pdev, 0);
190 + if (qdma->irq < 0)
191 + return qdma->irq;
192 +
193 + err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler,
194 IRQF_SHARED, KBUILD_MODNAME, eth);
195 if (err)
196 return err;
197 @@ -2061,7 +2065,8 @@ static int airoha_qdma_init(struct airoh
198 return 0;
199 }
200
201 -static int airoha_hw_init(struct airoha_eth *eth)
202 +static int airoha_hw_init(struct platform_device *pdev,
203 + struct airoha_eth *eth)
204 {
205 int err;
206
207 @@ -2077,7 +2082,7 @@ static int airoha_hw_init(struct airoha_
208 if (err)
209 return err;
210
211 - return airoha_qdma_init(eth);
212 + return airoha_qdma_init(pdev, eth);
213 }
214
215 static void airoha_hw_cleanup(struct airoha_eth *eth)
216 @@ -2674,11 +2679,6 @@ static int airoha_probe(struct platform_
217 return err;
218 }
219
220 - spin_lock_init(&eth->irq_lock);
221 - eth->irq = platform_get_irq(pdev, 0);
222 - if (eth->irq < 0)
223 - return eth->irq;
224 -
225 eth->napi_dev = alloc_netdev_dummy(0);
226 if (!eth->napi_dev)
227 return -ENOMEM;
228 @@ -2688,7 +2688,7 @@ static int airoha_probe(struct platform_
229 strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name));
230 platform_set_drvdata(pdev, eth);
231
232 - err = airoha_hw_init(eth);
233 + err = airoha_hw_init(pdev, eth);
234 if (err)
235 goto error;
236