// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Microsemi SoCs FDMA driver
 *
 * Copyright (c) 2021 Microchip
 *
 * Page recycling code is mostly taken from gianfar driver.
 */

#include <linux/align.h>
#include <linux/bitops.h>
#include <linux/dmapool.h>
#include <linux/dsa/ocelot.h>
#include <linux/netdevice.h>
#include <linux/of_platform.h>
#include <linux/skbuff.h>

#include "ocelot_fdma.h"
#include "ocelot_qs.h"

DEFINE_STATIC_KEY_FALSE(ocelot_fdma_enabled);

static void ocelot_fdma_writel(struct ocelot *ocelot, u32 reg, u32 data)
{
	regmap_write(ocelot->targets[FDMA], reg, data);
}

static u32 ocelot_fdma_readl(struct ocelot *ocelot, u32 reg)
{
	u32 retval;

	regmap_read(ocelot->targets[FDMA], reg, &retval);

	return retval;
}

static dma_addr_t ocelot_fdma_idx_dma(dma_addr_t base, u16 idx)
{
	return base + idx * sizeof(struct ocelot_fdma_dcb);
}

static u16 ocelot_fdma_dma_idx(dma_addr_t base, dma_addr_t dma)
{
	return (dma - base) / sizeof(struct ocelot_fdma_dcb);
}

static u16 ocelot_fdma_idx_next(u16 idx, u16 ring_sz)
{
	return unlikely(idx == ring_sz - 1) ? 0 : idx + 1;
}

static u16 ocelot_fdma_idx_prev(u16 idx, u16 ring_sz)
{
	return unlikely(idx == 0) ? ring_sz - 1 : idx - 1;
}

static int ocelot_fdma_rx_ring_free(struct ocelot_fdma *fdma)
{
	struct ocelot_fdma_rx_ring *rx_ring = &fdma->rx_ring;

	if (rx_ring->next_to_use >= rx_ring->next_to_clean)
		return OCELOT_FDMA_RX_RING_SIZE -
		       (rx_ring->next_to_use - rx_ring->next_to_clean) - 1;
	else
		return rx_ring->next_to_clean - rx_ring->next_to_use - 1;
}

static int ocelot_fdma_tx_ring_free(struct ocelot_fdma *fdma)
{
	struct ocelot_fdma_tx_ring *tx_ring = &fdma->tx_ring;

	if (tx_ring->next_to_use >= tx_ring->next_to_clean)
		return OCELOT_FDMA_TX_RING_SIZE -
		       (tx_ring->next_to_use - tx_ring->next_to_clean) - 1;
	else
		return tx_ring->next_to_clean - tx_ring->next_to_use - 1;
}

static bool ocelot_fdma_tx_ring_empty(struct ocelot_fdma *fdma)
{
	struct ocelot_fdma_tx_ring *tx_ring = &fdma->tx_ring;

	return tx_ring->next_to_clean == tx_ring->next_to_use;
}

static void ocelot_fdma_activate_chan(struct ocelot *ocelot, dma_addr_t dma,
				      int chan)
{
	ocelot_fdma_writel(ocelot, MSCC_FDMA_DCB_LLP(chan), dma);
	/* Barrier to force memory writes to DCB to be completed before starting
	 * the channel.
	 */
	wmb();
	ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_ACTIVATE, BIT(chan));
}

static u32 ocelot_fdma_read_ch_safe(struct ocelot *ocelot)
{
	return ocelot_fdma_readl(ocelot, MSCC_FDMA_CH_SAFE);
}

static int ocelot_fdma_wait_chan_safe(struct ocelot *ocelot, int chan)
{
	u32 safe;

	return readx_poll_timeout_atomic(ocelot_fdma_read_ch_safe, ocelot, safe,
					 safe & BIT(chan), 0,
					 OCELOT_FDMA_CH_SAFE_TIMEOUT_US);
}

static void ocelot_fdma_dcb_set_data(struct ocelot_fdma_dcb *dcb,
				     dma_addr_t dma_addr,
				     size_t size)
{
	u32 offset = dma_addr & 0x3;

	dcb->llp = 0;
	dcb->datap = ALIGN_DOWN(dma_addr, 4);
	dcb->datal = ALIGN_DOWN(size, 4);
	dcb->stat = MSCC_FDMA_DCB_STAT_BLOCKO(offset);
}

