// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Marvell PPv2 network controller for Armada 375 SoC.
 *
 * Copyright (C) 2014 Marvell
 *
 * Marcin Wojtas <mw@semihalf.com>
 */

#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/skbuff.h>
#include <linux/inetdevice.h>
#include <linux/mbus.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/interrupt.h>
#include <linux/cpumask.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/phy.h>
#include <linux/phylink.h>
#include <linux/phy/phy.h>
#include <linux/ptp_classify.h>
#include <linux/clk.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include <linux/regmap.h>
#include <uapi/linux/ppp_defs.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/tso.h>
#include <linux/bpf_trace.h>

#include "mvpp2.h"
#include "mvpp2_prs.h"
#include "mvpp2_cls.h"

enum mvpp2_bm_pool_log_num {
	MVPP2_BM_SHORT,
	MVPP2_BM_LONG,
	MVPP2_BM_JUMBO,
	MVPP2_BM_POOLS_NUM
};

static struct {
	int pkt_size;
	int buf_num;
} mvpp2_pools[MVPP2_BM_POOLS_NUM];

/* The prototype is added here to be used in start_dev when using ACPI. This
 * will be removed once phylink is used for all modes (dt+ACPI).
 */
static void mvpp2_acpi_start(struct mvpp2_port *port);

/* Queue modes */
#define MVPP2_QDIST_SINGLE_MODE	0
#define MVPP2_QDIST_MULTI_MODE	1

static int queue_mode = MVPP2_QDIST_MULTI_MODE;

module_param(queue_mode, int, 0444);
MODULE_PARM_DESC(queue_mode, "Set queue_mode (single=0, multi=1)");

/* Utility/helper methods */

void mvpp2_write(struct mvpp2 *priv, u32 offset, u32 data)
{
	writel(data, priv->swth_base[0] + offset);
}

u32 mvpp2_read(struct mvpp2 *priv, u32 offset)
{
	return readl(priv->swth_base[0] + offset);
}

static u32 mvpp2_read_relaxed(struct mvpp2 *priv, u32 offset)
{
	return readl_relaxed(priv->swth_base[0] + offset);
}

static inline u32 mvpp2_cpu_to_thread(struct mvpp2 *priv, int cpu)
{
	return cpu % priv->nthreads;
}

static void mvpp2_cm3_write(struct mvpp2 *priv, u32 offset, u32 data)
{
	writel(data, priv->cm3_base + offset);
}

static u32 mvpp2_cm3_read(struct mvpp2 *priv, u32 offset)
{
	return readl(priv->cm3_base + offset);
}

static struct page_pool *
mvpp2_create_page_pool(struct device *dev, int num, int len,
		       enum dma_data_direction dma_dir)
{
	struct page_pool_params pp_params = {
		/* internal DMA mapping in page_pool */
		.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
		.pool_size = num,
		.nid = NUMA_NO_NODE,
		.dev = dev,
		.dma_dir = dma_dir,
		.offset = MVPP2_SKB_HEADROOM,
		.max_len = len,
	};

	return page_pool_create(&pp_params);
}

/* These accessors should be used to access:
 *
 * - per-thread registers, where each thread has its own copy of the
 *   register.
 *
 *   MVPP2_BM_VIRT_ALLOC_REG
 *   MVPP2_BM_ADDR_HIGH_ALLOC
 *   MVPP22_BM_ADDR_HIGH_RLS_REG
 *   MVPP2_BM_VIRT_RLS_REG
 *   MVPP2_ISR_RX_TX_CAUSE_REG
 *   MVPP2_ISR_RX_TX_MASK_REG
 *   MVPP2_TXQ_NUM_REG
 *   MVPP2_AGGR_TXQ_UPDATE_REG
 *   MVPP2_TXQ_RSVD_REQ_REG
 *   MVPP2_TXQ_RSVD_RSLT_REG
 *   MVPP2_TXQ_SENT_REG
 *   MVPP2_RXQ_NUM_REG
 *
 * - global registers that must be accessed through a specific thread
 *   window, because they are related to an access to a per-thread
 *   register
 *
 *   MVPP2_BM_PHY_ALLOC_REG    (related to MVPP2_BM_VIRT_ALLOC_REG)
 *   MVPP2_BM_PHY_RLS_REG      (related to MVPP2_BM_VIRT_RLS_REG)
 *   MVPP2_RXQ_THRESH_REG      (related to MVPP2_RXQ_NUM_REG)
 *   MVPP2_RXQ_DESC_ADDR_REG   (related to MVPP2_RXQ_NUM_REG)
 *   MVPP2_RXQ_DESC_SIZE_REG   (related to MVPP2_RXQ_NUM_REG)
 *   MVPP2_RXQ_INDEX_REG       (related to MVPP2_RXQ_NUM_REG)
 *   MVPP2_TXQ_PENDING_REG     (related to MVPP2_TXQ_NUM_REG)
 *   MVPP2_TXQ_DESC_ADDR_REG   (related to MVPP2_TXQ_NUM_REG)
 *   MVPP2_TXQ_DESC_SIZE_REG   (related to MVPP2_TXQ_NUM_REG)
 *   MVPP2_TXQ_INDEX_REG       (related to MVPP2_TXQ_NUM_REG)
 *   MVPP2_TXQ_PENDING_REG     (related to MVPP2_TXQ_NUM_REG)
 *   MVPP2_TXQ_PREF_BUF_REG    (related to MVPP2_TXQ_NUM_REG)
 *   MVPP2_TXQ_PREF_BUF_REG    (related to MVPP2_TXQ_NUM_REG)
 */
static void mvpp2_thread_write(struct mvpp2 *priv, unsigned int thread,
			       u32 offset, u32 data)
{
	writel(data, priv->swth_base[thread] + offset);
}

static u32 mvpp2_thread_read(struct mvpp2 *priv, unsigned int thread,
			     u32 offset)
{
	return readl(priv->swth_base[thread] + offset);
}

static void mvpp2_thread_write_relaxed(struct mvpp2 *priv, unsigned int thread,
				       u32 offset, u32 data)
{
	writel_relaxed(data, priv->swth_base[thread] + offset);
}

static u32 mvpp2_thread_read_relaxed(struct mvpp2 *priv, unsigned int thread,
				     u32 offset)
{
	return readl_relaxed(priv->swth_base[thread] + offset);
}

static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port,
					    struct mvpp2_tx_desc *tx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return le32_to_cpu(tx_desc->pp21.buf_dma_addr);
	else
		return le64_to_cpu(tx_desc->pp22.buf_dma_addr_ptp) &
		       MVPP2_DESC_DMA_MASK;
}

static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
				      struct mvpp2_tx_desc *tx_desc,
				      dma_addr_t dma_addr)
{
	dma_addr_t addr, offset;

	addr = dma_addr & ~MVPP2_TX_DESC_ALIGN;
	offset = dma_addr & MVPP2_TX_DESC_ALIGN;

	if (port->priv->hw_version == MVPP21) {
		tx_desc->pp21.buf_dma_addr = cpu_to_le32(addr);
		tx_desc->pp21.packet_offset = offset;
	} else {
		__le64 val = cpu_to_le64(addr);

		tx_desc->pp22.buf_dma_addr_ptp &= ~cpu_to_le64(MVPP2_DESC_DMA_MASK);
		tx_desc->pp22.buf_dma_addr_ptp |= val;
		tx_desc->pp22.packet_offset = offset;
	}
}

static size_t mvpp2_txdesc_size_get(struct mvpp2_port *port,
				    struct mvpp2_tx_desc *tx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return le16_to_cpu(tx_desc->pp21.data_size);
	else
		return le16_to_cpu(tx_desc->pp22.data_size);
}

static void mvpp2_txdesc_size_set(struct mvpp2_port *port,
				  struct mvpp2_tx_desc *tx_desc,
				  size_t size)
{
	if (port->priv->hw_version == MVPP21)
		tx_desc->pp21.data_size = cpu_to_le16(size);
	else
		tx_desc->pp22.data_size = cpu_to_le16(size);
}

static void mvpp2_txdesc_txq_set(struct mvpp2_port *port,
				 struct mvpp2_tx_desc *tx_desc,
				 unsigned int txq)
{
	if (port->priv->hw_version == MVPP21)
		tx_desc->pp21.phys_txq = txq;
	else
		tx_desc->pp22.phys_txq = txq;
}

static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port,
				 struct mvpp2_tx_desc *tx_desc,
				 unsigned int command)
{
	if (port->priv->hw_version == MVPP21)
		tx_desc->pp21.command = cpu_to_le32(command);
	else
		tx_desc->pp22.command = cpu_to_le32(command);
}

static unsigned int mvpp2_txdesc_offset_get(struct mvpp2_port *port,
					    struct mvpp2_tx_desc *tx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return tx_desc->pp21.packet_offset;
	else
		return tx_desc->pp22.packet_offset;
}

static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port,
					    struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return le32_to_cpu(rx_desc->pp21.buf_dma_addr);
	else
		return le64_to_cpu(rx_desc->pp22.buf_dma_addr_key_hash) &
		       MVPP2_DESC_DMA_MASK;
}

static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
					     struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return le32_to_cpu(rx_desc->pp21.buf_cookie);
	else
		return le64_to_cpu(rx_desc->pp22.buf_cookie_misc) &
		       MVPP2_DESC_DMA_MASK;
}

static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
				    struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return le16_to_cpu(rx_desc->pp21.data_size);
	else
		return le16_to_cpu(rx_desc->pp22.data_size);
}

static u32 mvpp2_rxdesc_status_get(struct mvpp2_port *port,
				   struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return le32_to_cpu(rx_desc->pp21.status);
	else
		return le32_to_cpu(rx_desc->pp22.status);
}

static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)
{
	txq_pcpu->txq_get_index++;
	if (txq_pcpu->txq_get_index == txq_pcpu->size)
		txq_pcpu->txq_get_index = 0;
}

static void mvpp2_txq_inc_put(struct mvpp2_port *port,
			      struct mvpp2_txq_pcpu *txq_pcpu,
			      void *data,
			      struct mvpp2_tx_desc *tx_desc,
			      enum mvpp2_tx_buf_type buf_type)
{
	struct mvpp2_txq_pcpu_buf *tx_buf =
		txq_pcpu->buffs + txq_pcpu->txq_put_index;
	tx_buf->type = buf_type;
	if (buf_type == MVPP2_TYPE_SKB)
		tx_buf->skb = data;
	else
		tx_buf->xdpf = data;
	tx_buf->size = mvpp2_txdesc_size_get(port, tx_desc);
	tx_buf->dma = mvpp2_txdesc_dma_addr_get(port, tx_desc) +
		mvpp2_txdesc_offset_get(port, tx_desc);
	txq_pcpu->txq_put_index++;
	if (txq_pcpu->txq_put_index == txq_pcpu->size)
		txq_pcpu->txq_put_index = 0;
}

/* Get number of maximum RXQ */
static int mvpp2_get_nrxqs(struct mvpp2 *priv)
{
	unsigned int nrxqs;

	if (priv->hw_version >= MVPP22 && queue_mode == MVPP2_QDIST_SINGLE_MODE)
		return 1;

	/* According to the PPv2.2 datasheet and our experiments on
	 * PPv2.1, RX queues have an allocation granularity of 4 (when
	 * more than a single one on PPv2.2).
	 * Round up to nearest multiple of 4.
	 */
	nrxqs = (num_possible_cpus() + 3) & ~0x3;
	if (nrxqs > MVPP2_PORT_MAX_RXQ)
		nrxqs = MVPP2_PORT_MAX_RXQ;

	return nrxqs;
}

/* Get number of physical egress port */
static inline int mvpp2_egress_port(struct mvpp2_port *port)
{
	return MVPP2_MAX_TCONT + port->id;
}

/* Get number of physical TXQ */
static inline int mvpp2_txq_phys(int port, int txq)
{
	return (MVPP2_MAX_TCONT + port) * MVPP2_MAX_TXQ + txq;
}

/* Returns a struct page if page_pool is set, otherwise a buffer */
static void *mvpp2_frag_alloc(const struct mvpp2_bm_pool *pool,
			      struct page_pool *page_pool)
{
	if (page_pool)
		return page_pool_dev_alloc_pages(page_pool);

	if (likely(pool->frag_size <= PAGE_SIZE))
		return netdev_alloc_frag(pool->frag_size);

	return kmalloc(pool->frag_size, GFP_ATOMIC);
}

static void mvpp2_frag_free(const struct mvpp2_bm_pool *pool,
			    struct page_pool *page_pool, void *data)
{
	if (page_pool)
		page_pool_put_full_page(page_pool, virt_to_head_page(data), false);
	else if (likely(pool->frag_size <= PAGE_SIZE))
		skb_free_frag(data);
	else
		kfree(data);
}

/* Buffer Manager configuration routines */

/* Create pool */
static int mvpp2_bm_pool_create(struct device *dev, struct mvpp2 *priv,
				struct mvpp2_bm_pool *bm_pool, int size)
{
	u32 val;

	/* Number of buffer pointers must be a multiple of 16, as per
	 * hardware constraints
	 */
	if (!IS_ALIGNED(size, 16))
		return -EINVAL;

	/* PPv2.1 needs 8 bytes per buffer pointer, PPv2.2 and PPv2.3 needs 16
	 * bytes per buffer pointer
	 */
	if (priv->hw_version == MVPP21)
		bm_pool->size_bytes = 2 * sizeof(u32) * size;
	else
		bm_pool->size_bytes = 2 * sizeof(u64) * size;

	bm_pool->virt_addr = dma_alloc_coherent(dev, bm_pool->size_bytes,
						&bm_pool->dma_addr,
						GFP_KERNEL);
	if (!bm_pool->virt_addr)
		return -ENOMEM;

	if (!IS_ALIGNED((unsigned long)bm_pool->virt_addr,
			MVPP2_BM_POOL_PTR_ALIGN)) {
		dma_free_coherent(dev, bm_pool->size_bytes,
				  bm_pool->virt_addr, bm_pool->dma_addr);
		dev_err(dev, "BM pool %d is not %d bytes aligned\n",
			bm_pool->id, MVPP2_BM_POOL_PTR_ALIGN);
		return -ENOMEM;
	}

	mvpp2_write(priv, MVPP2_BM_POOL_BASE_REG(bm_pool->id),
		    lower_32_bits(bm_pool->dma_addr));
	mvpp2_write(priv, MVPP2_BM_POOL_SIZE_REG(bm_pool->id), size);

	val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id));
	val |= MVPP2_BM_START_MASK;

	val &= ~MVPP2_BM_LOW_THRESH_MASK;
	val &= ~MVPP2_BM_HIGH_THRESH_MASK;

	/* Set 8 Pools BPPI threshold for MVPP23 */
	if (priv->hw_version == MVPP23) {
		val |= MVPP2_BM_LOW_THRESH_VALUE(MVPP23_BM_BPPI_LOW_THRESH);
		val |= MVPP2_BM_HIGH_THRESH_VALUE(MVPP23_BM_BPPI_HIGH_THRESH);
	} else {
		val |= MVPP2_BM_LOW_THRESH_VALUE(MVPP2_BM_BPPI_LOW_THRESH);
		val |= MVPP2_BM_HIGH_THRESH_VALUE(MVPP2_BM_BPPI_HIGH_THRESH);
	}

	mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val);

	bm_pool->size = size;
	bm_pool->pkt_size = 0;
	bm_pool->buf_num = 0;

	return 0;
}

/* Set pool buffer size */
static void mvpp2_bm_pool_bufsize_set(struct mvpp2 *priv,
				      struct mvpp2_bm_pool *bm_pool,
				      int buf_size)
{
	u32 val;

	bm_pool->buf_size = buf_size;

	val = ALIGN(buf_size, 1 << MVPP2_POOL_BUF_SIZE_OFFSET);
	mvpp2_write(priv, MVPP2_POOL_BUF_SIZE_REG(bm_pool->id), val);
}

static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv,
				    struct mvpp2_bm_pool *bm_pool,
				    dma_addr_t *dma_addr,
				    phys_addr_t *phys_addr)
{
	unsigned int thread = mvpp2_cpu_to_thread(priv, get_cpu());

	*dma_addr = mvpp2_thread_read(priv, thread,
				      MVPP2_BM_PHY_ALLOC_REG(bm_pool->id));
	*phys_addr = mvpp2_thread_read(priv, thread, MVPP2_BM_VIRT_ALLOC_REG);

	if (priv->hw_version >= MVPP22) {
		u32 val;
		u32 dma_addr_highbits, phys_addr_highbits;

		val = mvpp2_thread_read(priv, thread, MVPP22_BM_ADDR_HIGH_ALLOC);
		dma_addr_highbits = (val & MVPP22_BM_ADDR_HIGH_PHYS_MASK);
		phys_addr_highbits = (val & MVPP22_BM_ADDR_HIGH_VIRT_MASK) >>
			MVPP22_BM_ADDR_HIGH_VIRT_SHIFT;

		if (sizeof(dma_addr_t) == 8)
			*dma_addr |= (u64)dma_addr_highbits << 32;

		if (sizeof(phys_addr_t) == 8)
			*phys_addr |= (u64)phys_addr_highbits << 32;
	}

	put_cpu();
}

/* Free all buffers from the pool */
static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
			       struct mvpp2_bm_pool *bm_pool, int buf_num)
{
	struct page_pool *pp = NULL;
	int i;

	if (buf_num > bm_pool->buf_num) {
		WARN(1, "Pool does not have so many bufs pool(%d) bufs(%d)\n",
		     bm_pool->id, buf_num);
		buf_num = bm_pool->buf_num;
	}

	if (priv->percpu_pools)
		pp = priv->page_pool[bm_pool->id];

	for (i = 0; i < buf_num; i++) {
		dma_addr_t buf_dma_addr;
		phys_addr_t buf_phys_addr;
		void *data;

		mvpp2_bm_bufs_get_addrs(dev, priv, bm_pool,
					&buf_dma_addr, &buf_phys_addr);

		if (!pp)
			dma_unmap_single(dev, buf_dma_addr,
					 bm_pool->buf_size, DMA_FROM_DEVICE);

		data = (void *)phys_to_virt(buf_phys_addr);
		if (!data)
			break;

		mvpp2_frag_free(bm_pool, pp, data);
	}

	/* Update BM driver with number of buffers removed from pool */
	bm_pool->buf_num -= i;
}

/* Check number of buffers in BM pool */
static int mvpp2_check_hw_buf_num(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool)
{
	int buf_num = 0;

	buf_num += mvpp2_read(priv, MVPP2_BM_POOL_PTRS_NUM_REG(bm_pool->id)) &
				    MVPP22_BM_POOL_PTRS_NUM_MASK;
	buf_num += mvpp2_read(priv, MVPP2_BM_BPPI_PTRS_NUM_REG(bm_pool->id)) &
				    MVPP2_BM_BPPI_PTR_NUM_MASK;

	/* HW has one buffer ready which is not reflected in the counters */
	if (buf_num)
		buf_num += 1;

	return buf_num;
}

/* Cleanup pool */
static int mvpp2_bm_pool_destroy(struct device *dev, struct mvpp2 *priv,
				 struct mvpp2_bm_pool *bm_pool)
{
	int buf_num;
	u32 val;

	buf_num = mvpp2_check_hw_buf_num(priv, bm_pool);
	mvpp2_bm_bufs_free(dev, priv, bm_pool, buf_num);

	/* Check buffer counters after free */
	buf_num = mvpp2_check_hw_buf_num(priv, bm_pool);
	if (buf_num) {
		WARN(1, "cannot free all buffers in pool %d, buf_num left %d\n",
		     bm_pool->id, bm_pool->buf_num);
		return 0;
	}

	val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id));
	val |= MVPP2_BM_STOP_MASK;
	mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val);

	if (priv->percpu_pools) {
		page_pool_destroy(priv->page_pool[bm_pool->id]);
		priv->page_pool[bm_pool->id] = NULL;
	}

	dma_free_coherent(dev, bm_pool->size_bytes,
			  bm_pool->virt_addr,
			  bm_pool->dma_addr);
	return 0;
}

static int mvpp2_bm_pools_init(struct device *dev, struct mvpp2 *priv)
{
	int i, err, size, poolnum = MVPP2_BM_POOLS_NUM;
	struct mvpp2_bm_pool *bm_pool;

	if (priv->percpu_pools)
		poolnum = mvpp2_get_nrxqs(priv) * 2;

	/* Create all pools with maximum size */
	size = MVPP2_BM_POOL_SIZE_MAX;
	for (i = 0; i < poolnum; i++) {
		bm_pool = &priv->bm_pools[i];
		bm_pool->id = i;
		err = mvpp2_bm_pool_create(dev, priv, bm_pool, size);
		if (err)
			goto err_unroll_pools;
		mvpp2_bm_pool_bufsize_set(priv, bm_pool, 0);
	}
	return 0;

err_unroll_pools:
	dev_err(dev, "failed to create BM pool %d, size %d\n", i, size);
	for (i = i - 1; i >= 0; i--)
		mvpp2_bm_pool_destroy(dev, priv, &priv->bm_pools[i]);
	return err;
}

/* Routine enable PPv23 8 pool mode */
static void mvpp23_bm_set_8pool_mode(struct mvpp2 *priv)
{
	int val;

	val = mvpp2_read(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG);
	val |= MVPP23_BM_8POOL_MODE;
	mvpp2_write(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG, val);
}

static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv)
{
	enum dma_data_direction dma_dir = DMA_FROM_DEVICE;
	int i, err, poolnum = MVPP2_BM_POOLS_NUM;
	struct mvpp2_port *port;

	if (priv->percpu_pools) {
		for (i = 0; i < priv->port_count; i++) {
			port = priv->port_list[i];
			if (port->xdp_prog) {
				dma_dir = DMA_BIDIRECTIONAL;
				break;
			}
		}

		poolnum = mvpp2_get_nrxqs(priv) * 2;
		for (i = 0; i < poolnum; i++) {
			/* the pool in use */
			int pn = i / (poolnum / 2);

			priv->page_pool[i] =
				mvpp2_create_page_pool(dev,
						       mvpp2_pools[pn].buf_num,
						       mvpp2_pools[pn].pkt_size,
						       dma_dir);
			if (IS_ERR(priv->page_pool[i])) {
				int j;

				for (j = 0; j < i; j++) {
					page_pool_destroy(priv->page_pool[j]);
					priv->page_pool[j] = NULL;
				}
				return PTR_ERR(priv->page_pool[i]);
			}
		}
	}

	dev_info(dev, "using %d %s buffers\n", poolnum,
		 priv->percpu_pools ? "per-cpu" : "shared");

	for (i = 0; i < poolnum; i++) {
		/* Mask BM all interrupts */
		mvpp2_write(priv, MVPP2_BM_INTR_MASK_REG(i), 0);
		/* Clear BM cause register */
		mvpp2_write(priv, MVPP2_BM_INTR_CAUSE_REG(i), 0);
	}

	/* Allocate and initialize BM pools */
	priv->bm_pools = devm_kcalloc(dev, poolnum,
				      sizeof(*priv->bm_pools), GFP_KERNEL);
	if (!priv->bm_pools)
		return -ENOMEM;

	if (priv->hw_version == MVPP23)
		mvpp23_bm_set_8pool_mode(priv);

	err = mvpp2_bm_pools_init(dev, priv);
	if (err < 0)
		return err;
	return 0;
}

static void mvpp2_setup_bm_pool(void)
{
	/* Short pool */
	mvpp2_pools[MVPP2_BM_SHORT].buf_num  = MVPP2_BM_SHORT_BUF_NUM;
	mvpp2_pools[MVPP2_BM_SHORT].pkt_size = MVPP2_BM_SHORT_PKT_SIZE;

	/* Long pool */
	mvpp2_pools[MVPP2_BM_LONG].buf_num  = MVPP2_BM_LONG_BUF_NUM;
	mvpp2_pools[MVPP2_BM_LONG].pkt_size = MVPP2_BM_LONG_PKT_SIZE;

	/* Jumbo pool */
	mvpp2_pools[MVPP2_BM_JUMBO].buf_num  = MVPP2_BM_JUMBO_BUF_NUM;
	mvpp2_pools[MVPP2_BM_JUMBO].pkt_size = MVPP2_BM_JUMBO_PKT_SIZE;
}

/* Attach long pool to rxq */
static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port,
				    int lrxq, int long_pool)
{
	u32 val, mask;
	int prxq;

	/* Get queue physical ID */
	prxq = port->rxqs[lrxq]->id;

	if (port->priv->hw_version == MVPP21)
		mask = MVPP21_RXQ_POOL_LONG_MASK;
	else
		mask = MVPP22_RXQ_POOL_LONG_MASK;

	val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
	val &= ~mask;
	val |= (long_pool << MVPP2_RXQ_POOL_LONG_OFFS) & mask;
	mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
}

/* Attach short pool to rxq */
static void mvpp2_rxq_short_pool_set(struct mvpp2_port *port,
				     int lrxq, int short_pool)
{
	u32 val, mask;
	int prxq;

	/* Get queue physical ID */
	prxq = port->rxqs[lrxq]->id;

	if (port->priv->hw_version == MVPP21)
		mask = MVPP21_RXQ_POOL_SHORT_MASK;
	else
		mask = MVPP22_RXQ_POOL_SHORT_MASK;

	val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
	val &= ~mask;
	val |= (short_pool << MVPP2_RXQ_POOL_SHORT_OFFS) & mask;
	mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
}

static void *mvpp2_buf_alloc(struct mvpp2_port *port,
			     struct mvpp2_bm_pool *bm_pool,
			     struct page_pool *page_pool,
			     dma_addr_t *buf_dma_addr,
			     phys_addr_t *buf_phys_addr,
			     gfp_t gfp_mask)
{
	dma_addr_t dma_addr;
	struct page *page;
	void *data;

	data = mvpp2_frag_alloc(bm_pool, page_pool);
	if (!data)
		return NULL;

	if (page_pool) {
		page = (struct page *)data;
		dma_addr = page_pool_get_dma_addr(page);
		data = page_to_virt(page);
	} else {
		dma_addr = dma_map_single(port->dev->dev.parent, data,
					  MVPP2_RX_BUF_SIZE(bm_pool->pkt_size),
					  DMA_FROM_DEVICE);
		if (unlikely(dma_mapping_error(port->dev->dev.parent, dma_addr))) {
			mvpp2_frag_free(bm_pool, NULL, data);
			return NULL;
		}
	}
	*buf_dma_addr = dma_addr;
	*buf_phys_addr = virt_to_phys(data);

	return data;
}

/* Routine enable flow control for RXQs condition */
static void mvpp2_rxq_enable_fc(struct mvpp2_port *port)
{
	int val, cm3_state, host_id, q;
	int fq = port->first_rxq;
	unsigned long flags;

	spin_lock_irqsave(&port->priv->mss_spinlock, flags);

	/* Remove Flow control enable bit to prevent race between FW and Kernel
	 * If Flow control was enabled, it would be re-enabled.
	 */
	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
	cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
	val &= ~FLOW_CONTROL_ENABLE_BIT;
	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);

	/* Set same Flow control for all RXQs */
	for (q = 0; q < port->nrxqs; q++) {
		/* Set stop and start Flow control RXQ thresholds */
		val = MSS_THRESHOLD_START;
		val |= (MSS_THRESHOLD_STOP << MSS_RXQ_TRESH_STOP_OFFS);
		mvpp2_cm3_write(port->priv, MSS_RXQ_TRESH_REG(q, fq), val);

		val = mvpp2_cm3_read(port->priv, MSS_RXQ_ASS_REG(q, fq));
		/* Set RXQ port ID */
		val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE(q, fq));
		val |= (port->id << MSS_RXQ_ASS_Q_BASE(q, fq));
		val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE(q, fq)
			+ MSS_RXQ_ASS_HOSTID_OFFS));

		/* Calculate RXQ host ID:
		 * In Single queue mode: Host ID equal to Host ID used for
		 *			 shared RX interrupt
		 * In Multi queue mode: Host ID equal to number of
		 *			RXQ ID / number of CoS queues
		 * In Single resource mode: Host ID always equal to 0
		 */
		if (queue_mode == MVPP2_QDIST_SINGLE_MODE)
			host_id = port->nqvecs;
		else if (queue_mode == MVPP2_QDIST_MULTI_MODE)
			host_id = q;
		else
			host_id = 0;

		/* Set RXQ host ID */
		val |= (host_id << (MSS_RXQ_ASS_Q_BASE(q, fq)
			+ MSS_RXQ_ASS_HOSTID_OFFS));

		mvpp2_cm3_write(port->priv, MSS_RXQ_ASS_REG(q, fq), val);
	}

	/* Notify Firmware that Flow control config space ready for update */
	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
	val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
	val |= cm3_state;
	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);

	spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
}

/* Routine disable flow control for RXQs condition */
static void mvpp2_rxq_disable_fc(struct mvpp2_port *port)
{
	int val, cm3_state, q;
	unsigned long flags;
	int fq = port->first_rxq;

	spin_lock_irqsave(&port->priv->mss_spinlock, flags);

	/* Remove Flow control enable bit to prevent race between FW and Kernel
	 * If Flow control was enabled, it would be re-enabled.
	 */
	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
	cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
	val &= ~FLOW_CONTROL_ENABLE_BIT;
	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);

	/* Disable Flow control for all RXQs */
	for (q = 0; q < port->nrxqs; q++) {
		/* Set threshold 0 to disable Flow control */
		val = 0;
		val |= (0 << MSS_RXQ_TRESH_STOP_OFFS);
		mvpp2_cm3_write(port->priv, MSS_RXQ_TRESH_REG(q, fq), val);

		val = mvpp2_cm3_read(port->priv, MSS_RXQ_ASS_REG(q, fq));

		val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE(q, fq));

		val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE(q, fq)
			+ MSS_RXQ_ASS_HOSTID_OFFS));

		mvpp2_cm3_write(port->priv, MSS_RXQ_ASS_REG(q, fq), val);
	}

	/* Notify Firmware that Flow control config space ready for update */
	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
	val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
	val |= cm3_state;
	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);

	spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
}

/* Routine disable/enable flow control for BM pool condition */
static void mvpp2_bm_pool_update_fc(struct mvpp2_port *port,
				    struct mvpp2_bm_pool *pool,
				    bool en)
{
	int val, cm3_state;
	unsigned long flags;

	spin_lock_irqsave(&port->priv->mss_spinlock, flags);

	/* Remove Flow control enable bit to prevent race between FW and Kernel
	 * If Flow control were enabled, it would be re-enabled.
	 */
	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
	cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
	val &= ~FLOW_CONTROL_ENABLE_BIT;
	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);

	/* Check if BM pool should be enabled/disable */
	if (en) {
		/* Set BM pool start and stop thresholds per port */
		val = mvpp2_cm3_read(port->priv, MSS_BUF_POOL_REG(pool->id));
		val |= MSS_BUF_POOL_PORT_OFFS(port->id);
		val &= ~MSS_BUF_POOL_START_MASK;
		val |= (MSS_THRESHOLD_START << MSS_BUF_POOL_START_OFFS);
		val &= ~MSS_BUF_POOL_STOP_MASK;
		val |= MSS_THRESHOLD_STOP;
		mvpp2_cm3_write(port->priv, MSS_BUF_POOL_REG(pool->id), val);
	} else {
		/* Remove BM pool from the port */
		val = mvpp2_cm3_read(port->priv, MSS_BUF_POOL_REG(pool->id));
		val &= ~MSS_BUF_POOL_PORT_OFFS(port->id);

		/* Zero BM pool start and stop thresholds to disable pool
		 * flow control if pool empty (not used by any port)
		 */
		if (!pool->buf_num) {
			val &= ~MSS_BUF_POOL_START_MASK;
			val &= ~MSS_BUF_POOL_STOP_MASK;
		}

		mvpp2_cm3_write(port->priv, MSS_BUF_POOL_REG(pool->id), val);
	}

	/* Notify Firmware that Flow control config space ready for update */
	val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
	val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
	val |= cm3_state;
	mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);

	spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
}

/* disable/enable flow control for BM pool on all ports */
static void mvpp2_bm_pool_update_priv_fc(struct mvpp2 *priv, bool en)
{
	struct mvpp2_port *port;
	int i;

	for (i = 0; i < priv->port_count; i++) {
		port = priv->port_list[i];
		if (port->priv->percpu_pools) {
			for (i = 0; i < port->nrxqs; i++)
				mvpp2_bm_pool_update_fc(port, &port->priv->bm_pools[i],
							port->tx_fc & en);
		} else {
			mvpp2_bm_pool_update_fc(port, port->pool_long, port->tx_fc & en);
			mvpp2_bm_pool_update_fc(port, port->pool_short, port->tx_fc & en);
		}
	}
}

static int mvpp2_enable_global_fc(struct mvpp2 *priv)
{
	int val, timeout = 0;

	/* Enable global flow control. In this stage global
	 * flow control enabled, but still disabled per port.
	 */
	val = mvpp2_cm3_read(priv, MSS_FC_COM_REG);
	val |= FLOW_CONTROL_ENABLE_BIT;
	mvpp2_cm3_write(priv, MSS_FC_COM_REG, val);

	/* Check if Firmware running and disable FC if not*/
	val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
	mvpp2_cm3_write(priv, MSS_FC_COM_REG, val);

	while (timeout < MSS_FC_MAX_TIMEOUT) {
		val = mvpp2_cm3_read(priv, MSS_FC_COM_REG);

		if (!(val & FLOW_CONTROL_UPDATE_COMMAND_BIT))
			return 0;
		usleep_range(10, 20);
		timeout++;
	}

	priv->global_tx_fc = false;
	return -EOPNOTSUPP;
}

