* [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:23 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.