static bool ocelot_fdma_rx_alloc_page(struct ocelot *ocelot,
				      struct ocelot_fdma_rx_buf *rxb)
{
	dma_addr_t mapping;
	struct page *page;

	page = dev_alloc_page();
	if (unlikely(!page))
		return false;

	mapping = dma_map_page(ocelot->dev, page, 0, PAGE_SIZE,
			       DMA_FROM_DEVICE);
	if (unlikely(dma_mapping_error(ocelot->dev, mapping))) {
		__free_page(page);
		return false;
	}

	rxb->page = page;
	rxb->page_offset = 0;
	rxb->dma_addr = mapping;

	return true;
}

static int ocelot_fdma_alloc_rx_buffs(struct ocelot *ocelot, u16 alloc_cnt)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	struct ocelot_fdma_rx_ring *rx_ring;
	struct ocelot_fdma_rx_buf *rxb;
	struct ocelot_fdma_dcb *dcb;
	dma_addr_t dma_addr;
	int ret = 0;
	u16 idx;

	rx_ring = &fdma->rx_ring;
	idx = rx_ring->next_to_use;

	while (alloc_cnt--) {
		rxb = &rx_ring->bufs[idx];
		/* try reuse page */
		if (unlikely(!rxb->page)) {
			if (unlikely(!ocelot_fdma_rx_alloc_page(ocelot, rxb))) {
				dev_err_ratelimited(ocelot->dev,
						    "Failed to allocate rx\n");
				ret = -ENOMEM;
				break;
			}
		}

		dcb = &rx_ring->dcbs[idx];
		dma_addr = rxb->dma_addr + rxb->page_offset;
		ocelot_fdma_dcb_set_data(dcb, dma_addr, OCELOT_FDMA_RXB_SIZE);

		idx = ocelot_fdma_idx_next(idx, OCELOT_FDMA_RX_RING_SIZE);
		/* Chain the DCB to the next one */
		dcb->llp = ocelot_fdma_idx_dma(rx_ring->dcbs_dma, idx);
	}

	rx_ring->next_to_use = idx;
	rx_ring->next_to_alloc = idx;

	return ret;
}

static bool ocelot_fdma_tx_dcb_set_skb(struct ocelot *ocelot,
				       struct ocelot_fdma_tx_buf *tx_buf,
				       struct ocelot_fdma_dcb *dcb,
				       struct sk_buff *skb)
{
	dma_addr_t mapping;

	mapping = dma_map_single(ocelot->dev, skb->data, skb->len,
				 DMA_TO_DEVICE);
	if (unlikely(dma_mapping_error(ocelot->dev, mapping)))
		return false;

	dma_unmap_addr_set(tx_buf, dma_addr, mapping);

	ocelot_fdma_dcb_set_data(dcb, mapping, OCELOT_FDMA_RX_SIZE);
	tx_buf->skb = skb;
	dcb->stat |= MSCC_FDMA_DCB_STAT_BLOCKL(skb->len);
	dcb->stat |= MSCC_FDMA_DCB_STAT_SOF | MSCC_FDMA_DCB_STAT_EOF;

	return true;
}

static bool ocelot_fdma_check_stop_rx(struct ocelot *ocelot)
{
	u32 llp;

	/* Check if the FDMA hits the DCB with LLP == NULL */
	llp = ocelot_fdma_readl(ocelot, MSCC_FDMA_DCB_LLP(MSCC_FDMA_XTR_CHAN));
	if (unlikely(llp))
		return false;

	ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_DISABLE,
			   BIT(MSCC_FDMA_XTR_CHAN));

	return true;
}

static void ocelot_fdma_rx_set_llp(struct ocelot_fdma_rx_ring *rx_ring)
{
	struct ocelot_fdma_dcb *dcb;
	unsigned int idx;

	idx = ocelot_fdma_idx_prev(rx_ring->next_to_use,
				   OCELOT_FDMA_RX_RING_SIZE);
	dcb = &rx_ring->dcbs[idx];
	dcb->llp = 0;
}