/* Release buffer to BM */
static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
				     dma_addr_t buf_dma_addr,
				     phys_addr_t buf_phys_addr)
{
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, get_cpu());
	unsigned long flags = 0;

	if (test_bit(thread, &port->priv->lock_map))
		spin_lock_irqsave(&port->bm_lock[thread], flags);

	if (port->priv->hw_version >= MVPP22) {
		u32 val = 0;

		if (sizeof(dma_addr_t) == 8)
			val |= upper_32_bits(buf_dma_addr) &
				MVPP22_BM_ADDR_HIGH_PHYS_RLS_MASK;

		if (sizeof(phys_addr_t) == 8)
			val |= (upper_32_bits(buf_phys_addr)
				<< MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT) &
				MVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK;

		mvpp2_thread_write_relaxed(port->priv, thread,
					   MVPP22_BM_ADDR_HIGH_RLS_REG, val);
	}

	/* MVPP2_BM_VIRT_RLS_REG is not interpreted by HW, and simply
	 * returned in the "cookie" field of the RX
	 * descriptor. Instead of storing the virtual address, we
	 * store the physical address
	 */
	mvpp2_thread_write_relaxed(port->priv, thread,
				   MVPP2_BM_VIRT_RLS_REG, buf_phys_addr);
	mvpp2_thread_write_relaxed(port->priv, thread,
				   MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr);

	if (test_bit(thread, &port->priv->lock_map))
		spin_unlock_irqrestore(&port->bm_lock[thread], flags);

	put_cpu();
}

/* Allocate buffers for the pool */
static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
			     struct mvpp2_bm_pool *bm_pool, int buf_num)
{
	int i, buf_size, total_size;
	dma_addr_t dma_addr;
	phys_addr_t phys_addr;
	struct page_pool *pp = NULL;
	void *buf;

	if (port->priv->percpu_pools &&
	    bm_pool->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
		netdev_err(port->dev,
			   "attempted to use jumbo frames with per-cpu pools");
		return 0;
	}

	buf_size = MVPP2_RX_BUF_SIZE(bm_pool->pkt_size);
	total_size = MVPP2_RX_TOTAL_SIZE(buf_size);

	if (buf_num < 0 ||
	    (buf_num + bm_pool->buf_num > bm_pool->size)) {
		netdev_err(port->dev,
			   "cannot allocate %d buffers for pool %d\n",
			   buf_num, bm_pool->id);
		return 0;
	}

	if (port->priv->percpu_pools)
		pp = port->priv->page_pool[bm_pool->id];
	for (i = 0; i < buf_num; i++) {
		buf = mvpp2_buf_alloc(port, bm_pool, pp, &dma_addr,
				      &phys_addr, GFP_KERNEL);
		if (!buf)
			break;

		mvpp2_bm_pool_put(port, bm_pool->id, dma_addr,
				  phys_addr);
	}

	/* Update BM driver with number of buffers added to pool */
	bm_pool->buf_num += i;

	netdev_dbg(port->dev,
		   "pool %d: pkt_size=%4d, buf_size=%4d, total_size=%4d\n",
		   bm_pool->id, bm_pool->pkt_size, buf_size, total_size);

	netdev_dbg(port->dev,
		   "pool %d: %d of %d buffers added\n",
		   bm_pool->id, i, buf_num);
	return i;
}

/* Notify the driver that BM pool is being used as specific type and return the
 * pool pointer on success
 */
static struct mvpp2_bm_pool *
mvpp2_bm_pool_use(struct mvpp2_port *port, unsigned pool, int pkt_size)
{
	struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool];
	int num;

	if ((port->priv->percpu_pools && pool > mvpp2_get_nrxqs(port->priv) * 2) ||
	    (!port->priv->percpu_pools && pool >= MVPP2_BM_POOLS_NUM)) {
		netdev_err(port->dev, "Invalid pool %d\n", pool);
		return NULL;
	}

	/* Allocate buffers in case BM pool is used as long pool, but packet
	 * size doesn't match MTU or BM pool hasn't being used yet
	 */
	if (new_pool->pkt_size == 0) {
		int pkts_num;

		/* Set default buffer number or free all the buffers in case
		 * the pool is not empty
		 */
		pkts_num = new_pool->buf_num;
		if (pkts_num == 0) {
			if (port->priv->percpu_pools) {
				if (pool < port->nrxqs)
					pkts_num = mvpp2_pools[MVPP2_BM_SHORT].buf_num;
				else
					pkts_num = mvpp2_pools[MVPP2_BM_LONG].buf_num;
			} else {
				pkts_num = mvpp2_pools[pool].buf_num;
			}
		} else {
			mvpp2_bm_bufs_free(port->dev->dev.parent,
					   port->priv, new_pool, pkts_num);
		}

		new_pool->pkt_size = pkt_size;
		new_pool->frag_size =
			SKB_DATA_ALIGN(MVPP2_RX_BUF_SIZE(pkt_size)) +
			MVPP2_SKB_SHINFO_SIZE;

		/* Allocate buffers for this pool */
		num = mvpp2_bm_bufs_add(port, new_pool, pkts_num);
		if (num != pkts_num) {
			WARN(1, "pool %d: %d of %d allocated\n",
			     new_pool->id, num, pkts_num);
			return NULL;
		}
	}

	mvpp2_bm_pool_bufsize_set(port->priv, new_pool,
				  MVPP2_RX_BUF_SIZE(new_pool->pkt_size));

	return new_pool;
}

static struct mvpp2_bm_pool *
mvpp2_bm_pool_use_percpu(struct mvpp2_port *port, int type,
			 unsigned int pool, int pkt_size)
{
	struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool];
	int num;

	if (pool > port->nrxqs * 2) {
		netdev_err(port->dev, "Invalid pool %d\n", pool);
		return NULL;
	}

	/* Allocate buffers in case BM pool is used as long pool, but packet
	 * size doesn't match MTU or BM pool hasn't being used yet
	 */
	if (new_pool->pkt_size == 0) {
		int pkts_num;

		/* Set default buffer number or free all the buffers in case
		 * the pool is not empty
		 */
		pkts_num = new_pool->buf_num;
		if (pkts_num == 0)
			pkts_num = mvpp2_pools[type].buf_num;
		else
			mvpp2_bm_bufs_free(port->dev->dev.parent,
					   port->priv, new_pool, pkts_num);

		new_pool->pkt_size = pkt_size;
		new_pool->frag_size =
			SKB_DATA_ALIGN(MVPP2_RX_BUF_SIZE(pkt_size)) +
			MVPP2_SKB_SHINFO_SIZE;

		/* Allocate buffers for this pool */
		num = mvpp2_bm_bufs_add(port, new_pool, pkts_num);
		if (num != pkts_num) {
			WARN(1, "pool %d: %d of %d allocated\n",
			     new_pool->id, num, pkts_num);
			return NULL;
		}
	}

	mvpp2_bm_pool_bufsize_set(port->priv, new_pool,
				  MVPP2_RX_BUF_SIZE(new_pool->pkt_size));

	return new_pool;
}

/* Initialize pools for swf, shared buffers variant */
static int mvpp2_swf_bm_pool_init_shared(struct mvpp2_port *port)
{
	enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
	int rxq;

	/* If port pkt_size is higher than 1518B:
	 * HW Long pool - SW Jumbo pool, HW Short pool - SW Long pool
	 * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
	 */
	if (port->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
		long_log_pool = MVPP2_BM_JUMBO;
		short_log_pool = MVPP2_BM_LONG;
	} else {
		long_log_pool = MVPP2_BM_LONG;
		short_log_pool = MVPP2_BM_SHORT;
	}

	if (!port->pool_long) {
		port->pool_long =
			mvpp2_bm_pool_use(port, long_log_pool,
					  mvpp2_pools[long_log_pool].pkt_size);
		if (!port->pool_long)
			return -ENOMEM;

		port->pool_long->port_map |= BIT(port->id);

		for (rxq = 0; rxq < port->nrxqs; rxq++)
			mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id);
	}

	if (!port->pool_short) {
		port->pool_short =
			mvpp2_bm_pool_use(port, short_log_pool,
					  mvpp2_pools[short_log_pool].pkt_size);
		if (!port->pool_short)
			return -ENOMEM;

		port->pool_short->port_map |= BIT(port->id);

		for (rxq = 0; rxq < port->nrxqs; rxq++)
			mvpp2_rxq_short_pool_set(port, rxq,
						 port->pool_short->id);
	}

	return 0;
}

/* Initialize pools for swf, percpu buffers variant */
static int mvpp2_swf_bm_pool_init_percpu(struct mvpp2_port *port)
{
	struct mvpp2_bm_pool *bm_pool;
	int i;

	for (i = 0; i < port->nrxqs; i++) {
		bm_pool = mvpp2_bm_pool_use_percpu(port, MVPP2_BM_SHORT, i,
						   mvpp2_pools[MVPP2_BM_SHORT].pkt_size);
		if (!bm_pool)
			return -ENOMEM;

		bm_pool->port_map |= BIT(port->id);
		mvpp2_rxq_short_pool_set(port, i, bm_pool->id);
	}

	for (i = 0; i < port->nrxqs; i++) {
		bm_pool = mvpp2_bm_pool_use_percpu(port, MVPP2_BM_LONG, i + port->nrxqs,
						   mvpp2_pools[MVPP2_BM_LONG].pkt_size);
		if (!bm_pool)
			return -ENOMEM;

		bm_pool->port_map |= BIT(port->id);
		mvpp2_rxq_long_pool_set(port, i, bm_pool->id);
	}

	port->pool_long = NULL;
	port->pool_short = NULL;

	return 0;
}

static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
{
	if (port->priv->percpu_pools)
		return mvpp2_swf_bm_pool_init_percpu(port);
	else
		return mvpp2_swf_bm_pool_init_shared(port);
}

static void mvpp2_set_hw_csum(struct mvpp2_port *port,
			      enum mvpp2_bm_pool_log_num new_long_pool)
{
	const netdev_features_t csums = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;

	/* Update L4 checksum when jumbo enable/disable on port.
	 * Only port 0 supports hardware checksum offload due to
	 * the Tx FIFO size limitation.
	 * Also, don't set NETIF_F_HW_CSUM because L3_offset in TX descriptor
	 * has 7 bits, so the maximum L3 offset is 128.
	 */
	if (new_long_pool == MVPP2_BM_JUMBO && port->id != 0) {
		port->dev->features &= ~csums;
		port->dev->hw_features &= ~csums;
	} else {
		port->dev->features |= csums;
		port->dev->hw_features |= csums;
	}
}

static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
{
	struct mvpp2_port *port = netdev_priv(dev);
	enum mvpp2_bm_pool_log_num new_long_pool;
	int pkt_size = MVPP2_RX_PKT_SIZE(mtu);

	if (port->priv->percpu_pools)
		goto out_set;

	/* If port MTU is higher than 1518B:
	 * HW Long pool - SW Jumbo pool, HW Short pool - SW Long pool
	 * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
	 */
	if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
		new_long_pool = MVPP2_BM_JUMBO;
	else
		new_long_pool = MVPP2_BM_LONG;

	if (new_long_pool != port->pool_long->id) {
		if (port->tx_fc) {
			if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
				mvpp2_bm_pool_update_fc(port,
							port->pool_short,
							false);
			else
				mvpp2_bm_pool_update_fc(port, port->pool_long,
							false);
		}

		/* Remove port from old short & long pool */
		port->pool_long = mvpp2_bm_pool_use(port, port->pool_long->id,
						    port->pool_long->pkt_size);
		port->pool_long->port_map &= ~BIT(port->id);
		port->pool_long = NULL;

		port->pool_short = mvpp2_bm_pool_use(port, port->pool_short->id,
						     port->pool_short->pkt_size);
		port->pool_short->port_map &= ~BIT(port->id);
		port->pool_short = NULL;

		port->pkt_size =  pkt_size;

		/* Add port to new short & long pool */
		mvpp2_swf_bm_pool_init(port);

		mvpp2_set_hw_csum(port, new_long_pool);

		if (port->tx_fc) {
			if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
				mvpp2_bm_pool_update_fc(port, port->pool_long,
							true);
			else
				mvpp2_bm_pool_update_fc(port, port->pool_short,
							true);
		}

		/* Update L4 checksum when jumbo enable/disable on port */
		if (new_long_pool == MVPP2_BM_JUMBO && port->id != 0) {
			dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
			dev->hw_features &= ~(NETIF_F_IP_CSUM |
					      NETIF_F_IPV6_CSUM);
		} else {
			dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
			dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
		}
	}

out_set:
	dev->mtu = mtu;
	dev->wanted_features = dev->features;

	netdev_update_features(dev);
	return 0;
}

static inline void mvpp2_interrupts_enable(struct mvpp2_port *port)
{
	int i, sw_thread_mask = 0;

	for (i = 0; i < port->nqvecs; i++)
		sw_thread_mask |= port->qvecs[i].sw_thread_mask;

	mvpp2_write(port->priv, MVPP2_ISR_ENABLE_REG(port->id),
		    MVPP2_ISR_ENABLE_INTERRUPT(sw_thread_mask));
}

static inline void mvpp2_interrupts_disable(struct mvpp2_port *port)
{
	int i, sw_thread_mask = 0;

	for (i = 0; i < port->nqvecs; i++)
		sw_thread_mask |= port->qvecs[i].sw_thread_mask;

	mvpp2_write(port->priv, MVPP2_ISR_ENABLE_REG(port->id),
		    MVPP2_ISR_DISABLE_INTERRUPT(sw_thread_mask));
}

static inline void mvpp2_qvec_interrupt_enable(struct mvpp2_queue_vector *qvec)
{
	struct mvpp2_port *port = qvec->port;

	mvpp2_write(port->priv, MVPP2_ISR_ENABLE_REG(port->id),
		    MVPP2_ISR_ENABLE_INTERRUPT(qvec->sw_thread_mask));
}

static inline void mvpp2_qvec_interrupt_disable(struct mvpp2_queue_vector *qvec)
{
	struct mvpp2_port *port = qvec->port;

	mvpp2_write(port->priv, MVPP2_ISR_ENABLE_REG(port->id),
		    MVPP2_ISR_DISABLE_INTERRUPT(qvec->sw_thread_mask));
}

/* Mask the current thread's Rx/Tx interrupts
 * Called by on_each_cpu(), guaranteed to run with migration disabled,
 * using smp_processor_id() is OK.
 */
static void mvpp2_interrupts_mask(void *arg)
{
	struct mvpp2_port *port = arg;
	int cpu = smp_processor_id();
	u32 thread;

	/* If the thread isn't used, don't do anything */
	if (cpu > port->priv->nthreads)
		return;

	thread = mvpp2_cpu_to_thread(port->priv, cpu);

	mvpp2_thread_write(port->priv, thread,
			   MVPP2_ISR_RX_TX_MASK_REG(port->id), 0);
	mvpp2_thread_write(port->priv, thread,
			   MVPP2_ISR_RX_ERR_CAUSE_REG(port->id), 0);
}

/* Unmask the current thread's Rx/Tx interrupts.
 * Called by on_each_cpu(), guaranteed to run with migration disabled,
 * using smp_processor_id() is OK.
 */
static void mvpp2_interrupts_unmask(void *arg)
{
	struct mvpp2_port *port = arg;
	int cpu = smp_processor_id();
	u32 val, thread;

	/* If the thread isn't used, don't do anything */
	if (cpu >= port->priv->nthreads)
		return;

	thread = mvpp2_cpu_to_thread(port->priv, cpu);

	val = MVPP2_CAUSE_MISC_SUM_MASK |
		MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK(port->priv->hw_version);
	if (port->has_tx_irqs)
		val |= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;

	mvpp2_thread_write(port->priv, thread,
			   MVPP2_ISR_RX_TX_MASK_REG(port->id), val);
	mvpp2_thread_write(port->priv, thread,
			   MVPP2_ISR_RX_ERR_CAUSE_REG(port->id),
			   MVPP2_ISR_RX_ERR_CAUSE_NONOCC_MASK);
}

static void
mvpp2_shared_interrupt_mask_unmask(struct mvpp2_port *port, bool mask)
{
	u32 val;
	int i;

	if (port->priv->hw_version == MVPP21)
		return;

	if (mask)
		val = 0;
	else
		val = MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK(MVPP22);

	for (i = 0; i < port->nqvecs; i++) {
		struct mvpp2_queue_vector *v = port->qvecs + i;

		if (v->type != MVPP2_QUEUE_VECTOR_SHARED)
			continue;

		mvpp2_thread_write(port->priv, v->sw_thread_id,
				   MVPP2_ISR_RX_TX_MASK_REG(port->id), val);
		mvpp2_thread_write(port->priv, v->sw_thread_id,
				   MVPP2_ISR_RX_ERR_CAUSE_REG(port->id),
				   MVPP2_ISR_RX_ERR_CAUSE_NONOCC_MASK);
	}
}

/* Only GOP port 0 has an XLG MAC */
static bool mvpp2_port_supports_xlg(struct mvpp2_port *port)
{
	return port->gop_id == 0;
}

static bool mvpp2_port_supports_rgmii(struct mvpp2_port *port)
{
	return !(port->priv->hw_version >= MVPP22 && port->gop_id == 0);
}

/* Port configuration routines */
static bool mvpp2_is_xlg(phy_interface_t interface)
{
	return interface == PHY_INTERFACE_MODE_10GBASER ||
	       interface == PHY_INTERFACE_MODE_XAUI;
}

static void mvpp2_modify(void __iomem *ptr, u32 mask, u32 set)
{
	u32 old, val;

	old = val = readl(ptr);
	val &= ~mask;
	val |= set;
	if (old != val)
		writel(val, ptr);
}

static void mvpp22_gop_init_rgmii(struct mvpp2_port *port)
{
	struct mvpp2 *priv = port->priv;
	u32 val;

	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL0, &val);
	val |= GENCONF_PORT_CTRL0_BUS_WIDTH_SELECT;
	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL0, val);

	regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val);
	if (port->gop_id == 2)
		val |= GENCONF_CTRL0_PORT2_RGMII;
	else if (port->gop_id == 3)
		val |= GENCONF_CTRL0_PORT3_RGMII_MII;
	regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val);
}

static void mvpp22_gop_init_sgmii(struct mvpp2_port *port)
{
	struct mvpp2 *priv = port->priv;
	u32 val;

	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL0, &val);
	val |= GENCONF_PORT_CTRL0_BUS_WIDTH_SELECT |
	       GENCONF_PORT_CTRL0_RX_DATA_SAMPLE;
	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL0, val);

	if (port->gop_id > 1) {
		regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val);
		if (port->gop_id == 2)
			val &= ~GENCONF_CTRL0_PORT2_RGMII;
		else if (port->gop_id == 3)
			val &= ~GENCONF_CTRL0_PORT3_RGMII_MII;
		regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val);
	}
}

static void mvpp22_gop_init_10gkr(struct mvpp2_port *port)
{
	struct mvpp2 *priv = port->priv;
	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
	u32 val;

	val = readl(xpcs + MVPP22_XPCS_CFG0);
	val &= ~(MVPP22_XPCS_CFG0_PCS_MODE(0x3) |
		 MVPP22_XPCS_CFG0_ACTIVE_LANE(0x3));
	val |= MVPP22_XPCS_CFG0_ACTIVE_LANE(2);
	writel(val, xpcs + MVPP22_XPCS_CFG0);

	val = readl(mpcs + MVPP22_MPCS_CTRL);
	val &= ~MVPP22_MPCS_CTRL_FWD_ERR_CONN;
	writel(val, mpcs + MVPP22_MPCS_CTRL);

	val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
	val &= ~MVPP22_MPCS_CLK_RESET_DIV_RATIO(0x7);
	val |= MVPP22_MPCS_CLK_RESET_DIV_RATIO(1);
	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
}

static void mvpp22_gop_fca_enable_periodic(struct mvpp2_port *port, bool en)
{
	struct mvpp2 *priv = port->priv;
	void __iomem *fca = priv->iface_base + MVPP22_FCA_BASE(port->gop_id);
	u32 val;

	val = readl(fca + MVPP22_FCA_CONTROL_REG);
	val &= ~MVPP22_FCA_ENABLE_PERIODIC;
	if (en)
		val |= MVPP22_FCA_ENABLE_PERIODIC;
	writel(val, fca + MVPP22_FCA_CONTROL_REG);
}

static void mvpp22_gop_fca_set_timer(struct mvpp2_port *port, u32 timer)
{
	struct mvpp2 *priv = port->priv;
	void __iomem *fca = priv->iface_base + MVPP22_FCA_BASE(port->gop_id);
	u32 lsb, msb;

	lsb = timer & MVPP22_FCA_REG_MASK;
	msb = timer >> MVPP22_FCA_REG_SIZE;

	writel(lsb, fca + MVPP22_PERIODIC_COUNTER_LSB_REG);
	writel(msb, fca + MVPP22_PERIODIC_COUNTER_MSB_REG);
}

/* Set Flow Control timer x100 faster than pause quanta to ensure that link
 * partner won't send traffic if port is in XOFF mode.
 */
static void mvpp22_gop_fca_set_periodic_timer(struct mvpp2_port *port)
{
	u32 timer;

	timer = (port->priv->tclk / (USEC_PER_SEC * FC_CLK_DIVIDER))
		* FC_QUANTA;

	mvpp22_gop_fca_enable_periodic(port, false);

	mvpp22_gop_fca_set_timer(port, timer);

	mvpp22_gop_fca_enable_periodic(port, true);
}

static int mvpp22_gop_init(struct mvpp2_port *port, phy_interface_t interface)
{
	struct mvpp2 *priv = port->priv;
	u32 val;

	if (!priv->sysctrl_base)
		return 0;

	switch (interface) {
	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII_RXID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
		if (!mvpp2_port_supports_rgmii(port))
			goto invalid_conf;
		mvpp22_gop_init_rgmii(port);
		break;
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_1000BASEX:
	case PHY_INTERFACE_MODE_2500BASEX:
		mvpp22_gop_init_sgmii(port);
		break;
	case PHY_INTERFACE_MODE_10GBASER:
		if (!mvpp2_port_supports_xlg(port))
			goto invalid_conf;
		mvpp22_gop_init_10gkr(port);
		break;
	default:
		goto unsupported_conf;
	}

	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL1, &val);
	val |= GENCONF_PORT_CTRL1_RESET(port->gop_id) |
	       GENCONF_PORT_CTRL1_EN(port->gop_id);
	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL1, val);

	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL0, &val);
	val |= GENCONF_PORT_CTRL0_CLK_DIV_PHASE_CLR;
	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL0, val);

	regmap_read(priv->sysctrl_base, GENCONF_SOFT_RESET1, &val);
	val |= GENCONF_SOFT_RESET1_GOP;
	regmap_write(priv->sysctrl_base, GENCONF_SOFT_RESET1, val);

	mvpp22_gop_fca_set_periodic_timer(port);

unsupported_conf:
	return 0;

invalid_conf:
	netdev_err(port->dev, "Invalid port configuration\n");
	return -EINVAL;
}

static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)
{
	u32 val;

	if (phy_interface_mode_is_rgmii(port->phy_interface) ||
	    phy_interface_mode_is_8023z(port->phy_interface) ||
	    port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
		/* Enable the GMAC link status irq for this port */
		val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
		val |= MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
		writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK);
	}

	if (mvpp2_port_supports_xlg(port)) {
		/* Enable the XLG/GIG irqs for this port */
		val = readl(port->base + MVPP22_XLG_EXT_INT_MASK);
		if (mvpp2_is_xlg(port->phy_interface))
			val |= MVPP22_XLG_EXT_INT_MASK_XLG;
		else
			val |= MVPP22_XLG_EXT_INT_MASK_GIG;
		writel(val, port->base + MVPP22_XLG_EXT_INT_MASK);
	}
}

static void mvpp22_gop_mask_irq(struct mvpp2_port *port)
{
	u32 val;

	if (mvpp2_port_supports_xlg(port)) {
		val = readl(port->base + MVPP22_XLG_EXT_INT_MASK);
		val &= ~(MVPP22_XLG_EXT_INT_MASK_XLG |
			 MVPP22_XLG_EXT_INT_MASK_GIG);
		writel(val, port->base + MVPP22_XLG_EXT_INT_MASK);
	}

	if (phy_interface_mode_is_rgmii(port->phy_interface) ||
	    phy_interface_mode_is_8023z(port->phy_interface) ||
	    port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
		val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK);
		val &= ~MVPP22_GMAC_INT_SUM_MASK_LINK_STAT;
		writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK);
	}
}

static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
{
	u32 val;

	mvpp2_modify(port->base + MVPP22_GMAC_INT_SUM_MASK,
		     MVPP22_GMAC_INT_SUM_MASK_PTP,
		     MVPP22_GMAC_INT_SUM_MASK_PTP);

	if (port->phylink ||
	    phy_interface_mode_is_rgmii(port->phy_interface) ||
	    phy_interface_mode_is_8023z(port->phy_interface) ||
	    port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
		val = readl(port->base + MVPP22_GMAC_INT_MASK);
		val |= MVPP22_GMAC_INT_MASK_LINK_STAT;
		writel(val, port->base + MVPP22_GMAC_INT_MASK);
	}

	if (mvpp2_port_supports_xlg(port)) {
		val = readl(port->base + MVPP22_XLG_INT_MASK);
		val |= MVPP22_XLG_INT_MASK_LINK;
		writel(val, port->base + MVPP22_XLG_INT_MASK);

		mvpp2_modify(port->base + MVPP22_XLG_EXT_INT_MASK,
			     MVPP22_XLG_EXT_INT_MASK_PTP,
			     MVPP22_XLG_EXT_INT_MASK_PTP);
	}

	mvpp22_gop_unmask_irq(port);
}

/* Sets the PHY mode of the COMPHY (which configures the serdes lanes).
 *
 * The PHY mode used by the PPv2 driver comes from the network subsystem, while
 * the one given to the COMPHY comes from the generic PHY subsystem. Hence they
 * differ.
 *
 * The COMPHY configures the serdes lanes regardless of the actual use of the
 * lanes by the physical layer. This is why configurations like
 * "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid.
 */
static int mvpp22_comphy_init(struct mvpp2_port *port,
			      phy_interface_t interface)
{
	int ret;

	if (!port->comphy)
		return 0;

	ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET, interface);
	if (ret)
		return ret;

	return phy_power_on(port->comphy);
}

static void mvpp2_port_enable(struct mvpp2_port *port)
{
	u32 val;

	if (mvpp2_port_supports_xlg(port) &&
	    mvpp2_is_xlg(port->phy_interface)) {
		val = readl(port->base + MVPP22_XLG_CTRL0_REG);
		val |= MVPP22_XLG_CTRL0_PORT_EN;
		val &= ~MVPP22_XLG_CTRL0_MIB_CNT_DIS;
		writel(val, port->base + MVPP22_XLG_CTRL0_REG);
	} else {
		val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
		val |= MVPP2_GMAC_PORT_EN_MASK;
		val |= MVPP2_GMAC_MIB_CNTR_EN_MASK;
		writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
	}
}

static void mvpp2_port_disable(struct mvpp2_port *port)
{
	u32 val;

	if (mvpp2_port_supports_xlg(port) &&
	    mvpp2_is_xlg(port->phy_interface)) {
		val = readl(port->base + MVPP22_XLG_CTRL0_REG);
		val &= ~MVPP22_XLG_CTRL0_PORT_EN;
		writel(val, port->base + MVPP22_XLG_CTRL0_REG);
	}

	val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
	val &= ~(MVPP2_GMAC_PORT_EN_MASK);
	writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
}

/* Set IEEE 802.3x Flow Control Xon Packet Transmission Mode */
static void mvpp2_port_periodic_xon_disable(struct mvpp2_port *port)
{
	u32 val;

	val = readl(port->base + MVPP2_GMAC_CTRL_1_REG) &
		    ~MVPP2_GMAC_PERIODIC_XON_EN_MASK;
	writel(val, port->base + MVPP2_GMAC_CTRL_1_REG);
}

/* Configure loopback port */
static void mvpp2_port_loopback_set(struct mvpp2_port *port,
				    const struct phylink_link_state *state)
{
	u32 val;

	val = readl(port->base + MVPP2_GMAC_CTRL_1_REG);

	if (state->speed == 1000)
		val |= MVPP2_GMAC_GMII_LB_EN_MASK;
	else
		val &= ~MVPP2_GMAC_GMII_LB_EN_MASK;

	if (phy_interface_mode_is_8023z(state->interface) ||
	    state->interface == PHY_INTERFACE_MODE_SGMII)
		val |= MVPP2_GMAC_PCS_LB_EN_MASK;
	else
		val &= ~MVPP2_GMAC_PCS_LB_EN_MASK;

	writel(val, port->base + MVPP2_GMAC_CTRL_1_REG);
}

enum {
	ETHTOOL_XDP_REDIRECT,
	ETHTOOL_XDP_PASS,
	ETHTOOL_XDP_DROP,
	ETHTOOL_XDP_TX,
	ETHTOOL_XDP_TX_ERR,
	ETHTOOL_XDP_XMIT,
	ETHTOOL_XDP_XMIT_ERR,
};

struct mvpp2_ethtool_counter {
	unsigned int offset;
	const char string[ETH_GSTRING_LEN];
	bool reg_is_64b;
};

static u64 mvpp2_read_count(struct mvpp2_port *port,
			    const struct mvpp2_ethtool_counter *counter)
{
	u64 val;

	val = readl(port->stats_base + counter->offset);
	if (counter->reg_is_64b)
		val += (u64)readl(port->stats_base + counter->offset + 4) << 32;

	return val;
}

/* Some counters are accessed indirectly by first writing an index to
 * MVPP2_CTRS_IDX. The index can represent various resources depending on the
 * register we access, it can be a hit counter for some classification tables,
 * a counter specific to a rxq, a txq or a buffer pool.
 */
static u32 mvpp2_read_index(struct mvpp2 *priv, u32 index, u32 reg)
{
	mvpp2_write(priv, MVPP2_CTRS_IDX, index);
	return mvpp2_read(priv, reg);
}

/* Due to the fact that software statistics and hardware statistics are, by
 * design, incremented at different moments in the chain of packet processing,
 * it is very likely that incoming packets could have been dropped after being
 * counted by hardware but before reaching software statistics (most probably
 * multicast packets), and in the oppposite way, during transmission, FCS bytes
 * are added in between as well as TSO skb will be split and header bytes added.
 * Hence, statistics gathered from userspace with ifconfig (software) and
 * ethtool (hardware) cannot be compared.
 */
static const struct mvpp2_ethtool_counter mvpp2_ethtool_mib_regs[] = {
	{ MVPP2_MIB_GOOD_OCTETS_RCVD, "good_octets_received", true },
	{ MVPP2_MIB_BAD_OCTETS_RCVD, "bad_octets_received" },
	{ MVPP2_MIB_CRC_ERRORS_SENT, "crc_errors_sent" },
	{ MVPP2_MIB_UNICAST_FRAMES_RCVD, "unicast_frames_received" },
	{ MVPP2_MIB_BROADCAST_FRAMES_RCVD, "broadcast_frames_received" },
	{ MVPP2_MIB_MULTICAST_FRAMES_RCVD, "multicast_frames_received" },
	{ MVPP2_MIB_FRAMES_64_OCTETS, "frames_64_octets" },
	{ MVPP2_MIB_FRAMES_65_TO_127_OCTETS, "frames_65_to_127_octet" },
	{ MVPP2_MIB_FRAMES_128_TO_255_OCTETS, "frames_128_to_255_octet" },
	{ MVPP2_MIB_FRAMES_256_TO_511_OCTETS, "frames_256_to_511_octet" },
	{ MVPP2_MIB_FRAMES_512_TO_1023_OCTETS, "frames_512_to_1023_octet" },
	{ MVPP2_MIB_FRAMES_1024_TO_MAX_OCTETS, "frames_1024_to_max_octet" },
	{ MVPP2_MIB_GOOD_OCTETS_SENT, "good_octets_sent", true },
	{ MVPP2_MIB_UNICAST_FRAMES_SENT, "unicast_frames_sent" },
	{ MVPP2_MIB_MULTICAST_FRAMES_SENT, "multicast_frames_sent" },
	{ MVPP2_MIB_BROADCAST_FRAMES_SENT, "broadcast_frames_sent" },
	{ MVPP2_MIB_FC_SENT, "fc_sent" },
	{ MVPP2_MIB_FC_RCVD, "fc_received" },
	{ MVPP2_MIB_RX_FIFO_OVERRUN, "rx_fifo_overrun" },
	{ MVPP2_MIB_UNDERSIZE_RCVD, "undersize_received" },
	{ MVPP2_MIB_FRAGMENTS_RCVD, "fragments_received" },
	{ MVPP2_MIB_OVERSIZE_RCVD, "oversize_received" },
	{ MVPP2_MIB_JABBER_RCVD, "jabber_received" },
	{ MVPP2_MIB_MAC_RCV_ERROR, "mac_receive_error" },
	{ MVPP2_MIB_BAD_CRC_EVENT, "bad_crc_event" },
	{ MVPP2_MIB_COLLISION, "collision" },
	{ MVPP2_MIB_LATE_COLLISION, "late_collision" },
};

static const struct mvpp2_ethtool_counter mvpp2_ethtool_port_regs[] = {
	{ MVPP2_OVERRUN_ETH_DROP, "rx_fifo_or_parser_overrun_drops" },
	{ MVPP2_CLS_ETH_DROP, "rx_classifier_drops" },
};

static const struct mvpp2_ethtool_counter mvpp2_ethtool_txq_regs[] = {
	{ MVPP2_TX_DESC_ENQ_CTR, "txq_%d_desc_enqueue" },
	{ MVPP2_TX_DESC_ENQ_TO_DDR_CTR, "txq_%d_desc_enqueue_to_ddr" },
	{ MVPP2_TX_BUFF_ENQ_TO_DDR_CTR, "txq_%d_buff_euqueue_to_ddr" },
	{ MVPP2_TX_DESC_ENQ_HW_FWD_CTR, "txq_%d_desc_hardware_forwarded" },
	{ MVPP2_TX_PKTS_DEQ_CTR, "txq_%d_packets_dequeued" },
	{ MVPP2_TX_PKTS_FULL_QUEUE_DROP_CTR, "txq_%d_queue_full_drops" },
	{ MVPP2_TX_PKTS_EARLY_DROP_CTR, "txq_%d_packets_early_drops" },
	{ MVPP2_TX_PKTS_BM_DROP_CTR, "txq_%d_packets_bm_drops" },
	{ MVPP2_TX_PKTS_BM_MC_DROP_CTR, "txq_%d_packets_rep_bm_drops" },
};

