* [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller
@ 2024-07-30 16:22 Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 1/9] net: airoha: Introduce airoha_qdma struct Lorenzo Bianconi
` (8 more replies)
0 siblings, 9 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
EN7581 SoC supports two independent QDMA controllers to connect the
Ethernet Frame Engine (FE) to the CPU. Introduce support for the second
QDMA controller. This is a preliminary series to support multiple FE ports
(e.g. connected to a second PHY controller).
Lorenzo Bianconi (9):
net: airoha: Introduce airoha_qdma struct
net: airoha: Move airoha_queues in airoha_qdma
net: airoha: Move irq_mask in airoha_qdma structure
net: airoha: Add airoha_qdma pointer in
airoha_tx_irq_queue/airoha_queue structures
net: airoha: Use qdma pointer as private structure in
airoha_irq_handler routine
net: airoha: Allow mapping IO region for multiple qdma controllers
net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup()
net: airoha: Start all qdma NAPIs in airoha_probe()
net: airoha: Link the gdm port to the selected qdma controller
drivers/net/ethernet/mediatek/airoha_eth.c | 491 +++++++++++----------
1 file changed, 266 insertions(+), 225 deletions(-)
--
2.45.2
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net-next 1/9] net: airoha: Introduce airoha_qdma struct
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 2/9] net: airoha: Move airoha_queues in airoha_qdma Lorenzo Bianconi
` (7 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
Introduce airoha_qdma struct and move qdma IO register mapping in
airoha_qdma. This is a preliminary patch to enable both QDMA controllers
available on EN7581 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 168 ++++++++++++---------
1 file changed, 99 insertions(+), 69 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 1c5b85a86df1..4d0b3cbc8912 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -18,6 +18,7 @@
#include <uapi/linux/ppp_defs.h>
#define AIROHA_MAX_NUM_GDM_PORTS 1
+#define AIROHA_MAX_NUM_QDMA 1
#define AIROHA_MAX_NUM_RSTS 3
#define AIROHA_MAX_NUM_XSI_RSTS 5
#define AIROHA_MAX_MTU 2000
@@ -782,6 +783,10 @@ struct airoha_hw_stats {
u64 rx_len[7];
};
+struct airoha_qdma {
+ void __iomem *regs;
+};
+
struct airoha_gdm_port {
struct net_device *dev;
struct airoha_eth *eth;
@@ -794,8 +799,6 @@ struct airoha_eth {
struct device *dev;
unsigned long state;
-
- void __iomem *qdma_regs;
void __iomem *fe_regs;
/* protect concurrent irqmask accesses */
@@ -806,6 +809,7 @@ struct airoha_eth {
struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
+ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA];
struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
struct net_device *napi_dev;
@@ -850,16 +854,16 @@ static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
#define airoha_fe_clear(eth, offset, val) \
airoha_rmw((eth)->fe_regs, (offset), (val), 0)
-#define airoha_qdma_rr(eth, offset) \
- airoha_rr((eth)->qdma_regs, (offset))
-#define airoha_qdma_wr(eth, offset, val) \
- airoha_wr((eth)->qdma_regs, (offset), (val))
-#define airoha_qdma_rmw(eth, offset, mask, val) \
- airoha_rmw((eth)->qdma_regs, (offset), (mask), (val))
-#define airoha_qdma_set(eth, offset, val) \
- airoha_rmw((eth)->qdma_regs, (offset), 0, (val))
-#define airoha_qdma_clear(eth, offset, val) \
- airoha_rmw((eth)->qdma_regs, (offset), (val), 0)
+#define airoha_qdma_rr(qdma, offset) \
+ airoha_rr((qdma)->regs, (offset))
+#define airoha_qdma_wr(qdma, offset, val) \
+ airoha_wr((qdma)->regs, (offset), (val))
+#define airoha_qdma_rmw(qdma, offset, mask, val) \
+ airoha_rmw((qdma)->regs, (offset), (mask), (val))
+#define airoha_qdma_set(qdma, offset, val) \
+ airoha_rmw((qdma)->regs, (offset), 0, (val))
+#define airoha_qdma_clear(qdma, offset, val) \
+ airoha_rmw((qdma)->regs, (offset), (val), 0)
static void airoha_qdma_set_irqmask(struct airoha_eth *eth, int index,
u32 clear, u32 set)
@@ -873,11 +877,12 @@ static void airoha_qdma_set_irqmask(struct airoha_eth *eth, int index,
eth->irqmask[index] &= ~clear;
eth->irqmask[index] |= set;
- airoha_qdma_wr(eth, REG_INT_ENABLE(index), eth->irqmask[index]);
+ airoha_qdma_wr(ð->qdma[0], REG_INT_ENABLE(index),
+ eth->irqmask[index]);
/* Read irq_enable register in order to guarantee the update above
* completes in the spinlock critical section.
*/
- airoha_qdma_rr(eth, REG_INT_ENABLE(index));
+ airoha_qdma_rr(ð->qdma[0], REG_INT_ENABLE(index));
spin_unlock_irqrestore(ð->irq_lock, flags);
}
@@ -1420,7 +1425,8 @@ static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
WRITE_ONCE(desc->msg2, 0);
WRITE_ONCE(desc->msg3, 0);
- airoha_qdma_rmw(eth, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_RX_CPU_IDX(qid),
+ RX_RING_CPU_IDX_MASK,
FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
}
@@ -1568,14 +1574,17 @@ static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
- airoha_qdma_wr(eth, REG_RX_RING_BASE(qid), dma_addr);
- airoha_qdma_rmw(eth, REG_RX_RING_SIZE(qid), RX_RING_SIZE_MASK,
+ airoha_qdma_wr(ð->qdma[0], REG_RX_RING_BASE(qid), dma_addr);
+ airoha_qdma_rmw(ð->qdma[0], REG_RX_RING_SIZE(qid),
+ RX_RING_SIZE_MASK,
FIELD_PREP(RX_RING_SIZE_MASK, ndesc));
thr = clamp(ndesc >> 3, 1, 32);
- airoha_qdma_rmw(eth, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_RX_RING_SIZE(qid),
+ RX_RING_THR_MASK,
FIELD_PREP(RX_RING_THR_MASK, thr));
- airoha_qdma_rmw(eth, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_RX_DMA_IDX(qid),
+ RX_RING_DMA_IDX_MASK,
FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head));
airoha_qdma_fill_rx_queue(q);
@@ -1697,9 +1706,9 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
int i, len = done >> 7;
for (i = 0; i < len; i++)
- airoha_qdma_rmw(eth, REG_IRQ_CLEAR_LEN(id),
+ airoha_qdma_rmw(ð->qdma[0], REG_IRQ_CLEAR_LEN(id),
IRQ_CLEAR_LEN_MASK, 0x80);
- airoha_qdma_rmw(eth, REG_IRQ_CLEAR_LEN(id),
+ airoha_qdma_rmw(ð->qdma[0], REG_IRQ_CLEAR_LEN(id),
IRQ_CLEAR_LEN_MASK, (done & 0x7f));
}
@@ -1738,10 +1747,12 @@ static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
}
- airoha_qdma_wr(eth, REG_TX_RING_BASE(qid), dma_addr);
- airoha_qdma_rmw(eth, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
+ airoha_qdma_wr(ð->qdma[0], REG_TX_RING_BASE(qid), dma_addr);
+ airoha_qdma_rmw(ð->qdma[0], REG_TX_CPU_IDX(qid),
+ TX_RING_CPU_IDX_MASK,
FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head));
- airoha_qdma_rmw(eth, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_TX_DMA_IDX(qid),
+ TX_RING_DMA_IDX_MASK,
FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head));
return 0;
@@ -1765,10 +1776,12 @@ static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
irq_q->size = size;
irq_q->eth = eth;
- airoha_qdma_wr(eth, REG_TX_IRQ_BASE(id), dma_addr);
- airoha_qdma_rmw(eth, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
+ airoha_qdma_wr(ð->qdma[0], REG_TX_IRQ_BASE(id), dma_addr);
+ airoha_qdma_rmw(ð->qdma[0], REG_TX_IRQ_CFG(id),
+ TX_IRQ_DEPTH_MASK,
FIELD_PREP(TX_IRQ_DEPTH_MASK, size));
- airoha_qdma_rmw(eth, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_TX_IRQ_CFG(id),
+ TX_IRQ_THR_MASK,
FIELD_PREP(TX_IRQ_THR_MASK, 1));
return 0;
@@ -1826,7 +1839,7 @@ static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth)
if (!eth->hfwd.desc)
return -ENOMEM;
- airoha_qdma_wr(eth, REG_FWD_DSCP_BASE, dma_addr);
+ airoha_qdma_wr(ð->qdma[0], REG_FWD_DSCP_BASE, dma_addr);
size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM;
eth->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr,
@@ -1834,14 +1847,15 @@ static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth)
if (!eth->hfwd.q)
return -ENOMEM;
- airoha_qdma_wr(eth, REG_FWD_BUF_BASE, dma_addr);
+ airoha_qdma_wr(ð->qdma[0], REG_FWD_BUF_BASE, dma_addr);
- airoha_qdma_rmw(eth, REG_HW_FWD_DSCP_CFG,
+ airoha_qdma_rmw(ð->qdma[0], REG_HW_FWD_DSCP_CFG,
HW_FWD_DSCP_PAYLOAD_SIZE_MASK,
FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0));
- airoha_qdma_rmw(eth, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_FWD_DSCP_LOW_THR,
+ FWD_DSCP_LOW_THR_MASK,
FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128));
- airoha_qdma_rmw(eth, REG_LMGR_INIT_CFG,
+ airoha_qdma_rmw(ð->qdma[0], REG_LMGR_INIT_CFG,
LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
HW_FWD_DESC_NUM_MASK,
FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) |
@@ -1849,57 +1863,65 @@ static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth)
return read_poll_timeout(airoha_qdma_rr, status,
!(status & LMGR_INIT_START), USEC_PER_MSEC,
- 30 * USEC_PER_MSEC, true, eth,
+ 30 * USEC_PER_MSEC, true, ð->qdma[0],
REG_LMGR_INIT_CFG);
}
static void airoha_qdma_init_qos(struct airoha_eth *eth)
{
- airoha_qdma_clear(eth, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK);
- airoha_qdma_set(eth, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK);
+ airoha_qdma_clear(ð->qdma[0], REG_TXWRR_MODE_CFG,
+ TWRR_WEIGHT_SCALE_MASK);
+ airoha_qdma_set(ð->qdma[0], REG_TXWRR_MODE_CFG,
+ TWRR_WEIGHT_BASE_MASK);
- airoha_qdma_clear(eth, REG_PSE_BUF_USAGE_CFG,
+ airoha_qdma_clear(ð->qdma[0], REG_PSE_BUF_USAGE_CFG,
PSE_BUF_ESTIMATE_EN_MASK);
- airoha_qdma_set(eth, REG_EGRESS_RATE_METER_CFG,
+ airoha_qdma_set(ð->qdma[0], REG_EGRESS_RATE_METER_CFG,
EGRESS_RATE_METER_EN_MASK |
EGRESS_RATE_METER_EQ_RATE_EN_MASK);
/* 2047us x 31 = 63.457ms */
- airoha_qdma_rmw(eth, REG_EGRESS_RATE_METER_CFG,
+ airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_RATE_METER_CFG,
EGRESS_RATE_METER_WINDOW_SZ_MASK,
FIELD_PREP(EGRESS_RATE_METER_WINDOW_SZ_MASK, 0x1f));
- airoha_qdma_rmw(eth, REG_EGRESS_RATE_METER_CFG,
+ airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_RATE_METER_CFG,
EGRESS_RATE_METER_TIMESLICE_MASK,
FIELD_PREP(EGRESS_RATE_METER_TIMESLICE_MASK, 0x7ff));
/* ratelimit init */
- airoha_qdma_set(eth, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK);
+ airoha_qdma_set(ð->qdma[0], REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK);
/* fast-tick 25us */
- airoha_qdma_rmw(eth, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK,
FIELD_PREP(GLB_FAST_TICK_MASK, 25));
- airoha_qdma_rmw(eth, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_GLB_TRTCM_CFG,
+ GLB_SLOW_TICK_RATIO_MASK,
FIELD_PREP(GLB_SLOW_TICK_RATIO_MASK, 40));
- airoha_qdma_set(eth, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK);
- airoha_qdma_rmw(eth, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK,
+ airoha_qdma_set(ð->qdma[0], REG_EGRESS_TRTCM_CFG,
+ EGRESS_TRTCM_EN_MASK);
+ airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_TRTCM_CFG,
+ EGRESS_FAST_TICK_MASK,
FIELD_PREP(EGRESS_FAST_TICK_MASK, 25));
- airoha_qdma_rmw(eth, REG_EGRESS_TRTCM_CFG,
+ airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_TRTCM_CFG,
EGRESS_SLOW_TICK_RATIO_MASK,
FIELD_PREP(EGRESS_SLOW_TICK_RATIO_MASK, 40));
- airoha_qdma_set(eth, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK);
- airoha_qdma_clear(eth, REG_INGRESS_TRTCM_CFG,
+ airoha_qdma_set(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
+ INGRESS_TRTCM_EN_MASK);
+ airoha_qdma_clear(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
INGRESS_TRTCM_MODE_MASK);
- airoha_qdma_rmw(eth, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
+ INGRESS_FAST_TICK_MASK,
FIELD_PREP(INGRESS_FAST_TICK_MASK, 125));
- airoha_qdma_rmw(eth, REG_INGRESS_TRTCM_CFG,
+ airoha_qdma_rmw(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
INGRESS_SLOW_TICK_RATIO_MASK,
FIELD_PREP(INGRESS_SLOW_TICK_RATIO_MASK, 8));
- airoha_qdma_set(eth, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK);
- airoha_qdma_rmw(eth, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK,
+ airoha_qdma_set(ð->qdma[0], REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK);
+ airoha_qdma_rmw(ð->qdma[0], REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK,
FIELD_PREP(SLA_FAST_TICK_MASK, 25));
- airoha_qdma_rmw(eth, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_SLA_TRTCM_CFG,
+ SLA_SLOW_TICK_RATIO_MASK,
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
}
@@ -1909,7 +1931,7 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth)
/* clear pending irqs */
for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++)
- airoha_qdma_wr(eth, REG_INT_STATUS(i), 0xffffffff);
+ airoha_qdma_wr(ð->qdma[0], REG_INT_STATUS(i), 0xffffffff);
/* setup irqs */
airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
@@ -1922,14 +1944,16 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth)
continue;
if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i))
- airoha_qdma_set(eth, REG_TX_RING_BLOCKING(i),
+ airoha_qdma_set(ð->qdma[0],
+ REG_TX_RING_BLOCKING(i),
TX_RING_IRQ_BLOCKING_CFG_MASK);
else
- airoha_qdma_clear(eth, REG_TX_RING_BLOCKING(i),
+ airoha_qdma_clear(ð->qdma[0],
+ REG_TX_RING_BLOCKING(i),
TX_RING_IRQ_BLOCKING_CFG_MASK);
}
- airoha_qdma_wr(eth, REG_QDMA_GLOBAL_CFG,
+ airoha_qdma_wr(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
GLOBAL_CFG_RX_2B_OFFSET_MASK |
FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) |
GLOBAL_CFG_CPU_TXR_RR_MASK |
@@ -1947,11 +1971,11 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth)
if (!eth->q_rx[i].ndesc)
continue;
- airoha_qdma_clear(eth, REG_RX_DELAY_INT_IDX(i),
+ airoha_qdma_clear(ð->qdma[0], REG_RX_DELAY_INT_IDX(i),
RX_DELAY_INT_MASK);
}
- airoha_qdma_set(eth, REG_TXQ_CNGST_CFG,
+ airoha_qdma_set(ð->qdma[0], REG_TXQ_CNGST_CFG,
TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN);
return 0;
@@ -1964,9 +1988,9 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
int i;
for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++) {
- intr[i] = airoha_qdma_rr(eth, REG_INT_STATUS(i));
+ intr[i] = airoha_qdma_rr(ð->qdma[0], REG_INT_STATUS(i));
intr[i] &= eth->irqmask[i];
- airoha_qdma_wr(eth, REG_INT_STATUS(i), intr[i]);
+ airoha_qdma_wr(ð->qdma[0], REG_INT_STATUS(i), intr[i]);
}
if (!test_bit(DEV_STATE_INITIALIZED, ð->state))
@@ -1996,7 +2020,8 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX0,
TX_DONE_INT_MASK(i));
- status = airoha_qdma_rr(eth, REG_IRQ_STATUS(i));
+ status = airoha_qdma_rr(ð->qdma[0],
+ REG_IRQ_STATUS(i));
head = FIELD_GET(IRQ_HEAD_IDX_MASK, status);
irq_q->head = head % irq_q->size;
irq_q->queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
@@ -2262,8 +2287,9 @@ static int airoha_dev_open(struct net_device *dev)
airoha_fe_clear(eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
- airoha_qdma_set(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_TX_DMA_EN_MASK);
- airoha_qdma_set(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_RX_DMA_EN_MASK);
+ airoha_qdma_set(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
+ GLOBAL_CFG_TX_DMA_EN_MASK |
+ GLOBAL_CFG_RX_DMA_EN_MASK);
return 0;
}
@@ -2279,8 +2305,9 @@ static int airoha_dev_stop(struct net_device *dev)
if (err)
return err;
- airoha_qdma_clear(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_TX_DMA_EN_MASK);
- airoha_qdma_clear(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_RX_DMA_EN_MASK);
+ airoha_qdma_clear(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
+ GLOBAL_CFG_TX_DMA_EN_MASK |
+ GLOBAL_CFG_RX_DMA_EN_MASK);
return 0;
}
@@ -2411,7 +2438,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
e->dma_addr = addr;
e->dma_len = len;
- airoha_qdma_rmw(eth, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
+ airoha_qdma_rmw(ð->qdma[0], REG_TX_CPU_IDX(qid),
+ TX_RING_CPU_IDX_MASK,
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
data = skb_frag_address(frag);
@@ -2613,9 +2641,11 @@ static int airoha_probe(struct platform_device *pdev)
return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs),
"failed to iomap fe regs\n");
- eth->qdma_regs = devm_platform_ioremap_resource_byname(pdev, "qdma0");
- if (IS_ERR(eth->qdma_regs))
- return dev_err_probe(eth->dev, PTR_ERR(eth->qdma_regs),
+ eth->qdma[0].regs = devm_platform_ioremap_resource_byname(pdev,
+ "qdma0");
+ if (IS_ERR(eth->qdma[0].regs))
+ return dev_err_probe(eth->dev,
+ PTR_ERR(eth->qdma[0].regs),
"failed to iomap qdma regs\n");
eth->rsts[0].id = "fe";
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 2/9] net: airoha: Move airoha_queues in airoha_qdma
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 1/9] net: airoha: Introduce airoha_qdma struct Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-08-01 2:15 ` Jakub Kicinski
2024-07-30 16:22 ` [PATCH net-next 3/9] net: airoha: Move irq_mask in airoha_qdma structure Lorenzo Bianconi
` (6 subsequent siblings)
8 siblings, 1 reply; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
QDMA controllers available in EN7581 SoC have independent tx/rx hw queues
so move them in airoha_queues structure.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 285 +++++++++++----------
1 file changed, 144 insertions(+), 141 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 4d0b3cbc8912..10bb30732c32 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -785,6 +785,17 @@ struct airoha_hw_stats {
struct airoha_qdma {
void __iomem *regs;
+
+ struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
+
+ struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
+ struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
+
+ /* descriptor and packet buffers for qdma hw forward */
+ struct {
+ void *desc;
+ void *q;
+ } hfwd;
};
struct airoha_gdm_port {
@@ -809,20 +820,10 @@ struct airoha_eth {
struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
- struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA];
- struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
-
struct net_device *napi_dev;
- struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
- struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
- struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
-
- /* descriptor and packet buffers for qdma hw forward */
- struct {
- void *desc;
- void *q;
- } hfwd;
+ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA];
+ struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
};
static u32 airoha_rr(void __iomem *base, u32 offset)
@@ -1388,8 +1389,9 @@ static int airoha_fe_init(struct airoha_eth *eth)
static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
{
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
+ struct airoha_qdma *qdma = &q->eth->qdma[0];
struct airoha_eth *eth = q->eth;
- int qid = q - ð->q_rx[0];
+ int qid = q - &qdma->q_rx[0];
int nframes = 0;
while (q->queued < q->ndesc - 1) {
@@ -1425,7 +1427,7 @@ static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
WRITE_ONCE(desc->msg2, 0);
WRITE_ONCE(desc->msg3, 0);
- airoha_qdma_rmw(ð->qdma[0], REG_RX_CPU_IDX(qid),
+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid),
RX_RING_CPU_IDX_MASK,
FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
}
@@ -1456,8 +1458,9 @@ static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
{
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
+ struct airoha_qdma *qdma = &q->eth->qdma[0];
struct airoha_eth *eth = q->eth;
- int qid = q - ð->q_rx[0];
+ int qid = q - &qdma->q_rx[0];
int done = 0;
while (done < budget) {
@@ -1535,7 +1538,8 @@ static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
}
static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
- struct airoha_queue *q, int ndesc)
+ struct airoha_queue *q,
+ struct airoha_qdma *qdma, int ndesc)
{
const struct page_pool_params pp_params = {
.order = 0,
@@ -1547,7 +1551,7 @@ static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
.dev = eth->dev,
.napi = &q->napi,
};
- int qid = q - ð->q_rx[0], thr;
+ int qid = q - &qdma->q_rx[0], thr;
dma_addr_t dma_addr;
q->buf_size = PAGE_SIZE / 2;
@@ -1574,17 +1578,15 @@ static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
- airoha_qdma_wr(ð->qdma[0], REG_RX_RING_BASE(qid), dma_addr);
- airoha_qdma_rmw(ð->qdma[0], REG_RX_RING_SIZE(qid),
+ airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr);
+ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid),
RX_RING_SIZE_MASK,
FIELD_PREP(RX_RING_SIZE_MASK, ndesc));
thr = clamp(ndesc >> 3, 1, 32);
- airoha_qdma_rmw(ð->qdma[0], REG_RX_RING_SIZE(qid),
- RX_RING_THR_MASK,
+ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK,
FIELD_PREP(RX_RING_THR_MASK, thr));
- airoha_qdma_rmw(ð->qdma[0], REG_RX_DMA_IDX(qid),
- RX_RING_DMA_IDX_MASK,
+ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head));
airoha_qdma_fill_rx_queue(q);
@@ -1608,11 +1610,12 @@ static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
}
}
-static int airoha_qdma_init_rx(struct airoha_eth *eth)
+static int airoha_qdma_init_rx(struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
int i;
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
int err;
if (!(RX_DONE_INT_MASK & BIT(i))) {
@@ -1620,8 +1623,8 @@ static int airoha_qdma_init_rx(struct airoha_eth *eth)
continue;
}
- err = airoha_qdma_init_rx_queue(eth, ð->q_rx[i],
- RX_DSCP_NUM(i));
+ err = airoha_qdma_init_rx_queue(eth, &qdma->q_rx[i],
+ qdma, RX_DSCP_NUM(i));
if (err)
return err;
}
@@ -1632,12 +1635,14 @@ static int airoha_qdma_init_rx(struct airoha_eth *eth)
static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
{
struct airoha_tx_irq_queue *irq_q;
+ struct airoha_qdma *qdma;
struct airoha_eth *eth;
int id, done = 0;
irq_q = container_of(napi, struct airoha_tx_irq_queue, napi);
eth = irq_q->eth;
- id = irq_q - ð->q_tx_irq[0];
+ qdma = ð->qdma[0];
+ id = irq_q - &qdma->q_tx_irq[0];
while (irq_q->queued > 0 && done < budget) {
u32 qid, last, val = irq_q->q[irq_q->head];
@@ -1654,10 +1659,10 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
last = FIELD_GET(IRQ_DESC_IDX_MASK, val);
qid = FIELD_GET(IRQ_RING_IDX_MASK, val);
- if (qid >= ARRAY_SIZE(eth->q_tx))
+ if (qid >= ARRAY_SIZE(qdma->q_tx))
continue;
- q = ð->q_tx[qid];
+ q = &qdma->q_tx[qid];
if (!q->ndesc)
continue;
@@ -1706,9 +1711,9 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
int i, len = done >> 7;
for (i = 0; i < len; i++)
- airoha_qdma_rmw(ð->qdma[0], REG_IRQ_CLEAR_LEN(id),
+ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id),
IRQ_CLEAR_LEN_MASK, 0x80);
- airoha_qdma_rmw(ð->qdma[0], REG_IRQ_CLEAR_LEN(id),
+ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id),
IRQ_CLEAR_LEN_MASK, (done & 0x7f));
}
@@ -1720,9 +1725,10 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
}
static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
- struct airoha_queue *q, int size)
+ struct airoha_queue *q,
+ struct airoha_qdma *qdma, int size)
{
- int i, qid = q - ð->q_tx[0];
+ int i, qid = q - &qdma->q_tx[0];
dma_addr_t dma_addr;
spin_lock_init(&q->lock);
@@ -1747,12 +1753,10 @@ static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
}
- airoha_qdma_wr(ð->qdma[0], REG_TX_RING_BASE(qid), dma_addr);
- airoha_qdma_rmw(ð->qdma[0], REG_TX_CPU_IDX(qid),
- TX_RING_CPU_IDX_MASK,
+ airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr);
+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head));
- airoha_qdma_rmw(ð->qdma[0], REG_TX_DMA_IDX(qid),
- TX_RING_DMA_IDX_MASK,
+ airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head));
return 0;
@@ -1760,9 +1764,9 @@ static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
struct airoha_tx_irq_queue *irq_q,
- int size)
+ struct airoha_qdma *qdma, int size)
{
- int id = irq_q - ð->q_tx_irq[0];
+ int id = irq_q - &qdma->q_tx_irq[0];
dma_addr_t dma_addr;
netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
@@ -1776,31 +1780,30 @@ static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
irq_q->size = size;
irq_q->eth = eth;
- airoha_qdma_wr(ð->qdma[0], REG_TX_IRQ_BASE(id), dma_addr);
- airoha_qdma_rmw(ð->qdma[0], REG_TX_IRQ_CFG(id),
- TX_IRQ_DEPTH_MASK,
+ airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr);
+ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
FIELD_PREP(TX_IRQ_DEPTH_MASK, size));
- airoha_qdma_rmw(ð->qdma[0], REG_TX_IRQ_CFG(id),
- TX_IRQ_THR_MASK,
+ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK,
FIELD_PREP(TX_IRQ_THR_MASK, 1));
return 0;
}
-static int airoha_qdma_init_tx(struct airoha_eth *eth)
+static int airoha_qdma_init_tx(struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
int i, err;
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++) {
- err = airoha_qdma_tx_irq_init(eth, ð->q_tx_irq[i],
- IRQ_QUEUE_LEN(i));
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
+ err = airoha_qdma_tx_irq_init(eth, &qdma->q_tx_irq[i],
+ qdma, IRQ_QUEUE_LEN(i));
if (err)
return err;
}
- for (i = 0; i < ARRAY_SIZE(eth->q_tx); i++) {
- err = airoha_qdma_init_tx_queue(eth, ð->q_tx[i],
- TX_DSCP_NUM);
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
+ err = airoha_qdma_init_tx_queue(eth, &qdma->q_tx[i],
+ qdma, TX_DSCP_NUM);
if (err)
return err;
}
@@ -1827,35 +1830,36 @@ static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
spin_unlock_bh(&q->lock);
}
-static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth)
+static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
dma_addr_t dma_addr;
u32 status;
int size;
size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc);
- eth->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr,
- GFP_KERNEL);
- if (!eth->hfwd.desc)
+ qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr,
+ GFP_KERNEL);
+ if (!qdma->hfwd.desc)
return -ENOMEM;
- airoha_qdma_wr(ð->qdma[0], REG_FWD_DSCP_BASE, dma_addr);
+ airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr);
size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM;
- eth->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr,
- GFP_KERNEL);
- if (!eth->hfwd.q)
+ qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr,
+ GFP_KERNEL);
+ if (!qdma->hfwd.q)
return -ENOMEM;
- airoha_qdma_wr(ð->qdma[0], REG_FWD_BUF_BASE, dma_addr);
+ airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr);
- airoha_qdma_rmw(ð->qdma[0], REG_HW_FWD_DSCP_CFG,
+ airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG,
HW_FWD_DSCP_PAYLOAD_SIZE_MASK,
FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0));
- airoha_qdma_rmw(ð->qdma[0], REG_FWD_DSCP_LOW_THR,
+ airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR,
FWD_DSCP_LOW_THR_MASK,
FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128));
- airoha_qdma_rmw(ð->qdma[0], REG_LMGR_INIT_CFG,
+ airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG,
LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
HW_FWD_DESC_NUM_MASK,
FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) |
@@ -1863,75 +1867,69 @@ static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth)
return read_poll_timeout(airoha_qdma_rr, status,
!(status & LMGR_INIT_START), USEC_PER_MSEC,
- 30 * USEC_PER_MSEC, true, ð->qdma[0],
+ 30 * USEC_PER_MSEC, true, qdma,
REG_LMGR_INIT_CFG);
}
-static void airoha_qdma_init_qos(struct airoha_eth *eth)
+static void airoha_qdma_init_qos(struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
- airoha_qdma_clear(ð->qdma[0], REG_TXWRR_MODE_CFG,
- TWRR_WEIGHT_SCALE_MASK);
- airoha_qdma_set(ð->qdma[0], REG_TXWRR_MODE_CFG,
- TWRR_WEIGHT_BASE_MASK);
+ airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK);
+ airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK);
- airoha_qdma_clear(ð->qdma[0], REG_PSE_BUF_USAGE_CFG,
+ airoha_qdma_clear(qdma, REG_PSE_BUF_USAGE_CFG,
PSE_BUF_ESTIMATE_EN_MASK);
- airoha_qdma_set(ð->qdma[0], REG_EGRESS_RATE_METER_CFG,
+ airoha_qdma_set(qdma, REG_EGRESS_RATE_METER_CFG,
EGRESS_RATE_METER_EN_MASK |
EGRESS_RATE_METER_EQ_RATE_EN_MASK);
/* 2047us x 31 = 63.457ms */
- airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_RATE_METER_CFG,
+ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG,
EGRESS_RATE_METER_WINDOW_SZ_MASK,
FIELD_PREP(EGRESS_RATE_METER_WINDOW_SZ_MASK, 0x1f));
- airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_RATE_METER_CFG,
+ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG,
EGRESS_RATE_METER_TIMESLICE_MASK,
FIELD_PREP(EGRESS_RATE_METER_TIMESLICE_MASK, 0x7ff));
/* ratelimit init */
- airoha_qdma_set(ð->qdma[0], REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK);
+ airoha_qdma_set(qdma, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK);
/* fast-tick 25us */
- airoha_qdma_rmw(ð->qdma[0], REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK,
+ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK,
FIELD_PREP(GLB_FAST_TICK_MASK, 25));
- airoha_qdma_rmw(ð->qdma[0], REG_GLB_TRTCM_CFG,
- GLB_SLOW_TICK_RATIO_MASK,
+ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK,
FIELD_PREP(GLB_SLOW_TICK_RATIO_MASK, 40));
- airoha_qdma_set(ð->qdma[0], REG_EGRESS_TRTCM_CFG,
- EGRESS_TRTCM_EN_MASK);
- airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_TRTCM_CFG,
- EGRESS_FAST_TICK_MASK,
+ airoha_qdma_set(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK);
+ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK,
FIELD_PREP(EGRESS_FAST_TICK_MASK, 25));
- airoha_qdma_rmw(ð->qdma[0], REG_EGRESS_TRTCM_CFG,
+ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG,
EGRESS_SLOW_TICK_RATIO_MASK,
FIELD_PREP(EGRESS_SLOW_TICK_RATIO_MASK, 40));
- airoha_qdma_set(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
- INGRESS_TRTCM_EN_MASK);
- airoha_qdma_clear(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
+ airoha_qdma_set(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK);
+ airoha_qdma_clear(qdma, REG_INGRESS_TRTCM_CFG,
INGRESS_TRTCM_MODE_MASK);
- airoha_qdma_rmw(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
- INGRESS_FAST_TICK_MASK,
+ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK,
FIELD_PREP(INGRESS_FAST_TICK_MASK, 125));
- airoha_qdma_rmw(ð->qdma[0], REG_INGRESS_TRTCM_CFG,
+ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG,
INGRESS_SLOW_TICK_RATIO_MASK,
FIELD_PREP(INGRESS_SLOW_TICK_RATIO_MASK, 8));
- airoha_qdma_set(ð->qdma[0], REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK);
- airoha_qdma_rmw(ð->qdma[0], REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK,
+ airoha_qdma_set(qdma, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK);
+ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK,
FIELD_PREP(SLA_FAST_TICK_MASK, 25));
- airoha_qdma_rmw(ð->qdma[0], REG_SLA_TRTCM_CFG,
- SLA_SLOW_TICK_RATIO_MASK,
+ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK,
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
}
-static int airoha_qdma_hw_init(struct airoha_eth *eth)
+static int airoha_qdma_hw_init(struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
int i;
/* clear pending irqs */
for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++)
- airoha_qdma_wr(ð->qdma[0], REG_INT_STATUS(i), 0xffffffff);
+ airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff);
/* setup irqs */
airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
@@ -1939,21 +1937,20 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth)
airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
/* setup irq binding */
- for (i = 0; i < ARRAY_SIZE(eth->q_tx); i++) {
- if (!eth->q_tx[i].ndesc)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
+ if (!qdma->q_tx[i].ndesc)
continue;
if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i))
- airoha_qdma_set(ð->qdma[0],
- REG_TX_RING_BLOCKING(i),
+ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(i),
TX_RING_IRQ_BLOCKING_CFG_MASK);
else
- airoha_qdma_clear(ð->qdma[0],
+ airoha_qdma_clear(qdma,
REG_TX_RING_BLOCKING(i),
TX_RING_IRQ_BLOCKING_CFG_MASK);
}
- airoha_qdma_wr(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
+ airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG,
GLOBAL_CFG_RX_2B_OFFSET_MASK |
FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) |
GLOBAL_CFG_CPU_TXR_RR_MASK |
@@ -1964,18 +1961,18 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth)
GLOBAL_CFG_TX_WB_DONE_MASK |
FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2));
- airoha_qdma_init_qos(eth);
+ airoha_qdma_init_qos(eth, qdma);
/* disable qdma rx delay interrupt */
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
- if (!eth->q_rx[i].ndesc)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+ if (!qdma->q_rx[i].ndesc)
continue;
- airoha_qdma_clear(ð->qdma[0], REG_RX_DELAY_INT_IDX(i),
+ airoha_qdma_clear(qdma, REG_RX_DELAY_INT_IDX(i),
RX_DELAY_INT_MASK);
}
- airoha_qdma_set(ð->qdma[0], REG_TXQ_CNGST_CFG,
+ airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG,
TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN);
return 0;
@@ -1985,12 +1982,14 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
{
struct airoha_eth *eth = dev_instance;
u32 intr[ARRAY_SIZE(eth->irqmask)];
+ struct airoha_qdma *qdma;
int i;
+ qdma = ð->qdma[0];
for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++) {
- intr[i] = airoha_qdma_rr(ð->qdma[0], REG_INT_STATUS(i));
+ intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i));
intr[i] &= eth->irqmask[i];
- airoha_qdma_wr(ð->qdma[0], REG_INT_STATUS(i), intr[i]);
+ airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
}
if (!test_bit(DEV_STATE_INITIALIZED, ð->state))
@@ -2000,18 +1999,18 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX1,
RX_DONE_INT_MASK);
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
- if (!eth->q_rx[i].ndesc)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+ if (!qdma->q_rx[i].ndesc)
continue;
if (intr[1] & BIT(i))
- napi_schedule(ð->q_rx[i].napi);
+ napi_schedule(&qdma->q_rx[i].napi);
}
}
if (intr[0] & INT_TX_MASK) {
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++) {
- struct airoha_tx_irq_queue *irq_q = ð->q_tx_irq[i];
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
+ struct airoha_tx_irq_queue *irq_q = &qdma->q_tx_irq[i];
u32 status, head;
if (!(intr[0] & TX_DONE_INT_MASK(i)))
@@ -2020,13 +2019,12 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX0,
TX_DONE_INT_MASK(i));
- status = airoha_qdma_rr(ð->qdma[0],
- REG_IRQ_STATUS(i));
+ status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(i));
head = FIELD_GET(IRQ_HEAD_IDX_MASK, status);
irq_q->head = head % irq_q->size;
irq_q->queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
- napi_schedule(ð->q_tx_irq[i].napi);
+ napi_schedule(&qdma->q_tx_irq[i].napi);
}
}
@@ -2035,6 +2033,7 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
static int airoha_qdma_init(struct airoha_eth *eth)
{
+ struct airoha_qdma *qdma = ð->qdma[0];
int err;
err = devm_request_irq(eth->dev, eth->irq, airoha_irq_handler,
@@ -2042,19 +2041,19 @@ static int airoha_qdma_init(struct airoha_eth *eth)
if (err)
return err;
- err = airoha_qdma_init_rx(eth);
+ err = airoha_qdma_init_rx(eth, qdma);
if (err)
return err;
- err = airoha_qdma_init_tx(eth);
+ err = airoha_qdma_init_tx(eth, qdma);
if (err)
return err;
- err = airoha_qdma_init_hfwd_queues(eth);
+ err = airoha_qdma_init_hfwd_queues(eth, qdma);
if (err)
return err;
- err = airoha_qdma_hw_init(eth);
+ err = airoha_qdma_hw_init(eth, qdma);
if (err)
return err;
@@ -2084,44 +2083,46 @@ static int airoha_hw_init(struct airoha_eth *eth)
static void airoha_hw_cleanup(struct airoha_eth *eth)
{
+ struct airoha_qdma *qdma = ð->qdma[0];
int i;
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
- if (!eth->q_rx[i].ndesc)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+ if (!qdma->q_rx[i].ndesc)
continue;
- napi_disable(ð->q_rx[i].napi);
- netif_napi_del(ð->q_rx[i].napi);
- airoha_qdma_cleanup_rx_queue(ð->q_rx[i]);
- if (eth->q_rx[i].page_pool)
- page_pool_destroy(eth->q_rx[i].page_pool);
+ napi_disable(&qdma->q_rx[i].napi);
+ netif_napi_del(&qdma->q_rx[i].napi);
+ airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
+ if (qdma->q_rx[i].page_pool)
+ page_pool_destroy(qdma->q_rx[i].page_pool);
}
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++) {
- napi_disable(ð->q_tx_irq[i].napi);
- netif_napi_del(ð->q_tx_irq[i].napi);
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
+ napi_disable(&qdma->q_tx_irq[i].napi);
+ netif_napi_del(&qdma->q_tx_irq[i].napi);
}
- for (i = 0; i < ARRAY_SIZE(eth->q_tx); i++) {
- if (!eth->q_tx[i].ndesc)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
+ if (!qdma->q_tx[i].ndesc)
continue;
- airoha_qdma_cleanup_tx_queue(ð->q_tx[i]);
+ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
}
}
static void airoha_qdma_start_napi(struct airoha_eth *eth)
{
+ struct airoha_qdma *qdma = ð->qdma[0];
int i;
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++)
- napi_enable(ð->q_tx_irq[i].napi);
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
+ napi_enable(&qdma->q_tx_irq[i].napi);
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
- if (!eth->q_rx[i].ndesc)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+ if (!qdma->q_rx[i].ndesc)
continue;
- napi_enable(ð->q_rx[i].napi);
+ napi_enable(&qdma->q_rx[i].napi);
}
}
@@ -2367,6 +2368,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct airoha_eth *eth = port->eth;
u32 nr_frags = 1 + sinfo->nr_frags;
struct netdev_queue *txq;
+ struct airoha_qdma *qdma;
struct airoha_queue *q;
void *data = skb->data;
u16 index;
@@ -2394,7 +2396,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
- q = ð->q_tx[qid];
+ qdma = ð->qdma[0];
+ q = &qdma->q_tx[qid];
if (WARN_ON_ONCE(!q->ndesc))
goto error;
@@ -2438,7 +2441,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
e->dma_addr = addr;
e->dma_len = len;
- airoha_qdma_rmw(ð->qdma[0], REG_TX_CPU_IDX(qid),
+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
TX_RING_CPU_IDX_MASK,
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 3/9] net: airoha: Move irq_mask in airoha_qdma structure
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 1/9] net: airoha: Introduce airoha_qdma struct Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 2/9] net: airoha: Move airoha_queues in airoha_qdma Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 4/9] net: airoha: Add airoha_qdma pointer in airoha_tx_irq_queue/airoha_queue structures Lorenzo Bianconi
` (5 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
QDMA controllers have independent irq lines, so move irqmask in
airoha_qdma structure. This is a preliminary patch to support multiple
QDMA controllers.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 84 +++++++++++-----------
1 file changed, 42 insertions(+), 42 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 10bb30732c32..6e46558f4277 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -786,6 +786,11 @@ struct airoha_hw_stats {
struct airoha_qdma {
void __iomem *regs;
+ /* protect concurrent irqmask accesses */
+ spinlock_t irq_lock;
+ u32 irqmask[QDMA_INT_REG_MAX];
+ int irq;
+
struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
@@ -812,11 +817,6 @@ struct airoha_eth {
unsigned long state;
void __iomem *fe_regs;
- /* protect concurrent irqmask accesses */
- spinlock_t irq_lock;
- u32 irqmask[QDMA_INT_REG_MAX];
- int irq;
-
struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
@@ -866,38 +866,37 @@ static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
#define airoha_qdma_clear(qdma, offset, val) \
airoha_rmw((qdma)->regs, (offset), (val), 0)
-static void airoha_qdma_set_irqmask(struct airoha_eth *eth, int index,
+static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index,
u32 clear, u32 set)
{
unsigned long flags;
- if (WARN_ON_ONCE(index >= ARRAY_SIZE(eth->irqmask)))
+ if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask)))
return;
- spin_lock_irqsave(ð->irq_lock, flags);
+ spin_lock_irqsave(&qdma->irq_lock, flags);
- eth->irqmask[index] &= ~clear;
- eth->irqmask[index] |= set;
- airoha_qdma_wr(ð->qdma[0], REG_INT_ENABLE(index),
- eth->irqmask[index]);
+ qdma->irqmask[index] &= ~clear;
+ qdma->irqmask[index] |= set;
+ airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]);
/* Read irq_enable register in order to guarantee the update above
* completes in the spinlock critical section.
*/
- airoha_qdma_rr(ð->qdma[0], REG_INT_ENABLE(index));
+ airoha_qdma_rr(qdma, REG_INT_ENABLE(index));
- spin_unlock_irqrestore(ð->irq_lock, flags);
+ spin_unlock_irqrestore(&qdma->irq_lock, flags);
}
-static void airoha_qdma_irq_enable(struct airoha_eth *eth, int index,
+static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index,
u32 mask)
{
- airoha_qdma_set_irqmask(eth, index, 0, mask);
+ airoha_qdma_set_irqmask(qdma, index, 0, mask);
}
-static void airoha_qdma_irq_disable(struct airoha_eth *eth, int index,
+static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index,
u32 mask)
{
- airoha_qdma_set_irqmask(eth, index, mask, 0);
+ airoha_qdma_set_irqmask(qdma, index, mask, 0);
}
static void airoha_set_macaddr(struct airoha_eth *eth, const u8 *addr)
@@ -1522,7 +1521,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
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_eth *eth = q->eth;
+ struct airoha_qdma *qdma = &q->eth->qdma[0];
int cur, done = 0;
do {
@@ -1531,7 +1530,7 @@ static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
} while (cur && done < budget);
if (done < budget && napi_complete(napi))
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX1,
+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1,
RX_DONE_INT_MASK);
return done;
@@ -1718,7 +1717,7 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
}
if (done < budget && napi_complete(napi))
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0,
+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0,
TX_DONE_INT_MASK(id));
return done;
@@ -1928,13 +1927,13 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth,
int i;
/* clear pending irqs */
- for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++)
+ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++)
airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff);
/* setup irqs */
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX1, INT_IDX1_MASK);
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
+ 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);
/* setup irq binding */
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
@@ -1981,14 +1980,13 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth,
static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
{
struct airoha_eth *eth = dev_instance;
- u32 intr[ARRAY_SIZE(eth->irqmask)];
- struct airoha_qdma *qdma;
+ struct airoha_qdma *qdma = ð->qdma[0];
+ u32 intr[ARRAY_SIZE(qdma->irqmask)];
int i;
- qdma = ð->qdma[0];
- for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++) {
+ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) {
intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i));
- intr[i] &= eth->irqmask[i];
+ intr[i] &= qdma->irqmask[i];
airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
}
@@ -1996,7 +1994,7 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
return IRQ_NONE;
if (intr[1] & RX_DONE_INT_MASK) {
- airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX1,
+ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1,
RX_DONE_INT_MASK);
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -2016,7 +2014,7 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
if (!(intr[0] & TX_DONE_INT_MASK(i)))
continue;
- airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX0,
+ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0,
TX_DONE_INT_MASK(i));
status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(i));
@@ -2031,12 +2029,18 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
return IRQ_HANDLED;
}
-static int airoha_qdma_init(struct airoha_eth *eth)
+static int airoha_qdma_init(struct platform_device *pdev,
+ struct airoha_eth *eth)
{
struct airoha_qdma *qdma = ð->qdma[0];
int err;
- err = devm_request_irq(eth->dev, eth->irq, airoha_irq_handler,
+ spin_lock_init(&qdma->irq_lock);
+ qdma->irq = platform_get_irq(pdev, 0);
+ if (qdma->irq < 0)
+ return qdma->irq;
+
+ err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler,
IRQF_SHARED, KBUILD_MODNAME, eth);
if (err)
return err;
@@ -2062,7 +2066,8 @@ static int airoha_qdma_init(struct airoha_eth *eth)
return 0;
}
-static int airoha_hw_init(struct airoha_eth *eth)
+static int airoha_hw_init(struct platform_device *pdev,
+ struct airoha_eth *eth)
{
int err;
@@ -2078,7 +2083,7 @@ static int airoha_hw_init(struct airoha_eth *eth)
if (err)
return err;
- return airoha_qdma_init(eth);
+ return airoha_qdma_init(pdev, eth);
}
static void airoha_hw_cleanup(struct airoha_eth *eth)
@@ -2675,11 +2680,6 @@ static int airoha_probe(struct platform_device *pdev)
return err;
}
- spin_lock_init(ð->irq_lock);
- eth->irq = platform_get_irq(pdev, 0);
- if (eth->irq < 0)
- return eth->irq;
-
eth->napi_dev = alloc_netdev_dummy(0);
if (!eth->napi_dev)
return -ENOMEM;
@@ -2689,7 +2689,7 @@ static int airoha_probe(struct platform_device *pdev)
strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name));
platform_set_drvdata(pdev, eth);
- err = airoha_hw_init(eth);
+ err = airoha_hw_init(pdev, eth);
if (err)
goto error;
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 4/9] net: airoha: Add airoha_qdma pointer in airoha_tx_irq_queue/airoha_queue structures
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
` (2 preceding siblings ...)
2024-07-30 16:22 ` [PATCH net-next 3/9] net: airoha: Move irq_mask in airoha_qdma structure Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 5/9] net: airoha: Use qdma pointer as private structure in airoha_irq_handler routine Lorenzo Bianconi
` (4 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
Move airoha_eth pointer in airoha_qdma structure from
airoha_tx_irq_queue/airoha_queue ones. This is a preliminary patch to
introduce support for multi-QDMA controllers available on EN7581.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 84 +++++++++++-----------
1 file changed, 41 insertions(+), 43 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 6e46558f4277..763b8df73552 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -728,7 +728,7 @@ struct airoha_queue_entry {
};
struct airoha_queue {
- struct airoha_eth *eth;
+ struct airoha_qdma *qdma;
/* protect concurrent queue accesses */
spinlock_t lock;
@@ -747,7 +747,7 @@ struct airoha_queue {
};
struct airoha_tx_irq_queue {
- struct airoha_eth *eth;
+ struct airoha_qdma *qdma;
struct napi_struct napi;
u32 *q;
@@ -784,6 +784,7 @@ struct airoha_hw_stats {
};
struct airoha_qdma {
+ struct airoha_eth *eth;
void __iomem *regs;
/* protect concurrent irqmask accesses */
@@ -1388,8 +1389,8 @@ static int airoha_fe_init(struct airoha_eth *eth)
static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
{
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
- struct airoha_qdma *qdma = &q->eth->qdma[0];
- struct airoha_eth *eth = q->eth;
+ struct airoha_qdma *qdma = q->qdma;
+ struct airoha_eth *eth = qdma->eth;
int qid = q - &qdma->q_rx[0];
int nframes = 0;
@@ -1457,8 +1458,8 @@ static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
{
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
- struct airoha_qdma *qdma = &q->eth->qdma[0];
- struct airoha_eth *eth = q->eth;
+ struct airoha_qdma *qdma = q->qdma;
+ struct airoha_eth *eth = qdma->eth;
int qid = q - &qdma->q_rx[0];
int done = 0;
@@ -1521,7 +1522,6 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
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_qdma *qdma = &q->eth->qdma[0];
int cur, done = 0;
do {
@@ -1530,14 +1530,13 @@ static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
} while (cur && done < budget);
if (done < budget && napi_complete(napi))
- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1,
+ airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1,
RX_DONE_INT_MASK);
return done;
}
-static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
- struct airoha_queue *q,
+static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
struct airoha_qdma *qdma, int ndesc)
{
const struct page_pool_params pp_params = {
@@ -1547,15 +1546,16 @@ static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
.dma_dir = DMA_FROM_DEVICE,
.max_len = PAGE_SIZE,
.nid = NUMA_NO_NODE,
- .dev = eth->dev,
+ .dev = qdma->eth->dev,
.napi = &q->napi,
};
+ struct airoha_eth *eth = qdma->eth;
int qid = q - &qdma->q_rx[0], thr;
dma_addr_t dma_addr;
q->buf_size = PAGE_SIZE / 2;
q->ndesc = ndesc;
- q->eth = eth;
+ q->qdma = qdma;
q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
GFP_KERNEL);
@@ -1595,7 +1595,7 @@ static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
{
- struct airoha_eth *eth = q->eth;
+ struct airoha_eth *eth = q->qdma->eth;
while (q->queued) {
struct airoha_queue_entry *e = &q->entry[q->tail];
@@ -1609,8 +1609,7 @@ static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
}
}
-static int airoha_qdma_init_rx(struct airoha_eth *eth,
- struct airoha_qdma *qdma)
+static int airoha_qdma_init_rx(struct airoha_qdma *qdma)
{
int i;
@@ -1622,8 +1621,8 @@ static int airoha_qdma_init_rx(struct airoha_eth *eth,
continue;
}
- err = airoha_qdma_init_rx_queue(eth, &qdma->q_rx[i],
- qdma, RX_DSCP_NUM(i));
+ err = airoha_qdma_init_rx_queue(&qdma->q_rx[i], qdma,
+ RX_DSCP_NUM(i));
if (err)
return err;
}
@@ -1639,9 +1638,9 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
int id, done = 0;
irq_q = container_of(napi, struct airoha_tx_irq_queue, napi);
- eth = irq_q->eth;
- qdma = ð->qdma[0];
+ qdma = irq_q->qdma;
id = irq_q - &qdma->q_tx_irq[0];
+ eth = qdma->eth;
while (irq_q->queued > 0 && done < budget) {
u32 qid, last, val = irq_q->q[irq_q->head];
@@ -1723,16 +1722,16 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
return done;
}
-static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
- struct airoha_queue *q,
+static int airoha_qdma_init_tx_queue(struct airoha_queue *q,
struct airoha_qdma *qdma, int size)
{
+ struct airoha_eth *eth = qdma->eth;
int i, qid = q - &qdma->q_tx[0];
dma_addr_t dma_addr;
spin_lock_init(&q->lock);
q->ndesc = size;
- q->eth = eth;
+ q->qdma = qdma;
q->free_thr = 1 + MAX_SKB_FRAGS;
q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
@@ -1761,11 +1760,11 @@ static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
return 0;
}
-static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
- struct airoha_tx_irq_queue *irq_q,
+static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q,
struct airoha_qdma *qdma, int size)
{
int id = irq_q - &qdma->q_tx_irq[0];
+ struct airoha_eth *eth = qdma->eth;
dma_addr_t dma_addr;
netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
@@ -1777,7 +1776,7 @@ static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
memset(irq_q->q, 0xff, size * sizeof(u32));
irq_q->size = size;
- irq_q->eth = eth;
+ irq_q->qdma = qdma;
airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr);
airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
@@ -1788,21 +1787,20 @@ static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
return 0;
}
-static int airoha_qdma_init_tx(struct airoha_eth *eth,
- struct airoha_qdma *qdma)
+static int airoha_qdma_init_tx(struct airoha_qdma *qdma)
{
int i, err;
for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
- err = airoha_qdma_tx_irq_init(eth, &qdma->q_tx_irq[i],
- qdma, IRQ_QUEUE_LEN(i));
+ err = airoha_qdma_tx_irq_init(&qdma->q_tx_irq[i], qdma,
+ IRQ_QUEUE_LEN(i));
if (err)
return err;
}
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
- err = airoha_qdma_init_tx_queue(eth, &qdma->q_tx[i],
- qdma, TX_DSCP_NUM);
+ err = airoha_qdma_init_tx_queue(&qdma->q_tx[i], qdma,
+ TX_DSCP_NUM);
if (err)
return err;
}
@@ -1812,7 +1810,7 @@ static int airoha_qdma_init_tx(struct airoha_eth *eth,
static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
{
- struct airoha_eth *eth = q->eth;
+ struct airoha_eth *eth = q->qdma->eth;
spin_lock_bh(&q->lock);
while (q->queued) {
@@ -1829,9 +1827,9 @@ static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
spin_unlock_bh(&q->lock);
}
-static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth,
- struct airoha_qdma *qdma)
+static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
{
+ struct airoha_eth *eth = qdma->eth;
dma_addr_t dma_addr;
u32 status;
int size;
@@ -1870,8 +1868,7 @@ static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth,
REG_LMGR_INIT_CFG);
}
-static void airoha_qdma_init_qos(struct airoha_eth *eth,
- struct airoha_qdma *qdma)
+static void airoha_qdma_init_qos(struct airoha_qdma *qdma)
{
airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK);
airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK);
@@ -1921,8 +1918,7 @@ static void airoha_qdma_init_qos(struct airoha_eth *eth,
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
}
-static int airoha_qdma_hw_init(struct airoha_eth *eth,
- struct airoha_qdma *qdma)
+static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
{
int i;
@@ -1960,7 +1956,7 @@ static int airoha_qdma_hw_init(struct airoha_eth *eth,
GLOBAL_CFG_TX_WB_DONE_MASK |
FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2));
- airoha_qdma_init_qos(eth, qdma);
+ airoha_qdma_init_qos(qdma);
/* disable qdma rx delay interrupt */
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -2036,6 +2032,8 @@ static int airoha_qdma_init(struct platform_device *pdev,
int err;
spin_lock_init(&qdma->irq_lock);
+ qdma->eth = eth;
+
qdma->irq = platform_get_irq(pdev, 0);
if (qdma->irq < 0)
return qdma->irq;
@@ -2045,19 +2043,19 @@ static int airoha_qdma_init(struct platform_device *pdev,
if (err)
return err;
- err = airoha_qdma_init_rx(eth, qdma);
+ err = airoha_qdma_init_rx(qdma);
if (err)
return err;
- err = airoha_qdma_init_tx(eth, qdma);
+ err = airoha_qdma_init_tx(qdma);
if (err)
return err;
- err = airoha_qdma_init_hfwd_queues(eth, qdma);
+ err = airoha_qdma_init_hfwd_queues(qdma);
if (err)
return err;
- err = airoha_qdma_hw_init(eth, qdma);
+ err = airoha_qdma_hw_init(qdma);
if (err)
return err;
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 5/9] net: airoha: Use qdma pointer as private structure in airoha_irq_handler routine
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
` (3 preceding siblings ...)
2024-07-30 16:22 ` [PATCH net-next 4/9] net: airoha: Add airoha_qdma pointer in airoha_tx_irq_queue/airoha_queue structures Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 6/9] net: airoha: Allow mapping IO region for multiple qdma controllers Lorenzo Bianconi
` (3 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
This is a preliminary patch to support multi-QDMA controllers.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 763b8df73552..18a0c8889073 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1975,8 +1975,7 @@ static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
{
- struct airoha_eth *eth = dev_instance;
- struct airoha_qdma *qdma = ð->qdma[0];
+ struct airoha_qdma *qdma = dev_instance;
u32 intr[ARRAY_SIZE(qdma->irqmask)];
int i;
@@ -1986,7 +1985,7 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
}
- if (!test_bit(DEV_STATE_INITIALIZED, ð->state))
+ if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state))
return IRQ_NONE;
if (intr[1] & RX_DONE_INT_MASK) {
@@ -2039,7 +2038,7 @@ static int airoha_qdma_init(struct platform_device *pdev,
return qdma->irq;
err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler,
- IRQF_SHARED, KBUILD_MODNAME, eth);
+ IRQF_SHARED, KBUILD_MODNAME, qdma);
if (err)
return err;
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 6/9] net: airoha: Allow mapping IO region for multiple qdma controllers
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
` (4 preceding siblings ...)
2024-07-30 16:22 ` [PATCH net-next 5/9] net: airoha: Use qdma pointer as private structure in airoha_irq_handler routine Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-08-01 2:14 ` Jakub Kicinski
2024-07-30 16:22 ` [PATCH net-next 7/9] net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup() Lorenzo Bianconi
` (2 subsequent siblings)
8 siblings, 1 reply; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
Map MMIO regions of both qdma controllers available on EN7581 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 46 ++++++++++++----------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 18a0c8889073..498c65b4e449 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2025,15 +2025,26 @@ static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
}
static int airoha_qdma_init(struct platform_device *pdev,
- struct airoha_eth *eth)
+ struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
- struct airoha_qdma *qdma = ð->qdma[0];
- int err;
+ int err, id = qdma - ð->qdma[0];
+ const char *res;
spin_lock_init(&qdma->irq_lock);
qdma->eth = eth;
- qdma->irq = platform_get_irq(pdev, 0);
+ res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id);
+ if (!res)
+ return -ENOMEM;
+
+ qdma->regs = devm_platform_ioremap_resource_byname(pdev, res);
+ if (IS_ERR(eth->qdma[id].regs))
+ return dev_err_probe(eth->dev,
+ PTR_ERR(eth->qdma[id].regs),
+ "failed to iomap qdma%d regs\n", id);
+
+ qdma->irq = platform_get_irq(pdev, 4 * id);
if (qdma->irq < 0)
return qdma->irq;
@@ -2054,19 +2065,13 @@ static int airoha_qdma_init(struct platform_device *pdev,
if (err)
return err;
- err = airoha_qdma_hw_init(qdma);
- if (err)
- return err;
-
- set_bit(DEV_STATE_INITIALIZED, ð->state);
-
- return 0;
+ return airoha_qdma_hw_init(qdma);
}
static int airoha_hw_init(struct platform_device *pdev,
struct airoha_eth *eth)
{
- int err;
+ int err, i;
/* disable xsi */
reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts);
@@ -2080,7 +2085,15 @@ static int airoha_hw_init(struct platform_device *pdev,
if (err)
return err;
- return airoha_qdma_init(pdev, eth);
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
+ err = airoha_qdma_init(pdev, eth, ð->qdma[i]);
+ if (err)
+ return err;
+ }
+
+ set_bit(DEV_STATE_INITIALIZED, ð->state);
+
+ return 0;
}
static void airoha_hw_cleanup(struct airoha_eth *eth)
@@ -2646,13 +2659,6 @@ static int airoha_probe(struct platform_device *pdev)
return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs),
"failed to iomap fe regs\n");
- eth->qdma[0].regs = devm_platform_ioremap_resource_byname(pdev,
- "qdma0");
- if (IS_ERR(eth->qdma[0].regs))
- return dev_err_probe(eth->dev,
- PTR_ERR(eth->qdma[0].regs),
- "failed to iomap qdma regs\n");
-
eth->rsts[0].id = "fe";
eth->rsts[1].id = "pdma";
eth->rsts[2].id = "qdma";
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 7/9] net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup()
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
` (5 preceding siblings ...)
2024-07-30 16:22 ` [PATCH net-next 6/9] net: airoha: Allow mapping IO region for multiple qdma controllers Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-08-01 2:14 ` Jakub Kicinski
2024-07-30 16:22 ` [PATCH net-next 8/9] net: airoha: Start all qdma NAPIs in airoha_probe() Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 9/9] net: airoha: Link the gdm port to the selected qdma controller Lorenzo Bianconi
8 siblings, 1 reply; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
Run airoha_hw_cleanup routine for both QDMA controllers available on
EN7581 SoC removing airoha_eth module or in airoha_probe error path.
This is a preliminary patch to support multi-QDMA controllers.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 498c65b4e449..2e21577f9ce2 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2096,9 +2096,8 @@ static int airoha_hw_init(struct platform_device *pdev,
return 0;
}
-static void airoha_hw_cleanup(struct airoha_eth *eth)
+static void airoha_hw_cleanup(struct airoha_qdma *qdma)
{
- struct airoha_qdma *qdma = ð->qdma[0];
int i;
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -2714,7 +2713,9 @@ static int airoha_probe(struct platform_device *pdev)
return 0;
error:
- airoha_hw_cleanup(eth);
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+ airoha_hw_cleanup(ð->qdma[i]);
+
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
@@ -2732,7 +2733,9 @@ static void airoha_remove(struct platform_device *pdev)
struct airoha_eth *eth = platform_get_drvdata(pdev);
int i;
- airoha_hw_cleanup(eth);
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+ airoha_hw_cleanup(ð->qdma[i]);
+
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 8/9] net: airoha: Start all qdma NAPIs in airoha_probe()
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
` (6 preceding siblings ...)
2024-07-30 16:22 ` [PATCH net-next 7/9] net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup() Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 9/9] net: airoha: Link the gdm port to the selected qdma controller Lorenzo Bianconi
8 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
This is a preliminary patch to support multi-QDMA controllers.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 2e21577f9ce2..7a2acb550165 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2124,9 +2124,8 @@ static void airoha_hw_cleanup(struct airoha_qdma *qdma)
}
}
-static void airoha_qdma_start_napi(struct airoha_eth *eth)
+static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
{
- struct airoha_qdma *qdma = ð->qdma[0];
int i;
for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
@@ -2695,7 +2694,9 @@ static int airoha_probe(struct platform_device *pdev)
if (err)
goto error;
- airoha_qdma_start_napi(eth);
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+ airoha_qdma_start_napi(ð->qdma[i]);
+
for_each_child_of_node(pdev->dev.of_node, np) {
if (!of_device_is_compatible(np, "airoha,eth-mac"))
continue;
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 9/9] net: airoha: Link the gdm port to the selected qdma controller
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
` (7 preceding siblings ...)
2024-07-30 16:22 ` [PATCH net-next 8/9] net: airoha: Start all qdma NAPIs in airoha_probe() Lorenzo Bianconi
@ 2024-07-30 16:22 ` Lorenzo Bianconi
8 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-07-30 16:22 UTC (permalink / raw)
To: netdev
Cc: nbd, lorenzo.bianconi83, davem, edumazet, kuba, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
Link the running gdm port to the qdma controller used to connect with
the CPU. Moreover, load all QDMA controllers available on EN7581 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 37 +++++++++++-----------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 7a2acb550165..358e47280c65 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -18,7 +18,7 @@
#include <uapi/linux/ppp_defs.h>
#define AIROHA_MAX_NUM_GDM_PORTS 1
-#define AIROHA_MAX_NUM_QDMA 1
+#define AIROHA_MAX_NUM_QDMA 2
#define AIROHA_MAX_NUM_RSTS 3
#define AIROHA_MAX_NUM_XSI_RSTS 5
#define AIROHA_MAX_MTU 2000
@@ -805,8 +805,8 @@ struct airoha_qdma {
};
struct airoha_gdm_port {
+ struct airoha_qdma *qdma;
struct net_device *dev;
- struct airoha_eth *eth;
int id;
struct airoha_hw_stats stats;
@@ -2141,7 +2141,7 @@ static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
static void airoha_update_hw_stats(struct airoha_gdm_port *port)
{
- struct airoha_eth *eth = port->eth;
+ struct airoha_eth *eth = port->qdma->eth;
u32 val, i = 0;
spin_lock(&port->stats.lock);
@@ -2286,22 +2286,22 @@ static void airoha_update_hw_stats(struct airoha_gdm_port *port)
static int airoha_dev_open(struct net_device *dev)
{
struct airoha_gdm_port *port = netdev_priv(dev);
- struct airoha_eth *eth = port->eth;
+ struct airoha_qdma *qdma = port->qdma;
int err;
netif_tx_start_all_queues(dev);
- err = airoha_set_gdm_ports(eth, true);
+ err = airoha_set_gdm_ports(qdma->eth, true);
if (err)
return err;
if (netdev_uses_dsa(dev))
- airoha_fe_set(eth, REG_GDM_INGRESS_CFG(port->id),
+ airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
else
- airoha_fe_clear(eth, REG_GDM_INGRESS_CFG(port->id),
+ airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
- airoha_qdma_set(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
+ airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
GLOBAL_CFG_TX_DMA_EN_MASK |
GLOBAL_CFG_RX_DMA_EN_MASK);
@@ -2311,15 +2311,15 @@ static int airoha_dev_open(struct net_device *dev)
static int airoha_dev_stop(struct net_device *dev)
{
struct airoha_gdm_port *port = netdev_priv(dev);
- struct airoha_eth *eth = port->eth;
+ struct airoha_qdma *qdma = port->qdma;
int err;
netif_tx_disable(dev);
- err = airoha_set_gdm_ports(eth, false);
+ err = airoha_set_gdm_ports(qdma->eth, false);
if (err)
return err;
- airoha_qdma_clear(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
+ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
GLOBAL_CFG_TX_DMA_EN_MASK |
GLOBAL_CFG_RX_DMA_EN_MASK);
@@ -2335,7 +2335,7 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
if (err)
return err;
- airoha_set_macaddr(port->eth, dev->dev_addr);
+ airoha_set_macaddr(port->qdma->eth, dev->dev_addr);
return 0;
}
@@ -2344,7 +2344,7 @@ static int airoha_dev_init(struct net_device *dev)
{
struct airoha_gdm_port *port = netdev_priv(dev);
- airoha_set_macaddr(port->eth, dev->dev_addr);
+ airoha_set_macaddr(port->qdma->eth, dev->dev_addr);
return 0;
}
@@ -2378,10 +2378,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct airoha_gdm_port *port = netdev_priv(dev);
u32 msg0 = 0, msg1, len = skb_headlen(skb);
int i, qid = skb_get_queue_mapping(skb);
- struct airoha_eth *eth = port->eth;
+ struct airoha_qdma *qdma = port->qdma;
u32 nr_frags = 1 + sinfo->nr_frags;
struct netdev_queue *txq;
- struct airoha_qdma *qdma;
struct airoha_queue *q;
void *data = skb->data;
u16 index;
@@ -2409,7 +2408,6 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
- qdma = ð->qdma[0];
q = &qdma->q_tx[qid];
if (WARN_ON_ONCE(!q->ndesc))
goto error;
@@ -2492,7 +2490,7 @@ static void airoha_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct airoha_gdm_port *port = netdev_priv(dev);
- struct airoha_eth *eth = port->eth;
+ struct airoha_eth *eth = port->qdma->eth;
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
@@ -2573,6 +2571,7 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
{
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
struct airoha_gdm_port *port;
+ struct airoha_qdma *qdma;
struct net_device *dev;
int err, index;
u32 id;
@@ -2602,6 +2601,7 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
return -ENOMEM;
}
+ qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA];
dev->netdev_ops = &airoha_netdev_ops;
dev->ethtool_ops = &airoha_ethtool_ops;
dev->max_mtu = AIROHA_MAX_MTU;
@@ -2611,6 +2611,7 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
NETIF_F_SG | NETIF_F_TSO;
dev->features |= dev->hw_features;
dev->dev.of_node = np;
+ dev->irq = qdma->irq;
SET_NETDEV_DEV(dev, eth->dev);
err = of_get_ethdev_address(np, dev);
@@ -2626,8 +2627,8 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
port = netdev_priv(dev);
u64_stats_init(&port->stats.syncp);
spin_lock_init(&port->stats.lock);
+ port->qdma = qdma;
port->dev = dev;
- port->eth = eth;
port->id = id;
eth->ports[index] = port;
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 6/9] net: airoha: Allow mapping IO region for multiple qdma controllers
2024-07-30 16:22 ` [PATCH net-next 6/9] net: airoha: Allow mapping IO region for multiple qdma controllers Lorenzo Bianconi
@ 2024-08-01 2:14 ` Jakub Kicinski
2024-08-01 8:36 ` Lorenzo Bianconi
0 siblings, 1 reply; 16+ messages in thread
From: Jakub Kicinski @ 2024-08-01 2:14 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: netdev, nbd, lorenzo.bianconi83, davem, edumazet, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
On Tue, 30 Jul 2024 18:22:45 +0200 Lorenzo Bianconi wrote:
> + qdma->regs = devm_platform_ioremap_resource_byname(pdev, res);
> + if (IS_ERR(eth->qdma[id].regs))
qdma->regs vs eth->qdma[id].regs
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 7/9] net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup()
2024-07-30 16:22 ` [PATCH net-next 7/9] net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup() Lorenzo Bianconi
@ 2024-08-01 2:14 ` Jakub Kicinski
2024-08-01 8:37 ` Lorenzo Bianconi
0 siblings, 1 reply; 16+ messages in thread
From: Jakub Kicinski @ 2024-08-01 2:14 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: netdev, nbd, lorenzo.bianconi83, davem, edumazet, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
On Tue, 30 Jul 2024 18:22:46 +0200 Lorenzo Bianconi wrote:
> Run airoha_hw_cleanup routine for both QDMA controllers available on
> EN7581 SoC removing airoha_eth module or in airoha_probe error path.
> This is a preliminary patch to support multi-QDMA controllers.
Doesn't this have to be squashed with the previous patch?
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/9] net: airoha: Move airoha_queues in airoha_qdma
2024-07-30 16:22 ` [PATCH net-next 2/9] net: airoha: Move airoha_queues in airoha_qdma Lorenzo Bianconi
@ 2024-08-01 2:15 ` Jakub Kicinski
2024-08-01 13:22 ` Lorenzo Bianconi
0 siblings, 1 reply; 16+ messages in thread
From: Jakub Kicinski @ 2024-08-01 2:15 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: netdev, nbd, lorenzo.bianconi83, davem, edumazet, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
On Tue, 30 Jul 2024 18:22:41 +0200 Lorenzo Bianconi wrote:
> QDMA controllers available in EN7581 SoC have independent tx/rx hw queues
> so move them in airoha_queues structure.
You seem to be touching a lot of the same lines you touched in the
previous patch here :(
Maybe you can add some of the
+ struct airoha_qdma *qdma = &q->eth->qdma[0];
lines, and propagate qdma pointers in the previous patch already?
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 6/9] net: airoha: Allow mapping IO region for multiple qdma controllers
2024-08-01 2:14 ` Jakub Kicinski
@ 2024-08-01 8:36 ` Lorenzo Bianconi
0 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-08-01 8:36 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, nbd, lorenzo.bianconi83, davem, edumazet, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
[-- Attachment #1: Type: text/plain, Size: 295 bytes --]
On Jul 31, Jakub Kicinski wrote:
> On Tue, 30 Jul 2024 18:22:45 +0200 Lorenzo Bianconi wrote:
> > + qdma->regs = devm_platform_ioremap_resource_byname(pdev, res);
> > + if (IS_ERR(eth->qdma[id].regs))
>
> qdma->regs vs eth->qdma[id].regs
ack, I will fix it in v2.
Regards,
Lorenzo
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 7/9] net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup()
2024-08-01 2:14 ` Jakub Kicinski
@ 2024-08-01 8:37 ` Lorenzo Bianconi
0 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-08-01 8:37 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, nbd, lorenzo.bianconi83, davem, edumazet, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
[-- Attachment #1: Type: text/plain, Size: 393 bytes --]
> On Tue, 30 Jul 2024 18:22:46 +0200 Lorenzo Bianconi wrote:
> > Run airoha_hw_cleanup routine for both QDMA controllers available on
> > EN7581 SoC removing airoha_eth module or in airoha_probe error path.
> > This is a preliminary patch to support multi-QDMA controllers.
>
> Doesn't this have to be squashed with the previous patch?
ack, I will fix it in v2.
Regards,
Lorenzo
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/9] net: airoha: Move airoha_queues in airoha_qdma
2024-08-01 2:15 ` Jakub Kicinski
@ 2024-08-01 13:22 ` Lorenzo Bianconi
0 siblings, 0 replies; 16+ messages in thread
From: Lorenzo Bianconi @ 2024-08-01 13:22 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, nbd, lorenzo.bianconi83, davem, edumazet, pabeni,
linux-arm-kernel, upstream, angelogioacchino.delregno,
benjamin.larsson, rkannoth, sgoutham, andrew, arnd, horms
[-- Attachment #1: Type: text/plain, Size: 497 bytes --]
> On Tue, 30 Jul 2024 18:22:41 +0200 Lorenzo Bianconi wrote:
> > QDMA controllers available in EN7581 SoC have independent tx/rx hw queues
> > so move them in airoha_queues structure.
>
> You seem to be touching a lot of the same lines you touched in the
> previous patch here :(
> Maybe you can add some of the
>
> + struct airoha_qdma *qdma = &q->eth->qdma[0];
>
> lines, and propagate qdma pointers in the previous patch already?
ack, I will fix it in v2.
Regrads,
Lorenzo
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2024-08-01 13:22 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-30 16:22 [PATCH net-next 0/9] Add second QDMA support for EN7581 eth controller Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 1/9] net: airoha: Introduce airoha_qdma struct Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 2/9] net: airoha: Move airoha_queues in airoha_qdma Lorenzo Bianconi
2024-08-01 2:15 ` Jakub Kicinski
2024-08-01 13:22 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 3/9] net: airoha: Move irq_mask in airoha_qdma structure Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 4/9] net: airoha: Add airoha_qdma pointer in airoha_tx_irq_queue/airoha_queue structures Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 5/9] net: airoha: Use qdma pointer as private structure in airoha_irq_handler routine Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 6/9] net: airoha: Allow mapping IO region for multiple qdma controllers Lorenzo Bianconi
2024-08-01 2:14 ` Jakub Kicinski
2024-08-01 8:36 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 7/9] net: airoha: Clean-up all qdma controllers running airoha_hw_cleanup() Lorenzo Bianconi
2024-08-01 2:14 ` Jakub Kicinski
2024-08-01 8:37 ` Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 8/9] net: airoha: Start all qdma NAPIs in airoha_probe() Lorenzo Bianconi
2024-07-30 16:22 ` [PATCH net-next 9/9] net: airoha: Link the gdm port to the selected qdma controller Lorenzo Bianconi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).