static void ocelot_fdma_rx_restart(struct ocelot *ocelot)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	struct ocelot_fdma_rx_ring *rx_ring;
	const u8 chan = MSCC_FDMA_XTR_CHAN;
	dma_addr_t new_llp, dma_base;
	unsigned int idx;
	u32 llp_prev;
	int ret;

	rx_ring = &fdma->rx_ring;
	ret = ocelot_fdma_wait_chan_safe(ocelot, chan);
	if (ret) {
		dev_err_ratelimited(ocelot->dev,
				    "Unable to stop RX channel\n");
		return;
	}

	ocelot_fdma_rx_set_llp(rx_ring);

	/* FDMA stopped on the last DCB that contained a NULL LLP, since
	 * we processed some DCBs in RX, there is free space, and  we must set
	 * DCB_LLP to point to the next DCB
	 */
	llp_prev = ocelot_fdma_readl(ocelot, MSCC_FDMA_DCB_LLP_PREV(chan));
	dma_base = rx_ring->dcbs_dma;

	/* Get the next DMA addr located after LLP == NULL DCB */
	idx = ocelot_fdma_dma_idx(dma_base, llp_prev);
	idx = ocelot_fdma_idx_next(idx, OCELOT_FDMA_RX_RING_SIZE);
	new_llp = ocelot_fdma_idx_dma(dma_base, idx);

	/* Finally reactivate the channel */
	ocelot_fdma_activate_chan(ocelot, new_llp, chan);
}

static bool ocelot_fdma_add_rx_frag(struct ocelot_fdma_rx_buf *rxb, u32 stat,
				    struct sk_buff *skb, bool first)
{
	int size = MSCC_FDMA_DCB_STAT_BLOCKL(stat);
	struct page *page = rxb->page;

	if (likely(first)) {
		skb_put(skb, size);
	} else {
		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
				rxb->page_offset, size, OCELOT_FDMA_RX_SIZE);
	}

	/* Try to reuse page */
	if (unlikely(page_ref_count(page) != 1 || page_is_pfmemalloc(page)))
		return false;

	/* Change offset to the other half */
	rxb->page_offset ^= OCELOT_FDMA_RX_SIZE;

	page_ref_inc(page);

	return true;
}

static void ocelot_fdma_reuse_rx_page(struct ocelot *ocelot,
				      struct ocelot_fdma_rx_buf *old_rxb)
{
	struct ocelot_fdma_rx_ring *rx_ring = &ocelot->fdma->rx_ring;
	struct ocelot_fdma_rx_buf *new_rxb;

	new_rxb = &rx_ring->bufs[rx_ring->next_to_alloc];
	rx_ring->next_to_alloc = ocelot_fdma_idx_next(rx_ring->next_to_alloc,
						      OCELOT_FDMA_RX_RING_SIZE);

	/* Copy page reference */
	*new_rxb = *old_rxb;

	/* Sync for use by the device */
	dma_sync_single_range_for_device(ocelot->dev, old_rxb->dma_addr,
					 old_rxb->page_offset,
					 OCELOT_FDMA_RX_SIZE, DMA_FROM_DEVICE);
}

static struct sk_buff *ocelot_fdma_get_skb(struct ocelot *ocelot, u32 stat,
					   struct ocelot_fdma_rx_buf *rxb,
					   struct sk_buff *skb)
{
	bool first = false;

	/* Allocate skb head and data */
	if (likely(!skb)) {
		void *buff_addr = page_address(rxb->page) +
				  rxb->page_offset;

		skb = build_skb(buff_addr, OCELOT_FDMA_SKBFRAG_SIZE);
		if (unlikely(!skb)) {
			dev_err_ratelimited(ocelot->dev,
					    "build_skb failed !\n");
			return NULL;
		}
		first = true;
	}

	dma_sync_single_range_for_cpu(ocelot->dev, rxb->dma_addr,
				      rxb->page_offset, OCELOT_FDMA_RX_SIZE,
				      DMA_FROM_DEVICE);