static const struct mvpp2_ethtool_counter mvpp2_ethtool_rxq_regs[] = {
	{ MVPP2_RX_DESC_ENQ_CTR, "rxq_%d_desc_enqueue" },
	{ MVPP2_RX_PKTS_FULL_QUEUE_DROP_CTR, "rxq_%d_queue_full_drops" },
	{ MVPP2_RX_PKTS_EARLY_DROP_CTR, "rxq_%d_packets_early_drops" },
	{ MVPP2_RX_PKTS_BM_DROP_CTR, "rxq_%d_packets_bm_drops" },
};

static const struct mvpp2_ethtool_counter mvpp2_ethtool_xdp[] = {
	{ ETHTOOL_XDP_REDIRECT, "rx_xdp_redirect", },
	{ ETHTOOL_XDP_PASS, "rx_xdp_pass", },
	{ ETHTOOL_XDP_DROP, "rx_xdp_drop", },
	{ ETHTOOL_XDP_TX, "rx_xdp_tx", },
	{ ETHTOOL_XDP_TX_ERR, "rx_xdp_tx_errors", },
	{ ETHTOOL_XDP_XMIT, "tx_xdp_xmit", },
	{ ETHTOOL_XDP_XMIT_ERR, "tx_xdp_xmit_errors", },
};

#define MVPP2_N_ETHTOOL_STATS(ntxqs, nrxqs)	(ARRAY_SIZE(mvpp2_ethtool_mib_regs) + \
						 ARRAY_SIZE(mvpp2_ethtool_port_regs) + \
						 (ARRAY_SIZE(mvpp2_ethtool_txq_regs) * (ntxqs)) + \
						 (ARRAY_SIZE(mvpp2_ethtool_rxq_regs) * (nrxqs)) + \
						 ARRAY_SIZE(mvpp2_ethtool_xdp))

static void mvpp2_ethtool_get_strings(struct net_device *netdev, u32 sset,
				      u8 *data)
{
	struct mvpp2_port *port = netdev_priv(netdev);
	int i, q;

	if (sset != ETH_SS_STATS)
		return;

	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_mib_regs); i++) {
		strscpy(data, mvpp2_ethtool_mib_regs[i].string,
			ETH_GSTRING_LEN);
		data += ETH_GSTRING_LEN;
	}

	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_port_regs); i++) {
		strscpy(data, mvpp2_ethtool_port_regs[i].string,
			ETH_GSTRING_LEN);
		data += ETH_GSTRING_LEN;
	}

	for (q = 0; q < port->ntxqs; q++) {
		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++) {
			snprintf(data, ETH_GSTRING_LEN,
				 mvpp2_ethtool_txq_regs[i].string, q);
			data += ETH_GSTRING_LEN;
		}
	}

	for (q = 0; q < port->nrxqs; q++) {
		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++) {
			snprintf(data, ETH_GSTRING_LEN,
				 mvpp2_ethtool_rxq_regs[i].string,
				 q);
			data += ETH_GSTRING_LEN;
		}
	}

	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_xdp); i++) {
		strscpy(data, mvpp2_ethtool_xdp[i].string,
			ETH_GSTRING_LEN);
		data += ETH_GSTRING_LEN;
	}
}

static void
mvpp2_get_xdp_stats(struct mvpp2_port *port, struct mvpp2_pcpu_stats *xdp_stats)
{
	unsigned int start;
	unsigned int cpu;

	/* Gather XDP Statistics */
	for_each_possible_cpu(cpu) {
		struct mvpp2_pcpu_stats *cpu_stats;
		u64	xdp_redirect;
		u64	xdp_pass;
		u64	xdp_drop;
		u64	xdp_xmit;
		u64	xdp_xmit_err;
		u64	xdp_tx;
		u64	xdp_tx_err;

		cpu_stats = per_cpu_ptr(port->stats, cpu);
		do {
			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
			xdp_redirect = cpu_stats->xdp_redirect;
			xdp_pass   = cpu_stats->xdp_pass;
			xdp_drop = cpu_stats->xdp_drop;
			xdp_xmit   = cpu_stats->xdp_xmit;
			xdp_xmit_err   = cpu_stats->xdp_xmit_err;
			xdp_tx   = cpu_stats->xdp_tx;
			xdp_tx_err   = cpu_stats->xdp_tx_err;
		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));

		xdp_stats->xdp_redirect += xdp_redirect;
		xdp_stats->xdp_pass   += xdp_pass;
		xdp_stats->xdp_drop += xdp_drop;
		xdp_stats->xdp_xmit   += xdp_xmit;
		xdp_stats->xdp_xmit_err   += xdp_xmit_err;
		xdp_stats->xdp_tx   += xdp_tx;
		xdp_stats->xdp_tx_err   += xdp_tx_err;
	}
}

static void mvpp2_read_stats(struct mvpp2_port *port)
{
	struct mvpp2_pcpu_stats xdp_stats = {};
	const struct mvpp2_ethtool_counter *s;
	u64 *pstats;
	int i, q;

	pstats = port->ethtool_stats;

	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_mib_regs); i++)
		*pstats++ += mvpp2_read_count(port, &mvpp2_ethtool_mib_regs[i]);

	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_port_regs); i++)
		*pstats++ += mvpp2_read(port->priv,
					mvpp2_ethtool_port_regs[i].offset +
					4 * port->id);

	for (q = 0; q < port->ntxqs; q++)
		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++)
			*pstats++ += mvpp2_read_index(port->priv,
						      MVPP22_CTRS_TX_CTR(port->id, q),
						      mvpp2_ethtool_txq_regs[i].offset);

	/* Rxqs are numbered from 0 from the user standpoint, but not from the
	 * driver's. We need to add the  port->first_rxq offset.
	 */
	for (q = 0; q < port->nrxqs; q++)
		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++)
			*pstats++ += mvpp2_read_index(port->priv,
						      port->first_rxq + q,
						      mvpp2_ethtool_rxq_regs[i].offset);

	/* Gather XDP Statistics */
	mvpp2_get_xdp_stats(port, &xdp_stats);

	for (i = 0, s = mvpp2_ethtool_xdp;
		 s < mvpp2_ethtool_xdp + ARRAY_SIZE(mvpp2_ethtool_xdp);
	     s++, i++) {
		switch (s->offset) {
		case ETHTOOL_XDP_REDIRECT:
			*pstats++ = xdp_stats.xdp_redirect;
			break;
		case ETHTOOL_XDP_PASS:
			*pstats++ = xdp_stats.xdp_pass;
			break;
		case ETHTOOL_XDP_DROP:
			*pstats++ = xdp_stats.xdp_drop;
			break;
		case ETHTOOL_XDP_TX:
			*pstats++ = xdp_stats.xdp_tx;
			break;
		case ETHTOOL_XDP_TX_ERR:
			*pstats++ = xdp_stats.xdp_tx_err;
			break;
		case ETHTOOL_XDP_XMIT:
			*pstats++ = xdp_stats.xdp_xmit;
			break;
		case ETHTOOL_XDP_XMIT_ERR:
			*pstats++ = xdp_stats.xdp_xmit_err;
			break;
		}
	}
}

static void mvpp2_gather_hw_statistics(struct work_struct *work)
{
	struct delayed_work *del_work = to_delayed_work(work);
	struct mvpp2_port *port = container_of(del_work, struct mvpp2_port,
					       stats_work);

	mutex_lock(&port->gather_stats_lock);

	mvpp2_read_stats(port);

	/* No need to read again the counters right after this function if it
	 * was called asynchronously by the user (ie. use of ethtool).
	 */
	cancel_delayed_work(&port->stats_work);
	queue_delayed_work(port->priv->stats_queue, &port->stats_work,
			   MVPP2_MIB_COUNTERS_STATS_DELAY);

	mutex_unlock(&port->gather_stats_lock);
}

static void mvpp2_ethtool_get_stats(struct net_device *dev,
				    struct ethtool_stats *stats, u64 *data)
{
	struct mvpp2_port *port = netdev_priv(dev);

	/* Update statistics for the given port, then take the lock to avoid
	 * concurrent accesses on the ethtool_stats structure during its copy.
	 */
	mvpp2_gather_hw_statistics(&port->stats_work.work);

	mutex_lock(&port->gather_stats_lock);
	memcpy(data, port->ethtool_stats,
	       sizeof(u64) * MVPP2_N_ETHTOOL_STATS(port->ntxqs, port->nrxqs));
	mutex_unlock(&port->gather_stats_lock);
}

static int mvpp2_ethtool_get_sset_count(struct net_device *dev, int sset)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (sset == ETH_SS_STATS)
		return MVPP2_N_ETHTOOL_STATS(port->ntxqs, port->nrxqs);

	return -EOPNOTSUPP;
}

static void mvpp2_mac_reset_assert(struct mvpp2_port *port)
{
	u32 val;

	val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) |
	      MVPP2_GMAC_PORT_RESET_MASK;
	writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);

	if (port->priv->hw_version >= MVPP22 && port->gop_id == 0) {
		val = readl(port->base + MVPP22_XLG_CTRL0_REG) &
		      ~MVPP22_XLG_CTRL0_MAC_RESET_DIS;
		writel(val, port->base + MVPP22_XLG_CTRL0_REG);
	}
}

static void mvpp22_pcs_reset_assert(struct mvpp2_port *port)
{
	struct mvpp2 *priv = port->priv;
	void __iomem *mpcs, *xpcs;
	u32 val;

	if (port->priv->hw_version == MVPP21 || port->gop_id != 0)
		return;

	mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
	xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);

	val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
	val &= ~(MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX | MAC_CLK_RESET_SD_TX);
	val |= MVPP22_MPCS_CLK_RESET_DIV_SET;
	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);

	val = readl(xpcs + MVPP22_XPCS_CFG0);
	writel(val & ~MVPP22_XPCS_CFG0_RESET_DIS, xpcs + MVPP22_XPCS_CFG0);
}

static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port,
				      phy_interface_t interface)
{
	struct mvpp2 *priv = port->priv;
	void __iomem *mpcs, *xpcs;
	u32 val;

	if (port->priv->hw_version == MVPP21 || port->gop_id != 0)
		return;

	mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
	xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);

	switch (interface) {
	case PHY_INTERFACE_MODE_10GBASER:
		val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
		val |= MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX |
		       MAC_CLK_RESET_SD_TX;
		val &= ~MVPP22_MPCS_CLK_RESET_DIV_SET;
		writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
		break;
	case PHY_INTERFACE_MODE_XAUI:
	case PHY_INTERFACE_MODE_RXAUI:
		val = readl(xpcs + MVPP22_XPCS_CFG0);
		writel(val | MVPP22_XPCS_CFG0_RESET_DIS, xpcs + MVPP22_XPCS_CFG0);
		break;
	default:
		break;
	}
}

/* Change maximum receive size of the port */
static inline void mvpp2_gmac_max_rx_size_set(struct mvpp2_port *port)
{
	u32 val;

	val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
	val &= ~MVPP2_GMAC_MAX_RX_SIZE_MASK;
	val |= (((port->pkt_size - MVPP2_MH_SIZE) / 2) <<
		    MVPP2_GMAC_MAX_RX_SIZE_OFFS);
	writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
}

/* Change maximum receive size of the port */
static inline void mvpp2_xlg_max_rx_size_set(struct mvpp2_port *port)
{
	u32 val;

	val =  readl(port->base + MVPP22_XLG_CTRL1_REG);
	val &= ~MVPP22_XLG_CTRL1_FRAMESIZELIMIT_MASK;
	val |= ((port->pkt_size - MVPP2_MH_SIZE) / 2) <<
	       MVPP22_XLG_CTRL1_FRAMESIZELIMIT_OFFS;
	writel(val, port->base + MVPP22_XLG_CTRL1_REG);
}

/* Set defaults to the MVPP2 port */
static void mvpp2_defaults_set(struct mvpp2_port *port)
{
	int tx_port_num, val, queue, lrxq;

	if (port->priv->hw_version == MVPP21) {
		/* Update TX FIFO MIN Threshold */
		val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
		val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK;
		/* Min. TX threshold must be less than minimal packet length */
		val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(64 - 4 - 2);
		writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
	}

	/* Disable Legacy WRR, Disable EJP, Release from reset */
	tx_port_num = mvpp2_egress_port(port);
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG,
		    tx_port_num);
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_CMD_1_REG, 0);

	/* Set TXQ scheduling to Round-Robin */
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_FIXED_PRIO_REG, 0);

	/* Close bandwidth for all queues */
	for (queue = 0; queue < MVPP2_MAX_TXQ; queue++)
		mvpp2_write(port->priv,
			    MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(queue), 0);

	/* Set refill period to 1 usec, refill tokens
	 * and bucket size to maximum
	 */
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_PERIOD_REG,
		    port->priv->tclk / USEC_PER_SEC);
	val = mvpp2_read(port->priv, MVPP2_TXP_SCHED_REFILL_REG);
	val &= ~MVPP2_TXP_REFILL_PERIOD_ALL_MASK;
	val |= MVPP2_TXP_REFILL_PERIOD_MASK(1);
	val |= MVPP2_TXP_REFILL_TOKENS_ALL_MASK;
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_REFILL_REG, val);
	val = MVPP2_TXP_TOKEN_SIZE_MAX;
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val);

	/* Set MaximumLowLatencyPacketSize value to 256 */
	mvpp2_write(port->priv, MVPP2_RX_CTRL_REG(port->id),
		    MVPP2_RX_USE_PSEUDO_FOR_CSUM_MASK |
		    MVPP2_RX_LOW_LATENCY_PKT_SIZE(256));

	/* Enable Rx cache snoop */
	for (lrxq = 0; lrxq < port->nrxqs; lrxq++) {
		queue = port->rxqs[lrxq]->id;
		val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(queue));
		val |= MVPP2_SNOOP_PKT_SIZE_MASK |
			   MVPP2_SNOOP_BUF_HDR_MASK;
		mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(queue), val);
	}

	/* At default, mask all interrupts to all present cpus */
	mvpp2_interrupts_disable(port);
}

/* Enable/disable receiving packets */
static void mvpp2_ingress_enable(struct mvpp2_port *port)
{
	u32 val;
	int lrxq, queue;

	for (lrxq = 0; lrxq < port->nrxqs; lrxq++) {
		queue = port->rxqs[lrxq]->id;
		val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(queue));
		val &= ~MVPP2_RXQ_DISABLE_MASK;
		mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(queue), val);
	}
}

static void mvpp2_ingress_disable(struct mvpp2_port *port)
{
	u32 val;
	int lrxq, queue;

	for (lrxq = 0; lrxq < port->nrxqs; lrxq++) {
		queue = port->rxqs[lrxq]->id;
		val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(queue));
		val |= MVPP2_RXQ_DISABLE_MASK;
		mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(queue), val);
	}
}

/* Enable transmit via physical egress queue
 * - HW starts take descriptors from DRAM
 */
static void mvpp2_egress_enable(struct mvpp2_port *port)
{
	u32 qmap;
	int queue;
	int tx_port_num = mvpp2_egress_port(port);

	/* Enable all initialized TXs. */
	qmap = 0;
	for (queue = 0; queue < port->ntxqs; queue++) {
		struct mvpp2_tx_queue *txq = port->txqs[queue];

		if (txq->descs)
			qmap |= (1 << queue);
	}

	mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG, qmap);
}

/* Disable transmit via physical egress queue
 * - HW doesn't take descriptors from DRAM
 */
static void mvpp2_egress_disable(struct mvpp2_port *port)
{
	u32 reg_data;
	int delay;
	int tx_port_num = mvpp2_egress_port(port);

	/* Issue stop command for active channels only */
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);
	reg_data = (mvpp2_read(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG)) &
		    MVPP2_TXP_SCHED_ENQ_MASK;
	if (reg_data != 0)
		mvpp2_write(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG,
			    (reg_data << MVPP2_TXP_SCHED_DISQ_OFFSET));

	/* Wait for all Tx activity to terminate. */
	delay = 0;
	do {
		if (delay >= MVPP2_TX_DISABLE_TIMEOUT_MSEC) {
			netdev_warn(port->dev,
				    "Tx stop timed out, status=0x%08x\n",
				    reg_data);
			break;
		}
		mdelay(1);
		delay++;

		/* Check port TX Command register that all
		 * Tx queues are stopped
		 */
		reg_data = mvpp2_read(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG);
	} while (reg_data & MVPP2_TXP_SCHED_ENQ_MASK);
}

/* Rx descriptors helper methods */

/* Get number of Rx descriptors occupied by received packets */
static inline int
mvpp2_rxq_received(struct mvpp2_port *port, int rxq_id)
{
	u32 val = mvpp2_read(port->priv, MVPP2_RXQ_STATUS_REG(rxq_id));

	return val & MVPP2_RXQ_OCCUPIED_MASK;
}

/* Update Rx queue status with the number of occupied and available
 * Rx descriptor slots.
 */
static inline void
mvpp2_rxq_status_update(struct mvpp2_port *port, int rxq_id,
			int used_count, int free_count)
{
	/* Decrement the number of used descriptors and increment count
	 * increment the number of free descriptors.
	 */
	u32 val = used_count | (free_count << MVPP2_RXQ_NUM_NEW_OFFSET);

	mvpp2_write(port->priv, MVPP2_RXQ_STATUS_UPDATE_REG(rxq_id), val);
}

/* Get pointer to next RX descriptor to be processed by SW */
static inline struct mvpp2_rx_desc *
mvpp2_rxq_next_desc_get(struct mvpp2_rx_queue *rxq)
{
	int rx_desc = rxq->next_desc_to_proc;

	rxq->next_desc_to_proc = MVPP2_QUEUE_NEXT_DESC(rxq, rx_desc);
	prefetch(rxq->descs + rxq->next_desc_to_proc);
	return rxq->descs + rx_desc;
}

/* Set rx queue offset */
static void mvpp2_rxq_offset_set(struct mvpp2_port *port,
				 int prxq, int offset)
{
	u32 val;

	/* Convert offset from bytes to units of 32 bytes */
	offset = offset >> 5;

	val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
	val &= ~MVPP2_RXQ_PACKET_OFFSET_MASK;

	/* Offset is in */
	val |= ((offset << MVPP2_RXQ_PACKET_OFFSET_OFFS) &
		    MVPP2_RXQ_PACKET_OFFSET_MASK);

	mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
}

/* Tx descriptors helper methods */

/* Get pointer to next Tx descriptor to be processed (send) by HW */
static struct mvpp2_tx_desc *
mvpp2_txq_next_desc_get(struct mvpp2_tx_queue *txq)
{
	int tx_desc = txq->next_desc_to_proc;

	txq->next_desc_to_proc = MVPP2_QUEUE_NEXT_DESC(txq, tx_desc);
	return txq->descs + tx_desc;
}

/* Update HW with number of aggregated Tx descriptors to be sent
 *
 * Called only from mvpp2_tx(), so migration is disabled, using
 * smp_processor_id() is OK.
 */
static void mvpp2_aggr_txq_pend_desc_add(struct mvpp2_port *port, int pending)
{
	/* aggregated access - relevant TXQ number is written in TX desc */
	mvpp2_thread_write(port->priv,
			   mvpp2_cpu_to_thread(port->priv, smp_processor_id()),
			   MVPP2_AGGR_TXQ_UPDATE_REG, pending);
}

/* Check if there are enough free descriptors in aggregated txq.
 * If not, update the number of occupied descriptors and repeat the check.
 *
 * Called only from mvpp2_tx(), so migration is disabled, using
 * smp_processor_id() is OK.
 */
static int mvpp2_aggr_desc_num_check(struct mvpp2_port *port,
				     struct mvpp2_tx_queue *aggr_txq, int num)
{
	if ((aggr_txq->count + num) > MVPP2_AGGR_TXQ_SIZE) {
		/* Update number of occupied aggregated Tx descriptors */
		unsigned int thread =
			mvpp2_cpu_to_thread(port->priv, smp_processor_id());
		u32 val = mvpp2_read_relaxed(port->priv,
					     MVPP2_AGGR_TXQ_STATUS_REG(thread));

		aggr_txq->count = val & MVPP2_AGGR_TXQ_PENDING_MASK;

		if ((aggr_txq->count + num) > MVPP2_AGGR_TXQ_SIZE)
			return -ENOMEM;
	}
	return 0;
}

/* Reserved Tx descriptors allocation request
 *
 * Called only from mvpp2_txq_reserved_desc_num_proc(), itself called
 * only by mvpp2_tx(), so migration is disabled, using
 * smp_processor_id() is OK.
 */
static int mvpp2_txq_alloc_reserved_desc(struct mvpp2_port *port,
					 struct mvpp2_tx_queue *txq, int num)
{
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());
	struct mvpp2 *priv = port->priv;
	u32 val;

	val = (txq->id << MVPP2_TXQ_RSVD_REQ_Q_OFFSET) | num;
	mvpp2_thread_write_relaxed(priv, thread, MVPP2_TXQ_RSVD_REQ_REG, val);

	val = mvpp2_thread_read_relaxed(priv, thread, MVPP2_TXQ_RSVD_RSLT_REG);

	return val & MVPP2_TXQ_RSVD_RSLT_MASK;
}

/* Check if there are enough reserved descriptors for transmission.
 * If not, request chunk of reserved descriptors and check again.
 */
static int mvpp2_txq_reserved_desc_num_proc(struct mvpp2_port *port,
					    struct mvpp2_tx_queue *txq,
					    struct mvpp2_txq_pcpu *txq_pcpu,
					    int num)
{
	int req, desc_count;
	unsigned int thread;

	if (txq_pcpu->reserved_num >= num)
		return 0;

	/* Not enough descriptors reserved! Update the reserved descriptor
	 * count and check again.
	 */

	desc_count = 0;
	/* Compute total of used descriptors */
	for (thread = 0; thread < port->priv->nthreads; thread++) {
		struct mvpp2_txq_pcpu *txq_pcpu_aux;

		txq_pcpu_aux = per_cpu_ptr(txq->pcpu, thread);
		desc_count += txq_pcpu_aux->count;
		desc_count += txq_pcpu_aux->reserved_num;
	}

	req = max(MVPP2_CPU_DESC_CHUNK, num - txq_pcpu->reserved_num);
	desc_count += req;

	if (desc_count >
	   (txq->size - (MVPP2_MAX_THREADS * MVPP2_CPU_DESC_CHUNK)))
		return -ENOMEM;

	txq_pcpu->reserved_num += mvpp2_txq_alloc_reserved_desc(port, txq, req);

	/* OK, the descriptor could have been updated: check again. */
	if (txq_pcpu->reserved_num < num)
		return -ENOMEM;
	return 0;
}

/* Release the last allocated Tx descriptor. Useful to handle DMA
 * mapping failures in the Tx path.
 */
static void mvpp2_txq_desc_put(struct mvpp2_tx_queue *txq)
{
	if (txq->next_desc_to_proc == 0)
		txq->next_desc_to_proc = txq->last_desc - 1;
	else
		txq->next_desc_to_proc--;
}

/* Set Tx descriptors fields relevant for CSUM calculation */
static u32 mvpp2_txq_desc_csum(int l3_offs, __be16 l3_proto,
			       int ip_hdr_len, int l4_proto)
{
	u32 command;

	/* fields: L3_offset, IP_hdrlen, L3_type, G_IPv4_chk,
	 * G_L4_chk, L4_type required only for checksum calculation
	 */
	command = (l3_offs << MVPP2_TXD_L3_OFF_SHIFT);
	command |= (ip_hdr_len << MVPP2_TXD_IP_HLEN_SHIFT);
	command |= MVPP2_TXD_IP_CSUM_DISABLE;

	if (l3_proto == htons(ETH_P_IP)) {
		command &= ~MVPP2_TXD_IP_CSUM_DISABLE;	/* enable IPv4 csum */
		command &= ~MVPP2_TXD_L3_IP6;		/* enable IPv4 */
	} else {
		command |= MVPP2_TXD_L3_IP6;		/* enable IPv6 */
	}

	if (l4_proto == IPPROTO_TCP) {
		command &= ~MVPP2_TXD_L4_UDP;		/* enable TCP */
		command &= ~MVPP2_TXD_L4_CSUM_FRAG;	/* generate L4 csum */
	} else if (l4_proto == IPPROTO_UDP) {
		command |= MVPP2_TXD_L4_UDP;		/* enable UDP */
		command &= ~MVPP2_TXD_L4_CSUM_FRAG;	/* generate L4 csum */
	} else {
		command |= MVPP2_TXD_L4_CSUM_NOT;
	}

	return command;
}

/* Get number of sent descriptors and decrement counter.
 * The number of sent descriptors is returned.
 * Per-thread access
 *
 * Called only from mvpp2_txq_done(), called from mvpp2_tx()
 * (migration disabled) and from the TX completion tasklet (migration
 * disabled) so using smp_processor_id() is OK.
 */
static inline int mvpp2_txq_sent_desc_proc(struct mvpp2_port *port,
					   struct mvpp2_tx_queue *txq)
{
	u32 val;

	/* Reading status reg resets transmitted descriptor counter */
	val = mvpp2_thread_read_relaxed(port->priv,
					mvpp2_cpu_to_thread(port->priv, smp_processor_id()),
					MVPP2_TXQ_SENT_REG(txq->id));

	return (val & MVPP2_TRANSMITTED_COUNT_MASK) >>
		MVPP2_TRANSMITTED_COUNT_OFFSET;
}

/* Called through on_each_cpu(), so runs on all CPUs, with migration
 * disabled, therefore using smp_processor_id() is OK.
 */
static void mvpp2_txq_sent_counter_clear(void *arg)
{
	struct mvpp2_port *port = arg;
	int queue;

	/* If the thread isn't used, don't do anything */
	if (smp_processor_id() >= port->priv->nthreads)
		return;

	for (queue = 0; queue < port->ntxqs; queue++) {
		int id = port->txqs[queue]->id;

		mvpp2_thread_read(port->priv,
				  mvpp2_cpu_to_thread(port->priv, smp_processor_id()),
				  MVPP2_TXQ_SENT_REG(id));
	}
}

/* Set max sizes for Tx queues */
static void mvpp2_txp_max_tx_size_set(struct mvpp2_port *port)
{
	u32	val, size, mtu;
	int	txq, tx_port_num;

	mtu = port->pkt_size * 8;
	if (mtu > MVPP2_TXP_MTU_MAX)
		mtu = MVPP2_TXP_MTU_MAX;

	/* WA for wrong Token bucket update: Set MTU value = 3*real MTU value */
	mtu = 3 * mtu;

	/* Indirect access to registers */
	tx_port_num = mvpp2_egress_port(port);
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);

	/* Set MTU */
	val = mvpp2_read(port->priv, MVPP2_TXP_SCHED_MTU_REG);
	val &= ~MVPP2_TXP_MTU_MAX;
	val |= mtu;
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_MTU_REG, val);

	/* TXP token size and all TXQs token size must be larger that MTU */
	val = mvpp2_read(port->priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG);
	size = val & MVPP2_TXP_TOKEN_SIZE_MAX;
	if (size < mtu) {
		size = mtu;
		val &= ~MVPP2_TXP_TOKEN_SIZE_MAX;
		val |= size;
		mvpp2_write(port->priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val);
	}

	for (txq = 0; txq < port->ntxqs; txq++) {
		val = mvpp2_read(port->priv,
				 MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq));
		size = val & MVPP2_TXQ_TOKEN_SIZE_MAX;

		if (size < mtu) {
			size = mtu;
			val &= ~MVPP2_TXQ_TOKEN_SIZE_MAX;
			val |= size;
			mvpp2_write(port->priv,
				    MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq),
				    val);
		}
	}
}

/* Set the number of non-occupied descriptors threshold */
static void mvpp2_set_rxq_free_tresh(struct mvpp2_port *port,
				     struct mvpp2_rx_queue *rxq)
{
	u32 val;

	mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);

	val = mvpp2_read(port->priv, MVPP2_RXQ_THRESH_REG);
	val &= ~MVPP2_RXQ_NON_OCCUPIED_MASK;
	val |= MSS_THRESHOLD_STOP << MVPP2_RXQ_NON_OCCUPIED_OFFSET;
	mvpp2_write(port->priv, MVPP2_RXQ_THRESH_REG, val);
}

/* Set the number of packets that will be received before Rx interrupt
 * will be generated by HW.
 */
static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port,
				   struct mvpp2_rx_queue *rxq)
{
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, get_cpu());

	if (rxq->pkts_coal > MVPP2_OCCUPIED_THRESH_MASK)
		rxq->pkts_coal = MVPP2_OCCUPIED_THRESH_MASK;

	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_NUM_REG, rxq->id);
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_THRESH_REG,
			   rxq->pkts_coal);

	put_cpu();
}

/* For some reason in the LSP this is done on each CPU. Why ? */
static void mvpp2_tx_pkts_coal_set(struct mvpp2_port *port,
				   struct mvpp2_tx_queue *txq)
{
	unsigned int thread;
	u32 val;

	if (txq->done_pkts_coal > MVPP2_TXQ_THRESH_MASK)
		txq->done_pkts_coal = MVPP2_TXQ_THRESH_MASK;

	val = (txq->done_pkts_coal << MVPP2_TXQ_THRESH_OFFSET);
	/* PKT-coalescing registers are per-queue + per-thread */
	for (thread = 0; thread < MVPP2_MAX_THREADS; thread++) {
		mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id);
		mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val);
	}
}

static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz)
{
	u64 tmp = (u64)clk_hz * usec;

	do_div(tmp, USEC_PER_SEC);

	return tmp > U32_MAX ? U32_MAX : tmp;
}

static u32 mvpp2_cycles_to_usec(u32 cycles, unsigned long clk_hz)
{
	u64 tmp = (u64)cycles * USEC_PER_SEC;

	do_div(tmp, clk_hz);

	return tmp > U32_MAX ? U32_MAX : tmp;
}

/* Set the time delay in usec before Rx interrupt */
static void mvpp2_rx_time_coal_set(struct mvpp2_port *port,
				   struct mvpp2_rx_queue *rxq)
{
	unsigned long freq = port->priv->tclk;
	u32 val = mvpp2_usec_to_cycles(rxq->time_coal, freq);

	if (val > MVPP2_MAX_ISR_RX_THRESHOLD) {
		rxq->time_coal =
			mvpp2_cycles_to_usec(MVPP2_MAX_ISR_RX_THRESHOLD, freq);

		/* re-evaluate to get actual register value */
		val = mvpp2_usec_to_cycles(rxq->time_coal, freq);
	}

	mvpp2_write(port->priv, MVPP2_ISR_RX_THRESHOLD_REG(rxq->id), val);
}

static void mvpp2_tx_time_coal_set(struct mvpp2_port *port)
{
	unsigned long freq = port->priv->tclk;
	u32 val = mvpp2_usec_to_cycles(port->tx_time_coal, freq);

	if (val > MVPP2_MAX_ISR_TX_THRESHOLD) {
		port->tx_time_coal =
			mvpp2_cycles_to_usec(MVPP2_MAX_ISR_TX_THRESHOLD, freq);

		/* re-evaluate to get actual register value */
		val = mvpp2_usec_to_cycles(port->tx_time_coal, freq);
	}

	mvpp2_write(port->priv, MVPP2_ISR_TX_THRESHOLD_REG(port->id), val);
}

/* Free Tx queue skbuffs */
static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
				struct mvpp2_tx_queue *txq,
				struct mvpp2_txq_pcpu *txq_pcpu, int num)
{
	struct xdp_frame_bulk bq;
	int i;

	xdp_frame_bulk_init(&bq);

	rcu_read_lock(); /* need for xdp_return_frame_bulk */

	for (i = 0; i < num; i++) {
		struct mvpp2_txq_pcpu_buf *tx_buf =
			txq_pcpu->buffs + txq_pcpu->txq_get_index;

		if (!IS_TSO_HEADER(txq_pcpu, tx_buf->dma) &&
		    tx_buf->type != MVPP2_TYPE_XDP_TX)
			dma_unmap_single(port->dev->dev.parent, tx_buf->dma,
					 tx_buf->size, DMA_TO_DEVICE);
		if (tx_buf->type == MVPP2_TYPE_SKB && tx_buf->skb)
			dev_kfree_skb_any(tx_buf->skb);
		else if (tx_buf->type == MVPP2_TYPE_XDP_TX ||
			 tx_buf->type == MVPP2_TYPE_XDP_NDO)
			xdp_return_frame_bulk(tx_buf->xdpf, &bq);

		mvpp2_txq_inc_get(txq_pcpu);
	}
	xdp_flush_frame_bulk(&bq);

	rcu_read_unlock();
}

static inline struct mvpp2_rx_queue *mvpp2_get_rx_queue(struct mvpp2_port *port,
							u32 cause)
{
	int queue = fls(cause) - 1;

	return port->rxqs[queue];
}

static inline struct mvpp2_tx_queue *mvpp2_get_tx_queue(struct mvpp2_port *port,
							u32 cause)
{
	int queue = fls(cause) - 1;

	return port->txqs[queue];
}

/* Handle end of transmission */
static void mvpp2_txq_done(struct mvpp2_port *port, struct mvpp2_tx_queue *txq,
			   struct mvpp2_txq_pcpu *txq_pcpu)
{
	struct netdev_queue *nq = netdev_get_tx_queue(port->dev, txq->log_id);
	int tx_done;

	if (txq_pcpu->thread != mvpp2_cpu_to_thread(port->priv, smp_processor_id()))
		netdev_err(port->dev, "wrong cpu on the end of Tx processing\n");

	tx_done = mvpp2_txq_sent_desc_proc(port, txq);
	if (!tx_done)
		return;
	mvpp2_txq_bufs_free(port, txq, txq_pcpu, tx_done);

	txq_pcpu->count -= tx_done;

	if (netif_tx_queue_stopped(nq))
		if (txq_pcpu->count <= txq_pcpu->wake_threshold)
			netif_tx_wake_queue(nq);
}

