Lines Matching +full:ocelot +full:- +full:1
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
13 #include <linux/dsa/ocelot.h>
22 static void ocelot_fdma_writel(struct ocelot *ocelot, u32 reg, u32 data) in ocelot_fdma_writel() argument
24 regmap_write(ocelot->targets[FDMA], reg, data); in ocelot_fdma_writel()
27 static u32 ocelot_fdma_readl(struct ocelot *ocelot, u32 reg) in ocelot_fdma_readl() argument
31 regmap_read(ocelot->targets[FDMA], reg, &retval); in ocelot_fdma_readl()
43 return (dma - base) / sizeof(struct ocelot_fdma_dcb); in ocelot_fdma_dma_idx()
48 return unlikely(idx == ring_sz - 1) ? 0 : idx + 1; in ocelot_fdma_idx_next()
53 return unlikely(idx == 0) ? ring_sz - 1 : idx - 1; in ocelot_fdma_idx_prev()
58 struct ocelot_fdma_rx_ring *rx_ring = &fdma->rx_ring; in ocelot_fdma_rx_ring_free()
60 if (rx_ring->next_to_use >= rx_ring->next_to_clean) in ocelot_fdma_rx_ring_free()
61 return OCELOT_FDMA_RX_RING_SIZE - in ocelot_fdma_rx_ring_free()
62 (rx_ring->next_to_use - rx_ring->next_to_clean) - 1; in ocelot_fdma_rx_ring_free()
64 return rx_ring->next_to_clean - rx_ring->next_to_use - 1; in ocelot_fdma_rx_ring_free()
69 struct ocelot_fdma_tx_ring *tx_ring = &fdma->tx_ring; in ocelot_fdma_tx_ring_free()
71 if (tx_ring->next_to_use >= tx_ring->next_to_clean) in ocelot_fdma_tx_ring_free()
72 return OCELOT_FDMA_TX_RING_SIZE - in ocelot_fdma_tx_ring_free()
73 (tx_ring->next_to_use - tx_ring->next_to_clean) - 1; in ocelot_fdma_tx_ring_free()
75 return tx_ring->next_to_clean - tx_ring->next_to_use - 1; in ocelot_fdma_tx_ring_free()
80 struct ocelot_fdma_tx_ring *tx_ring = &fdma->tx_ring; in ocelot_fdma_tx_ring_empty()
82 return tx_ring->next_to_clean == tx_ring->next_to_use; in ocelot_fdma_tx_ring_empty()
85 static void ocelot_fdma_activate_chan(struct ocelot *ocelot, dma_addr_t dma, in ocelot_fdma_activate_chan() argument
88 ocelot_fdma_writel(ocelot, MSCC_FDMA_DCB_LLP(chan), dma); in ocelot_fdma_activate_chan()
93 ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_ACTIVATE, BIT(chan)); in ocelot_fdma_activate_chan()
96 static u32 ocelot_fdma_read_ch_safe(struct ocelot *ocelot) in ocelot_fdma_read_ch_safe() argument
98 return ocelot_fdma_readl(ocelot, MSCC_FDMA_CH_SAFE); in ocelot_fdma_read_ch_safe()
101 static int ocelot_fdma_wait_chan_safe(struct ocelot *ocelot, int chan) in ocelot_fdma_wait_chan_safe() argument
105 return readx_poll_timeout_atomic(ocelot_fdma_read_ch_safe, ocelot, safe, in ocelot_fdma_wait_chan_safe()
116 dcb->llp = 0; in ocelot_fdma_dcb_set_data()
117 dcb->datap = ALIGN_DOWN(dma_addr, 4); in ocelot_fdma_dcb_set_data()
118 dcb->datal = ALIGN_DOWN(size, 4); in ocelot_fdma_dcb_set_data()
119 dcb->stat = MSCC_FDMA_DCB_STAT_BLOCKO(offset); in ocelot_fdma_dcb_set_data()
122 static bool ocelot_fdma_rx_alloc_page(struct ocelot *ocelot, in ocelot_fdma_rx_alloc_page() argument
132 mapping = dma_map_page(ocelot->dev, page, 0, PAGE_SIZE, in ocelot_fdma_rx_alloc_page()
134 if (unlikely(dma_mapping_error(ocelot->dev, mapping))) { in ocelot_fdma_rx_alloc_page()
139 rxb->page = page; in ocelot_fdma_rx_alloc_page()
140 rxb->page_offset = 0; in ocelot_fdma_rx_alloc_page()
141 rxb->dma_addr = mapping; in ocelot_fdma_rx_alloc_page()
146 static int ocelot_fdma_alloc_rx_buffs(struct ocelot *ocelot, u16 alloc_cnt) in ocelot_fdma_alloc_rx_buffs() argument
148 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_alloc_rx_buffs()
156 rx_ring = &fdma->rx_ring; in ocelot_fdma_alloc_rx_buffs()
157 idx = rx_ring->next_to_use; in ocelot_fdma_alloc_rx_buffs()
159 while (alloc_cnt--) { in ocelot_fdma_alloc_rx_buffs()
160 rxb = &rx_ring->bufs[idx]; in ocelot_fdma_alloc_rx_buffs()
162 if (unlikely(!rxb->page)) { in ocelot_fdma_alloc_rx_buffs()
163 if (unlikely(!ocelot_fdma_rx_alloc_page(ocelot, rxb))) { in ocelot_fdma_alloc_rx_buffs()
164 dev_err_ratelimited(ocelot->dev, in ocelot_fdma_alloc_rx_buffs()
166 ret = -ENOMEM; in ocelot_fdma_alloc_rx_buffs()
171 dcb = &rx_ring->dcbs[idx]; in ocelot_fdma_alloc_rx_buffs()
172 dma_addr = rxb->dma_addr + rxb->page_offset; in ocelot_fdma_alloc_rx_buffs()
177 dcb->llp = ocelot_fdma_idx_dma(rx_ring->dcbs_dma, idx); in ocelot_fdma_alloc_rx_buffs()
180 rx_ring->next_to_use = idx; in ocelot_fdma_alloc_rx_buffs()
181 rx_ring->next_to_alloc = idx; in ocelot_fdma_alloc_rx_buffs()
186 static bool ocelot_fdma_tx_dcb_set_skb(struct ocelot *ocelot, in ocelot_fdma_tx_dcb_set_skb() argument
193 mapping = dma_map_single(ocelot->dev, skb->data, skb->len, in ocelot_fdma_tx_dcb_set_skb()
195 if (unlikely(dma_mapping_error(ocelot->dev, mapping))) in ocelot_fdma_tx_dcb_set_skb()
201 tx_buf->skb = skb; in ocelot_fdma_tx_dcb_set_skb()
202 dcb->stat |= MSCC_FDMA_DCB_STAT_BLOCKL(skb->len); in ocelot_fdma_tx_dcb_set_skb()
203 dcb->stat |= MSCC_FDMA_DCB_STAT_SOF | MSCC_FDMA_DCB_STAT_EOF; in ocelot_fdma_tx_dcb_set_skb()
208 static bool ocelot_fdma_check_stop_rx(struct ocelot *ocelot) in ocelot_fdma_check_stop_rx() argument
213 llp = ocelot_fdma_readl(ocelot, MSCC_FDMA_DCB_LLP(MSCC_FDMA_XTR_CHAN)); in ocelot_fdma_check_stop_rx()
217 ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_DISABLE, in ocelot_fdma_check_stop_rx()
228 idx = ocelot_fdma_idx_prev(rx_ring->next_to_use, in ocelot_fdma_rx_set_llp()
230 dcb = &rx_ring->dcbs[idx]; in ocelot_fdma_rx_set_llp()
231 dcb->llp = 0; in ocelot_fdma_rx_set_llp()
234 static void ocelot_fdma_rx_restart(struct ocelot *ocelot) in ocelot_fdma_rx_restart() argument
236 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_rx_restart()
244 rx_ring = &fdma->rx_ring; in ocelot_fdma_rx_restart()
245 ret = ocelot_fdma_wait_chan_safe(ocelot, chan); in ocelot_fdma_rx_restart()
247 dev_err_ratelimited(ocelot->dev, in ocelot_fdma_rx_restart()
258 llp_prev = ocelot_fdma_readl(ocelot, MSCC_FDMA_DCB_LLP_PREV(chan)); in ocelot_fdma_rx_restart()
259 dma_base = rx_ring->dcbs_dma; in ocelot_fdma_rx_restart()
267 ocelot_fdma_activate_chan(ocelot, new_llp, chan); in ocelot_fdma_rx_restart()
274 struct page *page = rxb->page; in ocelot_fdma_add_rx_frag()
279 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, in ocelot_fdma_add_rx_frag()
280 rxb->page_offset, size, OCELOT_FDMA_RX_SIZE); in ocelot_fdma_add_rx_frag()
284 if (unlikely(page_ref_count(page) != 1 || page_is_pfmemalloc(page))) in ocelot_fdma_add_rx_frag()
288 rxb->page_offset ^= OCELOT_FDMA_RX_SIZE; in ocelot_fdma_add_rx_frag()
295 static void ocelot_fdma_reuse_rx_page(struct ocelot *ocelot, in ocelot_fdma_reuse_rx_page() argument
298 struct ocelot_fdma_rx_ring *rx_ring = &ocelot->fdma->rx_ring; in ocelot_fdma_reuse_rx_page()
301 new_rxb = &rx_ring->bufs[rx_ring->next_to_alloc]; in ocelot_fdma_reuse_rx_page()
302 rx_ring->next_to_alloc = ocelot_fdma_idx_next(rx_ring->next_to_alloc, in ocelot_fdma_reuse_rx_page()
309 dma_sync_single_range_for_device(ocelot->dev, old_rxb->dma_addr, in ocelot_fdma_reuse_rx_page()
310 old_rxb->page_offset, in ocelot_fdma_reuse_rx_page()
314 static struct sk_buff *ocelot_fdma_get_skb(struct ocelot *ocelot, u32 stat, in ocelot_fdma_get_skb() argument
322 void *buff_addr = page_address(rxb->page) + in ocelot_fdma_get_skb()
323 rxb->page_offset; in ocelot_fdma_get_skb()
327 dev_err_ratelimited(ocelot->dev, in ocelot_fdma_get_skb()
334 dma_sync_single_range_for_cpu(ocelot->dev, rxb->dma_addr, in ocelot_fdma_get_skb()
335 rxb->page_offset, OCELOT_FDMA_RX_SIZE, in ocelot_fdma_get_skb()
340 ocelot_fdma_reuse_rx_page(ocelot, rxb); in ocelot_fdma_get_skb()
343 dma_unmap_page(ocelot->dev, rxb->dma_addr, PAGE_SIZE, in ocelot_fdma_get_skb()
348 rxb->page = NULL; in ocelot_fdma_get_skb()
353 static bool ocelot_fdma_receive_skb(struct ocelot *ocelot, struct sk_buff *skb) in ocelot_fdma_receive_skb() argument
356 void *xfh = skb->data; in ocelot_fdma_receive_skb()
363 if (unlikely(src_port >= ocelot->num_phys_ports)) in ocelot_fdma_receive_skb()
366 ndev = ocelot_port_to_netdev(ocelot, src_port); in ocelot_fdma_receive_skb()
370 if (pskb_trim(skb, skb->len - ETH_FCS_LEN)) in ocelot_fdma_receive_skb()
373 skb->dev = ndev; in ocelot_fdma_receive_skb()
374 skb->protocol = eth_type_trans(skb, skb->dev); in ocelot_fdma_receive_skb()
375 skb->dev->stats.rx_bytes += skb->len; in ocelot_fdma_receive_skb()
376 skb->dev->stats.rx_packets++; in ocelot_fdma_receive_skb()
378 if (ocelot->ptp) { in ocelot_fdma_receive_skb()
380 ocelot_ptp_rx_timestamp(ocelot, skb, timestamp); in ocelot_fdma_receive_skb()
389 static int ocelot_fdma_rx_get(struct ocelot *ocelot, int budget) in ocelot_fdma_rx_get() argument
391 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_rx_get()
402 rx_ring = &fdma->rx_ring; in ocelot_fdma_rx_get()
403 skb = rx_ring->skb; in ocelot_fdma_rx_get()
405 while (budget--) { in ocelot_fdma_rx_get()
406 idx = rx_ring->next_to_clean; in ocelot_fdma_rx_get()
407 dcb = &rx_ring->dcbs[idx]; in ocelot_fdma_rx_get()
408 stat = dcb->stat; in ocelot_fdma_rx_get()
420 rxb = &rx_ring->bufs[idx]; in ocelot_fdma_rx_get()
422 skb = ocelot_fdma_get_skb(ocelot, stat, rxb, skb); in ocelot_fdma_rx_get()
430 rx_ring->next_to_clean = idx; in ocelot_fdma_rx_get()
434 dev_err_ratelimited(ocelot->dev, in ocelot_fdma_rx_get()
447 if (unlikely(!ocelot_fdma_receive_skb(ocelot, skb))) in ocelot_fdma_rx_get()
453 rx_ring->skb = skb; in ocelot_fdma_rx_get()
456 ocelot_fdma_alloc_rx_buffs(ocelot, cleaned_cnt); in ocelot_fdma_rx_get()
461 static void ocelot_fdma_wakeup_netdev(struct ocelot *ocelot) in ocelot_fdma_wakeup_netdev() argument
468 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_fdma_wakeup_netdev()
469 ocelot_port = ocelot->ports[port]; in ocelot_fdma_wakeup_netdev()
474 dev = priv->dev; in ocelot_fdma_wakeup_netdev()
481 static void ocelot_fdma_tx_cleanup(struct ocelot *ocelot, int budget) in ocelot_fdma_tx_cleanup() argument
483 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_tx_cleanup()
495 tx_ring = &fdma->tx_ring; in ocelot_fdma_tx_cleanup()
501 ntc = tx_ring->next_to_clean; in ocelot_fdma_tx_cleanup()
502 dcb = &tx_ring->dcbs[ntc]; in ocelot_fdma_tx_cleanup()
503 if (!(dcb->stat & MSCC_FDMA_DCB_STAT_PD)) in ocelot_fdma_tx_cleanup()
506 buf = &tx_ring->bufs[ntc]; in ocelot_fdma_tx_cleanup()
507 skb = buf->skb; in ocelot_fdma_tx_cleanup()
508 dma_unmap_single(ocelot->dev, dma_unmap_addr(buf, dma_addr), in ocelot_fdma_tx_cleanup()
509 skb->len, DMA_TO_DEVICE); in ocelot_fdma_tx_cleanup()
511 dcb_llp = dcb->llp; in ocelot_fdma_tx_cleanup()
514 tx_ring->next_to_clean = ocelot_fdma_idx_next(ntc, in ocelot_fdma_tx_cleanup()
526 ocelot_fdma_wakeup_netdev(ocelot); in ocelot_fdma_tx_cleanup()
534 ret = ocelot_fdma_wait_chan_safe(ocelot, MSCC_FDMA_INJ_CHAN); in ocelot_fdma_tx_cleanup()
536 dev_warn(ocelot->dev, in ocelot_fdma_tx_cleanup()
542 new_null_llp_idx = ocelot_fdma_idx_prev(tx_ring->next_to_use, in ocelot_fdma_tx_cleanup()
544 dcb = &tx_ring->dcbs[new_null_llp_idx]; in ocelot_fdma_tx_cleanup()
545 dcb->llp = 0; in ocelot_fdma_tx_cleanup()
547 dma = ocelot_fdma_idx_dma(tx_ring->dcbs_dma, tx_ring->next_to_clean); in ocelot_fdma_tx_cleanup()
548 ocelot_fdma_activate_chan(ocelot, dma, MSCC_FDMA_INJ_CHAN); in ocelot_fdma_tx_cleanup()
554 struct ocelot *ocelot = fdma->ocelot; in ocelot_fdma_napi_poll() local
558 ocelot_fdma_tx_cleanup(ocelot, budget); in ocelot_fdma_napi_poll()
560 rx_stopped = ocelot_fdma_check_stop_rx(ocelot); in ocelot_fdma_napi_poll()
562 work_done = ocelot_fdma_rx_get(ocelot, budget); in ocelot_fdma_napi_poll()
565 ocelot_fdma_rx_restart(ocelot); in ocelot_fdma_napi_poll()
568 napi_complete_done(&fdma->napi, work_done); in ocelot_fdma_napi_poll()
569 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, in ocelot_fdma_napi_poll()
580 struct ocelot *ocelot = dev_id; in ocelot_fdma_interrupt() local
582 ident = ocelot_fdma_readl(ocelot, MSCC_FDMA_INTR_IDENT); in ocelot_fdma_interrupt()
583 frm = ocelot_fdma_readl(ocelot, MSCC_FDMA_INTR_FRM); in ocelot_fdma_interrupt()
584 llp = ocelot_fdma_readl(ocelot, MSCC_FDMA_INTR_LLP); in ocelot_fdma_interrupt()
586 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_LLP, llp & ident); in ocelot_fdma_interrupt()
587 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_FRM, frm & ident); in ocelot_fdma_interrupt()
589 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, 0); in ocelot_fdma_interrupt()
590 napi_schedule(&ocelot->fdma->napi); in ocelot_fdma_interrupt()
593 err = ocelot_fdma_readl(ocelot, MSCC_FDMA_EVT_ERR); in ocelot_fdma_interrupt()
595 err_code = ocelot_fdma_readl(ocelot, MSCC_FDMA_EVT_ERR_CODE); in ocelot_fdma_interrupt()
596 dev_err_ratelimited(ocelot->dev, in ocelot_fdma_interrupt()
600 ocelot_fdma_writel(ocelot, MSCC_FDMA_EVT_ERR, err); in ocelot_fdma_interrupt()
601 ocelot_fdma_writel(ocelot, MSCC_FDMA_EVT_ERR_CODE, err_code); in ocelot_fdma_interrupt()
607 static void ocelot_fdma_send_skb(struct ocelot *ocelot, in ocelot_fdma_send_skb() argument
610 struct ocelot_fdma_tx_ring *tx_ring = &fdma->tx_ring; in ocelot_fdma_send_skb()
616 dcb = &tx_ring->dcbs[tx_ring->next_to_use]; in ocelot_fdma_send_skb()
617 tx_buf = &tx_ring->bufs[tx_ring->next_to_use]; in ocelot_fdma_send_skb()
618 if (!ocelot_fdma_tx_dcb_set_skb(ocelot, tx_buf, dcb, skb)) { in ocelot_fdma_send_skb()
623 next_idx = ocelot_fdma_idx_next(tx_ring->next_to_use, in ocelot_fdma_send_skb()
629 dma = ocelot_fdma_idx_dma(tx_ring->dcbs_dma, in ocelot_fdma_send_skb()
630 tx_ring->next_to_use); in ocelot_fdma_send_skb()
631 ocelot_fdma_activate_chan(ocelot, dma, MSCC_FDMA_INJ_CHAN); in ocelot_fdma_send_skb()
634 dcb->llp = ocelot_fdma_idx_dma(tx_ring->dcbs_dma, next_idx); in ocelot_fdma_send_skb()
637 tx_ring->next_to_use = next_idx; in ocelot_fdma_send_skb()
640 static int ocelot_fdma_prepare_skb(struct ocelot *ocelot, int port, u32 rew_op, in ocelot_fdma_prepare_skb() argument
643 int needed_headroom = max_t(int, OCELOT_TAG_LEN - skb_headroom(skb), 0); in ocelot_fdma_prepare_skb()
644 int needed_tailroom = max_t(int, ETH_FCS_LEN - skb_tailroom(skb), 0); in ocelot_fdma_prepare_skb()
654 return 1; in ocelot_fdma_prepare_skb()
661 dev->name, err); in ocelot_fdma_prepare_skb()
663 return 1; in ocelot_fdma_prepare_skb()
668 ocelot_ifh_set_basic(ifh, ocelot, port, rew_op, skb); in ocelot_fdma_prepare_skb()
673 int ocelot_fdma_inject_frame(struct ocelot *ocelot, int port, u32 rew_op, in ocelot_fdma_inject_frame() argument
676 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_inject_frame()
679 spin_lock(&fdma->tx_ring.xmit_lock); in ocelot_fdma_inject_frame()
687 if (ocelot_fdma_prepare_skb(ocelot, port, rew_op, skb, dev)) in ocelot_fdma_inject_frame()
690 ocelot_fdma_send_skb(ocelot, fdma, skb); in ocelot_fdma_inject_frame()
693 spin_unlock(&fdma->tx_ring.xmit_lock); in ocelot_fdma_inject_frame()
698 static void ocelot_fdma_free_rx_ring(struct ocelot *ocelot) in ocelot_fdma_free_rx_ring() argument
700 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_free_rx_ring()
705 rx_ring = &fdma->rx_ring; in ocelot_fdma_free_rx_ring()
706 idx = rx_ring->next_to_clean; in ocelot_fdma_free_rx_ring()
709 while (idx != rx_ring->next_to_use) { in ocelot_fdma_free_rx_ring()
710 rxb = &rx_ring->bufs[idx]; in ocelot_fdma_free_rx_ring()
711 dma_unmap_page(ocelot->dev, rxb->dma_addr, PAGE_SIZE, in ocelot_fdma_free_rx_ring()
713 __free_page(rxb->page); in ocelot_fdma_free_rx_ring()
717 if (fdma->rx_ring.skb) in ocelot_fdma_free_rx_ring()
718 dev_kfree_skb_any(fdma->rx_ring.skb); in ocelot_fdma_free_rx_ring()
721 static void ocelot_fdma_free_tx_ring(struct ocelot *ocelot) in ocelot_fdma_free_tx_ring() argument
723 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_free_tx_ring()
729 tx_ring = &fdma->tx_ring; in ocelot_fdma_free_tx_ring()
730 idx = tx_ring->next_to_clean; in ocelot_fdma_free_tx_ring()
732 while (idx != tx_ring->next_to_use) { in ocelot_fdma_free_tx_ring()
733 txb = &tx_ring->bufs[idx]; in ocelot_fdma_free_tx_ring()
734 skb = txb->skb; in ocelot_fdma_free_tx_ring()
735 dma_unmap_single(ocelot->dev, dma_unmap_addr(txb, dma_addr), in ocelot_fdma_free_tx_ring()
736 skb->len, DMA_TO_DEVICE); in ocelot_fdma_free_tx_ring()
742 static int ocelot_fdma_rings_alloc(struct ocelot *ocelot) in ocelot_fdma_rings_alloc() argument
744 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_rings_alloc()
751 fdma->dcbs_base = dmam_alloc_coherent(ocelot->dev, in ocelot_fdma_rings_alloc()
753 &fdma->dcbs_dma_base, GFP_KERNEL); in ocelot_fdma_rings_alloc()
754 if (!fdma->dcbs_base) in ocelot_fdma_rings_alloc()
755 return -ENOMEM; in ocelot_fdma_rings_alloc()
758 dcbs = fdma->dcbs_base; in ocelot_fdma_rings_alloc()
759 dcbs_dma = fdma->dcbs_dma_base; in ocelot_fdma_rings_alloc()
767 fdma->tx_ring.dcbs = dcbs; in ocelot_fdma_rings_alloc()
768 fdma->tx_ring.dcbs_dma = dcbs_dma; in ocelot_fdma_rings_alloc()
769 spin_lock_init(&fdma->tx_ring.xmit_lock); in ocelot_fdma_rings_alloc()
772 fdma->rx_ring.dcbs = dcbs + OCELOT_FDMA_TX_RING_SIZE; in ocelot_fdma_rings_alloc()
773 fdma->rx_ring.dcbs_dma = dcbs_dma + OCELOT_FDMA_TX_DCB_SIZE; in ocelot_fdma_rings_alloc()
774 ret = ocelot_fdma_alloc_rx_buffs(ocelot, in ocelot_fdma_rings_alloc()
777 ocelot_fdma_free_rx_ring(ocelot); in ocelot_fdma_rings_alloc()
784 ocelot_fdma_rx_set_llp(&fdma->rx_ring); in ocelot_fdma_rings_alloc()
789 void ocelot_fdma_netdev_init(struct ocelot *ocelot, struct net_device *dev) in ocelot_fdma_netdev_init() argument
791 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_netdev_init()
793 dev->needed_headroom = OCELOT_TAG_LEN; in ocelot_fdma_netdev_init()
794 dev->needed_tailroom = ETH_FCS_LEN; in ocelot_fdma_netdev_init()
796 if (fdma->ndev) in ocelot_fdma_netdev_init()
799 fdma->ndev = dev; in ocelot_fdma_netdev_init()
800 netif_napi_add_weight(dev, &fdma->napi, ocelot_fdma_napi_poll, in ocelot_fdma_netdev_init()
804 void ocelot_fdma_netdev_deinit(struct ocelot *ocelot, struct net_device *dev) in ocelot_fdma_netdev_deinit() argument
806 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_netdev_deinit()
808 if (fdma->ndev == dev) { in ocelot_fdma_netdev_deinit()
809 netif_napi_del(&fdma->napi); in ocelot_fdma_netdev_deinit()
810 fdma->ndev = NULL; in ocelot_fdma_netdev_deinit()
814 void ocelot_fdma_init(struct platform_device *pdev, struct ocelot *ocelot) in ocelot_fdma_init() argument
816 struct device *dev = ocelot->dev; in ocelot_fdma_init()
824 ocelot->fdma = fdma; in ocelot_fdma_init()
825 ocelot->dev->coherent_dma_mask = DMA_BIT_MASK(32); in ocelot_fdma_init()
827 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, 0); in ocelot_fdma_init()
829 fdma->ocelot = ocelot; in ocelot_fdma_init()
830 fdma->irq = platform_get_irq_byname(pdev, "fdma"); in ocelot_fdma_init()
831 ret = devm_request_irq(dev, fdma->irq, ocelot_fdma_interrupt, 0, in ocelot_fdma_init()
832 dev_name(dev), ocelot); in ocelot_fdma_init()
836 ret = ocelot_fdma_rings_alloc(ocelot); in ocelot_fdma_init()
845 devm_free_irq(dev, fdma->irq, fdma); in ocelot_fdma_init()
849 ocelot->fdma = NULL; in ocelot_fdma_init()
852 void ocelot_fdma_start(struct ocelot *ocelot) in ocelot_fdma_start() argument
854 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_start()
857 ocelot_write_rix(ocelot, QS_INJ_GRP_CFG_MODE(2), QS_INJ_GRP_CFG, 0); in ocelot_fdma_start()
858 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(0), QS_INJ_CTRL, 0); in ocelot_fdma_start()
860 ocelot_write_rix(ocelot, QS_XTR_GRP_CFG_MODE(2), QS_XTR_GRP_CFG, 0); in ocelot_fdma_start()
862 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_LLP, 0xffffffff); in ocelot_fdma_start()
863 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_FRM, 0xffffffff); in ocelot_fdma_start()
865 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_LLP_ENA, in ocelot_fdma_start()
867 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_FRM_ENA, in ocelot_fdma_start()
869 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, in ocelot_fdma_start()
872 napi_enable(&fdma->napi); in ocelot_fdma_start()
874 ocelot_fdma_activate_chan(ocelot, ocelot->fdma->rx_ring.dcbs_dma, in ocelot_fdma_start()
878 void ocelot_fdma_deinit(struct ocelot *ocelot) in ocelot_fdma_deinit() argument
880 struct ocelot_fdma *fdma = ocelot->fdma; in ocelot_fdma_deinit()
882 ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, 0); in ocelot_fdma_deinit()
883 ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_FORCEDIS, in ocelot_fdma_deinit()
885 ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_FORCEDIS, in ocelot_fdma_deinit()
887 napi_synchronize(&fdma->napi); in ocelot_fdma_deinit()
888 napi_disable(&fdma->napi); in ocelot_fdma_deinit()
890 ocelot_fdma_free_rx_ring(ocelot); in ocelot_fdma_deinit()
891 ocelot_fdma_free_tx_ring(ocelot); in ocelot_fdma_deinit()