	if (ocelot_fdma_add_rx_frag(rxb, stat, skb, first)) {
		/* Reuse the free half of the page for the next_to_alloc DCB*/
		ocelot_fdma_reuse_rx_page(ocelot, rxb);
	} else {
		/* page cannot be reused, unmap it */
		dma_unmap_page(ocelot->dev, rxb->dma_addr, PAGE_SIZE,
			       DMA_FROM_DEVICE);
	}

	/* clear rx buff content */
	rxb->page = NULL;

	return skb;
}

static bool ocelot_fdma_receive_skb(struct ocelot *ocelot, struct sk_buff *skb)
{
	struct net_device *ndev;
	void *xfh = skb->data;
	u64 timestamp;
	u64 src_port;

	skb_pull(skb, OCELOT_TAG_LEN);

	ocelot_xfh_get_src_port(xfh, &src_port);
	if (unlikely(src_port >= ocelot->num_phys_ports))
		return false;

	ndev = ocelot_port_to_netdev(ocelot, src_port);
	if (unlikely(!ndev))
		return false;

	pskb_trim(skb, skb->len - ETH_FCS_LEN);

	skb->dev = ndev;
	skb->protocol = eth_type_trans(skb, skb->dev);
	skb->dev->stats.rx_bytes += skb->len;
	skb->dev->stats.rx_packets++;

	if (ocelot->ptp) {
		ocelot_xfh_get_rew_val(xfh, &timestamp);
		ocelot_ptp_rx_timestamp(ocelot, skb, timestamp);
	}

	if (likely(!skb_defer_rx_timestamp(skb)))
		netif_receive_skb(skb);

	return true;
}

static int ocelot_fdma_rx_get(struct ocelot *ocelot, int budget)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	struct ocelot_fdma_rx_ring *rx_ring;
	struct ocelot_fdma_rx_buf *rxb;
	struct ocelot_fdma_dcb *dcb;
	struct sk_buff *skb;
	int work_done = 0;
	int cleaned_cnt;
	u32 stat;
	u16 idx;

	cleaned_cnt = ocelot_fdma_rx_ring_free(fdma);
	rx_ring = &fdma->rx_ring;
	skb = rx_ring->skb;

	while (budget--) {
		idx = rx_ring->next_to_clean;
		dcb = &rx_ring->dcbs[idx];
		stat = dcb->stat;
		if (MSCC_FDMA_DCB_STAT_BLOCKL(stat) == 0)
			break;

		/* New packet is a start of frame but we already got a skb set,
		 * we probably lost an EOF packet, free skb
		 */
		if (unlikely(skb && (stat & MSCC_FDMA_DCB_STAT_SOF))) {
			dev_kfree_skb(skb);
			skb = NULL;
		}

		rxb = &rx_ring->bufs[idx];
		/* Fetch next to clean buffer from the rx_ring */
		skb = ocelot_fdma_get_skb(ocelot, stat, rxb, skb);
		if (unlikely(!skb))
			break;

		work_done++;
		cleaned_cnt++;

		idx = ocelot_fdma_idx_next(idx, OCELOT_FDMA_RX_RING_SIZE);
		rx_ring->next_to_clean = idx;

		if (unlikely(stat & MSCC_FDMA_DCB_STAT_ABORT ||
			     stat & MSCC_FDMA_DCB_STAT_PD)) {
			dev_err_ratelimited(ocelot->dev,
					    "DCB aborted or pruned\n");
			dev_kfree_skb(skb);
			skb = NULL;
			continue;
		}

		/* We still need to process the other fragment of the packet
		 * before delivering it to the network stack
		 */
		if (!(stat & MSCC_FDMA_DCB_STAT_EOF))
			continue;

		if (unlikely(!ocelot_fdma_receive_skb(ocelot, skb)))
			dev_kfree_skb(skb);

		skb = NULL;
	}

	rx_ring->skb = skb;

	if (cleaned_cnt)
		ocelot_fdma_alloc_rx_buffs(ocelot, cleaned_cnt);

	return work_done;
}