static unsigned int mvpp2_tx_done(struct mvpp2_port *port, u32 cause,
				  unsigned int thread)
{
	struct mvpp2_tx_queue *txq;
	struct mvpp2_txq_pcpu *txq_pcpu;
	unsigned int tx_todo = 0;

	while (cause) {
		txq = mvpp2_get_tx_queue(port, cause);
		if (!txq)
			break;

		txq_pcpu = per_cpu_ptr(txq->pcpu, thread);

		if (txq_pcpu->count) {
			mvpp2_txq_done(port, txq, txq_pcpu);
			tx_todo += txq_pcpu->count;
		}

		cause &= ~(1 << txq->log_id);
	}
	return tx_todo;
}

/* Rx/Tx queue initialization/cleanup methods */

/* Allocate and initialize descriptors for aggr TXQ */
static int mvpp2_aggr_txq_init(struct platform_device *pdev,
			       struct mvpp2_tx_queue *aggr_txq,
			       unsigned int thread, struct mvpp2 *priv)
{
	u32 txq_dma;

	/* Allocate memory for TX descriptors */
	aggr_txq->descs = dma_alloc_coherent(&pdev->dev,
					     MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE,
					     &aggr_txq->descs_dma, GFP_KERNEL);
	if (!aggr_txq->descs)
		return -ENOMEM;

	aggr_txq->last_desc = MVPP2_AGGR_TXQ_SIZE - 1;

	/* Aggr TXQ no reset WA */
	aggr_txq->next_desc_to_proc = mvpp2_read(priv,
						 MVPP2_AGGR_TXQ_INDEX_REG(thread));

	/* Set Tx descriptors queue starting address indirect
	 * access
	 */
	if (priv->hw_version == MVPP21)
		txq_dma = aggr_txq->descs_dma;
	else
		txq_dma = aggr_txq->descs_dma >>
			MVPP22_AGGR_TXQ_DESC_ADDR_OFFS;

	mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_ADDR_REG(thread), txq_dma);
	mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_SIZE_REG(thread),
		    MVPP2_AGGR_TXQ_SIZE);

	return 0;
}

/* Create a specified Rx queue */
static int mvpp2_rxq_init(struct mvpp2_port *port,
			  struct mvpp2_rx_queue *rxq)
{
	struct mvpp2 *priv = port->priv;
	unsigned int thread;
	u32 rxq_dma;
	int err;

	rxq->size = port->rx_ring_size;

	/* Allocate memory for RX descriptors */
	rxq->descs = dma_alloc_coherent(port->dev->dev.parent,
					rxq->size * MVPP2_DESC_ALIGNED_SIZE,
					&rxq->descs_dma, GFP_KERNEL);
	if (!rxq->descs)
		return -ENOMEM;

	rxq->last_desc = rxq->size - 1;

	/* Zero occupied and non-occupied counters - direct access */
	mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);

	/* Set Rx descriptors queue starting address - indirect access */
	thread = mvpp2_cpu_to_thread(port->priv, get_cpu());
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_NUM_REG, rxq->id);
	if (port->priv->hw_version == MVPP21)
		rxq_dma = rxq->descs_dma;
	else
		rxq_dma = rxq->descs_dma >> MVPP22_DESC_ADDR_OFFS;
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_DESC_ADDR_REG, rxq_dma);
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_DESC_SIZE_REG, rxq->size);
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_INDEX_REG, 0);
	put_cpu();

	/* Set Offset */
	mvpp2_rxq_offset_set(port, rxq->id, MVPP2_SKB_HEADROOM);

	/* Set coalescing pkts and time */
	mvpp2_rx_pkts_coal_set(port, rxq);
	mvpp2_rx_time_coal_set(port, rxq);

	/* Set the number of non occupied descriptors threshold */
	mvpp2_set_rxq_free_tresh(port, rxq);

	/* Add number of descriptors ready for receiving packets */
	mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size);

	if (priv->percpu_pools) {
		err = xdp_rxq_info_reg(&rxq->xdp_rxq_short, port->dev, rxq->id, 0);
		if (err < 0)
			goto err_free_dma;

		err = xdp_rxq_info_reg(&rxq->xdp_rxq_long, port->dev, rxq->id, 0);
		if (err < 0)
			goto err_unregister_rxq_short;

		/* Every RXQ has a pool for short and another for long packets */
		err = xdp_rxq_info_reg_mem_model(&rxq->xdp_rxq_short,
						 MEM_TYPE_PAGE_POOL,
						 priv->page_pool[rxq->logic_rxq]);
		if (err < 0)
			goto err_unregister_rxq_long;

		err = xdp_rxq_info_reg_mem_model(&rxq->xdp_rxq_long,
						 MEM_TYPE_PAGE_POOL,
						 priv->page_pool[rxq->logic_rxq +
								 port->nrxqs]);
		if (err < 0)
			goto err_unregister_mem_rxq_short;
	}

	return 0;

err_unregister_mem_rxq_short:
	xdp_rxq_info_unreg_mem_model(&rxq->xdp_rxq_short);
err_unregister_rxq_long:
	xdp_rxq_info_unreg(&rxq->xdp_rxq_long);
err_unregister_rxq_short:
	xdp_rxq_info_unreg(&rxq->xdp_rxq_short);
err_free_dma:
	dma_free_coherent(port->dev->dev.parent,
			  rxq->size * MVPP2_DESC_ALIGNED_SIZE,
			  rxq->descs, rxq->descs_dma);
	return err;
}

/* Push packets received by the RXQ to BM pool */
static void mvpp2_rxq_drop_pkts(struct mvpp2_port *port,
				struct mvpp2_rx_queue *rxq)
{
	int rx_received, i;

	rx_received = mvpp2_rxq_received(port, rxq->id);
	if (!rx_received)
		return;

	for (i = 0; i < rx_received; i++) {
		struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
		u32 status = mvpp2_rxdesc_status_get(port, rx_desc);
		int pool;

		pool = (status & MVPP2_RXD_BM_POOL_ID_MASK) >>
			MVPP2_RXD_BM_POOL_ID_OFFS;

		mvpp2_bm_pool_put(port, pool,
				  mvpp2_rxdesc_dma_addr_get(port, rx_desc),
				  mvpp2_rxdesc_cookie_get(port, rx_desc));
	}
	mvpp2_rxq_status_update(port, rxq->id, rx_received, rx_received);
}

/* Cleanup Rx queue */
static void mvpp2_rxq_deinit(struct mvpp2_port *port,
			     struct mvpp2_rx_queue *rxq)
{
	unsigned int thread;

	if (xdp_rxq_info_is_reg(&rxq->xdp_rxq_short))
		xdp_rxq_info_unreg(&rxq->xdp_rxq_short);

	if (xdp_rxq_info_is_reg(&rxq->xdp_rxq_long))
		xdp_rxq_info_unreg(&rxq->xdp_rxq_long);

	mvpp2_rxq_drop_pkts(port, rxq);

	if (rxq->descs)
		dma_free_coherent(port->dev->dev.parent,
				  rxq->size * MVPP2_DESC_ALIGNED_SIZE,
				  rxq->descs,
				  rxq->descs_dma);

	rxq->descs             = NULL;
	rxq->last_desc         = 0;
	rxq->next_desc_to_proc = 0;
	rxq->descs_dma         = 0;

	/* Clear Rx descriptors queue starting address and size;
	 * free descriptor number
	 */
	mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
	thread = mvpp2_cpu_to_thread(port->priv, get_cpu());
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_NUM_REG, rxq->id);
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_DESC_ADDR_REG, 0);
	mvpp2_thread_write(port->priv, thread, MVPP2_RXQ_DESC_SIZE_REG, 0);
	put_cpu();
}

/* Create and initialize a Tx queue */
static int mvpp2_txq_init(struct mvpp2_port *port,
			  struct mvpp2_tx_queue *txq)
{
	u32 val;
	unsigned int thread;
	int desc, desc_per_txq, tx_port_num;
	struct mvpp2_txq_pcpu *txq_pcpu;

	txq->size = port->tx_ring_size;

	/* Allocate memory for Tx descriptors */
	txq->descs = dma_alloc_coherent(port->dev->dev.parent,
				txq->size * MVPP2_DESC_ALIGNED_SIZE,
				&txq->descs_dma, GFP_KERNEL);
	if (!txq->descs)
		return -ENOMEM;

	txq->last_desc = txq->size - 1;

	/* Set Tx descriptors queue starting address - indirect access */
	thread = mvpp2_cpu_to_thread(port->priv, get_cpu());
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id);
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_DESC_ADDR_REG,
			   txq->descs_dma);
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_DESC_SIZE_REG,
			   txq->size & MVPP2_TXQ_DESC_SIZE_MASK);
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_INDEX_REG, 0);
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_RSVD_CLR_REG,
			   txq->id << MVPP2_TXQ_RSVD_CLR_OFFSET);
	val = mvpp2_thread_read(port->priv, thread, MVPP2_TXQ_PENDING_REG);
	val &= ~MVPP2_TXQ_PENDING_MASK;
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_PENDING_REG, val);

	/* Calculate base address in prefetch buffer. We reserve 16 descriptors
	 * for each existing TXQ.
	 * TCONTS for PON port must be continuous from 0 to MVPP2_MAX_TCONT
	 * GBE ports assumed to be continuous from 0 to MVPP2_MAX_PORTS
	 */
	desc_per_txq = 16;
	desc = (port->id * MVPP2_MAX_TXQ * desc_per_txq) +
	       (txq->log_id * desc_per_txq);

	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_PREF_BUF_REG,
			   MVPP2_PREF_BUF_PTR(desc) | MVPP2_PREF_BUF_SIZE_16 |
			   MVPP2_PREF_BUF_THRESH(desc_per_txq / 2));
	put_cpu();

	/* WRR / EJP configuration - indirect access */
	tx_port_num = mvpp2_egress_port(port);
	mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);

	val = mvpp2_read(port->priv, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id));
	val &= ~MVPP2_TXQ_REFILL_PERIOD_ALL_MASK;
	val |= MVPP2_TXQ_REFILL_PERIOD_MASK(1);
	val |= MVPP2_TXQ_REFILL_TOKENS_ALL_MASK;
	mvpp2_write(port->priv, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id), val);

	val = MVPP2_TXQ_TOKEN_SIZE_MAX;
	mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq->log_id),
		    val);

	for (thread = 0; thread < port->priv->nthreads; thread++) {
		txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
		txq_pcpu->size = txq->size;
		txq_pcpu->buffs = kmalloc_array(txq_pcpu->size,
						sizeof(*txq_pcpu->buffs),
						GFP_KERNEL);
		if (!txq_pcpu->buffs)
			return -ENOMEM;

		txq_pcpu->count = 0;
		txq_pcpu->reserved_num = 0;
		txq_pcpu->txq_put_index = 0;
		txq_pcpu->txq_get_index = 0;
		txq_pcpu->tso_headers = NULL;

		txq_pcpu->stop_threshold = txq->size - MVPP2_MAX_SKB_DESCS;
		txq_pcpu->wake_threshold = txq_pcpu->stop_threshold / 2;

		txq_pcpu->tso_headers =
			dma_alloc_coherent(port->dev->dev.parent,
					   txq_pcpu->size * TSO_HEADER_SIZE,
					   &txq_pcpu->tso_headers_dma,
					   GFP_KERNEL);
		if (!txq_pcpu->tso_headers)
			return -ENOMEM;
	}

	return 0;
}

/* Free allocated TXQ resources */
static void mvpp2_txq_deinit(struct mvpp2_port *port,
			     struct mvpp2_tx_queue *txq)
{
	struct mvpp2_txq_pcpu *txq_pcpu;
	unsigned int thread;

	for (thread = 0; thread < port->priv->nthreads; thread++) {
		txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
		kfree(txq_pcpu->buffs);

		if (txq_pcpu->tso_headers)
			dma_free_coherent(port->dev->dev.parent,
					  txq_pcpu->size * TSO_HEADER_SIZE,
					  txq_pcpu->tso_headers,
					  txq_pcpu->tso_headers_dma);

		txq_pcpu->tso_headers = NULL;
	}

	if (txq->descs)
		dma_free_coherent(port->dev->dev.parent,
				  txq->size * MVPP2_DESC_ALIGNED_SIZE,
				  txq->descs, txq->descs_dma);

	txq->descs             = NULL;
	txq->last_desc         = 0;
	txq->next_desc_to_proc = 0;
	txq->descs_dma         = 0;

	/* Set minimum bandwidth for disabled TXQs */
	mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->log_id), 0);

	/* Set Tx descriptors queue starting address and size */
	thread = mvpp2_cpu_to_thread(port->priv, get_cpu());
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id);
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_DESC_ADDR_REG, 0);
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_DESC_SIZE_REG, 0);
	put_cpu();
}

/* Cleanup Tx ports */
static void mvpp2_txq_clean(struct mvpp2_port *port, struct mvpp2_tx_queue *txq)
{
	struct mvpp2_txq_pcpu *txq_pcpu;
	int delay, pending;
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, get_cpu());
	u32 val;

	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id);
	val = mvpp2_thread_read(port->priv, thread, MVPP2_TXQ_PREF_BUF_REG);
	val |= MVPP2_TXQ_DRAIN_EN_MASK;
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_PREF_BUF_REG, val);

	/* The napi queue has been stopped so wait for all packets
	 * to be transmitted.
	 */
	delay = 0;
	do {
		if (delay >= MVPP2_TX_PENDING_TIMEOUT_MSEC) {
			netdev_warn(port->dev,
				    "port %d: cleaning queue %d timed out\n",
				    port->id, txq->log_id);
			break;
		}
		mdelay(1);
		delay++;

		pending = mvpp2_thread_read(port->priv, thread,
					    MVPP2_TXQ_PENDING_REG);
		pending &= MVPP2_TXQ_PENDING_MASK;
	} while (pending);

	val &= ~MVPP2_TXQ_DRAIN_EN_MASK;
	mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_PREF_BUF_REG, val);
	put_cpu();

	for (thread = 0; thread < port->priv->nthreads; thread++) {
		txq_pcpu = per_cpu_ptr(txq->pcpu, thread);

		/* Release all packets */
		mvpp2_txq_bufs_free(port, txq, txq_pcpu, txq_pcpu->count);

		/* Reset queue */
		txq_pcpu->count = 0;
		txq_pcpu->txq_put_index = 0;
		txq_pcpu->txq_get_index = 0;
	}
}

/* Cleanup all Tx queues */
static void mvpp2_cleanup_txqs(struct mvpp2_port *port)
{
	struct mvpp2_tx_queue *txq;
	int queue;
	u32 val;

	val = mvpp2_read(port->priv, MVPP2_TX_PORT_FLUSH_REG);

	/* Reset Tx ports and delete Tx queues */
	val |= MVPP2_TX_PORT_FLUSH_MASK(port->id);
	mvpp2_write(port->priv, MVPP2_TX_PORT_FLUSH_REG, val);

	for (queue = 0; queue < port->ntxqs; queue++) {
		txq = port->txqs[queue];
		mvpp2_txq_clean(port, txq);
		mvpp2_txq_deinit(port, txq);
	}

	on_each_cpu(mvpp2_txq_sent_counter_clear, port, 1);

	val &= ~MVPP2_TX_PORT_FLUSH_MASK(port->id);
	mvpp2_write(port->priv, MVPP2_TX_PORT_FLUSH_REG, val);
}

/* Cleanup all Rx queues */
static void mvpp2_cleanup_rxqs(struct mvpp2_port *port)
{
	int queue;

	for (queue = 0; queue < port->nrxqs; queue++)
		mvpp2_rxq_deinit(port, port->rxqs[queue]);

	if (port->tx_fc)
		mvpp2_rxq_disable_fc(port);
}

/* Init all Rx queues for port */
static int mvpp2_setup_rxqs(struct mvpp2_port *port)
{
	int queue, err;

	for (queue = 0; queue < port->nrxqs; queue++) {
		err = mvpp2_rxq_init(port, port->rxqs[queue]);
		if (err)
			goto err_cleanup;
	}

	if (port->tx_fc)
		mvpp2_rxq_enable_fc(port);

	return 0;

err_cleanup:
	mvpp2_cleanup_rxqs(port);
	return err;
}

/* Init all tx queues for port */
static int mvpp2_setup_txqs(struct mvpp2_port *port)
{
	struct mvpp2_tx_queue *txq;
	int queue, err;

	for (queue = 0; queue < port->ntxqs; queue++) {
		txq = port->txqs[queue];
		err = mvpp2_txq_init(port, txq);
		if (err)
			goto err_cleanup;

		/* Assign this queue to a CPU */
		if (queue < num_possible_cpus())
			netif_set_xps_queue(port->dev, cpumask_of(queue), queue);
	}

	if (port->has_tx_irqs) {
		mvpp2_tx_time_coal_set(port);
		for (queue = 0; queue < port->ntxqs; queue++) {
			txq = port->txqs[queue];
			mvpp2_tx_pkts_coal_set(port, txq);
		}
	}

	on_each_cpu(mvpp2_txq_sent_counter_clear, port, 1);
	return 0;

err_cleanup:
	mvpp2_cleanup_txqs(port);
	return err;
}

/* The callback for per-port interrupt */
static irqreturn_t mvpp2_isr(int irq, void *dev_id)
{
	struct mvpp2_queue_vector *qv = dev_id;

	mvpp2_qvec_interrupt_disable(qv);

	napi_schedule(&qv->napi);

	return IRQ_HANDLED;
}

static void mvpp2_isr_handle_ptp_queue(struct mvpp2_port *port, int nq)
{
	struct skb_shared_hwtstamps shhwtstamps;
	struct mvpp2_hwtstamp_queue *queue;
	struct sk_buff *skb;
	void __iomem *ptp_q;
	unsigned int id;
	u32 r0, r1, r2;

	ptp_q = port->priv->iface_base + MVPP22_PTP_BASE(port->gop_id);
	if (nq)
		ptp_q += MVPP22_PTP_TX_Q1_R0 - MVPP22_PTP_TX_Q0_R0;

	queue = &port->tx_hwtstamp_queue[nq];

	while (1) {
		r0 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R0) & 0xffff;
		if (!r0)
			break;

		r1 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R1) & 0xffff;
		r2 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R2) & 0xffff;

		id = (r0 >> 1) & 31;

		skb = queue->skb[id];
		queue->skb[id] = NULL;
		if (skb) {
			u32 ts = r2 << 19 | r1 << 3 | r0 >> 13;

			mvpp22_tai_tstamp(port->priv->tai, ts, &shhwtstamps);
			skb_tstamp_tx(skb, &shhwtstamps);
			dev_kfree_skb_any(skb);
		}
	}
}

static void mvpp2_isr_handle_ptp(struct mvpp2_port *port)
{
	void __iomem *ptp;
	u32 val;

	ptp = port->priv->iface_base + MVPP22_PTP_BASE(port->gop_id);
	val = readl(ptp + MVPP22_PTP_INT_CAUSE);
	if (val & MVPP22_PTP_INT_CAUSE_QUEUE0)
		mvpp2_isr_handle_ptp_queue(port, 0);
	if (val & MVPP22_PTP_INT_CAUSE_QUEUE1)
		mvpp2_isr_handle_ptp_queue(port, 1);
}

static void mvpp2_isr_handle_link(struct mvpp2_port *port, bool link)
{
	struct net_device *dev = port->dev;

	if (port->phylink) {
		phylink_mac_change(port->phylink, link);
		return;
	}

	if (!netif_running(dev))
		return;

	if (link) {
		mvpp2_interrupts_enable(port);

		mvpp2_egress_enable(port);
		mvpp2_ingress_enable(port);
		netif_carrier_on(dev);
		netif_tx_wake_all_queues(dev);
	} else {
		netif_tx_stop_all_queues(dev);
		netif_carrier_off(dev);
		mvpp2_ingress_disable(port);
		mvpp2_egress_disable(port);

		mvpp2_interrupts_disable(port);
	}
}

static void mvpp2_isr_handle_xlg(struct mvpp2_port *port)
{
	bool link;
	u32 val;

	val = readl(port->base + MVPP22_XLG_INT_STAT);
	if (val & MVPP22_XLG_INT_STAT_LINK) {
		val = readl(port->base + MVPP22_XLG_STATUS);
		link = (val & MVPP22_XLG_STATUS_LINK_UP);
		mvpp2_isr_handle_link(port, link);
	}
}

static void mvpp2_isr_handle_gmac_internal(struct mvpp2_port *port)
{
	bool link;
	u32 val;

	if (phy_interface_mode_is_rgmii(port->phy_interface) ||
	    phy_interface_mode_is_8023z(port->phy_interface) ||
	    port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
		val = readl(port->base + MVPP22_GMAC_INT_STAT);
		if (val & MVPP22_GMAC_INT_STAT_LINK) {
			val = readl(port->base + MVPP2_GMAC_STATUS0);
			link = (val & MVPP2_GMAC_STATUS0_LINK_UP);
			mvpp2_isr_handle_link(port, link);
		}
	}
}

/* Per-port interrupt for link status changes */
static irqreturn_t mvpp2_port_isr(int irq, void *dev_id)
{
	struct mvpp2_port *port = (struct mvpp2_port *)dev_id;
	u32 val;

	mvpp22_gop_mask_irq(port);

	if (mvpp2_port_supports_xlg(port) &&
	    mvpp2_is_xlg(port->phy_interface)) {
		/* Check the external status register */
		val = readl(port->base + MVPP22_XLG_EXT_INT_STAT);
		if (val & MVPP22_XLG_EXT_INT_STAT_XLG)
			mvpp2_isr_handle_xlg(port);
		if (val & MVPP22_XLG_EXT_INT_STAT_PTP)
			mvpp2_isr_handle_ptp(port);
	} else {
		/* If it's not the XLG, we must be using the GMAC.
		 * Check the summary status.
		 */
		val = readl(port->base + MVPP22_GMAC_INT_SUM_STAT);
		if (val & MVPP22_GMAC_INT_SUM_STAT_INTERNAL)
			mvpp2_isr_handle_gmac_internal(port);
		if (val & MVPP22_GMAC_INT_SUM_STAT_PTP)
			mvpp2_isr_handle_ptp(port);
	}

	mvpp22_gop_unmask_irq(port);
	return IRQ_HANDLED;
}

static enum hrtimer_restart mvpp2_hr_timer_cb(struct hrtimer *timer)
{
	struct net_device *dev;
	struct mvpp2_port *port;
	struct mvpp2_port_pcpu *port_pcpu;
	unsigned int tx_todo, cause;

	port_pcpu = container_of(timer, struct mvpp2_port_pcpu, tx_done_timer);
	dev = port_pcpu->dev;

	if (!netif_running(dev))
		return HRTIMER_NORESTART;

	port_pcpu->timer_scheduled = false;
	port = netdev_priv(dev);

	/* Process all the Tx queues */
	cause = (1 << port->ntxqs) - 1;
	tx_todo = mvpp2_tx_done(port, cause,
				mvpp2_cpu_to_thread(port->priv, smp_processor_id()));

	/* Set the timer in case not all the packets were processed */
	if (tx_todo && !port_pcpu->timer_scheduled) {
		port_pcpu->timer_scheduled = true;
		hrtimer_forward_now(&port_pcpu->tx_done_timer,
				    MVPP2_TXDONE_HRTIMER_PERIOD_NS);

		return HRTIMER_RESTART;
	}
	return HRTIMER_NORESTART;
}

/* Main RX/TX processing routines */

/* Display more error info */
static void mvpp2_rx_error(struct mvpp2_port *port,
			   struct mvpp2_rx_desc *rx_desc)
{
	u32 status = mvpp2_rxdesc_status_get(port, rx_desc);
	size_t sz = mvpp2_rxdesc_size_get(port, rx_desc);
	char *err_str = NULL;

	switch (status & MVPP2_RXD_ERR_CODE_MASK) {
	case MVPP2_RXD_ERR_CRC:
		err_str = "crc";
		break;
	case MVPP2_RXD_ERR_OVERRUN:
		err_str = "overrun";
		break;
	case MVPP2_RXD_ERR_RESOURCE:
		err_str = "resource";
		break;
	}
	if (err_str && net_ratelimit())
		netdev_err(port->dev,
			   "bad rx status %08x (%s error), size=%zu\n",
			   status, err_str, sz);
}

/* Handle RX checksum offload */
static int mvpp2_rx_csum(struct mvpp2_port *port, u32 status)
{
	if (((status & MVPP2_RXD_L3_IP4) &&
	     !(status & MVPP2_RXD_IP4_HEADER_ERR)) ||
	    (status & MVPP2_RXD_L3_IP6))
		if (((status & MVPP2_RXD_L4_UDP) ||
		     (status & MVPP2_RXD_L4_TCP)) &&
		     (status & MVPP2_RXD_L4_CSUM_OK))
			return CHECKSUM_UNNECESSARY;

	return CHECKSUM_NONE;
}

/* Allocate a new skb and add it to BM pool */
static int mvpp2_rx_refill(struct mvpp2_port *port,
			   struct mvpp2_bm_pool *bm_pool,
			   struct page_pool *page_pool, int pool)
{
	dma_addr_t dma_addr;
	phys_addr_t phys_addr;
	void *buf;

	buf = mvpp2_buf_alloc(port, bm_pool, page_pool,
			      &dma_addr, &phys_addr, GFP_ATOMIC);
	if (!buf)
		return -ENOMEM;

	mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);

	return 0;
}

/* Handle tx checksum */
static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
{
	if (skb->ip_summed == CHECKSUM_PARTIAL) {
		int ip_hdr_len = 0;
		u8 l4_proto;
		__be16 l3_proto = vlan_get_protocol(skb);

		if (l3_proto == htons(ETH_P_IP)) {
			struct iphdr *ip4h = ip_hdr(skb);

			/* Calculate IPv4 checksum and L4 checksum */
			ip_hdr_len = ip4h->ihl;
			l4_proto = ip4h->protocol;
		} else if (l3_proto == htons(ETH_P_IPV6)) {
			struct ipv6hdr *ip6h = ipv6_hdr(skb);

			/* Read l4_protocol from one of IPv6 extra headers */
			if (skb_network_header_len(skb) > 0)
				ip_hdr_len = (skb_network_header_len(skb) >> 2);
			l4_proto = ip6h->nexthdr;
		} else {
			return MVPP2_TXD_L4_CSUM_NOT;
		}

		return mvpp2_txq_desc_csum(skb_network_offset(skb),
					   l3_proto, ip_hdr_len, l4_proto);
	}

	return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE;
}

static void mvpp2_xdp_finish_tx(struct mvpp2_port *port, u16 txq_id, int nxmit, int nxmit_byte)
{
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());
	struct mvpp2_tx_queue *aggr_txq;
	struct mvpp2_txq_pcpu *txq_pcpu;
	struct mvpp2_tx_queue *txq;
	struct netdev_queue *nq;

	txq = port->txqs[txq_id];
	txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
	nq = netdev_get_tx_queue(port->dev, txq_id);
	aggr_txq = &port->priv->aggr_txqs[thread];

	txq_pcpu->reserved_num -= nxmit;
	txq_pcpu->count += nxmit;
	aggr_txq->count += nxmit;

	/* Enable transmit */
	wmb();
	mvpp2_aggr_txq_pend_desc_add(port, nxmit);

	if (txq_pcpu->count >= txq_pcpu->stop_threshold)
		netif_tx_stop_queue(nq);

	/* Finalize TX processing */
	if (!port->has_tx_irqs && txq_pcpu->count >= txq->done_pkts_coal)
		mvpp2_txq_done(port, txq, txq_pcpu);
}

static int
mvpp2_xdp_submit_frame(struct mvpp2_port *port, u16 txq_id,
		       struct xdp_frame *xdpf, bool dma_map)
{
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());
	u32 tx_cmd = MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE |
		     MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC;
	enum mvpp2_tx_buf_type buf_type;
	struct mvpp2_txq_pcpu *txq_pcpu;
	struct mvpp2_tx_queue *aggr_txq;
	struct mvpp2_tx_desc *tx_desc;
	struct mvpp2_tx_queue *txq;
	int ret = MVPP2_XDP_TX;
	dma_addr_t dma_addr;

	txq = port->txqs[txq_id];
	txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
	aggr_txq = &port->priv->aggr_txqs[thread];

	/* Check number of available descriptors */
	if (mvpp2_aggr_desc_num_check(port, aggr_txq, 1) ||
	    mvpp2_txq_reserved_desc_num_proc(port, txq, txq_pcpu, 1)) {
		ret = MVPP2_XDP_DROPPED;
		goto out;
	}

	/* Get a descriptor for the first part of the packet */
	tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
	mvpp2_txdesc_txq_set(port, tx_desc, txq->id);
	mvpp2_txdesc_size_set(port, tx_desc, xdpf->len);

	if (dma_map) {
		/* XDP_REDIRECT or AF_XDP */
		dma_addr = dma_map_single(port->dev->dev.parent, xdpf->data,
					  xdpf->len, DMA_TO_DEVICE);

		if (unlikely(dma_mapping_error(port->dev->dev.parent, dma_addr))) {
			mvpp2_txq_desc_put(txq);
			ret = MVPP2_XDP_DROPPED;
			goto out;
		}

		buf_type = MVPP2_TYPE_XDP_NDO;
	} else {
		/* XDP_TX */
		struct page *page = virt_to_page(xdpf->data);

		dma_addr = page_pool_get_dma_addr(page) +
			   sizeof(*xdpf) + xdpf->headroom;
		dma_sync_single_for_device(port->dev->dev.parent, dma_addr,
					   xdpf->len, DMA_BIDIRECTIONAL);

		buf_type = MVPP2_TYPE_XDP_TX;
	}

	mvpp2_txdesc_dma_addr_set(port, tx_desc, dma_addr);

	mvpp2_txdesc_cmd_set(port, tx_desc, tx_cmd);
	mvpp2_txq_inc_put(port, txq_pcpu, xdpf, tx_desc, buf_type);

out:
	return ret;
}

static int
mvpp2_xdp_xmit_back(struct mvpp2_port *port, struct xdp_buff *xdp)
{
	struct mvpp2_pcpu_stats *stats = this_cpu_ptr(port->stats);
	struct xdp_frame *xdpf;
	u16 txq_id;
	int ret;

	xdpf = xdp_convert_buff_to_frame(xdp);
	if (unlikely(!xdpf))
		return MVPP2_XDP_DROPPED;

	/* The first of the TX queues are used for XPS,
	 * the second half for XDP_TX
	 */
	txq_id = mvpp2_cpu_to_thread(port->priv, smp_processor_id()) + (port->ntxqs / 2);

	ret = mvpp2_xdp_submit_frame(port, txq_id, xdpf, false);
	if (ret == MVPP2_XDP_TX) {
		u64_stats_update_begin(&stats->syncp);
		stats->tx_bytes += xdpf->len;
		stats->tx_packets++;
		stats->xdp_tx++;
		u64_stats_update_end(&stats->syncp);

		mvpp2_xdp_finish_tx(port, txq_id, 1, xdpf->len);
	} else {
		u64_stats_update_begin(&stats->syncp);
		stats->xdp_tx_err++;
		u64_stats_update_end(&stats->syncp);
	}

	return ret;
}

static int
mvpp2_xdp_xmit(struct net_device *dev, int num_frame,
	       struct xdp_frame **frames, u32 flags)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int i, nxmit_byte = 0, nxmit = 0;
	struct mvpp2_pcpu_stats *stats;
	u16 txq_id;
	u32 ret;

	if (unlikely(test_bit(0, &port->state)))
		return -ENETDOWN;

	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
		return -EINVAL;

	/* The first of the TX queues are used for XPS,
	 * the second half for XDP_TX
	 */
	txq_id = mvpp2_cpu_to_thread(port->priv, smp_processor_id()) + (port->ntxqs / 2);

	for (i = 0; i < num_frame; i++) {
		ret = mvpp2_xdp_submit_frame(port, txq_id, frames[i], true);
		if (ret != MVPP2_XDP_TX)
			break;

		nxmit_byte += frames[i]->len;
		nxmit++;
	}

	if (likely(nxmit > 0))
		mvpp2_xdp_finish_tx(port, txq_id, nxmit, nxmit_byte);

	stats = this_cpu_ptr(port->stats);
	u64_stats_update_begin(&stats->syncp);
	stats->tx_bytes += nxmit_byte;
	stats->tx_packets += nxmit;
	stats->xdp_xmit += nxmit;
	stats->xdp_xmit_err += num_frame - nxmit;
	u64_stats_update_end(&stats->syncp);

	return nxmit;
}

static int
mvpp2_run_xdp(struct mvpp2_port *port, struct bpf_prog *prog,
	      struct xdp_buff *xdp, struct page_pool *pp,
	      struct mvpp2_pcpu_stats *stats)
{
	unsigned int len, sync, err;
	struct page *page;
	u32 ret, act;

	len = xdp->data_end - xdp->data_hard_start - MVPP2_SKB_HEADROOM;
	act = bpf_prog_run_xdp(prog, xdp);

