Lines Matching +full:eth +full:- +full:mac
1 // SPDX-License-Identifier: GPL-2.0-only
41 struct airoha_qdma *qdma = irq_bank->qdma; in airoha_qdma_set_irqmask()
42 int bank = irq_bank - &qdma->irq_banks[0]; in airoha_qdma_set_irqmask()
45 if (WARN_ON_ONCE(index >= ARRAY_SIZE(irq_bank->irqmask))) in airoha_qdma_set_irqmask()
48 spin_lock_irqsave(&irq_bank->irq_lock, flags); in airoha_qdma_set_irqmask()
50 irq_bank->irqmask[index] &= ~clear; in airoha_qdma_set_irqmask()
51 irq_bank->irqmask[index] |= set; in airoha_qdma_set_irqmask()
53 irq_bank->irqmask[index]); in airoha_qdma_set_irqmask()
59 spin_unlock_irqrestore(&irq_bank->irq_lock, flags); in airoha_qdma_set_irqmask()
76 struct airoha_eth *eth = port->qdma->eth; in airoha_set_macaddr() local
82 airoha_fe_wr(eth, reg, val); in airoha_set_macaddr()
85 airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); in airoha_set_macaddr()
86 airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); in airoha_set_macaddr()
91 static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, in airoha_set_gdm_port_fwd_cfg() argument
94 airoha_fe_rmw(eth, addr, GDM_OCFQ_MASK, in airoha_set_gdm_port_fwd_cfg()
96 airoha_fe_rmw(eth, addr, GDM_MCFQ_MASK, in airoha_set_gdm_port_fwd_cfg()
98 airoha_fe_rmw(eth, addr, GDM_BCFQ_MASK, in airoha_set_gdm_port_fwd_cfg()
100 airoha_fe_rmw(eth, addr, GDM_UCFQ_MASK, in airoha_set_gdm_port_fwd_cfg()
107 struct airoha_eth *eth = port->qdma->eth; in airoha_set_vip_for_gdm_port() local
110 switch (port->id) { in airoha_set_vip_for_gdm_port()
124 airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); in airoha_set_vip_for_gdm_port()
125 airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); in airoha_set_vip_for_gdm_port()
127 airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port); in airoha_set_vip_for_gdm_port()
128 airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); in airoha_set_vip_for_gdm_port()
134 static void airoha_fe_maccr_init(struct airoha_eth *eth) in airoha_fe_maccr_init() argument
138 for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) in airoha_fe_maccr_init()
139 airoha_fe_set(eth, REG_GDM_FWD_CFG(p), in airoha_fe_maccr_init()
143 airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK, in airoha_fe_maccr_init()
146 airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); in airoha_fe_maccr_init()
149 static void airoha_fe_vip_setup(struct airoha_eth *eth) in airoha_fe_vip_setup() argument
151 airoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC); in airoha_fe_vip_setup()
152 airoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK); in airoha_fe_vip_setup()
154 airoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP); in airoha_fe_vip_setup()
155 airoha_fe_wr(eth, REG_FE_VIP_EN(4), in airoha_fe_vip_setup()
159 airoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP); in airoha_fe_vip_setup()
160 airoha_fe_wr(eth, REG_FE_VIP_EN(6), in airoha_fe_vip_setup()
164 airoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP); in airoha_fe_vip_setup()
165 airoha_fe_wr(eth, REG_FE_VIP_EN(7), in airoha_fe_vip_setup()
170 airoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43); in airoha_fe_vip_setup()
171 airoha_fe_wr(eth, REG_FE_VIP_EN(8), in airoha_fe_vip_setup()
176 airoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44); in airoha_fe_vip_setup()
177 airoha_fe_wr(eth, REG_FE_VIP_EN(9), in airoha_fe_vip_setup()
182 airoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4); in airoha_fe_vip_setup()
183 airoha_fe_wr(eth, REG_FE_VIP_EN(10), in airoha_fe_vip_setup()
187 airoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP); in airoha_fe_vip_setup()
188 airoha_fe_wr(eth, REG_FE_VIP_EN(11), in airoha_fe_vip_setup()
193 airoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223); in airoha_fe_vip_setup()
194 airoha_fe_wr(eth, REG_FE_VIP_EN(12), in airoha_fe_vip_setup()
198 airoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP); in airoha_fe_vip_setup()
199 airoha_fe_wr(eth, REG_FE_VIP_EN(19), in airoha_fe_vip_setup()
203 /* ETH->ETH_P_1905 (0x893a) */ in airoha_fe_vip_setup()
204 airoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a); in airoha_fe_vip_setup()
205 airoha_fe_wr(eth, REG_FE_VIP_EN(20), in airoha_fe_vip_setup()
208 airoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP); in airoha_fe_vip_setup()
209 airoha_fe_wr(eth, REG_FE_VIP_EN(21), in airoha_fe_vip_setup()
213 static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth, in airoha_fe_get_pse_queue_rsv_pages() argument
218 airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, in airoha_fe_get_pse_queue_rsv_pages()
222 val = airoha_fe_rr(eth, REG_FE_PSE_QUEUE_CFG_VAL); in airoha_fe_get_pse_queue_rsv_pages()
227 static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth, in airoha_fe_set_pse_queue_rsv_pages() argument
230 airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK, in airoha_fe_set_pse_queue_rsv_pages()
232 airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, in airoha_fe_set_pse_queue_rsv_pages()
240 static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth) in airoha_fe_get_pse_all_rsv() argument
242 u32 val = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET); in airoha_fe_get_pse_all_rsv()
247 static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth, in airoha_fe_set_pse_oq_rsv() argument
250 u32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue); in airoha_fe_set_pse_oq_rsv()
253 airoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val); in airoha_fe_set_pse_oq_rsv()
256 all_rsv = airoha_fe_get_pse_all_rsv(eth); in airoha_fe_set_pse_oq_rsv()
257 all_rsv += (val - orig_val); in airoha_fe_set_pse_oq_rsv()
258 airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK, in airoha_fe_set_pse_oq_rsv()
262 tmp = airoha_fe_rr(eth, PSE_FQ_CFG); in airoha_fe_set_pse_oq_rsv()
264 tmp = fq_limit - all_rsv - 0x20; in airoha_fe_set_pse_oq_rsv()
265 airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, in airoha_fe_set_pse_oq_rsv()
269 tmp = fq_limit - all_rsv - 0x100; in airoha_fe_set_pse_oq_rsv()
270 airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, in airoha_fe_set_pse_oq_rsv()
274 airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, in airoha_fe_set_pse_oq_rsv()
281 static void airoha_fe_pse_ports_init(struct airoha_eth *eth) in airoha_fe_pse_ports_init() argument
299 all_rsv = airoha_fe_get_pse_all_rsv(eth); in airoha_fe_pse_ports_init()
300 if (airoha_ppe_is_enabled(eth, 1)) { in airoha_fe_pse_ports_init()
305 airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); in airoha_fe_pse_ports_init()
309 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q, in airoha_fe_pse_ports_init()
313 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q, in airoha_fe_pse_ports_init()
317 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0); in airoha_fe_pse_ports_init()
320 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q, in airoha_fe_pse_ports_init()
325 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, in airoha_fe_pse_ports_init()
328 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0); in airoha_fe_pse_ports_init()
332 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q, in airoha_fe_pse_ports_init()
335 for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++) in airoha_fe_pse_ports_init()
336 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0); in airoha_fe_pse_ports_init()
339 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, in airoha_fe_pse_ports_init()
341 if (airoha_ppe_is_enabled(eth, 1)) { in airoha_fe_pse_ports_init()
345 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, in airoha_fe_pse_ports_init()
349 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, in airoha_fe_pse_ports_init()
355 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q, in airoha_fe_pse_ports_init()
359 airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q, in airoha_fe_pse_ports_init()
363 static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth) in airoha_fe_mc_vlan_clear() argument
371 airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); in airoha_fe_mc_vlan_clear()
375 airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); in airoha_fe_mc_vlan_clear()
379 false, eth, REG_MC_VLAN_CFG); in airoha_fe_mc_vlan_clear()
384 airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); in airoha_fe_mc_vlan_clear()
389 airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); in airoha_fe_mc_vlan_clear()
393 5 * USEC_PER_MSEC, false, eth, in airoha_fe_mc_vlan_clear()
403 static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) in airoha_fe_crsn_qsel_init() argument
406 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_22 >> 2), in airoha_fe_crsn_qsel_init()
410 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_08 >> 2), in airoha_fe_crsn_qsel_init()
414 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_21 >> 2), in airoha_fe_crsn_qsel_init()
418 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_24 >> 2), in airoha_fe_crsn_qsel_init()
422 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_25 >> 2), in airoha_fe_crsn_qsel_init()
427 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_08 >> 2), in airoha_fe_crsn_qsel_init()
431 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_21 >> 2), in airoha_fe_crsn_qsel_init()
435 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_22 >> 2), in airoha_fe_crsn_qsel_init()
439 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_24 >> 2), in airoha_fe_crsn_qsel_init()
443 airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_25 >> 2), in airoha_fe_crsn_qsel_init()
449 static int airoha_fe_init(struct airoha_eth *eth) in airoha_fe_init() argument
451 airoha_fe_maccr_init(eth); in airoha_fe_init()
454 airoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK, in airoha_fe_init()
456 airoha_fe_rmw(eth, REG_PSE_IQ_REV2, in airoha_fe_init()
462 airoha_fe_wr(eth, REG_FE_PCE_CFG, in airoha_fe_init()
465 airoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK, in airoha_fe_init()
467 airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_VIP_QSEL_MASK, in airoha_fe_init()
470 airoha_fe_rmw(eth, REG_GDM_SRC_PORT_SET(4), in airoha_fe_init()
479 airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, in airoha_fe_init()
483 airoha_fe_wr(eth, REG_FE_RST_GLO_CFG, in airoha_fe_init()
488 /* connect RxRing1 and RxRing15 to PSE Port0 OQ-1 in airoha_fe_init()
489 * connect other rings to PSE Port0 OQ-0 in airoha_fe_init()
491 airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4)); in airoha_fe_init()
492 airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28)); in airoha_fe_init()
493 airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4)); in airoha_fe_init()
494 airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28)); in airoha_fe_init()
496 airoha_fe_vip_setup(eth); in airoha_fe_init()
497 airoha_fe_pse_ports_init(eth); in airoha_fe_init()
499 airoha_fe_set(eth, REG_GDM_MISC_CFG, in airoha_fe_init()
502 airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_OAM_QSEL_MASK, in airoha_fe_init()
506 /* NPU Core-3, NPU Bridge Channel-3 */ in airoha_fe_init()
507 airoha_fe_rmw(eth, REG_IP_FRAG_FP, in airoha_fe_init()
511 /* QDMA LAN, RX Ring-22 */ in airoha_fe_init()
512 airoha_fe_rmw(eth, REG_IP_FRAG_FP, in airoha_fe_init()
517 airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); in airoha_fe_init()
518 airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); in airoha_fe_init()
520 airoha_fe_crsn_qsel_init(eth); in airoha_fe_init()
522 airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK); in airoha_fe_init()
523 airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); in airoha_fe_init()
526 airoha_fe_rmw(eth, REG_GDM_CHN_RLS(2), in airoha_fe_init()
532 airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); in airoha_fe_init()
535 airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); in airoha_fe_init()
537 return airoha_fe_mc_vlan_clear(eth); in airoha_fe_init()
542 struct airoha_qdma *qdma = q->qdma; in airoha_qdma_fill_rx_queue()
543 int qid = q - &qdma->q_rx[0]; in airoha_qdma_fill_rx_queue()
546 while (q->queued < q->ndesc - 1) { in airoha_qdma_fill_rx_queue()
547 struct airoha_queue_entry *e = &q->entry[q->head]; in airoha_qdma_fill_rx_queue()
548 struct airoha_qdma_desc *desc = &q->desc[q->head]; in airoha_qdma_fill_rx_queue()
553 page = page_pool_dev_alloc_frag(q->page_pool, &offset, in airoha_qdma_fill_rx_queue()
554 q->buf_size); in airoha_qdma_fill_rx_queue()
558 q->head = (q->head + 1) % q->ndesc; in airoha_qdma_fill_rx_queue()
559 q->queued++; in airoha_qdma_fill_rx_queue()
562 e->buf = page_address(page) + offset; in airoha_qdma_fill_rx_queue()
563 e->dma_addr = page_pool_get_dma_addr(page) + offset; in airoha_qdma_fill_rx_queue()
564 e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); in airoha_qdma_fill_rx_queue()
566 val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); in airoha_qdma_fill_rx_queue()
567 WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); in airoha_qdma_fill_rx_queue()
568 WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr)); in airoha_qdma_fill_rx_queue()
569 val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, q->head); in airoha_qdma_fill_rx_queue()
570 WRITE_ONCE(desc->data, cpu_to_le32(val)); in airoha_qdma_fill_rx_queue()
571 WRITE_ONCE(desc->msg0, 0); in airoha_qdma_fill_rx_queue()
572 WRITE_ONCE(desc->msg1, 0); in airoha_qdma_fill_rx_queue()
573 WRITE_ONCE(desc->msg2, 0); in airoha_qdma_fill_rx_queue()
574 WRITE_ONCE(desc->msg3, 0); in airoha_qdma_fill_rx_queue()
578 FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); in airoha_qdma_fill_rx_queue()
584 static int airoha_qdma_get_gdm_port(struct airoha_eth *eth, in airoha_qdma_get_gdm_port() argument
587 u32 port, sport, msg1 = le32_to_cpu(desc->msg1); in airoha_qdma_get_gdm_port()
595 port = sport - 1; in airoha_qdma_get_gdm_port()
598 return -EINVAL; in airoha_qdma_get_gdm_port()
601 return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; in airoha_qdma_get_gdm_port()
606 enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); in airoha_qdma_rx_process()
607 struct airoha_qdma *qdma = q->qdma; in airoha_qdma_rx_process()
608 struct airoha_eth *eth = qdma->eth; in airoha_qdma_rx_process() local
609 int qid = q - &qdma->q_rx[0]; in airoha_qdma_rx_process()
613 struct airoha_queue_entry *e = &q->entry[q->tail]; in airoha_qdma_rx_process()
614 struct airoha_qdma_desc *desc = &q->desc[q->tail]; in airoha_qdma_rx_process()
615 u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); in airoha_qdma_rx_process()
616 struct page *page = virt_to_head_page(e->buf); in airoha_qdma_rx_process()
617 u32 desc_ctrl = le32_to_cpu(desc->ctrl); in airoha_qdma_rx_process()
624 q->tail = (q->tail + 1) % q->ndesc; in airoha_qdma_rx_process()
625 q->queued--; in airoha_qdma_rx_process()
627 dma_sync_single_for_cpu(eth->dev, e->dma_addr, in airoha_qdma_rx_process()
628 SKB_WITH_OVERHEAD(q->buf_size), dir); in airoha_qdma_rx_process()
631 data_len = q->skb ? q->buf_size in airoha_qdma_rx_process()
632 : SKB_WITH_OVERHEAD(q->buf_size); in airoha_qdma_rx_process()
636 p = airoha_qdma_get_gdm_port(eth, desc); in airoha_qdma_rx_process()
637 if (p < 0 || !eth->ports[p]) in airoha_qdma_rx_process()
640 port = eth->ports[p]; in airoha_qdma_rx_process()
641 if (!q->skb) { /* first buffer */ in airoha_qdma_rx_process()
642 q->skb = napi_build_skb(e->buf, q->buf_size); in airoha_qdma_rx_process()
643 if (!q->skb) in airoha_qdma_rx_process()
646 __skb_put(q->skb, len); in airoha_qdma_rx_process()
647 skb_mark_for_recycle(q->skb); in airoha_qdma_rx_process()
648 q->skb->dev = port->dev; in airoha_qdma_rx_process()
649 q->skb->protocol = eth_type_trans(q->skb, port->dev); in airoha_qdma_rx_process()
650 q->skb->ip_summed = CHECKSUM_UNNECESSARY; in airoha_qdma_rx_process()
651 skb_record_rx_queue(q->skb, qid); in airoha_qdma_rx_process()
653 struct skb_shared_info *shinfo = skb_shinfo(q->skb); in airoha_qdma_rx_process()
654 int nr_frags = shinfo->nr_frags; in airoha_qdma_rx_process()
656 if (nr_frags >= ARRAY_SIZE(shinfo->frags)) in airoha_qdma_rx_process()
659 skb_add_rx_frag(q->skb, nr_frags, page, in airoha_qdma_rx_process()
660 e->buf - page_address(page), len, in airoha_qdma_rx_process()
661 q->buf_size); in airoha_qdma_rx_process()
667 if (netdev_uses_dsa(port->dev)) { in airoha_qdma_rx_process()
674 le32_to_cpu(desc->msg0)); in airoha_qdma_rx_process()
676 if (sptag < ARRAY_SIZE(port->dsa_meta) && in airoha_qdma_rx_process()
677 port->dsa_meta[sptag]) in airoha_qdma_rx_process()
678 skb_dst_set_noref(q->skb, in airoha_qdma_rx_process()
679 &port->dsa_meta[sptag]->dst); in airoha_qdma_rx_process()
684 skb_set_hash(q->skb, jhash_1word(hash, 0), in airoha_qdma_rx_process()
689 airoha_ppe_check_skb(ð->ppe->dev, q->skb, hash, in airoha_qdma_rx_process()
693 napi_gro_receive(&q->napi, q->skb); in airoha_qdma_rx_process()
694 q->skb = NULL; in airoha_qdma_rx_process()
697 if (q->skb) { in airoha_qdma_rx_process()
698 dev_kfree_skb(q->skb); in airoha_qdma_rx_process()
699 q->skb = NULL; in airoha_qdma_rx_process()
701 page_pool_put_full_page(q->page_pool, page, true); in airoha_qdma_rx_process()
715 cur = airoha_qdma_rx_process(q, budget - done); in airoha_qdma_rx_napi_poll()
720 struct airoha_qdma *qdma = q->qdma; in airoha_qdma_rx_napi_poll()
721 int i, qid = q - &qdma->q_rx[0]; in airoha_qdma_rx_napi_poll()
725 for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { in airoha_qdma_rx_napi_poll()
729 airoha_qdma_irq_enable(&qdma->irq_banks[i], intr_reg, in airoha_qdma_rx_napi_poll()
747 .dev = qdma->eth->dev, in airoha_qdma_init_rx_queue()
748 .napi = &q->napi, in airoha_qdma_init_rx_queue()
750 struct airoha_eth *eth = qdma->eth; in airoha_qdma_init_rx_queue() local
751 int qid = q - &qdma->q_rx[0], thr; in airoha_qdma_init_rx_queue()
754 q->buf_size = PAGE_SIZE / 2; in airoha_qdma_init_rx_queue()
755 q->ndesc = ndesc; in airoha_qdma_init_rx_queue()
756 q->qdma = qdma; in airoha_qdma_init_rx_queue()
758 q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), in airoha_qdma_init_rx_queue()
760 if (!q->entry) in airoha_qdma_init_rx_queue()
761 return -ENOMEM; in airoha_qdma_init_rx_queue()
763 q->page_pool = page_pool_create(&pp_params); in airoha_qdma_init_rx_queue()
764 if (IS_ERR(q->page_pool)) { in airoha_qdma_init_rx_queue()
765 int err = PTR_ERR(q->page_pool); in airoha_qdma_init_rx_queue()
767 q->page_pool = NULL; in airoha_qdma_init_rx_queue()
771 q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), in airoha_qdma_init_rx_queue()
773 if (!q->desc) in airoha_qdma_init_rx_queue()
774 return -ENOMEM; in airoha_qdma_init_rx_queue()
776 netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll); in airoha_qdma_init_rx_queue()
787 FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); in airoha_qdma_init_rx_queue()
797 struct airoha_eth *eth = q->qdma->eth; in airoha_qdma_cleanup_rx_queue() local
799 while (q->queued) { in airoha_qdma_cleanup_rx_queue()
800 struct airoha_queue_entry *e = &q->entry[q->tail]; in airoha_qdma_cleanup_rx_queue()
801 struct page *page = virt_to_head_page(e->buf); in airoha_qdma_cleanup_rx_queue()
803 dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len, in airoha_qdma_cleanup_rx_queue()
804 page_pool_get_dma_dir(q->page_pool)); in airoha_qdma_cleanup_rx_queue()
805 page_pool_put_full_page(q->page_pool, page, false); in airoha_qdma_cleanup_rx_queue()
806 q->tail = (q->tail + 1) % q->ndesc; in airoha_qdma_cleanup_rx_queue()
807 q->queued--; in airoha_qdma_cleanup_rx_queue()
815 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { in airoha_qdma_init_rx()
819 /* rx-queue not binded to irq */ in airoha_qdma_init_rx()
823 err = airoha_qdma_init_rx_queue(&qdma->q_rx[i], qdma, in airoha_qdma_init_rx()
837 struct airoha_eth *eth; in airoha_qdma_tx_napi_poll() local
841 qdma = irq_q->qdma; in airoha_qdma_tx_napi_poll()
842 id = irq_q - &qdma->q_tx_irq[0]; in airoha_qdma_tx_napi_poll()
843 eth = qdma->eth; in airoha_qdma_tx_napi_poll()
847 head = head % irq_q->size; in airoha_qdma_tx_napi_poll()
851 u32 qid, val = irq_q->q[head]; in airoha_qdma_tx_napi_poll()
861 irq_q->q[head] = 0xff; /* mark as done */ in airoha_qdma_tx_napi_poll()
862 head = (head + 1) % irq_q->size; in airoha_qdma_tx_napi_poll()
863 irq_queued--; in airoha_qdma_tx_napi_poll()
867 if (qid >= ARRAY_SIZE(qdma->q_tx)) in airoha_qdma_tx_napi_poll()
870 q = &qdma->q_tx[qid]; in airoha_qdma_tx_napi_poll()
871 if (!q->ndesc) in airoha_qdma_tx_napi_poll()
875 if (index >= q->ndesc) in airoha_qdma_tx_napi_poll()
878 spin_lock_bh(&q->lock); in airoha_qdma_tx_napi_poll()
880 if (!q->queued) in airoha_qdma_tx_napi_poll()
883 desc = &q->desc[index]; in airoha_qdma_tx_napi_poll()
884 desc_ctrl = le32_to_cpu(desc->ctrl); in airoha_qdma_tx_napi_poll()
890 e = &q->entry[index]; in airoha_qdma_tx_napi_poll()
891 skb = e->skb; in airoha_qdma_tx_napi_poll()
893 dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, in airoha_qdma_tx_napi_poll()
895 e->dma_addr = 0; in airoha_qdma_tx_napi_poll()
896 list_add_tail(&e->list, &q->tx_list); in airoha_qdma_tx_napi_poll()
898 WRITE_ONCE(desc->msg0, 0); in airoha_qdma_tx_napi_poll()
899 WRITE_ONCE(desc->msg1, 0); in airoha_qdma_tx_napi_poll()
900 q->queued--; in airoha_qdma_tx_napi_poll()
906 txq = netdev_get_tx_queue(skb->dev, queue); in airoha_qdma_tx_napi_poll()
907 netdev_tx_completed_queue(txq, 1, skb->len); in airoha_qdma_tx_napi_poll()
909 q->ndesc - q->queued >= q->free_thr) in airoha_qdma_tx_napi_poll()
915 spin_unlock_bh(&q->lock); in airoha_qdma_tx_napi_poll()
929 airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, in airoha_qdma_tx_napi_poll()
938 struct airoha_eth *eth = qdma->eth; in airoha_qdma_init_tx_queue() local
939 int i, qid = q - &qdma->q_tx[0]; in airoha_qdma_init_tx_queue()
942 spin_lock_init(&q->lock); in airoha_qdma_init_tx_queue()
943 q->ndesc = size; in airoha_qdma_init_tx_queue()
944 q->qdma = qdma; in airoha_qdma_init_tx_queue()
945 q->free_thr = 1 + MAX_SKB_FRAGS; in airoha_qdma_init_tx_queue()
946 INIT_LIST_HEAD(&q->tx_list); in airoha_qdma_init_tx_queue()
948 q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), in airoha_qdma_init_tx_queue()
950 if (!q->entry) in airoha_qdma_init_tx_queue()
951 return -ENOMEM; in airoha_qdma_init_tx_queue()
953 q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), in airoha_qdma_init_tx_queue()
955 if (!q->desc) in airoha_qdma_init_tx_queue()
956 return -ENOMEM; in airoha_qdma_init_tx_queue()
958 for (i = 0; i < q->ndesc; i++) { in airoha_qdma_init_tx_queue()
961 list_add_tail(&q->entry[i].list, &q->tx_list); in airoha_qdma_init_tx_queue()
962 WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); in airoha_qdma_init_tx_queue()
981 int id = irq_q - &qdma->q_tx_irq[0]; in airoha_qdma_tx_irq_init()
982 struct airoha_eth *eth = qdma->eth; in airoha_qdma_tx_irq_init() local
985 netif_napi_add_tx(eth->napi_dev, &irq_q->napi, in airoha_qdma_tx_irq_init()
987 irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32), in airoha_qdma_tx_irq_init()
989 if (!irq_q->q) in airoha_qdma_tx_irq_init()
990 return -ENOMEM; in airoha_qdma_tx_irq_init()
992 memset(irq_q->q, 0xff, size * sizeof(u32)); in airoha_qdma_tx_irq_init()
993 irq_q->size = size; in airoha_qdma_tx_irq_init()
994 irq_q->qdma = qdma; in airoha_qdma_tx_irq_init()
1009 for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { in airoha_qdma_init_tx()
1010 err = airoha_qdma_tx_irq_init(&qdma->q_tx_irq[i], qdma, in airoha_qdma_init_tx()
1016 for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { in airoha_qdma_init_tx()
1017 err = airoha_qdma_init_tx_queue(&qdma->q_tx[i], qdma, in airoha_qdma_init_tx()
1028 struct airoha_eth *eth = q->qdma->eth; in airoha_qdma_cleanup_tx_queue() local
1031 spin_lock_bh(&q->lock); in airoha_qdma_cleanup_tx_queue()
1032 for (i = 0; i < q->ndesc; i++) { in airoha_qdma_cleanup_tx_queue()
1033 struct airoha_queue_entry *e = &q->entry[i]; in airoha_qdma_cleanup_tx_queue()
1035 if (!e->dma_addr) in airoha_qdma_cleanup_tx_queue()
1038 dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, in airoha_qdma_cleanup_tx_queue()
1040 dev_kfree_skb_any(e->skb); in airoha_qdma_cleanup_tx_queue()
1041 e->dma_addr = 0; in airoha_qdma_cleanup_tx_queue()
1042 e->skb = NULL; in airoha_qdma_cleanup_tx_queue()
1043 list_add_tail(&e->list, &q->tx_list); in airoha_qdma_cleanup_tx_queue()
1044 q->queued--; in airoha_qdma_cleanup_tx_queue()
1046 spin_unlock_bh(&q->lock); in airoha_qdma_cleanup_tx_queue()
1052 struct airoha_eth *eth = qdma->eth; in airoha_qdma_init_hfwd_queues() local
1053 int id = qdma - ð->qdma[0]; in airoha_qdma_init_hfwd_queues()
1058 name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); in airoha_qdma_init_hfwd_queues()
1060 return -ENOMEM; in airoha_qdma_init_hfwd_queues()
1063 index = of_property_match_string(eth->dev->of_node, in airoha_qdma_init_hfwd_queues()
1064 "memory-region-names", name); in airoha_qdma_init_hfwd_queues()
1072 np = of_parse_phandle(eth->dev->of_node, "memory-region", in airoha_qdma_init_hfwd_queues()
1075 return -ENODEV; in airoha_qdma_init_hfwd_queues()
1079 dma_addr = rmem->base; in airoha_qdma_init_hfwd_queues()
1083 num_desc = div_u64(rmem->size, buf_size); in airoha_qdma_init_hfwd_queues()
1086 if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, in airoha_qdma_init_hfwd_queues()
1088 return -ENOMEM; in airoha_qdma_init_hfwd_queues()
1094 if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) in airoha_qdma_init_hfwd_queues()
1095 return -ENOMEM; in airoha_qdma_init_hfwd_queues()
1137 /* fast-tick 25us */ in airoha_qdma_init_qos()
1171 /* Tx-cpu transferred count */ in airoha_qdma_init_qos_stats()
1177 /* Tx-fwd transferred count */ in airoha_qdma_init_qos_stats()
1191 for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { in airoha_qdma_hw_init()
1195 airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX0, in airoha_qdma_hw_init()
1197 airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX1, in airoha_qdma_hw_init()
1199 airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX2, in airoha_qdma_hw_init()
1201 airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX3, in airoha_qdma_hw_init()
1205 airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, in airoha_qdma_hw_init()
1207 airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX4, in airoha_qdma_hw_init()
1211 for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { in airoha_qdma_hw_init()
1212 if (!qdma->q_tx[i].ndesc) in airoha_qdma_hw_init()
1236 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { in airoha_qdma_hw_init()
1237 if (!qdma->q_rx[i].ndesc) in airoha_qdma_hw_init()
1254 struct airoha_qdma *qdma = irq_bank->qdma; in airoha_irq_handler()
1256 u32 intr[ARRAY_SIZE(irq_bank->irqmask)]; in airoha_irq_handler()
1261 intr[i] &= irq_bank->irqmask[i]; in airoha_irq_handler()
1265 if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state)) in airoha_irq_handler()
1280 for (i = 0; rx_intr_mask && i < ARRAY_SIZE(qdma->q_rx); i++) { in airoha_irq_handler()
1281 if (!qdma->q_rx[i].ndesc) in airoha_irq_handler()
1285 napi_schedule(&qdma->q_rx[i].napi); in airoha_irq_handler()
1289 for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { in airoha_irq_handler()
1295 napi_schedule(&qdma->q_tx_irq[i].napi); in airoha_irq_handler()
1305 struct airoha_eth *eth = qdma->eth; in airoha_qdma_init_irq_banks() local
1306 int i, id = qdma - ð->qdma[0]; in airoha_qdma_init_irq_banks()
1308 for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { in airoha_qdma_init_irq_banks()
1309 struct airoha_irq_bank *irq_bank = &qdma->irq_banks[i]; in airoha_qdma_init_irq_banks()
1313 spin_lock_init(&irq_bank->irq_lock); in airoha_qdma_init_irq_banks()
1314 irq_bank->qdma = qdma; in airoha_qdma_init_irq_banks()
1316 irq_bank->irq = platform_get_irq(pdev, irq_index); in airoha_qdma_init_irq_banks()
1317 if (irq_bank->irq < 0) in airoha_qdma_init_irq_banks()
1318 return irq_bank->irq; in airoha_qdma_init_irq_banks()
1320 name = devm_kasprintf(eth->dev, GFP_KERNEL, in airoha_qdma_init_irq_banks()
1323 return -ENOMEM; in airoha_qdma_init_irq_banks()
1325 err = devm_request_irq(eth->dev, irq_bank->irq, in airoha_qdma_init_irq_banks()
1336 struct airoha_eth *eth, in airoha_qdma_init() argument
1339 int err, id = qdma - ð->qdma[0]; in airoha_qdma_init()
1342 qdma->eth = eth; in airoha_qdma_init()
1343 res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id); in airoha_qdma_init()
1345 return -ENOMEM; in airoha_qdma_init()
1347 qdma->regs = devm_platform_ioremap_resource_byname(pdev, res); in airoha_qdma_init()
1348 if (IS_ERR(qdma->regs)) in airoha_qdma_init()
1349 return dev_err_probe(eth->dev, PTR_ERR(qdma->regs), in airoha_qdma_init()
1372 struct airoha_eth *eth) in airoha_hw_init() argument
1377 err = reset_control_bulk_assert(eth->soc->num_xsi_rsts, eth->xsi_rsts); in airoha_hw_init()
1381 err = reset_control_bulk_assert(ARRAY_SIZE(eth->rsts), eth->rsts); in airoha_hw_init()
1386 err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts); in airoha_hw_init()
1391 err = airoha_fe_init(eth); in airoha_hw_init()
1395 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { in airoha_hw_init()
1396 err = airoha_qdma_init(pdev, eth, ð->qdma[i]); in airoha_hw_init()
1401 err = airoha_ppe_init(eth); in airoha_hw_init()
1405 set_bit(DEV_STATE_INITIALIZED, ð->state); in airoha_hw_init()
1414 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { in airoha_hw_cleanup()
1415 if (!qdma->q_rx[i].ndesc) in airoha_hw_cleanup()
1418 netif_napi_del(&qdma->q_rx[i].napi); in airoha_hw_cleanup()
1419 airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); in airoha_hw_cleanup()
1420 if (qdma->q_rx[i].page_pool) in airoha_hw_cleanup()
1421 page_pool_destroy(qdma->q_rx[i].page_pool); in airoha_hw_cleanup()
1424 for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) in airoha_hw_cleanup()
1425 netif_napi_del(&qdma->q_tx_irq[i].napi); in airoha_hw_cleanup()
1427 for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { in airoha_hw_cleanup()
1428 if (!qdma->q_tx[i].ndesc) in airoha_hw_cleanup()
1431 airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); in airoha_hw_cleanup()
1439 for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) in airoha_qdma_start_napi()
1440 napi_enable(&qdma->q_tx_irq[i].napi); in airoha_qdma_start_napi()
1442 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { in airoha_qdma_start_napi()
1443 if (!qdma->q_rx[i].ndesc) in airoha_qdma_start_napi()
1446 napi_enable(&qdma->q_rx[i].napi); in airoha_qdma_start_napi()
1454 for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) in airoha_qdma_stop_napi()
1455 napi_disable(&qdma->q_tx_irq[i].napi); in airoha_qdma_stop_napi()
1457 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { in airoha_qdma_stop_napi()
1458 if (!qdma->q_rx[i].ndesc) in airoha_qdma_stop_napi()
1461 napi_disable(&qdma->q_rx[i].napi); in airoha_qdma_stop_napi()
1467 struct airoha_eth *eth = port->qdma->eth; in airoha_update_hw_stats() local
1470 spin_lock(&port->stats.lock); in airoha_update_hw_stats()
1471 u64_stats_update_begin(&port->stats.syncp); in airoha_update_hw_stats()
1474 val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id)); in airoha_update_hw_stats()
1475 port->stats.tx_ok_pkts += ((u64)val << 32); in airoha_update_hw_stats()
1476 val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id)); in airoha_update_hw_stats()
1477 port->stats.tx_ok_pkts += val; in airoha_update_hw_stats()
1479 val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id)); in airoha_update_hw_stats()
1480 port->stats.tx_ok_bytes += ((u64)val << 32); in airoha_update_hw_stats()
1481 val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id)); in airoha_update_hw_stats()
1482 port->stats.tx_ok_bytes += val; in airoha_update_hw_stats()
1484 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id)); in airoha_update_hw_stats()
1485 port->stats.tx_drops += val; in airoha_update_hw_stats()
1487 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id)); in airoha_update_hw_stats()
1488 port->stats.tx_broadcast += val; in airoha_update_hw_stats()
1490 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id)); in airoha_update_hw_stats()
1491 port->stats.tx_multicast += val; in airoha_update_hw_stats()
1493 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id)); in airoha_update_hw_stats()
1494 port->stats.tx_len[i] += val; in airoha_update_hw_stats()
1496 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id)); in airoha_update_hw_stats()
1497 port->stats.tx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1498 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id)); in airoha_update_hw_stats()
1499 port->stats.tx_len[i++] += val; in airoha_update_hw_stats()
1501 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id)); in airoha_update_hw_stats()
1502 port->stats.tx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1503 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id)); in airoha_update_hw_stats()
1504 port->stats.tx_len[i++] += val; in airoha_update_hw_stats()
1506 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id)); in airoha_update_hw_stats()
1507 port->stats.tx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1508 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id)); in airoha_update_hw_stats()
1509 port->stats.tx_len[i++] += val; in airoha_update_hw_stats()
1511 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id)); in airoha_update_hw_stats()
1512 port->stats.tx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1513 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id)); in airoha_update_hw_stats()
1514 port->stats.tx_len[i++] += val; in airoha_update_hw_stats()
1516 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id)); in airoha_update_hw_stats()
1517 port->stats.tx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1518 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id)); in airoha_update_hw_stats()
1519 port->stats.tx_len[i++] += val; in airoha_update_hw_stats()
1521 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id)); in airoha_update_hw_stats()
1522 port->stats.tx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1523 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id)); in airoha_update_hw_stats()
1524 port->stats.tx_len[i++] += val; in airoha_update_hw_stats()
1526 val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id)); in airoha_update_hw_stats()
1527 port->stats.tx_len[i++] += val; in airoha_update_hw_stats()
1530 val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id)); in airoha_update_hw_stats()
1531 port->stats.rx_ok_pkts += ((u64)val << 32); in airoha_update_hw_stats()
1532 val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id)); in airoha_update_hw_stats()
1533 port->stats.rx_ok_pkts += val; in airoha_update_hw_stats()
1535 val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id)); in airoha_update_hw_stats()
1536 port->stats.rx_ok_bytes += ((u64)val << 32); in airoha_update_hw_stats()
1537 val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id)); in airoha_update_hw_stats()
1538 port->stats.rx_ok_bytes += val; in airoha_update_hw_stats()
1540 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id)); in airoha_update_hw_stats()
1541 port->stats.rx_drops += val; in airoha_update_hw_stats()
1543 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id)); in airoha_update_hw_stats()
1544 port->stats.rx_broadcast += val; in airoha_update_hw_stats()
1546 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id)); in airoha_update_hw_stats()
1547 port->stats.rx_multicast += val; in airoha_update_hw_stats()
1549 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id)); in airoha_update_hw_stats()
1550 port->stats.rx_errors += val; in airoha_update_hw_stats()
1552 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id)); in airoha_update_hw_stats()
1553 port->stats.rx_crc_error += val; in airoha_update_hw_stats()
1555 val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id)); in airoha_update_hw_stats()
1556 port->stats.rx_over_errors += val; in airoha_update_hw_stats()
1558 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id)); in airoha_update_hw_stats()
1559 port->stats.rx_fragment += val; in airoha_update_hw_stats()
1561 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id)); in airoha_update_hw_stats()
1562 port->stats.rx_jabber += val; in airoha_update_hw_stats()
1565 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id)); in airoha_update_hw_stats()
1566 port->stats.rx_len[i] += val; in airoha_update_hw_stats()
1568 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id)); in airoha_update_hw_stats()
1569 port->stats.rx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1570 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id)); in airoha_update_hw_stats()
1571 port->stats.rx_len[i++] += val; in airoha_update_hw_stats()
1573 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id)); in airoha_update_hw_stats()
1574 port->stats.rx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1575 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id)); in airoha_update_hw_stats()
1576 port->stats.rx_len[i++] += val; in airoha_update_hw_stats()
1578 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id)); in airoha_update_hw_stats()
1579 port->stats.rx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1580 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id)); in airoha_update_hw_stats()
1581 port->stats.rx_len[i++] += val; in airoha_update_hw_stats()
1583 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id)); in airoha_update_hw_stats()
1584 port->stats.rx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1585 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id)); in airoha_update_hw_stats()
1586 port->stats.rx_len[i++] += val; in airoha_update_hw_stats()
1588 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id)); in airoha_update_hw_stats()
1589 port->stats.rx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1590 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id)); in airoha_update_hw_stats()
1591 port->stats.rx_len[i++] += val; in airoha_update_hw_stats()
1593 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id)); in airoha_update_hw_stats()
1594 port->stats.rx_len[i] += ((u64)val << 32); in airoha_update_hw_stats()
1595 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id)); in airoha_update_hw_stats()
1596 port->stats.rx_len[i++] += val; in airoha_update_hw_stats()
1598 val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id)); in airoha_update_hw_stats()
1599 port->stats.rx_len[i++] += val; in airoha_update_hw_stats()
1602 airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id), in airoha_update_hw_stats()
1605 u64_stats_update_end(&port->stats.syncp); in airoha_update_hw_stats()
1606 spin_unlock(&port->stats.lock); in airoha_update_hw_stats()
1611 int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN; in airoha_dev_open()
1613 struct airoha_qdma *qdma = port->qdma; in airoha_dev_open()
1621 airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), in airoha_dev_open()
1624 airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), in airoha_dev_open()
1627 airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id), in airoha_dev_open()
1635 atomic_inc(&qdma->users); in airoha_dev_open()
1643 struct airoha_qdma *qdma = port->qdma; in airoha_dev_stop()
1651 for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) in airoha_dev_stop()
1654 if (atomic_dec_and_test(&qdma->users)) { in airoha_dev_stop()
1659 for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { in airoha_dev_stop()
1660 if (!qdma->q_tx[i].ndesc) in airoha_dev_stop()
1663 airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); in airoha_dev_stop()
1679 airoha_set_macaddr(port, dev->dev_addr); in airoha_dev_set_macaddr()
1686 struct airoha_eth *eth = port->qdma->eth; in airhoha_set_gdm2_loopback() local
1691 pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 in airhoha_set_gdm2_loopback()
1693 airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); in airhoha_set_gdm2_loopback()
1694 airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC_MASK); in airhoha_set_gdm2_loopback()
1697 airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); in airhoha_set_gdm2_loopback()
1698 airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); in airhoha_set_gdm2_loopback()
1700 chan = port->id == AIROHA_GDM3_IDX ? airoha_is_7581(eth) ? 4 : 3 : 0; in airhoha_set_gdm2_loopback()
1701 airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), in airhoha_set_gdm2_loopback()
1706 airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), in airhoha_set_gdm2_loopback()
1712 airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); in airhoha_set_gdm2_loopback()
1713 airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); in airhoha_set_gdm2_loopback()
1716 nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; in airhoha_set_gdm2_loopback()
1717 src_port = eth->soc->ops.get_src_port_id(port, nbq); in airhoha_set_gdm2_loopback()
1721 airoha_fe_rmw(eth, REG_FE_WAN_PORT, in airhoha_set_gdm2_loopback()
1725 airoha_fe_rmw(eth, in airhoha_set_gdm2_loopback()
1730 if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth)) in airhoha_set_gdm2_loopback()
1731 airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, in airhoha_set_gdm2_loopback()
1741 struct airoha_qdma *qdma = port->qdma; in airoha_dev_init()
1742 struct airoha_eth *eth = qdma->eth; in airoha_dev_init() local
1746 airoha_set_macaddr(port, dev->dev_addr); in airoha_dev_init()
1748 switch (port->id) { in airoha_dev_init()
1752 if (!eth->ports[1]) { in airoha_dev_init()
1761 if (airoha_ppe_is_enabled(eth, 1)) { in airoha_dev_init()
1769 u8 qdma_id = qdma - ð->qdma[0]; in airoha_dev_init()
1778 airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); in airoha_dev_init()
1780 airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), in airoha_dev_init()
1781 DFT_CPORT_MASK(port->id), in airoha_dev_init()
1782 fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id))); in airoha_dev_init()
1795 start = u64_stats_fetch_begin(&port->stats.syncp); in airoha_dev_get_stats64()
1796 storage->rx_packets = port->stats.rx_ok_pkts; in airoha_dev_get_stats64()
1797 storage->tx_packets = port->stats.tx_ok_pkts; in airoha_dev_get_stats64()
1798 storage->rx_bytes = port->stats.rx_ok_bytes; in airoha_dev_get_stats64()
1799 storage->tx_bytes = port->stats.tx_ok_bytes; in airoha_dev_get_stats64()
1800 storage->multicast = port->stats.rx_multicast; in airoha_dev_get_stats64()
1801 storage->rx_errors = port->stats.rx_errors; in airoha_dev_get_stats64()
1802 storage->rx_dropped = port->stats.rx_drops; in airoha_dev_get_stats64()
1803 storage->tx_dropped = port->stats.tx_drops; in airoha_dev_get_stats64()
1804 storage->rx_crc_errors = port->stats.rx_crc_error; in airoha_dev_get_stats64()
1805 storage->rx_over_errors = port->stats.rx_over_errors; in airoha_dev_get_stats64()
1806 } while (u64_stats_fetch_retry(&port->stats.syncp, start)); in airoha_dev_get_stats64()
1812 struct airoha_eth *eth = port->qdma->eth; in airoha_dev_change_mtu() local
1815 airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), in airoha_dev_change_mtu()
1818 WRITE_ONCE(dev->mtu, mtu); in airoha_dev_change_mtu()
1833 channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; in airoha_dev_select_queue()
1835 queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ in airoha_dev_select_queue()
1838 return queue < dev->num_tx_queues ? queue : 0; in airoha_dev_select_queue()
1851 if (dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) in airoha_get_dsa_tag()
1857 ehdr = (struct ethhdr *)skb->data; in airoha_get_dsa_tag()
1858 tag = be16_to_cpu(ehdr->h_proto); in airoha_get_dsa_tag()
1863 ehdr->h_proto = cpu_to_be16(ETH_P_8021Q); in airoha_get_dsa_tag()
1867 ehdr->h_proto = cpu_to_be16(ETH_P_8021AD); in airoha_get_dsa_tag()
1874 memmove(skb->data + MTK_HDR_LEN, skb->data, 2 * ETH_ALEN); in airoha_get_dsa_tag()
1887 struct airoha_qdma *qdma = port->qdma; in airoha_get_fe_port()
1888 struct airoha_eth *eth = qdma->eth; in airoha_get_fe_port() local
1890 switch (eth->soc->version) { in airoha_get_fe_port()
1892 return port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 in airoha_get_fe_port()
1893 : port->id; in airoha_get_fe_port()
1896 return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4 in airoha_get_fe_port()
1897 : port->id; in airoha_get_fe_port()
1905 struct airoha_qdma *qdma = port->qdma; in airoha_dev_xmit()
1916 qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); in airoha_dev_xmit()
1924 if (skb->ip_summed == CHECKSUM_PARTIAL) in airoha_dev_xmit()
1934 if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | in airoha_dev_xmit()
1936 __be16 csum = cpu_to_be16(skb_shinfo(skb)->gso_size); in airoha_dev_xmit()
1938 tcp_hdr(skb)->check = (__force __sum16)csum; in airoha_dev_xmit()
1947 q = &qdma->q_tx[qid]; in airoha_dev_xmit()
1948 if (WARN_ON_ONCE(!q->ndesc)) in airoha_dev_xmit()
1951 spin_lock_bh(&q->lock); in airoha_dev_xmit()
1954 nr_frags = 1 + skb_shinfo(skb)->nr_frags; in airoha_dev_xmit()
1956 if (q->queued + nr_frags >= q->ndesc) { in airoha_dev_xmit()
1959 spin_unlock_bh(&q->lock); in airoha_dev_xmit()
1964 data = skb->data; in airoha_dev_xmit()
1966 e = list_first_entry(&q->tx_list, struct airoha_queue_entry, in airoha_dev_xmit()
1968 index = e - q->entry; in airoha_dev_xmit()
1971 struct airoha_qdma_desc *desc = &q->desc[index]; in airoha_dev_xmit()
1972 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; in airoha_dev_xmit()
1976 addr = dma_map_single(dev->dev.parent, data, len, in airoha_dev_xmit()
1978 if (unlikely(dma_mapping_error(dev->dev.parent, addr))) in airoha_dev_xmit()
1981 list_move_tail(&e->list, &tx_list); in airoha_dev_xmit()
1982 e->skb = i ? NULL : skb; in airoha_dev_xmit()
1983 e->dma_addr = addr; in airoha_dev_xmit()
1984 e->dma_len = len; in airoha_dev_xmit()
1986 e = list_first_entry(&q->tx_list, struct airoha_queue_entry, in airoha_dev_xmit()
1988 index = e - q->entry; in airoha_dev_xmit()
1991 if (i < nr_frags - 1) in airoha_dev_xmit()
1993 WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); in airoha_dev_xmit()
1994 WRITE_ONCE(desc->addr, cpu_to_le32(addr)); in airoha_dev_xmit()
1996 WRITE_ONCE(desc->data, cpu_to_le32(val)); in airoha_dev_xmit()
1997 WRITE_ONCE(desc->msg0, cpu_to_le32(msg0)); in airoha_dev_xmit()
1998 WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); in airoha_dev_xmit()
1999 WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); in airoha_dev_xmit()
2004 q->queued += i; in airoha_dev_xmit()
2007 netdev_tx_sent_queue(txq, skb->len); in airoha_dev_xmit()
2014 if (q->ndesc - q->queued < q->free_thr) in airoha_dev_xmit()
2017 spin_unlock_bh(&q->lock); in airoha_dev_xmit()
2025 dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len, in airoha_dev_xmit()
2027 e->dma_addr = 0; in airoha_dev_xmit()
2028 list_move_tail(&e->list, &q->tx_list); in airoha_dev_xmit()
2031 spin_unlock_bh(&q->lock); in airoha_dev_xmit()
2034 dev->stats.tx_dropped++; in airoha_dev_xmit()
2043 struct airoha_eth *eth = port->qdma->eth; in airoha_ethtool_get_drvinfo() local
2045 strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); in airoha_ethtool_get_drvinfo()
2046 strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); in airoha_ethtool_get_drvinfo()
2057 start = u64_stats_fetch_begin(&port->stats.syncp); in airoha_ethtool_get_mac_stats()
2058 stats->FramesTransmittedOK = port->stats.tx_ok_pkts; in airoha_ethtool_get_mac_stats()
2059 stats->OctetsTransmittedOK = port->stats.tx_ok_bytes; in airoha_ethtool_get_mac_stats()
2060 stats->MulticastFramesXmittedOK = port->stats.tx_multicast; in airoha_ethtool_get_mac_stats()
2061 stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; in airoha_ethtool_get_mac_stats()
2062 stats->FramesReceivedOK = port->stats.rx_ok_pkts; in airoha_ethtool_get_mac_stats()
2063 stats->OctetsReceivedOK = port->stats.rx_ok_bytes; in airoha_ethtool_get_mac_stats()
2064 stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; in airoha_ethtool_get_mac_stats()
2065 } while (u64_stats_fetch_retry(&port->stats.syncp, start)); in airoha_ethtool_get_mac_stats()
2085 struct airoha_hw_stats *hw_stats = &port->stats; in airoha_ethtool_get_rmon_stats()
2089 ARRAY_SIZE(hw_stats->tx_len) + 1); in airoha_ethtool_get_rmon_stats()
2091 ARRAY_SIZE(hw_stats->rx_len) + 1); in airoha_ethtool_get_rmon_stats()
2098 start = u64_stats_fetch_begin(&port->stats.syncp); in airoha_ethtool_get_rmon_stats()
2099 stats->fragments = hw_stats->rx_fragment; in airoha_ethtool_get_rmon_stats()
2100 stats->jabbers = hw_stats->rx_jabber; in airoha_ethtool_get_rmon_stats()
2101 for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1; in airoha_ethtool_get_rmon_stats()
2103 stats->hist[i] = hw_stats->rx_len[i]; in airoha_ethtool_get_rmon_stats()
2104 stats->hist_tx[i] = hw_stats->tx_len[i]; in airoha_ethtool_get_rmon_stats()
2106 } while (u64_stats_fetch_retry(&port->stats.syncp, start)); in airoha_ethtool_get_rmon_stats()
2116 airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), in airoha_qdma_set_chan_tx_sched()
2123 airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, in airoha_qdma_set_chan_tx_sched()
2131 true, port->qdma, in airoha_qdma_set_chan_tx_sched()
2137 airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), in airoha_qdma_set_chan_tx_sched()
2157 struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; in airoha_qdma_set_tx_ets_sched()
2162 if (p->bands > AIROHA_NUM_QOS_QUEUES) in airoha_qdma_set_tx_ets_sched()
2163 return -EINVAL; in airoha_qdma_set_tx_ets_sched()
2165 for (i = 0; i < p->bands; i++) { in airoha_qdma_set_tx_ets_sched()
2166 if (!p->quanta[i]) in airoha_qdma_set_tx_ets_sched()
2171 if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) in airoha_qdma_set_tx_ets_sched()
2172 return -EINVAL; in airoha_qdma_set_tx_ets_sched()
2179 if (p->priomap[p->bands - i - 1] != i) in airoha_qdma_set_tx_ets_sched()
2180 return -EINVAL; in airoha_qdma_set_tx_ets_sched()
2183 for (i = 0; i < p->bands - nstrict; i++) { in airoha_qdma_set_tx_ets_sched()
2184 if (p->priomap[i] != nstrict + i) in airoha_qdma_set_tx_ets_sched()
2185 return -EINVAL; in airoha_qdma_set_tx_ets_sched()
2187 w[i] = p->weights[nstrict + i]; in airoha_qdma_set_tx_ets_sched()
2192 else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) in airoha_qdma_set_tx_ets_sched()
2203 u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, in airoha_qdma_get_tx_ets_stats()
2205 u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, in airoha_qdma_get_tx_ets_stats()
2207 u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + in airoha_qdma_get_tx_ets_stats()
2208 (fwd_tx_packets - port->fwd_tx_packets); in airoha_qdma_get_tx_ets_stats()
2209 _bstats_update(opt->stats.bstats, 0, tx_packets); in airoha_qdma_get_tx_ets_stats()
2211 port->cpu_tx_packets = cpu_tx_packets; in airoha_qdma_get_tx_ets_stats()
2212 port->fwd_tx_packets = fwd_tx_packets; in airoha_qdma_get_tx_ets_stats()
2222 if (opt->parent == TC_H_ROOT) in airoha_tc_setup_qdisc_ets()
2223 return -EINVAL; in airoha_tc_setup_qdisc_ets()
2225 channel = TC_H_MAJ(opt->handle) >> 16; in airoha_tc_setup_qdisc_ets()
2228 switch (opt->command) { in airoha_tc_setup_qdisc_ets()
2237 return -EOPNOTSUPP; in airoha_tc_setup_qdisc_ets()
2255 return -ETIMEDOUT; in airoha_qdma_get_rl_param()
2317 return -EINVAL; in airoha_qdma_set_rl_token_bucket()
2321 return -EINVAL; in airoha_qdma_set_rl_token_bucket()
2376 return -ETIMEDOUT; in airoha_qdma_get_trtcm_param()
2413 return -EINVAL; in airoha_qdma_set_trtcm_config()
2431 return -EINVAL; in airoha_qdma_set_trtcm_token_bucket()
2438 return -EINVAL; in airoha_qdma_set_trtcm_token_bucket()
2442 return -EINVAL; in airoha_qdma_set_trtcm_token_bucket()
2470 err = airoha_qdma_set_trtcm_config(port->qdma, channel, in airoha_qdma_set_tx_rate_limit()
2476 err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, in airoha_qdma_set_tx_rate_limit()
2489 u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; in airoha_tc_htb_alloc_leaf_queue()
2490 u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ in airoha_tc_htb_alloc_leaf_queue()
2491 struct net_device *dev = port->dev; in airoha_tc_htb_alloc_leaf_queue()
2492 int num_tx_queues = dev->real_num_tx_queues; in airoha_tc_htb_alloc_leaf_queue()
2495 if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { in airoha_tc_htb_alloc_leaf_queue()
2496 NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); in airoha_tc_htb_alloc_leaf_queue()
2497 return -EINVAL; in airoha_tc_htb_alloc_leaf_queue()
2500 err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); in airoha_tc_htb_alloc_leaf_queue()
2502 NL_SET_ERR_MSG_MOD(opt->extack, in airoha_tc_htb_alloc_leaf_queue()
2507 if (opt->command == TC_HTB_NODE_MODIFY) in airoha_tc_htb_alloc_leaf_queue()
2512 airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); in airoha_tc_htb_alloc_leaf_queue()
2513 NL_SET_ERR_MSG_MOD(opt->extack, in airoha_tc_htb_alloc_leaf_queue()
2518 set_bit(channel, port->qos_sq_bmap); in airoha_tc_htb_alloc_leaf_queue()
2519 opt->qid = AIROHA_NUM_TX_RING + channel; in airoha_tc_htb_alloc_leaf_queue()
2528 struct airoha_qdma *qdma = port->qdma; in airoha_qdma_set_rx_meter()
2531 for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { in airoha_qdma_set_rx_meter()
2534 if (!qdma->q_rx[i].ndesc) in airoha_qdma_set_rx_meter()
2552 const struct flow_action *actions = &f->rule->action; in airoha_tc_matchall_act_validate()
2556 NL_SET_ERR_MSG_MOD(f->common.extack, in airoha_tc_matchall_act_validate()
2558 return -EINVAL; in airoha_tc_matchall_act_validate()
2562 NL_SET_ERR_MSG_MOD(f->common.extack, in airoha_tc_matchall_act_validate()
2564 return -EOPNOTSUPP; in airoha_tc_matchall_act_validate()
2567 act = &actions->entries[0]; in airoha_tc_matchall_act_validate()
2568 if (act->id != FLOW_ACTION_POLICE) { in airoha_tc_matchall_act_validate()
2569 NL_SET_ERR_MSG_MOD(f->common.extack, "unsupported action"); in airoha_tc_matchall_act_validate()
2570 return -EOPNOTSUPP; in airoha_tc_matchall_act_validate()
2573 if (act->police.exceed.act_id != FLOW_ACTION_DROP) { in airoha_tc_matchall_act_validate()
2574 NL_SET_ERR_MSG_MOD(f->common.extack, in airoha_tc_matchall_act_validate()
2576 return -EOPNOTSUPP; in airoha_tc_matchall_act_validate()
2579 if (act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) { in airoha_tc_matchall_act_validate()
2580 NL_SET_ERR_MSG_MOD(f->common.extack, in airoha_tc_matchall_act_validate()
2582 return -EOPNOTSUPP; in airoha_tc_matchall_act_validate()
2585 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT && in airoha_tc_matchall_act_validate()
2587 NL_SET_ERR_MSG_MOD(f->common.extack, in airoha_tc_matchall_act_validate()
2589 return -EOPNOTSUPP; in airoha_tc_matchall_act_validate()
2592 if (act->police.peakrate_bytes_ps || act->police.avrate || in airoha_tc_matchall_act_validate()
2593 act->police.overhead || act->police.mtu) { in airoha_tc_matchall_act_validate()
2594 NL_SET_ERR_MSG_MOD(f->common.extack, in airoha_tc_matchall_act_validate()
2596 return -EOPNOTSUPP; in airoha_tc_matchall_act_validate()
2609 switch (f->command) { in airoha_dev_tc_matchall()
2618 act = &f->rule->action.entries[0]; in airoha_dev_tc_matchall()
2619 if (act->police.rate_pkt_ps) { in airoha_dev_tc_matchall()
2620 rate = act->police.rate_pkt_ps; in airoha_dev_tc_matchall()
2621 bucket_size = act->police.burst_pkt; in airoha_dev_tc_matchall()
2624 rate = div_u64(act->police.rate_bytes_ps, 1000); in airoha_dev_tc_matchall()
2626 bucket_size = act->police.burst; in airoha_dev_tc_matchall()
2634 return -EOPNOTSUPP; in airoha_dev_tc_matchall()
2643 struct airoha_eth *eth = port->qdma->eth; in airoha_dev_setup_tc_block_cb() local
2646 return -EOPNOTSUPP; in airoha_dev_setup_tc_block_cb()
2650 return airoha_ppe_setup_tc_block_cb(ð->ppe->dev, type_data); in airoha_dev_setup_tc_block_cb()
2654 return -EOPNOTSUPP; in airoha_dev_setup_tc_block_cb()
2665 if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) in airoha_dev_setup_tc_block()
2666 return -EOPNOTSUPP; in airoha_dev_setup_tc_block()
2668 f->driver_block_list = &block_cb_list; in airoha_dev_setup_tc_block()
2669 switch (f->command) { in airoha_dev_setup_tc_block()
2671 block_cb = flow_block_cb_lookup(f->block, cb, port->dev); in airoha_dev_setup_tc_block()
2676 block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL); in airoha_dev_setup_tc_block()
2682 list_add_tail(&block_cb->driver_list, &block_cb_list); in airoha_dev_setup_tc_block()
2685 block_cb = flow_block_cb_lookup(f->block, cb, port->dev); in airoha_dev_setup_tc_block()
2687 return -ENOENT; in airoha_dev_setup_tc_block()
2691 list_del(&block_cb->driver_list); in airoha_dev_setup_tc_block()
2695 return -EOPNOTSUPP; in airoha_dev_setup_tc_block()
2701 struct net_device *dev = port->dev; in airoha_tc_remove_htb_queue()
2703 netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); in airoha_tc_remove_htb_queue()
2705 clear_bit(queue, port->qos_sq_bmap); in airoha_tc_remove_htb_queue()
2711 u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; in airoha_tc_htb_delete_leaf_queue()
2713 if (!test_bit(channel, port->qos_sq_bmap)) { in airoha_tc_htb_delete_leaf_queue()
2714 NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); in airoha_tc_htb_delete_leaf_queue()
2715 return -EINVAL; in airoha_tc_htb_delete_leaf_queue()
2727 for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) in airoha_tc_htb_destroy()
2736 u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; in airoha_tc_get_htb_get_leaf_queue()
2738 if (!test_bit(channel, port->qos_sq_bmap)) { in airoha_tc_get_htb_get_leaf_queue()
2739 NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); in airoha_tc_get_htb_get_leaf_queue()
2740 return -EINVAL; in airoha_tc_get_htb_get_leaf_queue()
2743 opt->qid = AIROHA_NUM_TX_RING + channel; in airoha_tc_get_htb_get_leaf_queue()
2751 switch (opt->command) { in airoha_tc_setup_qdisc_htb()
2766 return -EOPNOTSUPP; in airoha_tc_setup_qdisc_htb()
2786 return -EOPNOTSUPP; in airoha_dev_tc_setup()
2813 for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { in airoha_metadata_dst_alloc()
2819 return -ENOMEM; in airoha_metadata_dst_alloc()
2821 md_dst->u.port_info.port_id = i; in airoha_metadata_dst_alloc()
2822 port->dsa_meta[i] = md_dst; in airoha_metadata_dst_alloc()
2832 for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { in airoha_metadata_dst_free()
2833 if (!port->dsa_meta[i]) in airoha_metadata_dst_free()
2836 metadata_dst_free(port->dsa_meta[i]); in airoha_metadata_dst_free()
2840 bool airoha_is_valid_gdm_port(struct airoha_eth *eth, in airoha_is_valid_gdm_port() argument
2845 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { in airoha_is_valid_gdm_port()
2846 if (eth->ports[i] == port) in airoha_is_valid_gdm_port()
2853 static int airoha_alloc_gdm_port(struct airoha_eth *eth, in airoha_alloc_gdm_port() argument
2864 dev_err(eth->dev, "missing gdm port id\n"); in airoha_alloc_gdm_port()
2865 return -EINVAL; in airoha_alloc_gdm_port()
2869 p = id - 1; in airoha_alloc_gdm_port()
2871 if (!id || id > ARRAY_SIZE(eth->ports)) { in airoha_alloc_gdm_port()
2872 dev_err(eth->dev, "invalid gdm port id: %d\n", id); in airoha_alloc_gdm_port()
2873 return -EINVAL; in airoha_alloc_gdm_port()
2876 if (eth->ports[p]) { in airoha_alloc_gdm_port()
2877 dev_err(eth->dev, "duplicate gdm port id: %d\n", id); in airoha_alloc_gdm_port()
2878 return -EINVAL; in airoha_alloc_gdm_port()
2881 dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), in airoha_alloc_gdm_port()
2885 dev_err(eth->dev, "alloc_etherdev failed\n"); in airoha_alloc_gdm_port()
2886 return -ENOMEM; in airoha_alloc_gdm_port()
2889 qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA]; in airoha_alloc_gdm_port()
2890 dev->netdev_ops = &airoha_netdev_ops; in airoha_alloc_gdm_port()
2891 dev->ethtool_ops = &airoha_ethtool_ops; in airoha_alloc_gdm_port()
2892 dev->max_mtu = AIROHA_MAX_MTU; in airoha_alloc_gdm_port()
2893 dev->watchdog_timeo = 5 * HZ; in airoha_alloc_gdm_port()
2894 dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | in airoha_alloc_gdm_port()
2898 dev->features |= dev->hw_features; in airoha_alloc_gdm_port()
2899 dev->vlan_features = dev->hw_features; in airoha_alloc_gdm_port()
2900 dev->dev.of_node = np; in airoha_alloc_gdm_port()
2901 dev->irq = qdma->irq_banks[0].irq; in airoha_alloc_gdm_port()
2902 SET_NETDEV_DEV(dev, eth->dev); in airoha_alloc_gdm_port()
2911 if (err == -EPROBE_DEFER) in airoha_alloc_gdm_port()
2915 dev_info(eth->dev, "generated random MAC address %pM\n", in airoha_alloc_gdm_port()
2916 dev->dev_addr); in airoha_alloc_gdm_port()
2920 u64_stats_init(&port->stats.syncp); in airoha_alloc_gdm_port()
2921 spin_lock_init(&port->stats.lock); in airoha_alloc_gdm_port()
2922 port->qdma = qdma; in airoha_alloc_gdm_port()
2923 port->dev = dev; in airoha_alloc_gdm_port()
2924 port->id = id; in airoha_alloc_gdm_port()
2925 eth->ports[p] = port; in airoha_alloc_gdm_port()
2946 struct airoha_eth *eth; in airoha_probe() local
2949 eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); in airoha_probe()
2950 if (!eth) in airoha_probe()
2951 return -ENOMEM; in airoha_probe()
2953 eth->soc = of_device_get_match_data(&pdev->dev); in airoha_probe()
2954 if (!eth->soc) in airoha_probe()
2955 return -EINVAL; in airoha_probe()
2957 eth->dev = &pdev->dev; in airoha_probe()
2959 err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); in airoha_probe()
2961 dev_err(eth->dev, "failed configuring DMA mask\n"); in airoha_probe()
2965 eth->fe_regs = devm_platform_ioremap_resource_byname(pdev, "fe"); in airoha_probe()
2966 if (IS_ERR(eth->fe_regs)) in airoha_probe()
2967 return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs), in airoha_probe()
2970 eth->rsts[0].id = "fe"; in airoha_probe()
2971 eth->rsts[1].id = "pdma"; in airoha_probe()
2972 eth->rsts[2].id = "qdma"; in airoha_probe()
2973 err = devm_reset_control_bulk_get_exclusive(eth->dev, in airoha_probe()
2974 ARRAY_SIZE(eth->rsts), in airoha_probe()
2975 eth->rsts); in airoha_probe()
2977 dev_err(eth->dev, "failed to get bulk reset lines\n"); in airoha_probe()
2981 xsi_rsts = devm_kcalloc(eth->dev, in airoha_probe()
2982 eth->soc->num_xsi_rsts, sizeof(*xsi_rsts), in airoha_probe()
2985 return -ENOMEM; in airoha_probe()
2987 eth->xsi_rsts = xsi_rsts; in airoha_probe()
2988 for (i = 0; i < eth->soc->num_xsi_rsts; i++) in airoha_probe()
2989 eth->xsi_rsts[i].id = eth->soc->xsi_rsts_names[i]; in airoha_probe()
2991 err = devm_reset_control_bulk_get_exclusive(eth->dev, in airoha_probe()
2992 eth->soc->num_xsi_rsts, in airoha_probe()
2993 eth->xsi_rsts); in airoha_probe()
2995 dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); in airoha_probe()
2999 eth->napi_dev = alloc_netdev_dummy(0); in airoha_probe()
3000 if (!eth->napi_dev) in airoha_probe()
3001 return -ENOMEM; in airoha_probe()
3004 eth->napi_dev->threaded = true; in airoha_probe()
3005 strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name)); in airoha_probe()
3006 platform_set_drvdata(pdev, eth); in airoha_probe()
3008 err = airoha_hw_init(pdev, eth); in airoha_probe()
3012 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) in airoha_probe()
3013 airoha_qdma_start_napi(ð->qdma[i]); in airoha_probe()
3016 for_each_child_of_node(pdev->dev.of_node, np) { in airoha_probe()
3017 if (!of_device_is_compatible(np, "airoha,eth-mac")) in airoha_probe()
3023 err = airoha_alloc_gdm_port(eth, np, i++); in airoha_probe()
3033 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) in airoha_probe()
3034 airoha_qdma_stop_napi(ð->qdma[i]); in airoha_probe()
3035 airoha_ppe_deinit(eth); in airoha_probe()
3037 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) in airoha_probe()
3038 airoha_hw_cleanup(ð->qdma[i]); in airoha_probe()
3040 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { in airoha_probe()
3041 struct airoha_gdm_port *port = eth->ports[i]; in airoha_probe()
3043 if (port && port->dev->reg_state == NETREG_REGISTERED) { in airoha_probe()
3044 unregister_netdev(port->dev); in airoha_probe()
3048 free_netdev(eth->napi_dev); in airoha_probe()
3056 struct airoha_eth *eth = platform_get_drvdata(pdev); in airoha_remove() local
3059 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { in airoha_remove()
3060 airoha_qdma_stop_napi(ð->qdma[i]); in airoha_remove()
3061 airoha_hw_cleanup(ð->qdma[i]); in airoha_remove()
3064 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { in airoha_remove()
3065 struct airoha_gdm_port *port = eth->ports[i]; in airoha_remove()
3070 airoha_dev_stop(port->dev); in airoha_remove()
3071 unregister_netdev(port->dev); in airoha_remove()
3074 free_netdev(eth->napi_dev); in airoha_remove()
3076 airoha_ppe_deinit(eth); in airoha_remove()
3081 "xsi-mac",
3082 "hsi0-mac",
3083 "hsi1-mac",
3084 "hsi-mac",
3085 "xfp-mac",
3090 switch (port->id) { in airoha_en7581_get_src_port_id()
3099 /* 7581 SoC supports eth and usb serdes on GDM4 port */ in airoha_en7581_get_src_port_id()
3109 return -EINVAL; in airoha_en7581_get_src_port_id()
3113 "xsi-mac",
3114 "hsi0-mac",
3115 "hsi1-mac",
3116 "xfp-mac",
3121 switch (port->id) { in airoha_an7583_get_src_port_id()
3123 /* 7583 SoC supports eth serdes on GDM3 port */ in airoha_an7583_get_src_port_id()
3138 return -EINVAL; in airoha_an7583_get_src_port_id()
3162 { .compatible = "airoha,en7581-eth", .data = &en7581_soc_data },
3163 { .compatible = "airoha,an7583-eth", .data = &an7583_soc_data },