static void ocelot_fdma_wakeup_netdev(struct ocelot *ocelot)
{
	struct ocelot_port_private *priv;
	struct ocelot_port *ocelot_port;
	struct net_device *dev;
	int port;

	for (port = 0; port < ocelot->num_phys_ports; port++) {
		ocelot_port = ocelot->ports[port];
		if (!ocelot_port)
			continue;
		priv = container_of(ocelot_port, struct ocelot_port_private,
				    port);
		dev = priv->dev;

		if (unlikely(netif_queue_stopped(dev)))
			netif_wake_queue(dev);
	}
}

static void ocelot_fdma_tx_cleanup(struct ocelot *ocelot, int budget)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	struct ocelot_fdma_tx_ring *tx_ring;
	struct ocelot_fdma_tx_buf *buf;
	unsigned int new_null_llp_idx;
	struct ocelot_fdma_dcb *dcb;
	bool end_of_list = false;
	struct sk_buff *skb;
	dma_addr_t dma;
	u32 dcb_llp;
	u16 ntc;
	int ret;

	tx_ring = &fdma->tx_ring;

	/* Purge the TX packets that have been sent up to the NULL llp or the
	 * end of done list.
	 */
	while (!ocelot_fdma_tx_ring_empty(fdma)) {
		ntc = tx_ring->next_to_clean;
		dcb = &tx_ring->dcbs[ntc];
		if (!(dcb->stat & MSCC_FDMA_DCB_STAT_PD))
			break;

		buf = &tx_ring->bufs[ntc];
		skb = buf->skb;
		dma_unmap_single(ocelot->dev, dma_unmap_addr(buf, dma_addr),
				 skb->len, DMA_TO_DEVICE);
		napi_consume_skb(skb, budget);
		dcb_llp = dcb->llp;

		/* Only update after accessing all dcb fields */
		tx_ring->next_to_clean = ocelot_fdma_idx_next(ntc,
							      OCELOT_FDMA_TX_RING_SIZE);

		/* If we hit the NULL LLP, stop, we might need to reload FDMA */
		if (dcb_llp == 0) {
			end_of_list = true;
			break;
		}
	}

	/* No need to try to wake if there were no TX cleaned_cnt up. */
	if (ocelot_fdma_tx_ring_free(fdma))
		ocelot_fdma_wakeup_netdev(ocelot);

	/* If there is still some DCBs to be processed by the FDMA or if the
	 * pending list is empty, there is no need to restart the FDMA.
	 */
	if (!end_of_list || ocelot_fdma_tx_ring_empty(fdma))
		return;

	ret = ocelot_fdma_wait_chan_safe(ocelot, MSCC_FDMA_INJ_CHAN);
	if (ret) {
		dev_warn(ocelot->dev,
			 "Failed to wait for TX channel to stop\n");
		return;
	}

	/* Set NULL LLP to be the last DCB used */
	new_null_llp_idx = ocelot_fdma_idx_prev(tx_ring->next_to_use,
						OCELOT_FDMA_TX_RING_SIZE);
	dcb = &tx_ring->dcbs[new_null_llp_idx];
	dcb->llp = 0;

	dma = ocelot_fdma_idx_dma(tx_ring->dcbs_dma, tx_ring->next_to_clean);
	ocelot_fdma_activate_chan(ocelot, dma, MSCC_FDMA_INJ_CHAN);
}

static int ocelot_fdma_napi_poll(struct napi_struct *napi, int budget)
{
	struct ocelot_fdma *fdma = container_of(napi, struct ocelot_fdma, napi);
	struct ocelot *ocelot = fdma->ocelot;
	int work_done = 0;
	bool rx_stopped;

	ocelot_fdma_tx_cleanup(ocelot, budget);

	rx_stopped = ocelot_fdma_check_stop_rx(ocelot);

	work_done = ocelot_fdma_rx_get(ocelot, budget);

	if (rx_stopped)
		ocelot_fdma_rx_restart(ocelot);

	if (work_done < budget) {
		napi_complete_done(&fdma->napi, work_done);
		ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA,
				   BIT(MSCC_FDMA_INJ_CHAN) |
				   BIT(MSCC_FDMA_XTR_CHAN));
	}

	return work_done;
}