	/* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
	sync = xdp->data_end - xdp->data_hard_start - MVPP2_SKB_HEADROOM;
	sync = max(sync, len);

	switch (act) {
	case XDP_PASS:
		stats->xdp_pass++;
		ret = MVPP2_XDP_PASS;
		break;
	case XDP_REDIRECT:
		err = xdp_do_redirect(port->dev, xdp, prog);
		if (unlikely(err)) {
			ret = MVPP2_XDP_DROPPED;
			page = virt_to_head_page(xdp->data);
			page_pool_put_page(pp, page, sync, true);
		} else {
			ret = MVPP2_XDP_REDIR;
			stats->xdp_redirect++;
		}
		break;
	case XDP_TX:
		ret = mvpp2_xdp_xmit_back(port, xdp);
		if (ret != MVPP2_XDP_TX) {
			page = virt_to_head_page(xdp->data);
			page_pool_put_page(pp, page, sync, true);
		}
		break;
	default:
		bpf_warn_invalid_xdp_action(act);
		fallthrough;
	case XDP_ABORTED:
		trace_xdp_exception(port->dev, prog, act);
		fallthrough;
	case XDP_DROP:
		page = virt_to_head_page(xdp->data);
		page_pool_put_page(pp, page, sync, true);
		ret = MVPP2_XDP_DROPPED;
		stats->xdp_drop++;
		break;
	}

	return ret;
}

static void mvpp2_buff_hdr_pool_put(struct mvpp2_port *port, struct mvpp2_rx_desc *rx_desc,
				    int pool, u32 rx_status)
{
	phys_addr_t phys_addr, phys_addr_next;
	dma_addr_t dma_addr, dma_addr_next;
	struct mvpp2_buff_hdr *buff_hdr;

	phys_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
	dma_addr = mvpp2_rxdesc_cookie_get(port, rx_desc);

	do {
		buff_hdr = (struct mvpp2_buff_hdr *)phys_to_virt(phys_addr);

		phys_addr_next = le32_to_cpu(buff_hdr->next_phys_addr);
		dma_addr_next = le32_to_cpu(buff_hdr->next_dma_addr);

		if (port->priv->hw_version >= MVPP22) {
			phys_addr_next |= ((u64)buff_hdr->next_phys_addr_high << 32);
			dma_addr_next |= ((u64)buff_hdr->next_dma_addr_high << 32);
		}

		mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);

		phys_addr = phys_addr_next;
		dma_addr = dma_addr_next;

	} while (!MVPP2_B_HDR_INFO_IS_LAST(le16_to_cpu(buff_hdr->info)));
}

/* Main rx processing */
static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
		    int rx_todo, struct mvpp2_rx_queue *rxq)
{
	struct net_device *dev = port->dev;
	struct mvpp2_pcpu_stats ps = {};
	enum dma_data_direction dma_dir;
	struct bpf_prog *xdp_prog;
	struct xdp_buff xdp;
	int rx_received;
	int rx_done = 0;
	u32 xdp_ret = 0;

	xdp_prog = READ_ONCE(port->xdp_prog);

	/* Get number of received packets and clamp the to-do */
	rx_received = mvpp2_rxq_received(port, rxq->id);
	if (rx_todo > rx_received)
		rx_todo = rx_received;

	while (rx_done < rx_todo) {
		struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
		struct mvpp2_bm_pool *bm_pool;
		struct page_pool *pp = NULL;
		struct sk_buff *skb;
		unsigned int frag_size;
		dma_addr_t dma_addr;
		phys_addr_t phys_addr;
		u32 rx_status, timestamp;
		int pool, rx_bytes, err, ret;
		struct page *page;
		void *data;

		phys_addr = mvpp2_rxdesc_cookie_get(port, rx_desc);
		data = (void *)phys_to_virt(phys_addr);
		page = virt_to_page(data);
		prefetch(page);

		rx_done++;
		rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
		rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
		rx_bytes -= MVPP2_MH_SIZE;
		dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);

		pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
			MVPP2_RXD_BM_POOL_ID_OFFS;
		bm_pool = &port->priv->bm_pools[pool];

		if (port->priv->percpu_pools) {
			pp = port->priv->page_pool[pool];
			dma_dir = page_pool_get_dma_dir(pp);
		} else {
			dma_dir = DMA_FROM_DEVICE;
		}

		dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
					rx_bytes + MVPP2_MH_SIZE,
					dma_dir);

		/* Buffer header not supported */
		if (rx_status & MVPP2_RXD_BUF_HDR)
			goto err_drop_frame;

		/* In case of an error, release the requested buffer pointer
		 * to the Buffer Manager. This request process is controlled
		 * by the hardware, and the information about the buffer is
		 * comprised by the RX descriptor.
		 */
		if (rx_status & MVPP2_RXD_ERR_SUMMARY)
			goto err_drop_frame;

		/* Prefetch header */
		prefetch(data + MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);

		if (bm_pool->frag_size > PAGE_SIZE)
			frag_size = 0;
		else
			frag_size = bm_pool->frag_size;

		if (xdp_prog) {
			struct xdp_rxq_info *xdp_rxq;

			if (bm_pool->pkt_size == MVPP2_BM_SHORT_PKT_SIZE)
				xdp_rxq = &rxq->xdp_rxq_short;
			else
				xdp_rxq = &rxq->xdp_rxq_long;

			xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
			xdp_prepare_buff(&xdp, data,
					 MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
					 rx_bytes, false);

			ret = mvpp2_run_xdp(port, xdp_prog, &xdp, pp, &ps);

			if (ret) {
				xdp_ret |= ret;
				err = mvpp2_rx_refill(port, bm_pool, pp, pool);
				if (err) {
					netdev_err(port->dev, "failed to refill BM pools\n");
					goto err_drop_frame;
				}

				ps.rx_packets++;
				ps.rx_bytes += rx_bytes;
				continue;
			}
		}

		skb = build_skb(data, frag_size);
		if (!skb) {
			netdev_warn(port->dev, "skb build failed\n");
			goto err_drop_frame;
		}

		/* If we have RX hardware timestamping enabled, grab the
		 * timestamp from the queue and convert.
		 */
		if (mvpp22_rx_hwtstamping(port)) {
			timestamp = le32_to_cpu(rx_desc->pp22.timestamp);
			mvpp22_tai_tstamp(port->priv->tai, timestamp,
					 skb_hwtstamps(skb));
		}

		err = mvpp2_rx_refill(port, bm_pool, pp, pool);
		if (err) {
			netdev_err(port->dev, "failed to refill BM pools\n");
			dev_kfree_skb_any(skb);
			goto err_drop_frame;
		}

		if (pp)
			skb_mark_for_recycle(skb);
		else
			dma_unmap_single_attrs(dev->dev.parent, dma_addr,
					       bm_pool->buf_size, DMA_FROM_DEVICE,
					       DMA_ATTR_SKIP_CPU_SYNC);

		ps.rx_packets++;
		ps.rx_bytes += rx_bytes;

		skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
		skb_put(skb, rx_bytes);
		skb->ip_summed = mvpp2_rx_csum(port, rx_status);
		skb->protocol = eth_type_trans(skb, dev);

		napi_gro_receive(napi, skb);
		continue;

err_drop_frame:
		dev->stats.rx_errors++;
		mvpp2_rx_error(port, rx_desc);
		/* Return the buffer to the pool */
		if (rx_status & MVPP2_RXD_BUF_HDR)
			mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
		else
			mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
	}

	if (xdp_ret & MVPP2_XDP_REDIR)
		xdp_do_flush_map();

	if (ps.rx_packets) {
		struct mvpp2_pcpu_stats *stats = this_cpu_ptr(port->stats);

		u64_stats_update_begin(&stats->syncp);
		stats->rx_packets += ps.rx_packets;
		stats->rx_bytes   += ps.rx_bytes;
		/* xdp */
		stats->xdp_redirect += ps.xdp_redirect;
		stats->xdp_pass += ps.xdp_pass;
		stats->xdp_drop += ps.xdp_drop;
		u64_stats_update_end(&stats->syncp);
	}

	/* Update Rx queue management counters */
	wmb();
	mvpp2_rxq_status_update(port, rxq->id, rx_done, rx_done);

	return rx_todo;
}

static inline void
tx_desc_unmap_put(struct mvpp2_port *port, struct mvpp2_tx_queue *txq,
		  struct mvpp2_tx_desc *desc)
{
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());
	struct mvpp2_txq_pcpu *txq_pcpu = per_cpu_ptr(txq->pcpu, thread);

	dma_addr_t buf_dma_addr =
		mvpp2_txdesc_dma_addr_get(port, desc);
	size_t buf_sz =
		mvpp2_txdesc_size_get(port, desc);
	if (!IS_TSO_HEADER(txq_pcpu, buf_dma_addr))
		dma_unmap_single(port->dev->dev.parent, buf_dma_addr,
				 buf_sz, DMA_TO_DEVICE);
	mvpp2_txq_desc_put(txq);
}

static void mvpp2_txdesc_clear_ptp(struct mvpp2_port *port,
				   struct mvpp2_tx_desc *desc)
{
	/* We only need to clear the low bits */
	if (port->priv->hw_version >= MVPP22)
		desc->pp22.ptp_descriptor &=
			cpu_to_le32(~MVPP22_PTP_DESC_MASK_LOW);
}

static bool mvpp2_tx_hw_tstamp(struct mvpp2_port *port,
			       struct mvpp2_tx_desc *tx_desc,
			       struct sk_buff *skb)
{
	struct mvpp2_hwtstamp_queue *queue;
	unsigned int mtype, type, i;
	struct ptp_header *hdr;
	u64 ptpdesc;

	if (port->priv->hw_version == MVPP21 ||
	    port->tx_hwtstamp_type == HWTSTAMP_TX_OFF)
		return false;

	type = ptp_classify_raw(skb);
	if (!type)
		return false;

	hdr = ptp_parse_header(skb, type);
	if (!hdr)
		return false;

	skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;

	ptpdesc = MVPP22_PTP_MACTIMESTAMPINGEN |
		  MVPP22_PTP_ACTION_CAPTURE;
	queue = &port->tx_hwtstamp_queue[0];

	switch (type & PTP_CLASS_VMASK) {
	case PTP_CLASS_V1:
		ptpdesc |= MVPP22_PTP_PACKETFORMAT(MVPP22_PTP_PKT_FMT_PTPV1);
		break;

	case PTP_CLASS_V2:
		ptpdesc |= MVPP22_PTP_PACKETFORMAT(MVPP22_PTP_PKT_FMT_PTPV2);
		mtype = hdr->tsmt & 15;
		/* Direct PTP Sync messages to queue 1 */
		if (mtype == 0) {
			ptpdesc |= MVPP22_PTP_TIMESTAMPQUEUESELECT;
			queue = &port->tx_hwtstamp_queue[1];
		}
		break;
	}

	/* Take a reference on the skb and insert into our queue */
	i = queue->next;
	queue->next = (i + 1) & 31;
	if (queue->skb[i])
		dev_kfree_skb_any(queue->skb[i]);
	queue->skb[i] = skb_get(skb);

	ptpdesc |= MVPP22_PTP_TIMESTAMPENTRYID(i);

	/*
	 * 3:0		- PTPAction
	 * 6:4		- PTPPacketFormat
	 * 7		- PTP_CF_WraparoundCheckEn
	 * 9:8		- IngressTimestampSeconds[1:0]
	 * 10		- Reserved
	 * 11		- MACTimestampingEn
	 * 17:12	- PTP_TimestampQueueEntryID[5:0]
	 * 18		- PTPTimestampQueueSelect
	 * 19		- UDPChecksumUpdateEn
	 * 27:20	- TimestampOffset
	 *			PTP, NTPTransmit, OWAMP/TWAMP - L3 to PTP header
	 *			NTPTs, Y.1731 - L3 to timestamp entry
	 * 35:28	- UDP Checksum Offset
	 *
	 * stored in tx descriptor bits 75:64 (11:0) and 191:168 (35:12)
	 */
	tx_desc->pp22.ptp_descriptor &=
		cpu_to_le32(~MVPP22_PTP_DESC_MASK_LOW);
	tx_desc->pp22.ptp_descriptor |=
		cpu_to_le32(ptpdesc & MVPP22_PTP_DESC_MASK_LOW);
	tx_desc->pp22.buf_dma_addr_ptp &= cpu_to_le64(~0xffffff0000000000ULL);
	tx_desc->pp22.buf_dma_addr_ptp |= cpu_to_le64((ptpdesc >> 12) << 40);

	return true;
}

/* Handle tx fragmentation processing */
static int mvpp2_tx_frag_process(struct mvpp2_port *port, struct sk_buff *skb,
				 struct mvpp2_tx_queue *aggr_txq,
				 struct mvpp2_tx_queue *txq)
{
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());
	struct mvpp2_txq_pcpu *txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
	struct mvpp2_tx_desc *tx_desc;
	int i;
	dma_addr_t buf_dma_addr;

	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
		void *addr = skb_frag_address(frag);

		tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
		mvpp2_txdesc_clear_ptp(port, tx_desc);
		mvpp2_txdesc_txq_set(port, tx_desc, txq->id);
		mvpp2_txdesc_size_set(port, tx_desc, skb_frag_size(frag));

		buf_dma_addr = dma_map_single(port->dev->dev.parent, addr,
					      skb_frag_size(frag),
					      DMA_TO_DEVICE);
		if (dma_mapping_error(port->dev->dev.parent, buf_dma_addr)) {
			mvpp2_txq_desc_put(txq);
			goto cleanup;
		}

		mvpp2_txdesc_dma_addr_set(port, tx_desc, buf_dma_addr);

		if (i == (skb_shinfo(skb)->nr_frags - 1)) {
			/* Last descriptor */
			mvpp2_txdesc_cmd_set(port, tx_desc,
					     MVPP2_TXD_L_DESC);
			mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc, MVPP2_TYPE_SKB);
		} else {
			/* Descriptor in the middle: Not First, Not Last */
			mvpp2_txdesc_cmd_set(port, tx_desc, 0);
			mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);
		}
	}

	return 0;
cleanup:
	/* Release all descriptors that were used to map fragments of
	 * this packet, as well as the corresponding DMA mappings
	 */
	for (i = i - 1; i >= 0; i--) {
		tx_desc = txq->descs + i;
		tx_desc_unmap_put(port, txq, tx_desc);
	}

	return -ENOMEM;
}

static inline void mvpp2_tso_put_hdr(struct sk_buff *skb,
				     struct net_device *dev,
				     struct mvpp2_tx_queue *txq,
				     struct mvpp2_tx_queue *aggr_txq,
				     struct mvpp2_txq_pcpu *txq_pcpu,
				     int hdr_sz)
{
	struct mvpp2_port *port = netdev_priv(dev);
	struct mvpp2_tx_desc *tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
	dma_addr_t addr;

	mvpp2_txdesc_clear_ptp(port, tx_desc);
	mvpp2_txdesc_txq_set(port, tx_desc, txq->id);
	mvpp2_txdesc_size_set(port, tx_desc, hdr_sz);

	addr = txq_pcpu->tso_headers_dma +
	       txq_pcpu->txq_put_index * TSO_HEADER_SIZE;
	mvpp2_txdesc_dma_addr_set(port, tx_desc, addr);

	mvpp2_txdesc_cmd_set(port, tx_desc, mvpp2_skb_tx_csum(port, skb) |
					    MVPP2_TXD_F_DESC |
					    MVPP2_TXD_PADDING_DISABLE);
	mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);
}

static inline int mvpp2_tso_put_data(struct sk_buff *skb,
				     struct net_device *dev, struct tso_t *tso,
				     struct mvpp2_tx_queue *txq,
				     struct mvpp2_tx_queue *aggr_txq,
				     struct mvpp2_txq_pcpu *txq_pcpu,
				     int sz, bool left, bool last)
{
	struct mvpp2_port *port = netdev_priv(dev);
	struct mvpp2_tx_desc *tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
	dma_addr_t buf_dma_addr;

	mvpp2_txdesc_clear_ptp(port, tx_desc);
	mvpp2_txdesc_txq_set(port, tx_desc, txq->id);
	mvpp2_txdesc_size_set(port, tx_desc, sz);

	buf_dma_addr = dma_map_single(dev->dev.parent, tso->data, sz,
				      DMA_TO_DEVICE);
	if (unlikely(dma_mapping_error(dev->dev.parent, buf_dma_addr))) {
		mvpp2_txq_desc_put(txq);
		return -ENOMEM;
	}

	mvpp2_txdesc_dma_addr_set(port, tx_desc, buf_dma_addr);

	if (!left) {
		mvpp2_txdesc_cmd_set(port, tx_desc, MVPP2_TXD_L_DESC);
		if (last) {
			mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc, MVPP2_TYPE_SKB);
			return 0;
		}
	} else {
		mvpp2_txdesc_cmd_set(port, tx_desc, 0);
	}

	mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);
	return 0;
}

static int mvpp2_tx_tso(struct sk_buff *skb, struct net_device *dev,
			struct mvpp2_tx_queue *txq,
			struct mvpp2_tx_queue *aggr_txq,
			struct mvpp2_txq_pcpu *txq_pcpu)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int hdr_sz, i, len, descs = 0;
	struct tso_t tso;

	/* Check number of available descriptors */
	if (mvpp2_aggr_desc_num_check(port, aggr_txq, tso_count_descs(skb)) ||
	    mvpp2_txq_reserved_desc_num_proc(port, txq, txq_pcpu,
					     tso_count_descs(skb)))
		return 0;

	hdr_sz = tso_start(skb, &tso);

	len = skb->len - hdr_sz;
	while (len > 0) {
		int left = min_t(int, skb_shinfo(skb)->gso_size, len);
		char *hdr = txq_pcpu->tso_headers +
			    txq_pcpu->txq_put_index * TSO_HEADER_SIZE;

		len -= left;
		descs++;

		tso_build_hdr(skb, hdr, &tso, left, len == 0);
		mvpp2_tso_put_hdr(skb, dev, txq, aggr_txq, txq_pcpu, hdr_sz);

		while (left > 0) {
			int sz = min_t(int, tso.size, left);
			left -= sz;
			descs++;

			if (mvpp2_tso_put_data(skb, dev, &tso, txq, aggr_txq,
					       txq_pcpu, sz, left, len == 0))
				goto release;
			tso_build_data(skb, &tso, sz);
		}
	}

	return descs;

release:
	for (i = descs - 1; i >= 0; i--) {
		struct mvpp2_tx_desc *tx_desc = txq->descs + i;
		tx_desc_unmap_put(port, txq, tx_desc);
	}
	return 0;
}

/* Main tx processing */
static netdev_tx_t mvpp2_tx(struct sk_buff *skb, struct net_device *dev)
{
	struct mvpp2_port *port = netdev_priv(dev);
	struct mvpp2_tx_queue *txq, *aggr_txq;
	struct mvpp2_txq_pcpu *txq_pcpu;
	struct mvpp2_tx_desc *tx_desc;
	dma_addr_t buf_dma_addr;
	unsigned long flags = 0;
	unsigned int thread;
	int frags = 0;
	u16 txq_id;
	u32 tx_cmd;

	thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());

	txq_id = skb_get_queue_mapping(skb);
	txq = port->txqs[txq_id];
	txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
	aggr_txq = &port->priv->aggr_txqs[thread];

	if (test_bit(thread, &port->priv->lock_map))
		spin_lock_irqsave(&port->tx_lock[thread], flags);

	if (skb_is_gso(skb)) {
		frags = mvpp2_tx_tso(skb, dev, txq, aggr_txq, txq_pcpu);
		goto out;
	}
	frags = skb_shinfo(skb)->nr_frags + 1;

	/* Check number of available descriptors */
	if (mvpp2_aggr_desc_num_check(port, aggr_txq, frags) ||
	    mvpp2_txq_reserved_desc_num_proc(port, txq, txq_pcpu, frags)) {
		frags = 0;
		goto out;
	}

	/* Get a descriptor for the first part of the packet */
	tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
	if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) ||
	    !mvpp2_tx_hw_tstamp(port, tx_desc, skb))
		mvpp2_txdesc_clear_ptp(port, tx_desc);
	mvpp2_txdesc_txq_set(port, tx_desc, txq->id);
	mvpp2_txdesc_size_set(port, tx_desc, skb_headlen(skb));

	buf_dma_addr = dma_map_single(dev->dev.parent, skb->data,
				      skb_headlen(skb), DMA_TO_DEVICE);
	if (unlikely(dma_mapping_error(dev->dev.parent, buf_dma_addr))) {
		mvpp2_txq_desc_put(txq);
		frags = 0;
		goto out;
	}

	mvpp2_txdesc_dma_addr_set(port, tx_desc, buf_dma_addr);

	tx_cmd = mvpp2_skb_tx_csum(port, skb);

	if (frags == 1) {
		/* First and Last descriptor */
		tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC;
		mvpp2_txdesc_cmd_set(port, tx_desc, tx_cmd);
		mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc, MVPP2_TYPE_SKB);
	} else {
		/* First but not Last */
		tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_PADDING_DISABLE;
		mvpp2_txdesc_cmd_set(port, tx_desc, tx_cmd);
		mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);

		/* Continue with other skb fragments */
		if (mvpp2_tx_frag_process(port, skb, aggr_txq, txq)) {
			tx_desc_unmap_put(port, txq, tx_desc);
			frags = 0;
		}
	}

out:
	if (frags > 0) {
		struct mvpp2_pcpu_stats *stats = per_cpu_ptr(port->stats, thread);
		struct netdev_queue *nq = netdev_get_tx_queue(dev, txq_id);

		txq_pcpu->reserved_num -= frags;
		txq_pcpu->count += frags;
		aggr_txq->count += frags;

		/* Enable transmit */
		wmb();
		mvpp2_aggr_txq_pend_desc_add(port, frags);

		if (txq_pcpu->count >= txq_pcpu->stop_threshold)
			netif_tx_stop_queue(nq);

		u64_stats_update_begin(&stats->syncp);
		stats->tx_packets++;
		stats->tx_bytes += skb->len;
		u64_stats_update_end(&stats->syncp);
	} else {
		dev->stats.tx_dropped++;
		dev_kfree_skb_any(skb);
	}

	/* Finalize TX processing */
	if (!port->has_tx_irqs && txq_pcpu->count >= txq->done_pkts_coal)
		mvpp2_txq_done(port, txq, txq_pcpu);

	/* Set the timer in case not all frags were processed */
	if (!port->has_tx_irqs && txq_pcpu->count <= frags &&
	    txq_pcpu->count > 0) {
		struct mvpp2_port_pcpu *port_pcpu = per_cpu_ptr(port->pcpu, thread);

		if (!port_pcpu->timer_scheduled) {
			port_pcpu->timer_scheduled = true;
			hrtimer_start(&port_pcpu->tx_done_timer,
				      MVPP2_TXDONE_HRTIMER_PERIOD_NS,
				      HRTIMER_MODE_REL_PINNED_SOFT);
		}
	}

	if (test_bit(thread, &port->priv->lock_map))
		spin_unlock_irqrestore(&port->tx_lock[thread], flags);

	return NETDEV_TX_OK;
}

static inline void mvpp2_cause_error(struct net_device *dev, int cause)
{
	if (cause & MVPP2_CAUSE_FCS_ERR_MASK)
		netdev_err(dev, "FCS error\n");
	if (cause & MVPP2_CAUSE_RX_FIFO_OVERRUN_MASK)
		netdev_err(dev, "rx fifo overrun error\n");
	if (cause & MVPP2_CAUSE_TX_FIFO_UNDERRUN_MASK)
		netdev_err(dev, "tx fifo underrun error\n");
}

static int mvpp2_poll(struct napi_struct *napi, int budget)
{
	u32 cause_rx_tx, cause_rx, cause_tx, cause_misc;
	int rx_done = 0;
	struct mvpp2_port *port = netdev_priv(napi->dev);
	struct mvpp2_queue_vector *qv;
	unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());

	qv = container_of(napi, struct mvpp2_queue_vector, napi);

	/* Rx/Tx cause register
	 *
	 * Bits 0-15: each bit indicates received packets on the Rx queue
	 * (bit 0 is for Rx queue 0).
	 *
	 * Bits 16-23: each bit indicates transmitted packets on the Tx queue
	 * (bit 16 is for Tx queue 0).
	 *
	 * Each CPU has its own Rx/Tx cause register
	 */
	cause_rx_tx = mvpp2_thread_read_relaxed(port->priv, qv->sw_thread_id,
						MVPP2_ISR_RX_TX_CAUSE_REG(port->id));

	cause_misc = cause_rx_tx & MVPP2_CAUSE_MISC_SUM_MASK;
	if (cause_misc) {
		mvpp2_cause_error(port->dev, cause_misc);

		/* Clear the cause register */
		mvpp2_write(port->priv, MVPP2_ISR_MISC_CAUSE_REG, 0);
		mvpp2_thread_write(port->priv, thread,
				   MVPP2_ISR_RX_TX_CAUSE_REG(port->id),
				   cause_rx_tx & ~MVPP2_CAUSE_MISC_SUM_MASK);
	}

	if (port->has_tx_irqs) {
		cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
		if (cause_tx) {
			cause_tx >>= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET;
			mvpp2_tx_done(port, cause_tx, qv->sw_thread_id);
		}
	}

	/* Process RX packets */
	cause_rx = cause_rx_tx &
		   MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK(port->priv->hw_version);
	cause_rx <<= qv->first_rxq;
	cause_rx |= qv->pending_cause_rx;
	while (cause_rx && budget > 0) {
		int count;
		struct mvpp2_rx_queue *rxq;

		rxq = mvpp2_get_rx_queue(port, cause_rx);
		if (!rxq)
			break;

		count = mvpp2_rx(port, napi, budget, rxq);
		rx_done += count;
		budget -= count;
		if (budget > 0) {
			/* Clear the bit associated to this Rx queue
			 * so that next iteration will continue from
			 * the next Rx queue.
			 */
			cause_rx &= ~(1 << rxq->logic_rxq);
		}
	}

	if (budget > 0) {
		cause_rx = 0;
		napi_complete_done(napi, rx_done);

		mvpp2_qvec_interrupt_enable(qv);
	}
	qv->pending_cause_rx = cause_rx;
	return rx_done;
}

static void mvpp22_mode_reconfigure(struct mvpp2_port *port,
				    phy_interface_t interface)
{
	u32 ctrl3;

	/* Set the GMAC & XLG MAC in reset */
	mvpp2_mac_reset_assert(port);

	/* Set the MPCS and XPCS in reset */
	mvpp22_pcs_reset_assert(port);

	/* comphy reconfiguration */
	mvpp22_comphy_init(port, interface);

	/* gop reconfiguration */
	mvpp22_gop_init(port, interface);

	mvpp22_pcs_reset_deassert(port, interface);

	if (mvpp2_port_supports_xlg(port)) {
		ctrl3 = readl(port->base + MVPP22_XLG_CTRL3_REG);
		ctrl3 &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK;

		if (mvpp2_is_xlg(interface))
			ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_10G;
		else
			ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_GMAC;

		writel(ctrl3, port->base + MVPP22_XLG_CTRL3_REG);
	}

	if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(interface))
		mvpp2_xlg_max_rx_size_set(port);
	else
		mvpp2_gmac_max_rx_size_set(port);
}

/* Set hw internals when starting port */
static void mvpp2_start_dev(struct mvpp2_port *port)
{
	int i;

	mvpp2_txp_max_tx_size_set(port);

	for (i = 0; i < port->nqvecs; i++)
		napi_enable(&port->qvecs[i].napi);

	/* Enable interrupts on all threads */
	mvpp2_interrupts_enable(port);

	if (port->priv->hw_version >= MVPP22)
		mvpp22_mode_reconfigure(port, port->phy_interface);

	if (port->phylink) {
		phylink_start(port->phylink);
	} else {
		mvpp2_acpi_start(port);
	}

	netif_tx_start_all_queues(port->dev);

	clear_bit(0, &port->state);
}

/* Set hw internals when stopping port */
static void mvpp2_stop_dev(struct mvpp2_port *port)
{
	int i;

	set_bit(0, &port->state);

	/* Disable interrupts on all threads */
	mvpp2_interrupts_disable(port);

	for (i = 0; i < port->nqvecs; i++)
		napi_disable(&port->qvecs[i].napi);

	if (port->phylink)
		phylink_stop(port->phylink);
	phy_power_off(port->comphy);
}

static int mvpp2_check_ringparam_valid(struct net_device *dev,
				       struct ethtool_ringparam *ring)
{
	u16 new_rx_pending = ring->rx_pending;
	u16 new_tx_pending = ring->tx_pending;

	if (ring->rx_pending == 0 || ring->tx_pending == 0)
		return -EINVAL;

	if (ring->rx_pending > MVPP2_MAX_RXD_MAX)
		new_rx_pending = MVPP2_MAX_RXD_MAX;
	else if (ring->rx_pending < MSS_THRESHOLD_START)
		new_rx_pending = MSS_THRESHOLD_START;
	else if (!IS_ALIGNED(ring->rx_pending, 16))
		new_rx_pending = ALIGN(ring->rx_pending, 16);

	if (ring->tx_pending > MVPP2_MAX_TXD_MAX)
		new_tx_pending = MVPP2_MAX_TXD_MAX;
	else if (!IS_ALIGNED(ring->tx_pending, 32))
		new_tx_pending = ALIGN(ring->tx_pending, 32);

	/* The Tx ring size cannot be smaller than the minimum number of
	 * descriptors needed for TSO.
	 */
	if (new_tx_pending < MVPP2_MAX_SKB_DESCS)
		new_tx_pending = ALIGN(MVPP2_MAX_SKB_DESCS, 32);

	if (ring->rx_pending != new_rx_pending) {
		netdev_info(dev, "illegal Rx ring size value %d, round to %d\n",
			    ring->rx_pending, new_rx_pending);
		ring->rx_pending = new_rx_pending;
	}

	if (ring->tx_pending != new_tx_pending) {
		netdev_info(dev, "illegal Tx ring size value %d, round to %d\n",
			    ring->tx_pending, new_tx_pending);
		ring->tx_pending = new_tx_pending;
	}

	return 0;
}

static void mvpp21_get_mac_address(struct mvpp2_port *port, unsigned char *addr)
{
	u32 mac_addr_l, mac_addr_m, mac_addr_h;

	mac_addr_l = readl(port->base + MVPP2_GMAC_CTRL_1_REG);
	mac_addr_m = readl(port->priv->lms_base + MVPP2_SRC_ADDR_MIDDLE);
	mac_addr_h = readl(port->priv->lms_base + MVPP2_SRC_ADDR_HIGH);
	addr[0] = (mac_addr_h >> 24) & 0xFF;
	addr[1] = (mac_addr_h >> 16) & 0xFF;
	addr[2] = (mac_addr_h >> 8) & 0xFF;
	addr[3] = mac_addr_h & 0xFF;
	addr[4] = mac_addr_m & 0xFF;
	addr[5] = (mac_addr_l >> MVPP2_GMAC_SA_LOW_OFFS) & 0xFF;
}

static int mvpp2_irqs_init(struct mvpp2_port *port)
{
	int err, i;

	for (i = 0; i < port->nqvecs; i++) {
		struct mvpp2_queue_vector *qv = port->qvecs + i;

		if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE) {
			qv->mask = kzalloc(cpumask_size(), GFP_KERNEL);
			if (!qv->mask) {
				err = -ENOMEM;
				goto err;
			}

			irq_set_status_flags(qv->irq, IRQ_NO_BALANCING);
		}

		err = request_irq(qv->irq, mvpp2_isr, 0, port->dev->name, qv);
		if (err)
			goto err;

		if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE) {
			unsigned int cpu;

			for_each_present_cpu(cpu) {
				if (mvpp2_cpu_to_thread(port->priv, cpu) ==
				    qv->sw_thread_id)
					cpumask_set_cpu(cpu, qv->mask);
			}

			irq_set_affinity_hint(qv->irq, qv->mask);
		}
	}

	return 0;
err:
	for (i = 0; i < port->nqvecs; i++) {
		struct mvpp2_queue_vector *qv = port->qvecs + i;

		irq_set_affinity_hint(qv->irq, NULL);
		kfree(qv->mask);
		qv->mask = NULL;
		free_irq(qv->irq, qv);
	}

	return err;
}

static void mvpp2_irqs_deinit(struct mvpp2_port *port)
{
	int i;

	for (i = 0; i < port->nqvecs; i++) {
		struct mvpp2_queue_vector *qv = port->qvecs + i;

		irq_set_affinity_hint(qv->irq, NULL);
		kfree(qv->mask);
		qv->mask = NULL;
		irq_clear_status_flags(qv->irq, IRQ_NO_BALANCING);
		free_irq(qv->irq, qv);
	}
}

static bool mvpp22_rss_is_supported(struct mvpp2_port *port)
{
	return (queue_mode == MVPP2_QDIST_MULTI_MODE) &&
		!(port->flags & MVPP2_F_LOOPBACK);
}