static irqreturn_t ocelot_fdma_interrupt(int irq, void *dev_id)
{
	u32 ident, llp, frm, err, err_code;
	struct ocelot *ocelot = dev_id;

	ident = ocelot_fdma_readl(ocelot, MSCC_FDMA_INTR_IDENT);
	frm = ocelot_fdma_readl(ocelot, MSCC_FDMA_INTR_FRM);
	llp = ocelot_fdma_readl(ocelot, MSCC_FDMA_INTR_LLP);

	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_LLP, llp & ident);
	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_FRM, frm & ident);
	if (frm || llp) {
		ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, 0);
		napi_schedule(&ocelot->fdma->napi);
	}

	err = ocelot_fdma_readl(ocelot, MSCC_FDMA_EVT_ERR);
	if (unlikely(err)) {
		err_code = ocelot_fdma_readl(ocelot, MSCC_FDMA_EVT_ERR_CODE);
		dev_err_ratelimited(ocelot->dev,
				    "Error ! chans mask: %#x, code: %#x\n",
				    err, err_code);

		ocelot_fdma_writel(ocelot, MSCC_FDMA_EVT_ERR, err);
		ocelot_fdma_writel(ocelot, MSCC_FDMA_EVT_ERR_CODE, err_code);
	}

	return IRQ_HANDLED;
}

static void ocelot_fdma_send_skb(struct ocelot *ocelot,
				 struct ocelot_fdma *fdma, struct sk_buff *skb)
{
	struct ocelot_fdma_tx_ring *tx_ring = &fdma->tx_ring;
	struct ocelot_fdma_tx_buf *tx_buf;
	struct ocelot_fdma_dcb *dcb;
	dma_addr_t dma;
	u16 next_idx;

	dcb = &tx_ring->dcbs[tx_ring->next_to_use];
	tx_buf = &tx_ring->bufs[tx_ring->next_to_use];
	if (!ocelot_fdma_tx_dcb_set_skb(ocelot, tx_buf, dcb, skb)) {
		dev_kfree_skb_any(skb);
		return;
	}

	next_idx = ocelot_fdma_idx_next(tx_ring->next_to_use,
					OCELOT_FDMA_TX_RING_SIZE);
	skb_tx_timestamp(skb);

	/* If the FDMA TX chan is empty, then enqueue the DCB directly */
	if (ocelot_fdma_tx_ring_empty(fdma)) {
		dma = ocelot_fdma_idx_dma(tx_ring->dcbs_dma,
					  tx_ring->next_to_use);
		ocelot_fdma_activate_chan(ocelot, dma, MSCC_FDMA_INJ_CHAN);
	} else {
		/* Chain the DCBs */
		dcb->llp = ocelot_fdma_idx_dma(tx_ring->dcbs_dma, next_idx);
	}

	tx_ring->next_to_use = next_idx;
}

static int ocelot_fdma_prepare_skb(struct ocelot *ocelot, int port, u32 rew_op,
				   struct sk_buff *skb, struct net_device *dev)
{
	int needed_headroom = max_t(int, OCELOT_TAG_LEN - skb_headroom(skb), 0);
	int needed_tailroom = max_t(int, ETH_FCS_LEN - skb_tailroom(skb), 0);
	void *ifh;
	int err;

	if (unlikely(needed_headroom || needed_tailroom ||
		     skb_header_cloned(skb))) {
		err = pskb_expand_head(skb, needed_headroom, needed_tailroom,
				       GFP_ATOMIC);
		if (unlikely(err)) {
			dev_kfree_skb_any(skb);
			return 1;
		}
	}

	err = skb_linearize(skb);
	if (err) {
		net_err_ratelimited("%s: skb_linearize error (%d)!\n",
				    dev->name, err);
		dev_kfree_skb_any(skb);
		return 1;
	}

	ifh = skb_push(skb, OCELOT_TAG_LEN);
	skb_put(skb, ETH_FCS_LEN);
	memset(ifh, 0, OCELOT_TAG_LEN);
	ocelot_ifh_port_set(ifh, port, rew_op, skb_vlan_tag_get(skb));

	return 0;
}

int ocelot_fdma_inject_frame(struct ocelot *ocelot, int port, u32 rew_op,
			     struct sk_buff *skb, struct net_device *dev)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	int ret = NETDEV_TX_OK;

	spin_lock(&fdma->tx_ring.xmit_lock);

	if (ocelot_fdma_tx_ring_free(fdma) == 0) {
		netif_stop_queue(dev);
		ret = NETDEV_TX_BUSY;
		goto out;
	}

	if (ocelot_fdma_prepare_skb(ocelot, port, rew_op, skb, dev))
		goto out;

	ocelot_fdma_send_skb(ocelot, fdma, skb);

out:
	spin_unlock(&fdma->tx_ring.xmit_lock);

	return ret;
}

static void ocelot_fdma_free_rx_ring(struct ocelot *ocelot)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	struct ocelot_fdma_rx_ring *rx_ring;
	struct ocelot_fdma_rx_buf *rxb;
	u16 idx;

	rx_ring = &fdma->rx_ring;
	idx = rx_ring->next_to_clean;

	/* Free the pages held in the RX ring */
	while (idx != rx_ring->next_to_use) {
		rxb = &rx_ring->bufs[idx];
		dma_unmap_page(ocelot->dev, rxb->dma_addr, PAGE_SIZE,
			       DMA_FROM_DEVICE);
		__free_page(rxb->page);
		idx = ocelot_fdma_idx_next(idx, OCELOT_FDMA_RX_RING_SIZE);
	}

	if (fdma->rx_ring.skb)
		dev_kfree_skb_any(fdma->rx_ring.skb);
}

static void ocelot_fdma_free_tx_ring(struct ocelot *ocelot)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	struct ocelot_fdma_tx_ring *tx_ring;
	struct ocelot_fdma_tx_buf *txb;
	struct sk_buff *skb;
	u16 idx;

	tx_ring = &fdma->tx_ring;
	idx = tx_ring->next_to_clean;

	while (idx != tx_ring->next_to_use) {
		txb = &tx_ring->bufs[idx];
		skb = txb->skb;
		dma_unmap_single(ocelot->dev, dma_unmap_addr(txb, dma_addr),
				 skb->len, DMA_TO_DEVICE);
		dev_kfree_skb_any(skb);
		idx = ocelot_fdma_idx_next(idx, OCELOT_FDMA_TX_RING_SIZE);
	}
}

static int ocelot_fdma_rings_alloc(struct ocelot *ocelot)
{
	struct ocelot_fdma *fdma = ocelot->fdma;
	struct ocelot_fdma_dcb *dcbs;
	unsigned int adjust;
	dma_addr_t dcbs_dma;
	int ret;

	/* Create a pool of consistent memory blocks for hardware descriptors */
	fdma->dcbs_base = dmam_alloc_coherent(ocelot->dev,
					      OCELOT_DCBS_HW_ALLOC_SIZE,
					      &fdma->dcbs_dma_base, GFP_KERNEL);
	if (!fdma->dcbs_base)
		return -ENOMEM;

	/* DCBs must be aligned on a 32bit boundary */
	dcbs = fdma->dcbs_base;
	dcbs_dma = fdma->dcbs_dma_base;
	if (!IS_ALIGNED(dcbs_dma, 4)) {
		adjust = dcbs_dma & 0x3;
		dcbs_dma = ALIGN(dcbs_dma, 4);
		dcbs = (void *)dcbs + adjust;
	}

	/* TX queue */
	fdma->tx_ring.dcbs = dcbs;
	fdma->tx_ring.dcbs_dma = dcbs_dma;
	spin_lock_init(&fdma->tx_ring.xmit_lock);

	/* RX queue */
	fdma->rx_ring.dcbs = dcbs + OCELOT_FDMA_TX_RING_SIZE;
	fdma->rx_ring.dcbs_dma = dcbs_dma + OCELOT_FDMA_TX_DCB_SIZE;
	ret = ocelot_fdma_alloc_rx_buffs(ocelot,
					 ocelot_fdma_tx_ring_free(fdma));
	if (ret) {
		ocelot_fdma_free_rx_ring(ocelot);
		return ret;
	}

	/* Set the last DCB LLP as NULL, this is normally done when restarting
	 * the RX chan, but this is for the first run
	 */
	ocelot_fdma_rx_set_llp(&fdma->rx_ring);

	return 0;
}