static int mvpp2_open(struct net_device *dev)
{
	struct mvpp2_port *port = netdev_priv(dev);
	struct mvpp2 *priv = port->priv;
	unsigned char mac_bcast[ETH_ALEN] = {
			0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	bool valid = false;
	int err;

	err = mvpp2_prs_mac_da_accept(port, mac_bcast, true);
	if (err) {
		netdev_err(dev, "mvpp2_prs_mac_da_accept BC failed\n");
		return err;
	}
	err = mvpp2_prs_mac_da_accept(port, dev->dev_addr, true);
	if (err) {
		netdev_err(dev, "mvpp2_prs_mac_da_accept own addr failed\n");
		return err;
	}
	err = mvpp2_prs_tag_mode_set(port->priv, port->id, MVPP2_TAG_TYPE_MH);
	if (err) {
		netdev_err(dev, "mvpp2_prs_tag_mode_set failed\n");
		return err;
	}
	err = mvpp2_prs_def_flow(port);
	if (err) {
		netdev_err(dev, "mvpp2_prs_def_flow failed\n");
		return err;
	}

	/* Allocate the Rx/Tx queues */
	err = mvpp2_setup_rxqs(port);
	if (err) {
		netdev_err(port->dev, "cannot allocate Rx queues\n");
		return err;
	}

	err = mvpp2_setup_txqs(port);
	if (err) {
		netdev_err(port->dev, "cannot allocate Tx queues\n");
		goto err_cleanup_rxqs;
	}

	err = mvpp2_irqs_init(port);
	if (err) {
		netdev_err(port->dev, "cannot init IRQs\n");
		goto err_cleanup_txqs;
	}

	if (port->phylink) {
		err = phylink_fwnode_phy_connect(port->phylink, port->fwnode, 0);
		if (err) {
			netdev_err(port->dev, "could not attach PHY (%d)\n",
				   err);
			goto err_free_irq;
		}

		valid = true;
	}

	if (priv->hw_version >= MVPP22 && port->port_irq) {
		err = request_irq(port->port_irq, mvpp2_port_isr, 0,
				  dev->name, port);
		if (err) {
			netdev_err(port->dev,
				   "cannot request port link/ptp IRQ %d\n",
				   port->port_irq);
			goto err_free_irq;
		}

		mvpp22_gop_setup_irq(port);

		/* In default link is down */
		netif_carrier_off(port->dev);

		valid = true;
	} else {
		port->port_irq = 0;
	}

	if (!valid) {
		netdev_err(port->dev,
			   "invalid configuration: no dt or link IRQ");
		err = -ENOENT;
		goto err_free_irq;
	}

	/* Unmask interrupts on all CPUs */
	on_each_cpu(mvpp2_interrupts_unmask, port, 1);
	mvpp2_shared_interrupt_mask_unmask(port, false);

	mvpp2_start_dev(port);

	/* Start hardware statistics gathering */
	queue_delayed_work(priv->stats_queue, &port->stats_work,
			   MVPP2_MIB_COUNTERS_STATS_DELAY);

	return 0;

err_free_irq:
	mvpp2_irqs_deinit(port);
err_cleanup_txqs:
	mvpp2_cleanup_txqs(port);
err_cleanup_rxqs:
	mvpp2_cleanup_rxqs(port);
	return err;
}

static int mvpp2_stop(struct net_device *dev)
{
	struct mvpp2_port *port = netdev_priv(dev);
	struct mvpp2_port_pcpu *port_pcpu;
	unsigned int thread;

	mvpp2_stop_dev(port);

	/* Mask interrupts on all threads */
	on_each_cpu(mvpp2_interrupts_mask, port, 1);
	mvpp2_shared_interrupt_mask_unmask(port, true);

	if (port->phylink)
		phylink_disconnect_phy(port->phylink);
	if (port->port_irq)
		free_irq(port->port_irq, port);

	mvpp2_irqs_deinit(port);
	if (!port->has_tx_irqs) {
		for (thread = 0; thread < port->priv->nthreads; thread++) {
			port_pcpu = per_cpu_ptr(port->pcpu, thread);

			hrtimer_cancel(&port_pcpu->tx_done_timer);
			port_pcpu->timer_scheduled = false;
		}
	}
	mvpp2_cleanup_rxqs(port);
	mvpp2_cleanup_txqs(port);

	cancel_delayed_work_sync(&port->stats_work);

	mvpp2_mac_reset_assert(port);
	mvpp22_pcs_reset_assert(port);

	return 0;
}

static int mvpp2_prs_mac_da_accept_list(struct mvpp2_port *port,
					struct netdev_hw_addr_list *list)
{
	struct netdev_hw_addr *ha;
	int ret;

	netdev_hw_addr_list_for_each(ha, list) {
		ret = mvpp2_prs_mac_da_accept(port, ha->addr, true);
		if (ret)
			return ret;
	}

	return 0;
}

static void mvpp2_set_rx_promisc(struct mvpp2_port *port, bool enable)
{
	if (!enable && (port->dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
		mvpp2_prs_vid_enable_filtering(port);
	else
		mvpp2_prs_vid_disable_filtering(port);

	mvpp2_prs_mac_promisc_set(port->priv, port->id,
				  MVPP2_PRS_L2_UNI_CAST, enable);

	mvpp2_prs_mac_promisc_set(port->priv, port->id,
				  MVPP2_PRS_L2_MULTI_CAST, enable);
}

static void mvpp2_set_rx_mode(struct net_device *dev)
{
	struct mvpp2_port *port = netdev_priv(dev);

	/* Clear the whole UC and MC list */
	mvpp2_prs_mac_del_all(port);

	if (dev->flags & IFF_PROMISC) {
		mvpp2_set_rx_promisc(port, true);
		return;
	}

	mvpp2_set_rx_promisc(port, false);

	if (netdev_uc_count(dev) > MVPP2_PRS_MAC_UC_FILT_MAX ||
	    mvpp2_prs_mac_da_accept_list(port, &dev->uc))
		mvpp2_prs_mac_promisc_set(port->priv, port->id,
					  MVPP2_PRS_L2_UNI_CAST, true);

	if (dev->flags & IFF_ALLMULTI) {
		mvpp2_prs_mac_promisc_set(port->priv, port->id,
					  MVPP2_PRS_L2_MULTI_CAST, true);
		return;
	}

	if (netdev_mc_count(dev) > MVPP2_PRS_MAC_MC_FILT_MAX ||
	    mvpp2_prs_mac_da_accept_list(port, &dev->mc))
		mvpp2_prs_mac_promisc_set(port->priv, port->id,
					  MVPP2_PRS_L2_MULTI_CAST, true);
}

static int mvpp2_set_mac_address(struct net_device *dev, void *p)
{
	const struct sockaddr *addr = p;
	int err;

	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	err = mvpp2_prs_update_mac_da(dev, addr->sa_data);
	if (err) {
		/* Reconfigure parser accept the original MAC address */
		mvpp2_prs_update_mac_da(dev, dev->dev_addr);
		netdev_err(dev, "failed to change MAC address\n");
	}
	return err;
}

/* Shut down all the ports, reconfigure the pools as percpu or shared,
 * then bring up again all ports.
 */
static int mvpp2_bm_switch_buffers(struct mvpp2 *priv, bool percpu)
{
	bool change_percpu = (percpu != priv->percpu_pools);
	int numbufs = MVPP2_BM_POOLS_NUM, i;
	struct mvpp2_port *port = NULL;
	bool status[MVPP2_MAX_PORTS];

	for (i = 0; i < priv->port_count; i++) {
		port = priv->port_list[i];
		status[i] = netif_running(port->dev);
		if (status[i])
			mvpp2_stop(port->dev);
	}

	/* nrxqs is the same for all ports */
	if (priv->percpu_pools)
		numbufs = port->nrxqs * 2;

	if (change_percpu)
		mvpp2_bm_pool_update_priv_fc(priv, false);

	for (i = 0; i < numbufs; i++)
		mvpp2_bm_pool_destroy(port->dev->dev.parent, priv, &priv->bm_pools[i]);

	devm_kfree(port->dev->dev.parent, priv->bm_pools);
	priv->percpu_pools = percpu;
	mvpp2_bm_init(port->dev->dev.parent, priv);

	for (i = 0; i < priv->port_count; i++) {
		port = priv->port_list[i];
		mvpp2_swf_bm_pool_init(port);
		if (status[i])
			mvpp2_open(port->dev);
	}

	if (change_percpu)
		mvpp2_bm_pool_update_priv_fc(priv, true);

	return 0;
}

static int mvpp2_change_mtu(struct net_device *dev, int mtu)
{
	struct mvpp2_port *port = netdev_priv(dev);
	bool running = netif_running(dev);
	struct mvpp2 *priv = port->priv;
	int err;

	if (!IS_ALIGNED(MVPP2_RX_PKT_SIZE(mtu), 8)) {
		netdev_info(dev, "illegal MTU value %d, round to %d\n", mtu,
			    ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8));
		mtu = ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8);
	}

	if (MVPP2_RX_PKT_SIZE(mtu) > MVPP2_BM_LONG_PKT_SIZE) {
		if (port->xdp_prog) {
			netdev_err(dev, "Jumbo frames are not supported with XDP\n");
			return -EINVAL;
		}
		if (priv->percpu_pools) {
			netdev_warn(dev, "mtu %d too high, switching to shared buffers", mtu);
			mvpp2_bm_switch_buffers(priv, false);
		}
	} else {
		bool jumbo = false;
		int i;

		for (i = 0; i < priv->port_count; i++)
			if (priv->port_list[i] != port &&
			    MVPP2_RX_PKT_SIZE(priv->port_list[i]->dev->mtu) >
			    MVPP2_BM_LONG_PKT_SIZE) {
				jumbo = true;
				break;
			}

		/* No port is using jumbo frames */
		if (!jumbo) {
			dev_info(port->dev->dev.parent,
				 "all ports have a low MTU, switching to per-cpu buffers");
			mvpp2_bm_switch_buffers(priv, true);
		}
	}

	if (running)
		mvpp2_stop_dev(port);

	err = mvpp2_bm_update_mtu(dev, mtu);
	if (err) {
		netdev_err(dev, "failed to change MTU\n");
		/* Reconfigure BM to the original MTU */
		mvpp2_bm_update_mtu(dev, dev->mtu);
	} else {
		port->pkt_size =  MVPP2_RX_PKT_SIZE(mtu);
	}

	if (running) {
		mvpp2_start_dev(port);
		mvpp2_egress_enable(port);
		mvpp2_ingress_enable(port);
	}

	return err;
}

static int mvpp2_check_pagepool_dma(struct mvpp2_port *port)
{
	enum dma_data_direction dma_dir = DMA_FROM_DEVICE;
	struct mvpp2 *priv = port->priv;
	int err = -1, i;

	if (!priv->percpu_pools)
		return err;

	if (!priv->page_pool[0])
		return -ENOMEM;

	for (i = 0; i < priv->port_count; i++) {
		port = priv->port_list[i];
		if (port->xdp_prog) {
			dma_dir = DMA_BIDIRECTIONAL;
			break;
		}
	}

	/* All pools are equal in terms of DMA direction */
	if (priv->page_pool[0]->p.dma_dir != dma_dir)
		err = mvpp2_bm_switch_buffers(priv, true);

	return err;
}

static void
mvpp2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
	struct mvpp2_port *port = netdev_priv(dev);
	unsigned int start;
	unsigned int cpu;

	for_each_possible_cpu(cpu) {
		struct mvpp2_pcpu_stats *cpu_stats;
		u64 rx_packets;
		u64 rx_bytes;
		u64 tx_packets;
		u64 tx_bytes;

		cpu_stats = per_cpu_ptr(port->stats, cpu);
		do {
			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
			rx_packets = cpu_stats->rx_packets;
			rx_bytes   = cpu_stats->rx_bytes;
			tx_packets = cpu_stats->tx_packets;
			tx_bytes   = cpu_stats->tx_bytes;
		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));

		stats->rx_packets += rx_packets;
		stats->rx_bytes   += rx_bytes;
		stats->tx_packets += tx_packets;
		stats->tx_bytes   += tx_bytes;
	}

	stats->rx_errors	= dev->stats.rx_errors;
	stats->rx_dropped	= dev->stats.rx_dropped;
	stats->tx_dropped	= dev->stats.tx_dropped;
}

static int mvpp2_set_ts_config(struct mvpp2_port *port, struct ifreq *ifr)
{
	struct hwtstamp_config config;
	void __iomem *ptp;
	u32 gcr, int_mask;

	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
		return -EFAULT;

	if (config.flags)
		return -EINVAL;

	if (config.tx_type != HWTSTAMP_TX_OFF &&
	    config.tx_type != HWTSTAMP_TX_ON)
		return -ERANGE;

	ptp = port->priv->iface_base + MVPP22_PTP_BASE(port->gop_id);

	int_mask = gcr = 0;
	if (config.tx_type != HWTSTAMP_TX_OFF) {
		gcr |= MVPP22_PTP_GCR_TSU_ENABLE | MVPP22_PTP_GCR_TX_RESET;
		int_mask |= MVPP22_PTP_INT_MASK_QUEUE1 |
			    MVPP22_PTP_INT_MASK_QUEUE0;
	}

	/* It seems we must also release the TX reset when enabling the TSU */
	if (config.rx_filter != HWTSTAMP_FILTER_NONE)
		gcr |= MVPP22_PTP_GCR_TSU_ENABLE | MVPP22_PTP_GCR_RX_RESET |
		       MVPP22_PTP_GCR_TX_RESET;

	if (gcr & MVPP22_PTP_GCR_TSU_ENABLE)
		mvpp22_tai_start(port->priv->tai);

	if (config.rx_filter != HWTSTAMP_FILTER_NONE) {
		config.rx_filter = HWTSTAMP_FILTER_ALL;
		mvpp2_modify(ptp + MVPP22_PTP_GCR,
			     MVPP22_PTP_GCR_RX_RESET |
			     MVPP22_PTP_GCR_TX_RESET |
			     MVPP22_PTP_GCR_TSU_ENABLE, gcr);
		port->rx_hwtstamp = true;
	} else {
		port->rx_hwtstamp = false;
		mvpp2_modify(ptp + MVPP22_PTP_GCR,
			     MVPP22_PTP_GCR_RX_RESET |
			     MVPP22_PTP_GCR_TX_RESET |
			     MVPP22_PTP_GCR_TSU_ENABLE, gcr);
	}

	mvpp2_modify(ptp + MVPP22_PTP_INT_MASK,
		     MVPP22_PTP_INT_MASK_QUEUE1 |
		     MVPP22_PTP_INT_MASK_QUEUE0, int_mask);

	if (!(gcr & MVPP22_PTP_GCR_TSU_ENABLE))
		mvpp22_tai_stop(port->priv->tai);

	port->tx_hwtstamp_type = config.tx_type;

	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
		return -EFAULT;

	return 0;
}

static int mvpp2_get_ts_config(struct mvpp2_port *port, struct ifreq *ifr)
{
	struct hwtstamp_config config;

	memset(&config, 0, sizeof(config));

	config.tx_type = port->tx_hwtstamp_type;
	config.rx_filter = port->rx_hwtstamp ?
		HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE;

	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
		return -EFAULT;

	return 0;
}

static int mvpp2_ethtool_get_ts_info(struct net_device *dev,
				     struct ethtool_ts_info *info)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!port->hwtstamp)
		return -EOPNOTSUPP;

	info->phc_index = mvpp22_tai_ptp_clock_index(port->priv->tai);
	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
				SOF_TIMESTAMPING_RX_SOFTWARE |
				SOF_TIMESTAMPING_SOFTWARE |
				SOF_TIMESTAMPING_TX_HARDWARE |
				SOF_TIMESTAMPING_RX_HARDWARE |
				SOF_TIMESTAMPING_RAW_HARDWARE;
	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
			 BIT(HWTSTAMP_TX_ON);
	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
			   BIT(HWTSTAMP_FILTER_ALL);

	return 0;
}

static int mvpp2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct mvpp2_port *port = netdev_priv(dev);

	switch (cmd) {
	case SIOCSHWTSTAMP:
		if (port->hwtstamp)
			return mvpp2_set_ts_config(port, ifr);
		break;

	case SIOCGHWTSTAMP:
		if (port->hwtstamp)
			return mvpp2_get_ts_config(port, ifr);
		break;
	}

	if (!port->phylink)
		return -ENOTSUPP;

	return phylink_mii_ioctl(port->phylink, ifr, cmd);
}

static int mvpp2_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int ret;

	ret = mvpp2_prs_vid_entry_add(port, vid);
	if (ret)
		netdev_err(dev, "rx-vlan-filter offloading cannot accept more than %d VIDs per port\n",
			   MVPP2_PRS_VLAN_FILT_MAX - 1);
	return ret;
}

static int mvpp2_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
{
	struct mvpp2_port *port = netdev_priv(dev);

	mvpp2_prs_vid_entry_remove(port, vid);
	return 0;
}

static int mvpp2_set_features(struct net_device *dev,
			      netdev_features_t features)
{
	netdev_features_t changed = dev->features ^ features;
	struct mvpp2_port *port = netdev_priv(dev);

	if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
		if (features & NETIF_F_HW_VLAN_CTAG_FILTER) {
			mvpp2_prs_vid_enable_filtering(port);
		} else {
			/* Invalidate all registered VID filters for this
			 * port
			 */
			mvpp2_prs_vid_remove_all(port);

			mvpp2_prs_vid_disable_filtering(port);
		}
	}

	if (changed & NETIF_F_RXHASH) {
		if (features & NETIF_F_RXHASH)
			mvpp22_port_rss_enable(port);
		else
			mvpp22_port_rss_disable(port);
	}

	return 0;
}

static int mvpp2_xdp_setup(struct mvpp2_port *port, struct netdev_bpf *bpf)
{
	struct bpf_prog *prog = bpf->prog, *old_prog;
	bool running = netif_running(port->dev);
	bool reset = !prog != !port->xdp_prog;

	if (port->dev->mtu > ETH_DATA_LEN) {
		NL_SET_ERR_MSG_MOD(bpf->extack, "XDP is not supported with jumbo frames enabled");
		return -EOPNOTSUPP;
	}

	if (!port->priv->percpu_pools) {
		NL_SET_ERR_MSG_MOD(bpf->extack, "Per CPU Pools required for XDP");
		return -EOPNOTSUPP;
	}

	if (port->ntxqs < num_possible_cpus() * 2) {
		NL_SET_ERR_MSG_MOD(bpf->extack, "XDP_TX needs two TX queues per CPU");
		return -EOPNOTSUPP;
	}

	/* device is up and bpf is added/removed, must setup the RX queues */
	if (running && reset)
		mvpp2_stop(port->dev);

	old_prog = xchg(&port->xdp_prog, prog);
	if (old_prog)
		bpf_prog_put(old_prog);

	/* bpf is just replaced, RXQ and MTU are already setup */
	if (!reset)
		return 0;

	/* device was up, restore the link */
	if (running)
		mvpp2_open(port->dev);

	/* Check Page Pool DMA Direction */
	mvpp2_check_pagepool_dma(port);

	return 0;
}

static int mvpp2_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
	struct mvpp2_port *port = netdev_priv(dev);

	switch (xdp->command) {
	case XDP_SETUP_PROG:
		return mvpp2_xdp_setup(port, xdp);
	default:
		return -EINVAL;
	}
}

/* Ethtool methods */

static int mvpp2_ethtool_nway_reset(struct net_device *dev)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!port->phylink)
		return -ENOTSUPP;

	return phylink_ethtool_nway_reset(port->phylink);
}

/* Set interrupt coalescing for ethtools */
static int
mvpp2_ethtool_set_coalesce(struct net_device *dev,
			   struct ethtool_coalesce *c,
			   struct kernel_ethtool_coalesce *kernel_coal,
			   struct netlink_ext_ack *extack)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int queue;

	for (queue = 0; queue < port->nrxqs; queue++) {
		struct mvpp2_rx_queue *rxq = port->rxqs[queue];

		rxq->time_coal = c->rx_coalesce_usecs;
		rxq->pkts_coal = c->rx_max_coalesced_frames;
		mvpp2_rx_pkts_coal_set(port, rxq);
		mvpp2_rx_time_coal_set(port, rxq);
	}

	if (port->has_tx_irqs) {
		port->tx_time_coal = c->tx_coalesce_usecs;
		mvpp2_tx_time_coal_set(port);
	}

	for (queue = 0; queue < port->ntxqs; queue++) {
		struct mvpp2_tx_queue *txq = port->txqs[queue];

		txq->done_pkts_coal = c->tx_max_coalesced_frames;

		if (port->has_tx_irqs)
			mvpp2_tx_pkts_coal_set(port, txq);
	}

	return 0;
}

/* get coalescing for ethtools */
static int
mvpp2_ethtool_get_coalesce(struct net_device *dev,
			   struct ethtool_coalesce *c,
			   struct kernel_ethtool_coalesce *kernel_coal,
			   struct netlink_ext_ack *extack)
{
	struct mvpp2_port *port = netdev_priv(dev);

	c->rx_coalesce_usecs       = port->rxqs[0]->time_coal;
	c->rx_max_coalesced_frames = port->rxqs[0]->pkts_coal;
	c->tx_max_coalesced_frames = port->txqs[0]->done_pkts_coal;
	c->tx_coalesce_usecs       = port->tx_time_coal;
	return 0;
}

static void mvpp2_ethtool_get_drvinfo(struct net_device *dev,
				      struct ethtool_drvinfo *drvinfo)
{
	strlcpy(drvinfo->driver, MVPP2_DRIVER_NAME,
		sizeof(drvinfo->driver));
	strlcpy(drvinfo->version, MVPP2_DRIVER_VERSION,
		sizeof(drvinfo->version));
	strlcpy(drvinfo->bus_info, dev_name(&dev->dev),
		sizeof(drvinfo->bus_info));
}

static void mvpp2_ethtool_get_ringparam(struct net_device *dev,
					struct ethtool_ringparam *ring)
{
	struct mvpp2_port *port = netdev_priv(dev);

	ring->rx_max_pending = MVPP2_MAX_RXD_MAX;
	ring->tx_max_pending = MVPP2_MAX_TXD_MAX;
	ring->rx_pending = port->rx_ring_size;
	ring->tx_pending = port->tx_ring_size;
}

static int mvpp2_ethtool_set_ringparam(struct net_device *dev,
				       struct ethtool_ringparam *ring)
{
	struct mvpp2_port *port = netdev_priv(dev);
	u16 prev_rx_ring_size = port->rx_ring_size;
	u16 prev_tx_ring_size = port->tx_ring_size;
	int err;

	err = mvpp2_check_ringparam_valid(dev, ring);
	if (err)
		return err;

	if (!netif_running(dev)) {
		port->rx_ring_size = ring->rx_pending;
		port->tx_ring_size = ring->tx_pending;
		return 0;
	}

	/* The interface is running, so we have to force a
	 * reallocation of the queues
	 */
	mvpp2_stop_dev(port);
	mvpp2_cleanup_rxqs(port);
	mvpp2_cleanup_txqs(port);

	port->rx_ring_size = ring->rx_pending;
	port->tx_ring_size = ring->tx_pending;

	err = mvpp2_setup_rxqs(port);
	if (err) {
		/* Reallocate Rx queues with the original ring size */
		port->rx_ring_size = prev_rx_ring_size;
		ring->rx_pending = prev_rx_ring_size;
		err = mvpp2_setup_rxqs(port);
		if (err)
			goto err_out;
	}
	err = mvpp2_setup_txqs(port);
	if (err) {
		/* Reallocate Tx queues with the original ring size */
		port->tx_ring_size = prev_tx_ring_size;
		ring->tx_pending = prev_tx_ring_size;
		err = mvpp2_setup_txqs(port);
		if (err)
			goto err_clean_rxqs;
	}

	mvpp2_start_dev(port);
	mvpp2_egress_enable(port);
	mvpp2_ingress_enable(port);

	return 0;

err_clean_rxqs:
	mvpp2_cleanup_rxqs(port);
err_out:
	netdev_err(dev, "failed to change ring parameters");
	return err;
}

static void mvpp2_ethtool_get_pause_param(struct net_device *dev,
					  struct ethtool_pauseparam *pause)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!port->phylink)
		return;

	phylink_ethtool_get_pauseparam(port->phylink, pause);
}

static int mvpp2_ethtool_set_pause_param(struct net_device *dev,
					 struct ethtool_pauseparam *pause)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!port->phylink)
		return -ENOTSUPP;

	return phylink_ethtool_set_pauseparam(port->phylink, pause);
}

static int mvpp2_ethtool_get_link_ksettings(struct net_device *dev,
					    struct ethtool_link_ksettings *cmd)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!port->phylink)
		return -ENOTSUPP;

	return phylink_ethtool_ksettings_get(port->phylink, cmd);
}

static int mvpp2_ethtool_set_link_ksettings(struct net_device *dev,
					    const struct ethtool_link_ksettings *cmd)
{
	struct mvpp2_port *port = netdev_priv(dev);

	if (!port->phylink)
		return -ENOTSUPP;

	return phylink_ethtool_ksettings_set(port->phylink, cmd);
}

static int mvpp2_ethtool_get_rxnfc(struct net_device *dev,
				   struct ethtool_rxnfc *info, u32 *rules)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int ret = 0, i, loc = 0;

	if (!mvpp22_rss_is_supported(port))
		return -EOPNOTSUPP;

	switch (info->cmd) {
	case ETHTOOL_GRXFH:
		ret = mvpp2_ethtool_rxfh_get(port, info);
		break;
	case ETHTOOL_GRXRINGS:
		info->data = port->nrxqs;
		break;
	case ETHTOOL_GRXCLSRLCNT:
		info->rule_cnt = port->n_rfs_rules;
		break;
	case ETHTOOL_GRXCLSRULE:
		ret = mvpp2_ethtool_cls_rule_get(port, info);
		break;
	case ETHTOOL_GRXCLSRLALL:
		for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) {
			if (port->rfs_rules[i])
				rules[loc++] = i;
		}
		break;
	default:
		return -ENOTSUPP;
	}

	return ret;
}

static int mvpp2_ethtool_set_rxnfc(struct net_device *dev,
				   struct ethtool_rxnfc *info)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int ret = 0;

	if (!mvpp22_rss_is_supported(port))
		return -EOPNOTSUPP;

	switch (info->cmd) {
	case ETHTOOL_SRXFH:
		ret = mvpp2_ethtool_rxfh_set(port, info);
		break;
	case ETHTOOL_SRXCLSRLINS:
		ret = mvpp2_ethtool_cls_rule_ins(port, info);
		break;
	case ETHTOOL_SRXCLSRLDEL:
		ret = mvpp2_ethtool_cls_rule_del(port, info);
		break;
	default:
		return -EOPNOTSUPP;
	}
	return ret;
}

static u32 mvpp2_ethtool_get_rxfh_indir_size(struct net_device *dev)
{
	struct mvpp2_port *port = netdev_priv(dev);

	return mvpp22_rss_is_supported(port) ? MVPP22_RSS_TABLE_ENTRIES : 0;
}

static int mvpp2_ethtool_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
				  u8 *hfunc)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int ret = 0;

	if (!mvpp22_rss_is_supported(port))
		return -EOPNOTSUPP;

	if (indir)
		ret = mvpp22_port_rss_ctx_indir_get(port, 0, indir);

	if (hfunc)
		*hfunc = ETH_RSS_HASH_CRC32;

	return ret;
}

static int mvpp2_ethtool_set_rxfh(struct net_device *dev, const u32 *indir,
				  const u8 *key, const u8 hfunc)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int ret = 0;

	if (!mvpp22_rss_is_supported(port))
		return -EOPNOTSUPP;

	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_CRC32)
		return -EOPNOTSUPP;

	if (key)
		return -EOPNOTSUPP;

	if (indir)
		ret = mvpp22_port_rss_ctx_indir_set(port, 0, indir);

	return ret;
}

static int mvpp2_ethtool_get_rxfh_context(struct net_device *dev, u32 *indir,
					  u8 *key, u8 *hfunc, u32 rss_context)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int ret = 0;

	if (!mvpp22_rss_is_supported(port))
		return -EOPNOTSUPP;
	if (rss_context >= MVPP22_N_RSS_TABLES)
		return -EINVAL;

	if (hfunc)
		*hfunc = ETH_RSS_HASH_CRC32;

	if (indir)
		ret = mvpp22_port_rss_ctx_indir_get(port, rss_context, indir);

	return ret;
}

static int mvpp2_ethtool_set_rxfh_context(struct net_device *dev,
					  const u32 *indir, const u8 *key,
					  const u8 hfunc, u32 *rss_context,
					  bool delete)
{
	struct mvpp2_port *port = netdev_priv(dev);
	int ret;

	if (!mvpp22_rss_is_supported(port))
		return -EOPNOTSUPP;

	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_CRC32)
		return -EOPNOTSUPP;

	if (key)
		return -EOPNOTSUPP;

	if (delete)
		return mvpp22_port_rss_ctx_delete(port, *rss_context);

	if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
		ret = mvpp22_port_rss_ctx_create(port, rss_context);
		if (ret)
			return ret;
	}

	return mvpp22_port_rss_ctx_indir_set(port, *rss_context, indir);
}
/* Device ops */

static const struct net_device_ops mvpp2_netdev_ops = {
	.ndo_open		= mvpp2_open,
	.ndo_stop		= mvpp2_stop,
	.ndo_start_xmit		= mvpp2_tx,
	.ndo_set_rx_mode	= mvpp2_set_rx_mode,
	.ndo_set_mac_address	= mvpp2_set_mac_address,
	.ndo_change_mtu		= mvpp2_change_mtu,
	.ndo_get_stats64	= mvpp2_get_stats64,
	.ndo_eth_ioctl		= mvpp2_ioctl,
	.ndo_vlan_rx_add_vid	= mvpp2_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= mvpp2_vlan_rx_kill_vid,
	.ndo_set_features	= mvpp2_set_features,
	.ndo_bpf		= mvpp2_xdp,
	.ndo_xdp_xmit		= mvpp2_xdp_xmit,
};

static const struct ethtool_ops mvpp2_eth_tool_ops = {
	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
				     ETHTOOL_COALESCE_MAX_FRAMES,
	.nway_reset		= mvpp2_ethtool_nway_reset,
	.get_link		= ethtool_op_get_link,
	.get_ts_info		= mvpp2_ethtool_get_ts_info,
	.set_coalesce		= mvpp2_ethtool_set_coalesce,
	.get_coalesce		= mvpp2_ethtool_get_coalesce,
	.get_drvinfo		= mvpp2_ethtool_get_drvinfo,
	.get_ringparam		= mvpp2_ethtool_get_ringparam,
	.set_ringparam		= mvpp2_ethtool_set_ringparam,
	.get_strings		= mvpp2_ethtool_get_strings,
	.get_ethtool_stats	= mvpp2_ethtool_get_stats,
	.get_sset_count		= mvpp2_ethtool_get_sset_count,
	.get_pauseparam		= mvpp2_ethtool_get_pause_param,
	.set_pauseparam		= mvpp2_ethtool_set_pause_param,
	.get_link_ksettings	= mvpp2_ethtool_get_link_ksettings,
	.set_link_ksettings	= mvpp2_ethtool_set_link_ksettings,
	.get_rxnfc		= mvpp2_ethtool_get_rxnfc,
	.set_rxnfc		= mvpp2_ethtool_set_rxnfc,
	.get_rxfh_indir_size	= mvpp2_ethtool_get_rxfh_indir_size,
	.get_rxfh		= mvpp2_ethtool_get_rxfh,
	.set_rxfh		= mvpp2_ethtool_set_rxfh,
	.get_rxfh_context	= mvpp2_ethtool_get_rxfh_context,
	.set_rxfh_context	= mvpp2_ethtool_set_rxfh_context,
};

/* Used for PPv2.1, or PPv2.2 with the old Device Tree binding that
 * had a single IRQ defined per-port.
 */
static int mvpp2_simple_queue_vectors_init(struct mvpp2_port *port,
					   struct device_node *port_node)
{
	struct mvpp2_queue_vector *v = &port->qvecs[0];

	v->first_rxq = 0;
	v->nrxqs = port->nrxqs;
	v->type = MVPP2_QUEUE_VECTOR_SHARED;
	v->sw_thread_id = 0;
	v->sw_thread_mask = *cpumask_bits(cpu_online_mask);
	v->port = port;
	v->irq = irq_of_parse_and_map(port_node, 0);
	if (v->irq <= 0)
		return -EINVAL;
	netif_napi_add(port->dev, &v->napi, mvpp2_poll,
		       NAPI_POLL_WEIGHT);

	port->nqvecs = 1;

	return 0;
}

static int mvpp2_multi_queue_vectors_init(struct mvpp2_port *port,
					  struct device_node *port_node)
{
	struct mvpp2 *priv = port->priv;
	struct mvpp2_queue_vector *v;
	int i, ret;

	switch (queue_mode) {
	case MVPP2_QDIST_SINGLE_MODE:
		port->nqvecs = priv->nthreads + 1;
		break;
	case MVPP2_QDIST_MULTI_MODE:
		port->nqvecs = priv->nthreads;
		break;
	}

	for (i = 0; i < port->nqvecs; i++) {
		char irqname[16];

		v = port->qvecs + i;

		v->port = port;
		v->type = MVPP2_QUEUE_VECTOR_PRIVATE;
		v->sw_thread_id = i;
		v->sw_thread_mask = BIT(i);

		if (port->flags & MVPP2_F_DT_COMPAT)
			snprintf(irqname, sizeof(irqname), "tx-cpu%d", i);
		else
			snprintf(irqname, sizeof(irqname), "hif%d", i);

		if (queue_mode == MVPP2_QDIST_MULTI_MODE) {
			v->first_rxq = i;
			v->nrxqs = 1;
		} else if (queue_mode == MVPP2_QDIST_SINGLE_MODE &&
			   i == (port->nqvecs - 1)) {
			v->first_rxq = 0;
			v->nrxqs = port->nrxqs;
			v->type = MVPP2_QUEUE_VECTOR_SHARED;

			if (port->flags & MVPP2_F_DT_COMPAT)
				strncpy(irqname, "rx-shared", sizeof(irqname));
		}

		if (port_node)
			v->irq = of_irq_get_byname(port_node, irqname);
		else
			v->irq = fwnode_irq_get(port->fwnode, i);
		if (v->irq <= 0) {
			ret = -EINVAL;
			goto err;
		}

		netif_napi_add(port->dev, &v->napi, mvpp2_poll,
			       NAPI_POLL_WEIGHT);
	}

	return 0;

err:
	for (i = 0; i < port->nqvecs; i++)
		irq_dispose_mapping(port->qvecs[i].irq);
	return ret;
}

static int mvpp2_queue_vectors_init(struct mvpp2_port *port,
				    struct device_node *port_node)
{
	if (port->has_tx_irqs)
		return mvpp2_multi_queue_vectors_init(port, port_node);
	else
		return mvpp2_simple_queue_vectors_init(port, port_node);
}

static void mvpp2_queue_vectors_deinit(struct mvpp2_port *port)
{
	int i;

	for (i = 0; i < port->nqvecs; i++)
		irq_dispose_mapping(port->qvecs[i].irq);
}

/* Configure Rx queue group interrupt for this port */
static void mvpp2_rx_irqs_setup(struct mvpp2_port *port)
{
	struct mvpp2 *priv = port->priv;
	u32 val;
	int i;

	if (priv->hw_version == MVPP21) {
		mvpp2_write(priv, MVPP21_ISR_RXQ_GROUP_REG(port->id),
			    port->nrxqs);
		return;
	}

	/* Handle the more complicated PPv2.2 and PPv2.3 case */
	for (i = 0; i < port->nqvecs; i++) {
		struct mvpp2_queue_vector *qv = port->qvecs + i;

		if (!qv->nrxqs)
			continue;

		val = qv->sw_thread_id;
		val |= port->id << MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_OFFSET;
		mvpp2_write(priv, MVPP22_ISR_RXQ_GROUP_INDEX_REG, val);

		val = qv->first_rxq;
		val |= qv->nrxqs << MVPP22_ISR_RXQ_SUB_GROUP_SIZE_OFFSET;
		mvpp2_write(priv, MVPP22_ISR_RXQ_SUB_GROUP_CONFIG_REG, val);
	}
}