void ocelot_fdma_netdev_init(struct ocelot *ocelot, struct net_device *dev)
{
	struct ocelot_fdma *fdma = ocelot->fdma;

	dev->needed_headroom = OCELOT_TAG_LEN;
	dev->needed_tailroom = ETH_FCS_LEN;

	if (fdma->ndev)
		return;

	fdma->ndev = dev;
	netif_napi_add_weight(dev, &fdma->napi, ocelot_fdma_napi_poll,
			      OCELOT_FDMA_WEIGHT);
}

void ocelot_fdma_netdev_deinit(struct ocelot *ocelot, struct net_device *dev)
{
	struct ocelot_fdma *fdma = ocelot->fdma;

	if (fdma->ndev == dev) {
		netif_napi_del(&fdma->napi);
		fdma->ndev = NULL;
	}
}

void ocelot_fdma_init(struct platform_device *pdev, struct ocelot *ocelot)
{
	struct device *dev = ocelot->dev;
	struct ocelot_fdma *fdma;
	int ret;

	fdma = devm_kzalloc(dev, sizeof(*fdma), GFP_KERNEL);
	if (!fdma)
		return;

	ocelot->fdma = fdma;
	ocelot->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, 0);

	fdma->ocelot = ocelot;
	fdma->irq = platform_get_irq_byname(pdev, "fdma");
	ret = devm_request_irq(dev, fdma->irq, ocelot_fdma_interrupt, 0,
			       dev_name(dev), ocelot);
	if (ret)
		goto err_free_fdma;

	ret = ocelot_fdma_rings_alloc(ocelot);
	if (ret)
		goto err_free_irq;

	static_branch_enable(&ocelot_fdma_enabled);

	return;

err_free_irq:
	devm_free_irq(dev, fdma->irq, fdma);
err_free_fdma:
	devm_kfree(dev, fdma);

	ocelot->fdma = NULL;
}

void ocelot_fdma_start(struct ocelot *ocelot)
{
	struct ocelot_fdma *fdma = ocelot->fdma;

	/* Reconfigure for extraction and injection using DMA */
	ocelot_write_rix(ocelot, QS_INJ_GRP_CFG_MODE(2), QS_INJ_GRP_CFG, 0);
	ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(0), QS_INJ_CTRL, 0);

	ocelot_write_rix(ocelot, QS_XTR_GRP_CFG_MODE(2), QS_XTR_GRP_CFG, 0);

	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_LLP, 0xffffffff);
	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_FRM, 0xffffffff);

	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_LLP_ENA,
			   BIT(MSCC_FDMA_INJ_CHAN) | BIT(MSCC_FDMA_XTR_CHAN));
	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_FRM_ENA,
			   BIT(MSCC_FDMA_XTR_CHAN));
	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA,
			   BIT(MSCC_FDMA_INJ_CHAN) | BIT(MSCC_FDMA_XTR_CHAN));

	napi_enable(&fdma->napi);

	ocelot_fdma_activate_chan(ocelot, ocelot->fdma->rx_ring.dcbs_dma,
				  MSCC_FDMA_XTR_CHAN);
}

void ocelot_fdma_deinit(struct ocelot *ocelot)
{
	struct ocelot_fdma *fdma = ocelot->fdma;

	ocelot_fdma_writel(ocelot, MSCC_FDMA_INTR_ENA, 0);
	ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_FORCEDIS,
			   BIT(MSCC_FDMA_XTR_CHAN));
	ocelot_fdma_writel(ocelot, MSCC_FDMA_CH_FORCEDIS,
			   BIT(MSCC_FDMA_INJ_CHAN));
	napi_synchronize(&fdma->napi);
	napi_disable(&fdma->napi);

	ocelot_fdma_free_rx_ring(ocelot);
	ocelot_fdma_free_tx_ring(ocelot);
}