/* Initialize port HW */
static int mvpp2_port_init(struct mvpp2_port *port)
{
	struct device *dev = port->dev->dev.parent;
	struct mvpp2 *priv = port->priv;
	struct mvpp2_txq_pcpu *txq_pcpu;
	unsigned int thread;
	int queue, err, val;

	/* Checks for hardware constraints */
	if (port->first_rxq + port->nrxqs >
	    MVPP2_MAX_PORTS * priv->max_port_rxqs)
		return -EINVAL;

	if (port->nrxqs > priv->max_port_rxqs || port->ntxqs > MVPP2_MAX_TXQ)
		return -EINVAL;

	/* Disable port */
	mvpp2_egress_disable(port);
	mvpp2_port_disable(port);

	if (mvpp2_is_xlg(port->phy_interface)) {
		val = readl(port->base + MVPP22_XLG_CTRL0_REG);
		val &= ~MVPP22_XLG_CTRL0_FORCE_LINK_PASS;
		val |= MVPP22_XLG_CTRL0_FORCE_LINK_DOWN;
		writel(val, port->base + MVPP22_XLG_CTRL0_REG);
	} else {
		val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
		val &= ~MVPP2_GMAC_FORCE_LINK_PASS;
		val |= MVPP2_GMAC_FORCE_LINK_DOWN;
		writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
	}

	port->tx_time_coal = MVPP2_TXDONE_COAL_USEC;

	port->txqs = devm_kcalloc(dev, port->ntxqs, sizeof(*port->txqs),
				  GFP_KERNEL);
	if (!port->txqs)
		return -ENOMEM;

	/* Associate physical Tx queues to this port and initialize.
	 * The mapping is predefined.
	 */
	for (queue = 0; queue < port->ntxqs; queue++) {
		int queue_phy_id = mvpp2_txq_phys(port->id, queue);
		struct mvpp2_tx_queue *txq;

		txq = devm_kzalloc(dev, sizeof(*txq), GFP_KERNEL);
		if (!txq) {
			err = -ENOMEM;
			goto err_free_percpu;
		}

		txq->pcpu = alloc_percpu(struct mvpp2_txq_pcpu);
		if (!txq->pcpu) {
			err = -ENOMEM;
			goto err_free_percpu;
		}

		txq->id = queue_phy_id;
		txq->log_id = queue;
		txq->done_pkts_coal = MVPP2_TXDONE_COAL_PKTS_THRESH;
		for (thread = 0; thread < priv->nthreads; thread++) {
			txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
			txq_pcpu->thread = thread;
		}

		port->txqs[queue] = txq;
	}

	port->rxqs = devm_kcalloc(dev, port->nrxqs, sizeof(*port->rxqs),
				  GFP_KERNEL);
	if (!port->rxqs) {
		err = -ENOMEM;
		goto err_free_percpu;
	}

	/* Allocate and initialize Rx queue for this port */
	for (queue = 0; queue < port->nrxqs; queue++) {
		struct mvpp2_rx_queue *rxq;

		/* Map physical Rx queue to port's logical Rx queue */
		rxq = devm_kzalloc(dev, sizeof(*rxq), GFP_KERNEL);
		if (!rxq) {
			err = -ENOMEM;
			goto err_free_percpu;
		}
		/* Map this Rx queue to a physical queue */
		rxq->id = port->first_rxq + queue;
		rxq->port = port->id;
		rxq->logic_rxq = queue;

		port->rxqs[queue] = rxq;
	}

	mvpp2_rx_irqs_setup(port);

	/* Create Rx descriptor rings */
	for (queue = 0; queue < port->nrxqs; queue++) {
		struct mvpp2_rx_queue *rxq = port->rxqs[queue];

		rxq->size = port->rx_ring_size;
		rxq->pkts_coal = MVPP2_RX_COAL_PKTS;
		rxq->time_coal = MVPP2_RX_COAL_USEC;
	}

	mvpp2_ingress_disable(port);

	/* Port default configuration */
	mvpp2_defaults_set(port);

	/* Port's classifier configuration */
	mvpp2_cls_oversize_rxq_set(port);
	mvpp2_cls_port_config(port);

	if (mvpp22_rss_is_supported(port))
		mvpp22_port_rss_init(port);

	/* Provide an initial Rx packet size */
	port->pkt_size = MVPP2_RX_PKT_SIZE(port->dev->mtu);

	/* Initialize pools for swf */
	err = mvpp2_swf_bm_pool_init(port);
	if (err)
		goto err_free_percpu;

	/* Clear all port stats */
	mvpp2_read_stats(port);
	memset(port->ethtool_stats, 0,
	       MVPP2_N_ETHTOOL_STATS(port->ntxqs, port->nrxqs) * sizeof(u64));

	return 0;

err_free_percpu:
	for (queue = 0; queue < port->ntxqs; queue++) {
		if (!port->txqs[queue])
			continue;
		free_percpu(port->txqs[queue]->pcpu);
	}
	return err;
}

static bool mvpp22_port_has_legacy_tx_irqs(struct device_node *port_node,
					   unsigned long *flags)
{
	char *irqs[5] = { "rx-shared", "tx-cpu0", "tx-cpu1", "tx-cpu2",
			  "tx-cpu3" };
	int i;

	for (i = 0; i < 5; i++)
		if (of_property_match_string(port_node, "interrupt-names",
					     irqs[i]) < 0)
			return false;

	*flags |= MVPP2_F_DT_COMPAT;
	return true;
}

/* Checks if the port dt description has the required Tx interrupts:
 * - PPv2.1: there are no such interrupts.
 * - PPv2.2 and PPv2.3:
 *   - The old DTs have: "rx-shared", "tx-cpuX" with X in [0...3]
 *   - The new ones have: "hifX" with X in [0..8]
 *
 * All those variants are supported to keep the backward compatibility.
 */
static bool mvpp2_port_has_irqs(struct mvpp2 *priv,
				struct device_node *port_node,
				unsigned long *flags)
{
	char name[5];
	int i;

	/* ACPI */
	if (!port_node)
		return true;

	if (priv->hw_version == MVPP21)
		return false;

	if (mvpp22_port_has_legacy_tx_irqs(port_node, flags))
		return true;

	for (i = 0; i < MVPP2_MAX_THREADS; i++) {
		snprintf(name, 5, "hif%d", i);
		if (of_property_match_string(port_node, "interrupt-names",
					     name) < 0)
			return false;
	}

	return true;
}

static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
				     struct fwnode_handle *fwnode,
				     char **mac_from)
{
	struct mvpp2_port *port = netdev_priv(dev);
	char hw_mac_addr[ETH_ALEN] = {0};
	char fw_mac_addr[ETH_ALEN];

	if (!fwnode_get_mac_address(fwnode, fw_mac_addr)) {
		*mac_from = "firmware node";
		eth_hw_addr_set(dev, fw_mac_addr);
		return;
	}

	if (priv->hw_version == MVPP21) {
		mvpp21_get_mac_address(port, hw_mac_addr);
		if (is_valid_ether_addr(hw_mac_addr)) {
			*mac_from = "hardware";
			eth_hw_addr_set(dev, hw_mac_addr);
			return;
		}
	}

	*mac_from = "random";
	eth_hw_addr_random(dev);
}

static struct mvpp2_port *mvpp2_phylink_to_port(struct phylink_config *config)
{
	return container_of(config, struct mvpp2_port, phylink_config);
}

static struct mvpp2_port *mvpp2_pcs_to_port(struct phylink_pcs *pcs)
{
	return container_of(pcs, struct mvpp2_port, phylink_pcs);
}

static void mvpp2_xlg_pcs_get_state(struct phylink_pcs *pcs,
				    struct phylink_link_state *state)
{
	struct mvpp2_port *port = mvpp2_pcs_to_port(pcs);
	u32 val;

	state->speed = SPEED_10000;
	state->duplex = 1;
	state->an_complete = 1;

	val = readl(port->base + MVPP22_XLG_STATUS);
	state->link = !!(val & MVPP22_XLG_STATUS_LINK_UP);

	state->pause = 0;
	val = readl(port->base + MVPP22_XLG_CTRL0_REG);
	if (val & MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN)
		state->pause |= MLO_PAUSE_TX;
	if (val & MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN)
		state->pause |= MLO_PAUSE_RX;
}

static int mvpp2_xlg_pcs_config(struct phylink_pcs *pcs,
				unsigned int mode,
				phy_interface_t interface,
				const unsigned long *advertising,
				bool permit_pause_to_mac)
{
	return 0;
}

static const struct phylink_pcs_ops mvpp2_phylink_xlg_pcs_ops = {
	.pcs_get_state = mvpp2_xlg_pcs_get_state,
	.pcs_config = mvpp2_xlg_pcs_config,
};

static void mvpp2_gmac_pcs_get_state(struct phylink_pcs *pcs,
				     struct phylink_link_state *state)
{
	struct mvpp2_port *port = mvpp2_pcs_to_port(pcs);
	u32 val;

	val = readl(port->base + MVPP2_GMAC_STATUS0);

	state->an_complete = !!(val & MVPP2_GMAC_STATUS0_AN_COMPLETE);
	state->link = !!(val & MVPP2_GMAC_STATUS0_LINK_UP);
	state->duplex = !!(val & MVPP2_GMAC_STATUS0_FULL_DUPLEX);

	switch (port->phy_interface) {
	case PHY_INTERFACE_MODE_1000BASEX:
		state->speed = SPEED_1000;
		break;
	case PHY_INTERFACE_MODE_2500BASEX:
		state->speed = SPEED_2500;
		break;
	default:
		if (val & MVPP2_GMAC_STATUS0_GMII_SPEED)
			state->speed = SPEED_1000;
		else if (val & MVPP2_GMAC_STATUS0_MII_SPEED)
			state->speed = SPEED_100;
		else
			state->speed = SPEED_10;
	}

	state->pause = 0;
	if (val & MVPP2_GMAC_STATUS0_RX_PAUSE)
		state->pause |= MLO_PAUSE_RX;
	if (val & MVPP2_GMAC_STATUS0_TX_PAUSE)
		state->pause |= MLO_PAUSE_TX;
}

static int mvpp2_gmac_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
				 phy_interface_t interface,
				 const unsigned long *advertising,
				 bool permit_pause_to_mac)
{
	struct mvpp2_port *port = mvpp2_pcs_to_port(pcs);
	u32 mask, val, an, old_an, changed;

	mask = MVPP2_GMAC_IN_BAND_AUTONEG_BYPASS |
	       MVPP2_GMAC_IN_BAND_AUTONEG |
	       MVPP2_GMAC_AN_SPEED_EN |
	       MVPP2_GMAC_FLOW_CTRL_AUTONEG |
	       MVPP2_GMAC_AN_DUPLEX_EN;

	if (phylink_autoneg_inband(mode)) {
		mask |= MVPP2_GMAC_CONFIG_MII_SPEED |
			MVPP2_GMAC_CONFIG_GMII_SPEED |
			MVPP2_GMAC_CONFIG_FULL_DUPLEX;
		val = MVPP2_GMAC_IN_BAND_AUTONEG;

		if (interface == PHY_INTERFACE_MODE_SGMII) {
			/* SGMII mode receives the speed and duplex from PHY */
			val |= MVPP2_GMAC_AN_SPEED_EN |
			       MVPP2_GMAC_AN_DUPLEX_EN;
		} else {
			/* 802.3z mode has fixed speed and duplex */
			val |= MVPP2_GMAC_CONFIG_GMII_SPEED |
			       MVPP2_GMAC_CONFIG_FULL_DUPLEX;

			/* The FLOW_CTRL_AUTONEG bit selects either the hardware
			 * automatically or the bits in MVPP22_GMAC_CTRL_4_REG
			 * manually controls the GMAC pause modes.
			 */
			if (permit_pause_to_mac)
				val |= MVPP2_GMAC_FLOW_CTRL_AUTONEG;

			/* Configure advertisement bits */
			mask |= MVPP2_GMAC_FC_ADV_EN | MVPP2_GMAC_FC_ADV_ASM_EN;
			if (phylink_test(advertising, Pause))
				val |= MVPP2_GMAC_FC_ADV_EN;
			if (phylink_test(advertising, Asym_Pause))
				val |= MVPP2_GMAC_FC_ADV_ASM_EN;
		}
	} else {
		val = 0;
	}

	old_an = an = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
	an = (an & ~mask) | val;
	changed = an ^ old_an;
	if (changed)
		writel(an, port->base + MVPP2_GMAC_AUTONEG_CONFIG);

	/* We are only interested in the advertisement bits changing */
	return changed & (MVPP2_GMAC_FC_ADV_EN | MVPP2_GMAC_FC_ADV_ASM_EN);
}

static void mvpp2_gmac_pcs_an_restart(struct phylink_pcs *pcs)
{
	struct mvpp2_port *port = mvpp2_pcs_to_port(pcs);
	u32 val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);

	writel(val | MVPP2_GMAC_IN_BAND_RESTART_AN,
	       port->base + MVPP2_GMAC_AUTONEG_CONFIG);
	writel(val & ~MVPP2_GMAC_IN_BAND_RESTART_AN,
	       port->base + MVPP2_GMAC_AUTONEG_CONFIG);
}

static const struct phylink_pcs_ops mvpp2_phylink_gmac_pcs_ops = {
	.pcs_get_state = mvpp2_gmac_pcs_get_state,
	.pcs_config = mvpp2_gmac_pcs_config,
	.pcs_an_restart = mvpp2_gmac_pcs_an_restart,
};

static void mvpp2_phylink_validate(struct phylink_config *config,
				   unsigned long *supported,
				   struct phylink_link_state *state)
{
	struct mvpp2_port *port = mvpp2_phylink_to_port(config);
	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };

	/* When in 802.3z mode, we must have AN enabled:
	 * Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ...
	 * When <PortType> = 1 (1000BASE-X) this field must be set to 1.
	 */
	if (phy_interface_mode_is_8023z(state->interface) &&
	    !phylink_test(state->advertising, Autoneg))
		goto empty_set;

	phylink_set(mask, Autoneg);
	phylink_set_port_modes(mask);

	if (port->priv->global_tx_fc) {
		phylink_set(mask, Pause);
		phylink_set(mask, Asym_Pause);
	}

	switch (state->interface) {
	case PHY_INTERFACE_MODE_10GBASER:
	case PHY_INTERFACE_MODE_XAUI:
		if (mvpp2_port_supports_xlg(port)) {
			phylink_set_10g_modes(mask);
			phylink_set(mask, 10000baseKR_Full);
		}
		break;

	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII_RXID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
	case PHY_INTERFACE_MODE_SGMII:
		phylink_set(mask, 10baseT_Half);
		phylink_set(mask, 10baseT_Full);
		phylink_set(mask, 100baseT_Half);
		phylink_set(mask, 100baseT_Full);
		phylink_set(mask, 1000baseT_Full);
		phylink_set(mask, 1000baseX_Full);
		break;

	case PHY_INTERFACE_MODE_1000BASEX:
		phylink_set(mask, 1000baseT_Full);
		phylink_set(mask, 1000baseX_Full);
		break;

	case PHY_INTERFACE_MODE_2500BASEX:
		phylink_set(mask, 2500baseT_Full);
		phylink_set(mask, 2500baseX_Full);
		break;

	default:
		goto empty_set;
	}

	linkmode_and(supported, supported, mask);
	linkmode_and(state->advertising, state->advertising, mask);
	return;

empty_set:
	linkmode_zero(supported);
}

static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode,
			     const struct phylink_link_state *state)
{
	u32 val;

	mvpp2_modify(port->base + MVPP22_XLG_CTRL0_REG,
		     MVPP22_XLG_CTRL0_MAC_RESET_DIS,
		     MVPP22_XLG_CTRL0_MAC_RESET_DIS);
	mvpp2_modify(port->base + MVPP22_XLG_CTRL4_REG,
		     MVPP22_XLG_CTRL4_MACMODSELECT_GMAC |
		     MVPP22_XLG_CTRL4_EN_IDLE_CHECK |
		     MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC,
		     MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC);

	/* Wait for reset to deassert */
	do {
		val = readl(port->base + MVPP22_XLG_CTRL0_REG);
	} while (!(val & MVPP22_XLG_CTRL0_MAC_RESET_DIS));
}

static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
			      const struct phylink_link_state *state)
{
	u32 old_ctrl0, ctrl0;
	u32 old_ctrl2, ctrl2;
	u32 old_ctrl4, ctrl4;

	old_ctrl0 = ctrl0 = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
	old_ctrl2 = ctrl2 = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
	old_ctrl4 = ctrl4 = readl(port->base + MVPP22_GMAC_CTRL_4_REG);

	ctrl0 &= ~MVPP2_GMAC_PORT_TYPE_MASK;
	ctrl2 &= ~(MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK | MVPP2_GMAC_FLOW_CTRL_MASK);

	/* Configure port type */
	if (phy_interface_mode_is_8023z(state->interface)) {
		ctrl2 |= MVPP2_GMAC_PCS_ENABLE_MASK;
		ctrl4 &= ~MVPP22_CTRL4_EXT_PIN_GMII_SEL;
		ctrl4 |= MVPP22_CTRL4_SYNC_BYPASS_DIS |
			 MVPP22_CTRL4_DP_CLK_SEL |
			 MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
	} else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
		ctrl2 |= MVPP2_GMAC_PCS_ENABLE_MASK | MVPP2_GMAC_INBAND_AN_MASK;
		ctrl4 &= ~MVPP22_CTRL4_EXT_PIN_GMII_SEL;
		ctrl4 |= MVPP22_CTRL4_SYNC_BYPASS_DIS |
			 MVPP22_CTRL4_DP_CLK_SEL |
			 MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
	} else if (phy_interface_mode_is_rgmii(state->interface)) {
		ctrl4 &= ~MVPP22_CTRL4_DP_CLK_SEL;
		ctrl4 |= MVPP22_CTRL4_EXT_PIN_GMII_SEL |
			 MVPP22_CTRL4_SYNC_BYPASS_DIS |
			 MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
	}

	/* Configure negotiation style */
	if (!phylink_autoneg_inband(mode)) {
		/* Phy or fixed speed - no in-band AN, nothing to do, leave the
		 * configured speed, duplex and flow control as-is.
		 */
	} else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
		/* SGMII in-band mode receives the speed and duplex from
		 * the PHY. Flow control information is not received. */
	} else if (phy_interface_mode_is_8023z(state->interface)) {
		/* 1000BaseX and 2500BaseX ports cannot negotiate speed nor can
		 * they negotiate duplex: they are always operating with a fixed
		 * speed of 1000/2500Mbps in full duplex, so force 1000/2500
		 * speed and full duplex here.
		 */
		ctrl0 |= MVPP2_GMAC_PORT_TYPE_MASK;
	}

	if (old_ctrl0 != ctrl0)
		writel(ctrl0, port->base + MVPP2_GMAC_CTRL_0_REG);
	if (old_ctrl2 != ctrl2)
		writel(ctrl2, port->base + MVPP2_GMAC_CTRL_2_REG);
	if (old_ctrl4 != ctrl4)
		writel(ctrl4, port->base + MVPP22_GMAC_CTRL_4_REG);
}

static int mvpp2__mac_prepare(struct phylink_config *config, unsigned int mode,
			      phy_interface_t interface)
{
	struct mvpp2_port *port = mvpp2_phylink_to_port(config);

	/* Check for invalid configuration */
	if (mvpp2_is_xlg(interface) && port->gop_id != 0) {
		netdev_err(port->dev, "Invalid mode on %s\n", port->dev->name);
		return -EINVAL;
	}

	if (port->phy_interface != interface ||
	    phylink_autoneg_inband(mode)) {
		/* Force the link down when changing the interface or if in
		 * in-band mode to ensure we do not change the configuration
		 * while the hardware is indicating link is up. We force both
		 * XLG and GMAC down to ensure that they're both in a known
		 * state.
		 */
		mvpp2_modify(port->base + MVPP2_GMAC_AUTONEG_CONFIG,
			     MVPP2_GMAC_FORCE_LINK_PASS |
			     MVPP2_GMAC_FORCE_LINK_DOWN,
			     MVPP2_GMAC_FORCE_LINK_DOWN);

		if (mvpp2_port_supports_xlg(port))
			mvpp2_modify(port->base + MVPP22_XLG_CTRL0_REG,
				     MVPP22_XLG_CTRL0_FORCE_LINK_PASS |
				     MVPP22_XLG_CTRL0_FORCE_LINK_DOWN,
				     MVPP22_XLG_CTRL0_FORCE_LINK_DOWN);
	}

	/* Make sure the port is disabled when reconfiguring the mode */
	mvpp2_port_disable(port);

	if (port->phy_interface != interface) {
		/* Place GMAC into reset */
		mvpp2_modify(port->base + MVPP2_GMAC_CTRL_2_REG,
			     MVPP2_GMAC_PORT_RESET_MASK,
			     MVPP2_GMAC_PORT_RESET_MASK);

		if (port->priv->hw_version >= MVPP22) {
			mvpp22_gop_mask_irq(port);

			phy_power_off(port->comphy);

			/* Reconfigure the serdes lanes */
			mvpp22_mode_reconfigure(port, interface);
		}
	}

	/* Select the appropriate PCS operations depending on the
	 * configured interface mode. We will only switch to a mode
	 * that the validate() checks have already passed.
	 */
	if (mvpp2_is_xlg(interface))
		port->phylink_pcs.ops = &mvpp2_phylink_xlg_pcs_ops;
	else
		port->phylink_pcs.ops = &mvpp2_phylink_gmac_pcs_ops;

	return 0;
}

static int mvpp2_mac_prepare(struct phylink_config *config, unsigned int mode,
			     phy_interface_t interface)
{
	struct mvpp2_port *port = mvpp2_phylink_to_port(config);
	int ret;

	ret = mvpp2__mac_prepare(config, mode, interface);
	if (ret == 0)
		phylink_set_pcs(port->phylink, &port->phylink_pcs);

	return ret;
}

static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode,
			     const struct phylink_link_state *state)
{
	struct mvpp2_port *port = mvpp2_phylink_to_port(config);

	/* mac (re)configuration */
	if (mvpp2_is_xlg(state->interface))
		mvpp2_xlg_config(port, mode, state);
	else if (phy_interface_mode_is_rgmii(state->interface) ||
		 phy_interface_mode_is_8023z(state->interface) ||
		 state->interface == PHY_INTERFACE_MODE_SGMII)
		mvpp2_gmac_config(port, mode, state);

	if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK)
		mvpp2_port_loopback_set(port, state);
}

static int mvpp2_mac_finish(struct phylink_config *config, unsigned int mode,
			    phy_interface_t interface)
{
	struct mvpp2_port *port = mvpp2_phylink_to_port(config);

	if (port->priv->hw_version >= MVPP22 &&
	    port->phy_interface != interface) {
		port->phy_interface = interface;

		/* Unmask interrupts */
		mvpp22_gop_unmask_irq(port);
	}

	if (!mvpp2_is_xlg(interface)) {
		/* Release GMAC reset and wait */
		mvpp2_modify(port->base + MVPP2_GMAC_CTRL_2_REG,
			     MVPP2_GMAC_PORT_RESET_MASK, 0);

		while (readl(port->base + MVPP2_GMAC_CTRL_2_REG) &
		       MVPP2_GMAC_PORT_RESET_MASK)
			continue;
	}

	mvpp2_port_enable(port);

	/* Allow the link to come up if in in-band mode, otherwise the
	 * link is forced via mac_link_down()/mac_link_up()
	 */
	if (phylink_autoneg_inband(mode)) {
		if (mvpp2_is_xlg(interface))
			mvpp2_modify(port->base + MVPP22_XLG_CTRL0_REG,
				     MVPP22_XLG_CTRL0_FORCE_LINK_PASS |
				     MVPP22_XLG_CTRL0_FORCE_LINK_DOWN, 0);
		else
			mvpp2_modify(port->base + MVPP2_GMAC_AUTONEG_CONFIG,
				     MVPP2_GMAC_FORCE_LINK_PASS |
				     MVPP2_GMAC_FORCE_LINK_DOWN, 0);
	}

	return 0;
}

static void mvpp2_mac_link_up(struct phylink_config *config,
			      struct phy_device *phy,
			      unsigned int mode, phy_interface_t interface,
			      int speed, int duplex,
			      bool tx_pause, bool rx_pause)
{
	struct mvpp2_port *port = mvpp2_phylink_to_port(config);
	u32 val;
	int i;

	if (mvpp2_is_xlg(interface)) {
		if (!phylink_autoneg_inband(mode)) {
			val = MVPP22_XLG_CTRL0_FORCE_LINK_PASS;
			if (tx_pause)
				val |= MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN;
			if (rx_pause)
				val |= MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN;

			mvpp2_modify(port->base + MVPP22_XLG_CTRL0_REG,
				     MVPP22_XLG_CTRL0_FORCE_LINK_DOWN |
				     MVPP22_XLG_CTRL0_FORCE_LINK_PASS |
				     MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN |
				     MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN, val);
		}
	} else {
		if (!phylink_autoneg_inband(mode)) {
			val = MVPP2_GMAC_FORCE_LINK_PASS;

			if (speed == SPEED_1000 || speed == SPEED_2500)
				val |= MVPP2_GMAC_CONFIG_GMII_SPEED;
			else if (speed == SPEED_100)
				val |= MVPP2_GMAC_CONFIG_MII_SPEED;

			if (duplex == DUPLEX_FULL)
				val |= MVPP2_GMAC_CONFIG_FULL_DUPLEX;

			mvpp2_modify(port->base + MVPP2_GMAC_AUTONEG_CONFIG,
				     MVPP2_GMAC_FORCE_LINK_DOWN |
				     MVPP2_GMAC_FORCE_LINK_PASS |
				     MVPP2_GMAC_CONFIG_MII_SPEED |
				     MVPP2_GMAC_CONFIG_GMII_SPEED |
				     MVPP2_GMAC_CONFIG_FULL_DUPLEX, val);
		}

		/* We can always update the flow control enable bits;
		 * these will only be effective if flow control AN
		 * (MVPP2_GMAC_FLOW_CTRL_AUTONEG) is disabled.
		 */
		val = 0;
		if (tx_pause)
			val |= MVPP22_CTRL4_TX_FC_EN;
		if (rx_pause)
			val |= MVPP22_CTRL4_RX_FC_EN;

		mvpp2_modify(port->base + MVPP22_GMAC_CTRL_4_REG,
			     MVPP22_CTRL4_RX_FC_EN | MVPP22_CTRL4_TX_FC_EN,
			     val);
	}

	if (port->priv->global_tx_fc) {
		port->tx_fc = tx_pause;
		if (tx_pause)
			mvpp2_rxq_enable_fc(port);
		else
			mvpp2_rxq_disable_fc(port);
		if (port->priv->percpu_pools) {
			for (i = 0; i < port->nrxqs; i++)
				mvpp2_bm_pool_update_fc(port, &port->priv->bm_pools[i], tx_pause);
		} else {
			mvpp2_bm_pool_update_fc(port, port->pool_long, tx_pause);
			mvpp2_bm_pool_update_fc(port, port->pool_short, tx_pause);
		}
		if (port->priv->hw_version == MVPP23)
			mvpp23_rx_fifo_fc_en(port->priv, port->id, tx_pause);
	}

	mvpp2_port_enable(port);

	mvpp2_egress_enable(port);
	mvpp2_ingress_enable(port);
	netif_tx_wake_all_queues(port->dev);
}

static void mvpp2_mac_link_down(struct phylink_config *config,
				unsigned int mode, phy_interface_t interface)
{
	struct mvpp2_port *port = mvpp2_phylink_to_port(config);
	u32 val;

	if (!phylink_autoneg_inband(mode)) {
		if (mvpp2_is_xlg(interface)) {
			val = readl(port->base + MVPP22_XLG_CTRL0_REG);
			val &= ~MVPP22_XLG_CTRL0_FORCE_LINK_PASS;
			val |= MVPP22_XLG_CTRL0_FORCE_LINK_DOWN;
			writel(val, port->base + MVPP22_XLG_CTRL0_REG);
		} else {
			val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
			val &= ~MVPP2_GMAC_FORCE_LINK_PASS;
			val |= MVPP2_GMAC_FORCE_LINK_DOWN;
			writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
		}
	}

	netif_tx_stop_all_queues(port->dev);
	mvpp2_egress_disable(port);
	mvpp2_ingress_disable(port);

	mvpp2_port_disable(port);
}

static const struct phylink_mac_ops mvpp2_phylink_ops = {
	.validate = mvpp2_phylink_validate,
	.mac_prepare = mvpp2_mac_prepare,
	.mac_config = mvpp2_mac_config,
	.mac_finish = mvpp2_mac_finish,
	.mac_link_up = mvpp2_mac_link_up,
	.mac_link_down = mvpp2_mac_link_down,
};

/* Work-around for ACPI */
static void mvpp2_acpi_start(struct mvpp2_port *port)
{
	/* Phylink isn't used as of now for ACPI, so the MAC has to be
	 * configured manually when the interface is started. This will
	 * be removed as soon as the phylink ACPI support lands in.
	 */
	struct phylink_link_state state = {
		.interface = port->phy_interface,
	};
	mvpp2__mac_prepare(&port->phylink_config, MLO_AN_INBAND,
			   port->phy_interface);
	mvpp2_mac_config(&port->phylink_config, MLO_AN_INBAND, &state);
	port->phylink_pcs.ops->pcs_config(&port->phylink_pcs, MLO_AN_INBAND,
					  port->phy_interface,
					  state.advertising, false);
	mvpp2_mac_finish(&port->phylink_config, MLO_AN_INBAND,
			 port->phy_interface);
	mvpp2_mac_link_up(&port->phylink_config, NULL,
			  MLO_AN_INBAND, port->phy_interface,
			  SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false);
}

/* In order to ensure backward compatibility for ACPI, check if the port
 * firmware node comprises the necessary description allowing to use phylink.
 */
static bool mvpp2_use_acpi_compat_mode(struct fwnode_handle *port_fwnode)
{
	if (!is_acpi_node(port_fwnode))
		return false;

	return (!fwnode_property_present(port_fwnode, "phy-handle") &&
		!fwnode_property_present(port_fwnode, "managed") &&
		!fwnode_get_named_child_node(port_fwnode, "fixed-link"));
}

/* Ports initialization */
static int mvpp2_port_probe(struct platform_device *pdev,
			    struct fwnode_handle *port_fwnode,
			    struct mvpp2 *priv)
{
	struct phy *comphy = NULL;
	struct mvpp2_port *port;
	struct mvpp2_port_pcpu *port_pcpu;
	struct device_node *port_node = to_of_node(port_fwnode);
	netdev_features_t features;
	struct net_device *dev;
	struct phylink *phylink;
	char *mac_from = "";
	unsigned int ntxqs, nrxqs, thread;
	unsigned long flags = 0;
	bool has_tx_irqs;
	u32 id;
	int phy_mode;
	int err, i;

	has_tx_irqs = mvpp2_port_has_irqs(priv, port_node, &flags);
	if (!has_tx_irqs && queue_mode == MVPP2_QDIST_MULTI_MODE) {
		dev_err(&pdev->dev,
			"not enough IRQs to support multi queue mode\n");
		return -EINVAL;
	}

	ntxqs = MVPP2_MAX_TXQ;
	nrxqs = mvpp2_get_nrxqs(priv);

	dev = alloc_etherdev_mqs(sizeof(*port), ntxqs, nrxqs);
	if (!dev)
		return -ENOMEM;

	phy_mode = fwnode_get_phy_mode(port_fwnode);
	if (phy_mode < 0) {
		dev_err(&pdev->dev, "incorrect phy mode\n");
		err = phy_mode;
		goto err_free_netdev;
	}

	/*
	 * Rewrite 10GBASE-KR to 10GBASE-R for compatibility with existing DT.
	 * Existing usage of 10GBASE-KR is not correct; no backplane
	 * negotiation is done, and this driver does not actually support
	 * 10GBASE-KR.
	 */
	if (phy_mode == PHY_INTERFACE_MODE_10GKR)
		phy_mode = PHY_INTERFACE_MODE_10GBASER;

	if (port_node) {
		comphy = devm_of_phy_get(&pdev->dev, port_node, NULL);
		if (IS_ERR(comphy)) {
			if (PTR_ERR(comphy) == -EPROBE_DEFER) {
				err = -EPROBE_DEFER;
				goto err_free_netdev;
			}
			comphy = NULL;
		}
	}

	if (fwnode_property_read_u32(port_fwnode, "port-id", &id)) {
		err = -EINVAL;
		dev_err(&pdev->dev, "missing port-id value\n");
		goto err_free_netdev;
	}

	dev->tx_queue_len = MVPP2_MAX_TXD_MAX;
	dev->watchdog_timeo = 5 * HZ;
	dev->netdev_ops = &mvpp2_netdev_ops;
	dev->ethtool_ops = &mvpp2_eth_tool_ops;

	port = netdev_priv(dev);
	port->dev = dev;
	port->fwnode = port_fwnode;
	port->ntxqs = ntxqs;
	port->nrxqs = nrxqs;
	port->priv = priv;
	port->has_tx_irqs = has_tx_irqs;
	port->flags = flags;

	err = mvpp2_queue_vectors_init(port, port_node);
	if (err)
		goto err_free_netdev;

	if (port_node)
		port->port_irq = of_irq_get_byname(port_node, "link");
	else
		port->port_irq = fwnode_irq_get(port_fwnode, port->nqvecs + 1);
	if (port->port_irq == -EPROBE_DEFER) {
		err = -EPROBE_DEFER;
		goto err_deinit_qvecs;
	}
	if (port->port_irq <= 0)
		/* the link irq is optional */
		port->port_irq = 0;

	if (fwnode_property_read_bool(port_fwnode, "marvell,loopback"))
		port->flags |= MVPP2_F_LOOPBACK;

	port->id = id;
	if (priv->hw_version == MVPP21)
		port->first_rxq = port->id * port->nrxqs;
	else
		port->first_rxq = port->id * priv->max_port_rxqs;

	port->of_node = port_node;
	port->phy_interface = phy_mode;
	port->comphy = comphy;

	if (priv->hw_version == MVPP21) {
		port->base = devm_platform_ioremap_resource(pdev, 2 + id);
		if (IS_ERR(port->base)) {
			err = PTR_ERR(port->base);
			goto err_free_irq;
		}

		port->stats_base = port->priv->lms_base +
				   MVPP21_MIB_COUNTERS_OFFSET +
				   port->gop_id * MVPP21_MIB_COUNTERS_PORT_SZ;
	} else {
		if (fwnode_property_read_u32(port_fwnode, "gop-port-id",
					     &port->gop_id)) {
			err = -EINVAL;
			dev_err(&pdev->dev, "missing gop-port-id value\n");
			goto err_deinit_qvecs;
		}

		port->base = priv->iface_base + MVPP22_GMAC_BASE(port->gop_id);
		port->stats_base = port->priv->iface_base +
				   MVPP22_MIB_COUNTERS_OFFSET +
				   port->gop_id * MVPP22_MIB_COUNTERS_PORT_SZ;

		/* We may want a property to describe whether we should use
		 * MAC hardware timestamping.
		 */
		if (priv->tai)
			port->hwtstamp = true;
	}

	/* Alloc per-cpu and ethtool stats */
	port->stats = netdev_alloc_pcpu_stats(struct mvpp2_pcpu_stats);
	if (!port->stats) {
		err = -ENOMEM;
		goto err_free_irq;
	}

	port->ethtool_stats = devm_kcalloc(&pdev->dev,
					   MVPP2_N_ETHTOOL_STATS(ntxqs, nrxqs),
					   sizeof(u64), GFP_KERNEL);
	if (!port->ethtool_stats) {
		err = -ENOMEM;
		goto err_free_stats;
	}

	mutex_init(&port->gather_stats_lock);
	INIT_DELAYED_WORK(&port->stats_work, mvpp2_gather_hw_statistics);

	mvpp2_port_copy_mac_addr(dev, priv, port_fwnode, &mac_from);

	port->tx_ring_size = MVPP2_MAX_TXD_DFLT;
	port->rx_ring_size = MVPP2_MAX_RXD_DFLT;
	SET_NETDEV_DEV(dev, &pdev->dev);

	err = mvpp2_port_init(port);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to init port %d\n", id);
		goto err_free_stats;
	}

	mvpp2_port_periodic_xon_disable(port);

	mvpp2_mac_reset_assert(port);
	mvpp22_pcs_reset_assert(port);

	port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
	if (!port->pcpu) {
		err = -ENOMEM;
		goto err_free_txq_pcpu;
	}

	if (!port->has_tx_irqs) {
		for (thread = 0; thread < priv->nthreads; thread++) {
			port_pcpu = per_cpu_ptr(port->pcpu, thread);

			hrtimer_init(&port_pcpu->tx_done_timer, CLOCK_MONOTONIC,
				     HRTIMER_MODE_REL_PINNED_SOFT);
			port_pcpu->tx_done_timer.function = mvpp2_hr_timer_cb;
			port_pcpu->timer_scheduled = false;
			port_pcpu->dev = dev;
		}
	}

	features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
		   NETIF_F_TSO;
	dev->features = features | NETIF_F_RXCSUM;
	dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO |
			    NETIF_F_HW_VLAN_CTAG_FILTER;

	if (mvpp22_rss_is_supported(port)) {
		dev->hw_features |= NETIF_F_RXHASH;
		dev->features |= NETIF_F_NTUPLE;
	}

	if (!port->priv->percpu_pools)
		mvpp2_set_hw_csum(port, port->pool_long->id);

	dev->vlan_features |= features;
	dev->gso_max_segs = MVPP2_MAX_TSO_SEGS;
	dev->priv_flags |= IFF_UNICAST_FLT;

	/* MTU range: 68 - 9704 */
	dev->min_mtu = ETH_MIN_MTU;
	/* 9704 == 9728 - 20 and rounding to 8 */
	dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
	dev->dev.of_node = port_node;

	if (!mvpp2_use_acpi_compat_mode(port_fwnode)) {
		port->phylink_config.dev = &dev->dev;
		port->phylink_config.type = PHYLINK_NETDEV;

		if (mvpp2_port_supports_xlg(port)) {
			__set_bit(PHY_INTERFACE_MODE_10GBASER,
				  port->phylink_config.supported_interfaces);
			__set_bit(PHY_INTERFACE_MODE_XAUI,
				  port->phylink_config.supported_interfaces);
		}

		if (mvpp2_port_supports_rgmii(port))
			phy_interface_set_rgmii(port->phylink_config.supported_interfaces);

		if (comphy) {
			/* If a COMPHY is present, we can support any of the
			 * serdes modes and switch between them.
			 */
			__set_bit(PHY_INTERFACE_MODE_SGMII,
				  port->phylink_config.supported_interfaces);
			__set_bit(PHY_INTERFACE_MODE_1000BASEX,
				  port->phylink_config.supported_interfaces);
			__set_bit(PHY_INTERFACE_MODE_2500BASEX,
				  port->phylink_config.supported_interfaces);
		} else if (phy_mode == PHY_INTERFACE_MODE_2500BASEX) {
			/* No COMPHY, with only 2500BASE-X mode supported */
			__set_bit(PHY_INTERFACE_MODE_2500BASEX,
				  port->phylink_config.supported_interfaces);
		} else if (phy_mode == PHY_INTERFACE_MODE_1000BASEX ||
			   phy_mode == PHY_INTERFACE_MODE_SGMII) {
			/* No COMPHY, we can switch between 1000BASE-X and SGMII
			 */
			__set_bit(PHY_INTERFACE_MODE_1000BASEX,
				  port->phylink_config.supported_interfaces);
			__set_bit(PHY_INTERFACE_MODE_SGMII,
				  port->phylink_config.supported_interfaces);
		}

		phylink = phylink_create(&port->phylink_config, port_fwnode,
					 phy_mode, &mvpp2_phylink_ops);
		if (IS_ERR(phylink)) {
			err = PTR_ERR(phylink);
			goto err_free_port_pcpu;
		}
		port->phylink = phylink;
	} else {
		dev_warn(&pdev->dev, "Use link irqs for port#%d. FW update required\n", port->id);
		port->phylink = NULL;
	}

	/* Cycle the comphy to power it down, saving 270mW per port -
	 * don't worry about an error powering it up. When the comphy
	 * driver does this, we can remove this code.
	 */
	if (port->comphy) {
		err = mvpp22_comphy_init(port, port->phy_interface);
		if (err == 0)
			phy_power_off(port->comphy);
	}

	err = register_netdev(dev);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to register netdev\n");
		goto err_phylink;
	}
	netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);

	priv->port_list[priv->port_count++] = port;

	return 0;

err_phylink:
	if (port->phylink)
		phylink_destroy(port->phylink);
err_free_port_pcpu:
	free_percpu(port->pcpu);
err_free_txq_pcpu:
	for (i = 0; i < port->ntxqs; i++)
		free_percpu(port->txqs[i]->pcpu);
err_free_stats:
	free_percpu(port->stats);
err_free_irq:
	if (port->port_irq)
		irq_dispose_mapping(port->port_irq);
err_deinit_qvecs:
	mvpp2_queue_vectors_deinit(port);
err_free_netdev:
	free_netdev(dev);
	return err;
}

/* Ports removal routine */
static void mvpp2_port_remove(struct mvpp2_port *port)
{
	int i;

	unregister_netdev(port->dev);
	if (port->phylink)
		phylink_destroy(port->phylink);
	free_percpu(port->pcpu);
	free_percpu(port->stats);
	for (i = 0; i < port->ntxqs; i++)
		free_percpu(port->txqs[i]->pcpu);
	mvpp2_queue_vectors_deinit(port);
	if (port->port_irq)
		irq_dispose_mapping(port->port_irq);
	free_netdev(port->dev);
}

/* Initialize decoding windows */
static void mvpp2_conf_mbus_windows(const struct mbus_dram_target_info *dram,
				    struct mvpp2 *priv)
{
	u32 win_enable;
	int i;

	for (i = 0; i < 6; i++) {
		mvpp2_write(priv, MVPP2_WIN_BASE(i), 0);
		mvpp2_write(priv, MVPP2_WIN_SIZE(i), 0);

		if (i < 4)
			mvpp2_write(priv, MVPP2_WIN_REMAP(i), 0);
	}

	win_enable = 0;

	for (i = 0; i < dram->num_cs; i++) {
		const struct mbus_dram_window *cs = dram->cs + i;

		mvpp2_write(priv, MVPP2_WIN_BASE(i),
			    (cs->base & 0xffff0000) | (cs->mbus_attr << 8) |
			    dram->mbus_dram_target_id);

		mvpp2_write(priv, MVPP2_WIN_SIZE(i),
			    (cs->size - 1) & 0xffff0000);

		win_enable |= (1 << i);
	}

	mvpp2_write(priv, MVPP2_BASE_ADDR_ENABLE, win_enable);
}

/* Initialize Rx FIFO's */
static void mvpp2_rx_fifo_init(struct mvpp2 *priv)
{
	int port;

	for (port = 0; port < MVPP2_MAX_PORTS; port++) {
		mvpp2_write(priv, MVPP2_RX_DATA_FIFO_SIZE_REG(port),
			    MVPP2_RX_FIFO_PORT_DATA_SIZE_4KB);
		mvpp2_write(priv, MVPP2_RX_ATTR_FIFO_SIZE_REG(port),
			    MVPP2_RX_FIFO_PORT_ATTR_SIZE_4KB);
	}

	mvpp2_write(priv, MVPP2_RX_MIN_PKT_SIZE_REG,
		    MVPP2_RX_FIFO_PORT_MIN_PKT);
	mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1);
}

static void mvpp22_rx_fifo_set_hw(struct mvpp2 *priv, int port, int data_size)
{
	int attr_size = MVPP2_RX_FIFO_PORT_ATTR_SIZE(data_size);

	mvpp2_write(priv, MVPP2_RX_DATA_FIFO_SIZE_REG(port), data_size);
	mvpp2_write(priv, MVPP2_RX_ATTR_FIFO_SIZE_REG(port), attr_size);
}

/* Initialize TX FIFO's: the total FIFO size is 48kB on PPv2.2 and PPv2.3.
 * 4kB fixed space must be assigned for the loopback port.
 * Redistribute remaining avialable 44kB space among all active ports.
 * Guarantee minimum 32kB for 10G port and 8kB for port 1, capable of 2.5G
 * SGMII link.
 */
static void mvpp22_rx_fifo_init(struct mvpp2 *priv)
{
	int remaining_ports_count;
	unsigned long port_map;
	int size_remainder;
	int port, size;

	/* The loopback requires fixed 4kB of the FIFO space assignment. */
	mvpp22_rx_fifo_set_hw(priv, MVPP2_LOOPBACK_PORT_INDEX,
			      MVPP2_RX_FIFO_PORT_DATA_SIZE_4KB);
	port_map = priv->port_map & ~BIT(MVPP2_LOOPBACK_PORT_INDEX);

	/* Set RX FIFO size to 0 for inactive ports. */
	for_each_clear_bit(port, &port_map, MVPP2_LOOPBACK_PORT_INDEX)
		mvpp22_rx_fifo_set_hw(priv, port, 0);

	/* Assign remaining RX FIFO space among all active ports. */
	size_remainder = MVPP2_RX_FIFO_PORT_DATA_SIZE_44KB;
	remaining_ports_count = hweight_long(port_map);

	for_each_set_bit(port, &port_map, MVPP2_LOOPBACK_PORT_INDEX) {
		if (remaining_ports_count == 1)
			size = size_remainder;
		else if (port == 0)
			size = max(size_remainder / remaining_ports_count,
				   MVPP2_RX_FIFO_PORT_DATA_SIZE_32KB);
		else if (port == 1)
			size = max(size_remainder / remaining_ports_count,
				   MVPP2_RX_FIFO_PORT_DATA_SIZE_8KB);
		else
			size = size_remainder / remaining_ports_count;

		size_remainder -= size;
		remaining_ports_count--;

		mvpp22_rx_fifo_set_hw(priv, port, size);
	}

	mvpp2_write(priv, MVPP2_RX_MIN_PKT_SIZE_REG,
		    MVPP2_RX_FIFO_PORT_MIN_PKT);
	mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1);
}

/* Configure Rx FIFO Flow control thresholds */
static void mvpp23_rx_fifo_fc_set_tresh(struct mvpp2 *priv)
{
	int port, val;

	/* Port 0: maximum speed -10Gb/s port
	 *	   required by spec RX FIFO threshold 9KB
	 * Port 1: maximum speed -5Gb/s port
	 *	   required by spec RX FIFO threshold 4KB
	 * Port 2: maximum speed -1Gb/s port
	 *	   required by spec RX FIFO threshold 2KB
	 */

	/* Without loopback port */
	for (port = 0; port < (MVPP2_MAX_PORTS - 1); port++) {
		if (port == 0) {
			val = (MVPP23_PORT0_FIFO_TRSH / MVPP2_RX_FC_TRSH_UNIT)
				<< MVPP2_RX_FC_TRSH_OFFS;
			val &= MVPP2_RX_FC_TRSH_MASK;
			mvpp2_write(priv, MVPP2_RX_FC_REG(port), val);
		} else if (port == 1) {
			val = (MVPP23_PORT1_FIFO_TRSH / MVPP2_RX_FC_TRSH_UNIT)
				<< MVPP2_RX_FC_TRSH_OFFS;
			val &= MVPP2_RX_FC_TRSH_MASK;
			mvpp2_write(priv, MVPP2_RX_FC_REG(port), val);
		} else {
			val = (MVPP23_PORT2_FIFO_TRSH / MVPP2_RX_FC_TRSH_UNIT)
				<< MVPP2_RX_FC_TRSH_OFFS;
			val &= MVPP2_RX_FC_TRSH_MASK;
			mvpp2_write(priv, MVPP2_RX_FC_REG(port), val);
		}
	}
}

/* Configure Rx FIFO Flow control thresholds */
void mvpp23_rx_fifo_fc_en(struct mvpp2 *priv, int port, bool en)
{
	int val;

	val = mvpp2_read(priv, MVPP2_RX_FC_REG(port));

	if (en)
		val |= MVPP2_RX_FC_EN;
	else
		val &= ~MVPP2_RX_FC_EN;

	mvpp2_write(priv, MVPP2_RX_FC_REG(port), val);
}

static void mvpp22_tx_fifo_set_hw(struct mvpp2 *priv, int port, int size)
{
	int threshold = MVPP2_TX_FIFO_THRESHOLD(size);

	mvpp2_write(priv, MVPP22_TX_FIFO_SIZE_REG(port), size);
	mvpp2_write(priv, MVPP22_TX_FIFO_THRESH_REG(port), threshold);
}

/* Initialize TX FIFO's: the total FIFO size is 19kB on PPv2.2 and PPv2.3.
 * 1kB fixed space must be assigned for the loopback port.
 * Redistribute remaining avialable 18kB space among all active ports.
 * The 10G interface should use 10kB (which is maximum possible size
 * per single port).
 */
static void mvpp22_tx_fifo_init(struct mvpp2 *priv)
{
	int remaining_ports_count;
	unsigned long port_map;
	int size_remainder;
	int port, size;

	/* The loopback requires fixed 1kB of the FIFO space assignment. */
	mvpp22_tx_fifo_set_hw(priv, MVPP2_LOOPBACK_PORT_INDEX,
			      MVPP22_TX_FIFO_DATA_SIZE_1KB);
	port_map = priv->port_map & ~BIT(MVPP2_LOOPBACK_PORT_INDEX);

	/* Set TX FIFO size to 0 for inactive ports. */
	for_each_clear_bit(port, &port_map, MVPP2_LOOPBACK_PORT_INDEX)
		mvpp22_tx_fifo_set_hw(priv, port, 0);

	/* Assign remaining TX FIFO space among all active ports. */
	size_remainder = MVPP22_TX_FIFO_DATA_SIZE_18KB;
	remaining_ports_count = hweight_long(port_map);

	for_each_set_bit(port, &port_map, MVPP2_LOOPBACK_PORT_INDEX) {
		if (remaining_ports_count == 1)
			size = min(size_remainder,
				   MVPP22_TX_FIFO_DATA_SIZE_10KB);
		else if (port == 0)
			size = MVPP22_TX_FIFO_DATA_SIZE_10KB;
		else
			size = size_remainder / remaining_ports_count;

		size_remainder -= size;
		remaining_ports_count--;

		mvpp22_tx_fifo_set_hw(priv, port, size);
	}
}

static void mvpp2_axi_init(struct mvpp2 *priv)
{
	u32 val, rdval, wrval;

	mvpp2_write(priv, MVPP22_BM_ADDR_HIGH_RLS_REG, 0x0);

	/* AXI Bridge Configuration */

	rdval = MVPP22_AXI_CODE_CACHE_RD_CACHE
		<< MVPP22_AXI_ATTR_CACHE_OFFS;
	rdval |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
		<< MVPP22_AXI_ATTR_DOMAIN_OFFS;

	wrval = MVPP22_AXI_CODE_CACHE_WR_CACHE
		<< MVPP22_AXI_ATTR_CACHE_OFFS;
	wrval |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
		<< MVPP22_AXI_ATTR_DOMAIN_OFFS;

	/* BM */
	mvpp2_write(priv, MVPP22_AXI_BM_WR_ATTR_REG, wrval);
	mvpp2_write(priv, MVPP22_AXI_BM_RD_ATTR_REG, rdval);

	/* Descriptors */
	mvpp2_write(priv, MVPP22_AXI_AGGRQ_DESCR_RD_ATTR_REG, rdval);
	mvpp2_write(priv, MVPP22_AXI_TXQ_DESCR_WR_ATTR_REG, wrval);
	mvpp2_write(priv, MVPP22_AXI_TXQ_DESCR_RD_ATTR_REG, rdval);
	mvpp2_write(priv, MVPP22_AXI_RXQ_DESCR_WR_ATTR_REG, wrval);

	/* Buffer Data */
	mvpp2_write(priv, MVPP22_AXI_TX_DATA_RD_ATTR_REG, rdval);
	mvpp2_write(priv, MVPP22_AXI_RX_DATA_WR_ATTR_REG, wrval);

	val = MVPP22_AXI_CODE_CACHE_NON_CACHE
		<< MVPP22_AXI_CODE_CACHE_OFFS;
	val |= MVPP22_AXI_CODE_DOMAIN_SYSTEM
		<< MVPP22_AXI_CODE_DOMAIN_OFFS;
	mvpp2_write(priv, MVPP22_AXI_RD_NORMAL_CODE_REG, val);
	mvpp2_write(priv, MVPP22_AXI_WR_NORMAL_CODE_REG, val);

	val = MVPP22_AXI_CODE_CACHE_RD_CACHE
		<< MVPP22_AXI_CODE_CACHE_OFFS;
	val |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
		<< MVPP22_AXI_CODE_DOMAIN_OFFS;

	mvpp2_write(priv, MVPP22_AXI_RD_SNOOP_CODE_REG, val);

	val = MVPP22_AXI_CODE_CACHE_WR_CACHE
		<< MVPP22_AXI_CODE_CACHE_OFFS;
	val |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
		<< MVPP22_AXI_CODE_DOMAIN_OFFS;

	mvpp2_write(priv, MVPP22_AXI_WR_SNOOP_CODE_REG, val);
}

/* Initialize network controller common part HW */
static int mvpp2_init(struct platform_device *pdev, struct mvpp2 *priv)
{
	const struct mbus_dram_target_info *dram_target_info;
	int err, i;
	u32 val;

	/* MBUS windows configuration */
	dram_target_info = mv_mbus_dram_info();
	if (dram_target_info)
		mvpp2_conf_mbus_windows(dram_target_info, priv);

	if (priv->hw_version >= MVPP22)
		mvpp2_axi_init(priv);

	/* Disable HW PHY polling */
	if (priv->hw_version == MVPP21) {
		val = readl(priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
		val |= MVPP2_PHY_AN_STOP_SMI0_MASK;
		writel(val, priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
	} else {
		val = readl(priv->iface_base + MVPP22_SMI_MISC_CFG_REG);
		val &= ~MVPP22_SMI_POLLING_EN;
		writel(val, priv->iface_base + MVPP22_SMI_MISC_CFG_REG);
	}

	/* Allocate and initialize aggregated TXQs */
	priv->aggr_txqs = devm_kcalloc(&pdev->dev, MVPP2_MAX_THREADS,
				       sizeof(*priv->aggr_txqs),
				       GFP_KERNEL);
	if (!priv->aggr_txqs)
		return -ENOMEM;

	for (i = 0; i < MVPP2_MAX_THREADS; i++) {
		priv->aggr_txqs[i].id = i;
		priv->aggr_txqs[i].size = MVPP2_AGGR_TXQ_SIZE;
		err = mvpp2_aggr_txq_init(pdev, &priv->aggr_txqs[i], i, priv);
		if (err < 0)
			return err;
	}

	/* Fifo Init */
	if (priv->hw_version == MVPP21) {
		mvpp2_rx_fifo_init(priv);
	} else {
		mvpp22_rx_fifo_init(priv);
		mvpp22_tx_fifo_init(priv);
		if (priv->hw_version == MVPP23)
			mvpp23_rx_fifo_fc_set_tresh(priv);
	}

	if (priv->hw_version == MVPP21)
		writel(MVPP2_EXT_GLOBAL_CTRL_DEFAULT,
		       priv->lms_base + MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG);

	/* Allow cache snoop when transmiting packets */
	mvpp2_write(priv, MVPP2_TX_SNOOP_REG, 0x1);

	/* Buffer Manager initialization */
	err = mvpp2_bm_init(&pdev->dev, priv);
	if (err < 0)
		return err;

	/* Parser default initialization */
	err = mvpp2_prs_default_init(pdev, priv);
	if (err < 0)
		return err;

	/* Classifier default initialization */
	mvpp2_cls_init(priv);

	return 0;
}

static int mvpp2_get_sram(struct platform_device *pdev,
			  struct mvpp2 *priv)
{
	struct resource *res;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	if (!res) {
		if (has_acpi_companion(&pdev->dev))
			dev_warn(&pdev->dev, "ACPI is too old, Flow control not supported\n");
		else
			dev_warn(&pdev->dev, "DT is too old, Flow control not supported\n");
		return 0;
	}

	priv->cm3_base = devm_ioremap_resource(&pdev->dev, res);

	return PTR_ERR_OR_ZERO(priv->cm3_base);
}

static int mvpp2_probe(struct platform_device *pdev)
{
	struct fwnode_handle *fwnode = pdev->dev.fwnode;
	struct fwnode_handle *port_fwnode;
	struct mvpp2 *priv;
	struct resource *res;
	void __iomem *base;
	int i, shared;
	int err;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->hw_version = (unsigned long)device_get_match_data(&pdev->dev);

	/* multi queue mode isn't supported on PPV2.1, fallback to single
	 * mode
	 */
	if (priv->hw_version == MVPP21)
		queue_mode = MVPP2_QDIST_SINGLE_MODE;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	if (priv->hw_version == MVPP21) {
		priv->lms_base = devm_platform_ioremap_resource(pdev, 1);
		if (IS_ERR(priv->lms_base))
			return PTR_ERR(priv->lms_base);
	} else {
		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
		if (!res) {
			dev_err(&pdev->dev, "Invalid resource\n");
			return -EINVAL;
		}
		if (has_acpi_companion(&pdev->dev)) {
			/* In case the MDIO memory region is declared in
			 * the ACPI, it can already appear as 'in-use'
			 * in the OS. Because it is overlapped by second
			 * region of the network controller, make
			 * sure it is released, before requesting it again.
			 * The care is taken by mvpp2 driver to avoid
			 * concurrent access to this memory region.
			 */
			release_resource(res);
		}
		priv->iface_base = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(priv->iface_base))
			return PTR_ERR(priv->iface_base);

		/* Map CM3 SRAM */
		err = mvpp2_get_sram(pdev, priv);
		if (err)
			dev_warn(&pdev->dev, "Fail to alloc CM3 SRAM\n");

		/* Enable global Flow Control only if handler to SRAM not NULL */
		if (priv->cm3_base)
			priv->global_tx_fc = true;
	}

	if (priv->hw_version >= MVPP22 && dev_of_node(&pdev->dev)) {
		priv->sysctrl_base =
			syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
							"marvell,system-controller");
		if (IS_ERR(priv->sysctrl_base))
			/* The system controller regmap is optional for dt
			 * compatibility reasons. When not provided, the
			 * configuration of the GoP relies on the
			 * firmware/bootloader.
			 */
			priv->sysctrl_base = NULL;
	}

	if (priv->hw_version >= MVPP22 &&
	    mvpp2_get_nrxqs(priv) * 2 <= MVPP2_BM_MAX_POOLS)
		priv->percpu_pools = 1;

	mvpp2_setup_bm_pool();


	priv->nthreads = min_t(unsigned int, num_present_cpus(),
			       MVPP2_MAX_THREADS);

	shared = num_present_cpus() - priv->nthreads;
	if (shared > 0)
		bitmap_fill(&priv->lock_map,
			    min_t(int, shared, MVPP2_MAX_THREADS));

	for (i = 0; i < MVPP2_MAX_THREADS; i++) {
		u32 addr_space_sz;

		addr_space_sz = (priv->hw_version == MVPP21 ?
				 MVPP21_ADDR_SPACE_SZ : MVPP22_ADDR_SPACE_SZ);
		priv->swth_base[i] = base + i * addr_space_sz;
	}

	if (priv->hw_version == MVPP21)
		priv->max_port_rxqs = 8;
	else
		priv->max_port_rxqs = 32;

	if (dev_of_node(&pdev->dev)) {
		priv->pp_clk = devm_clk_get(&pdev->dev, "pp_clk");
		if (IS_ERR(priv->pp_clk))
			return PTR_ERR(priv->pp_clk);
		err = clk_prepare_enable(priv->pp_clk);
		if (err < 0)
			return err;

		priv->gop_clk = devm_clk_get(&pdev->dev, "gop_clk");
		if (IS_ERR(priv->gop_clk)) {
			err = PTR_ERR(priv->gop_clk);
			goto err_pp_clk;
		}
		err = clk_prepare_enable(priv->gop_clk);
		if (err < 0)
			goto err_pp_clk;

		if (priv->hw_version >= MVPP22) {
			priv->mg_clk = devm_clk_get(&pdev->dev, "mg_clk");
			if (IS_ERR(priv->mg_clk)) {
				err = PTR_ERR(priv->mg_clk);
				goto err_gop_clk;
			}

			err = clk_prepare_enable(priv->mg_clk);
			if (err < 0)
				goto err_gop_clk;

			priv->mg_core_clk = devm_clk_get_optional(&pdev->dev, "mg_core_clk");
			if (IS_ERR(priv->mg_core_clk)) {
				err = PTR_ERR(priv->mg_core_clk);
				goto err_mg_clk;
			}

			err = clk_prepare_enable(priv->mg_core_clk);
			if (err < 0)
				goto err_mg_clk;
		}

		priv->axi_clk = devm_clk_get_optional(&pdev->dev, "axi_clk");
		if (IS_ERR(priv->axi_clk)) {
			err = PTR_ERR(priv->axi_clk);
			goto err_mg_core_clk;
		}

		err = clk_prepare_enable(priv->axi_clk);
		if (err < 0)
			goto err_mg_core_clk;

		/* Get system's tclk rate */
		priv->tclk = clk_get_rate(priv->pp_clk);
	} else {
		err = device_property_read_u32(&pdev->dev, "clock-frequency", &priv->tclk);
		if (err) {
			dev_err(&pdev->dev, "missing clock-frequency value\n");
			return err;
		}
	}

	if (priv->hw_version >= MVPP22) {
		err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK);
		if (err)
			goto err_axi_clk;
		/* Sadly, the BM pools all share the same register to
		 * store the high 32 bits of their address. So they
		 * must all have the same high 32 bits, which forces
		 * us to restrict coherent memory to DMA_BIT_MASK(32).
		 */
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
		if (err)
			goto err_axi_clk;
	}

	/* Map DTS-active ports. Should be done before FIFO mvpp2_init */
	fwnode_for_each_available_child_node(fwnode, port_fwnode) {
		if (!fwnode_property_read_u32(port_fwnode, "port-id", &i))
			priv->port_map |= BIT(i);
	}

	if (mvpp2_read(priv, MVPP2_VER_ID_REG) == MVPP2_VER_PP23)
		priv->hw_version = MVPP23;

	/* Init mss lock */
	spin_lock_init(&priv->mss_spinlock);

	/* Initialize network controller */
	err = mvpp2_init(pdev, priv);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to initialize controller\n");
		goto err_axi_clk;
	}

	err = mvpp22_tai_probe(&pdev->dev, priv);
	if (err < 0)
		goto err_axi_clk;

	/* Initialize ports */
	fwnode_for_each_available_child_node(fwnode, port_fwnode) {
		err = mvpp2_port_probe(pdev, port_fwnode, priv);
		if (err < 0)
			goto err_port_probe;
	}

	if (priv->port_count == 0) {
		dev_err(&pdev->dev, "no ports enabled\n");
		err = -ENODEV;
		goto err_axi_clk;
	}

	/* Statistics must be gathered regularly because some of them (like
	 * packets counters) are 32-bit registers and could overflow quite
	 * quickly. For instance, a 10Gb link used at full bandwidth with the
	 * smallest packets (64B) will overflow a 32-bit counter in less than
	 * 30 seconds. Then, use a workqueue to fill 64-bit counters.
	 */
	snprintf(priv->queue_name, sizeof(priv->queue_name),
		 "stats-wq-%s%s", netdev_name(priv->port_list[0]->dev),
		 priv->port_count > 1 ? "+" : "");
	priv->stats_queue = create_singlethread_workqueue(priv->queue_name);
	if (!priv->stats_queue) {
		err = -ENOMEM;
		goto err_port_probe;
	}

	if (priv->global_tx_fc && priv->hw_version >= MVPP22) {
		err = mvpp2_enable_global_fc(priv);
		if (err)
			dev_warn(&pdev->dev, "Minimum of CM3 firmware 18.09 and chip revision B0 required for flow control\n");
	}

	mvpp2_dbgfs_init(priv, pdev->name);

	platform_set_drvdata(pdev, priv);
	return 0;

err_port_probe:
	fwnode_handle_put(port_fwnode);

	i = 0;
	fwnode_for_each_available_child_node(fwnode, port_fwnode) {
		if (priv->port_list[i])
			mvpp2_port_remove(priv->port_list[i]);
		i++;
	}
err_axi_clk:
	clk_disable_unprepare(priv->axi_clk);
err_mg_core_clk:
	clk_disable_unprepare(priv->mg_core_clk);
err_mg_clk:
	clk_disable_unprepare(priv->mg_clk);
err_gop_clk:
	clk_disable_unprepare(priv->gop_clk);
err_pp_clk:
	clk_disable_unprepare(priv->pp_clk);
	return err;
}

static int mvpp2_remove(struct platform_device *pdev)
{
	struct mvpp2 *priv = platform_get_drvdata(pdev);
	struct fwnode_handle *fwnode = pdev->dev.fwnode;
	int i = 0, poolnum = MVPP2_BM_POOLS_NUM;
	struct fwnode_handle *port_fwnode;

	mvpp2_dbgfs_cleanup(priv);

	fwnode_for_each_available_child_node(fwnode, port_fwnode) {
		if (priv->port_list[i]) {
			mutex_destroy(&priv->port_list[i]->gather_stats_lock);
			mvpp2_port_remove(priv->port_list[i]);
		}
		i++;
	}

	destroy_workqueue(priv->stats_queue);

	if (priv->percpu_pools)
		poolnum = mvpp2_get_nrxqs(priv) * 2;

	for (i = 0; i < poolnum; i++) {
		struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i];

		mvpp2_bm_pool_destroy(&pdev->dev, priv, bm_pool);
	}

	for (i = 0; i < MVPP2_MAX_THREADS; i++) {
		struct mvpp2_tx_queue *aggr_txq = &priv->aggr_txqs[i];

		dma_free_coherent(&pdev->dev,
				  MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE,
				  aggr_txq->descs,
				  aggr_txq->descs_dma);
	}

	if (is_acpi_node(port_fwnode))
		return 0;

	clk_disable_unprepare(priv->axi_clk);
	clk_disable_unprepare(priv->mg_core_clk);
	clk_disable_unprepare(priv->mg_clk);
	clk_disable_unprepare(priv->pp_clk);
	clk_disable_unprepare(priv->gop_clk);

	return 0;
}

static const struct of_device_id mvpp2_match[] = {
	{
		.compatible = "marvell,armada-375-pp2",
		.data = (void *)MVPP21,
	},
	{
		.compatible = "marvell,armada-7k-pp22",
		.data = (void *)MVPP22,
	},
	{ }
};
MODULE_DEVICE_TABLE(of, mvpp2_match);

#ifdef CONFIG_ACPI
static const struct acpi_device_id mvpp2_acpi_match[] = {
	{ "MRVL0110", MVPP22 },
	{ },
};
MODULE_DEVICE_TABLE(acpi, mvpp2_acpi_match);
#endif

static struct platform_driver mvpp2_driver = {
	.probe = mvpp2_probe,
	.remove = mvpp2_remove,
	.driver = {
		.name = MVPP2_DRIVER_NAME,
		.of_match_table = mvpp2_match,
		.acpi_match_table = ACPI_PTR(mvpp2_acpi_match),
	},
};

module_platform_driver(mvpp2_driver);

MODULE_DESCRIPTION("Marvell PPv2 Ethernet Driver - www.marvell.com");
MODULE_AUTHOR("Marcin Wojtas <mw@semihalf.com>");
MODULE_LICENSE("GPL v2");
