// SPDX-License-Identifier: GPL-2.0-only
/* 10G controller driver for Samsung SoCs
 *
 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/clk.h>
#include <linux/crc32.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/mii.h>
#include <linux/module.h>
#include <linux/net_tstamp.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/prefetch.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/sxgbe_platform.h>

#include "sxgbe_common.h"
#include "sxgbe_desc.h"
#include "sxgbe_dma.h"
#include "sxgbe_mtl.h"
#include "sxgbe_reg.h"

#define SXGBE_ALIGN(x)	L1_CACHE_ALIGN(x)
#define JUMBO_LEN	9000

/* Module parameters */
#define TX_TIMEO	5000
#define DMA_TX_SIZE	512
#define DMA_RX_SIZE	1024
#define TC_DEFAULT	64
#define DMA_BUFFER_SIZE	BUF_SIZE_2KiB
/* The default timer value as per the sxgbe specification 1 sec(1000 ms) */
#define SXGBE_DEFAULT_LPI_TIMER	1000

static int debug = -1;
static int eee_timer = SXGBE_DEFAULT_LPI_TIMER;

module_param(eee_timer, int, 0644);

module_param(debug, int, 0644);
static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
				      NETIF_MSG_LINK | NETIF_MSG_IFUP |
				      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);

static irqreturn_t sxgbe_common_interrupt(int irq, void *dev_id);
static irqreturn_t sxgbe_tx_interrupt(int irq, void *dev_id);
static irqreturn_t sxgbe_rx_interrupt(int irq, void *dev_id);

#define SXGBE_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))

#define SXGBE_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))

/**
 * sxgbe_verify_args - verify the driver parameters.
 * Description: it verifies if some wrong parameter is passed to the driver.
 * Note that wrong parameters are replaced with the default values.
 */
static void sxgbe_verify_args(void)
{
	if (unlikely(eee_timer < 0))
		eee_timer = SXGBE_DEFAULT_LPI_TIMER;
}

static void sxgbe_enable_eee_mode(const struct sxgbe_priv_data *priv)
{
	/* Check and enter in LPI mode */
	if (!priv->tx_path_in_lpi_mode)
		priv->hw->mac->set_eee_mode(priv->ioaddr);
}

void sxgbe_disable_eee_mode(struct sxgbe_priv_data * const priv)
{
	/* Exit and disable EEE in case of we are are in LPI state. */
	priv->hw->mac->reset_eee_mode(priv->ioaddr);
	del_timer_sync(&priv->eee_ctrl_timer);
	priv->tx_path_in_lpi_mode = false;
}

/**
 * sxgbe_eee_ctrl_timer
 * @t: timer list containing a data
 * Description:
 *  If there is no data transfer and if we are not in LPI state,
 *  then MAC Transmitter can be moved to LPI state.
 */
static void sxgbe_eee_ctrl_timer(struct timer_list *t)
{
	struct sxgbe_priv_data *priv = from_timer(priv, t, eee_ctrl_timer);

	sxgbe_enable_eee_mode(priv);
	mod_timer(&priv->eee_ctrl_timer, SXGBE_LPI_TIMER(eee_timer));
}

/**
 * sxgbe_eee_init
 * @priv: private device pointer
 * Description:
 *  If the EEE support has been enabled while configuring the driver,
 *  if the GMAC actually supports the EEE (from the HW cap reg) and the
 *  phy can also manage EEE, so enable the LPI state and start the timer
 *  to verify if the tx path can enter in LPI state.
 */
bool sxgbe_eee_init(struct sxgbe_priv_data * const priv)
{
	struct net_device *ndev = priv->dev;
	bool ret = false;

	/* MAC core supports the EEE feature. */
	if (priv->hw_cap.eee) {
		/* Check if the PHY supports EEE */
		if (phy_init_eee(ndev->phydev, 1))
			return false;

		priv->eee_active = 1;
		timer_setup(&priv->eee_ctrl_timer, sxgbe_eee_ctrl_timer, 0);
		priv->eee_ctrl_timer.expires = SXGBE_LPI_TIMER(eee_timer);
		add_timer(&priv->eee_ctrl_timer);

		priv->hw->mac->set_eee_timer(priv->ioaddr,
					     SXGBE_DEFAULT_LPI_TIMER,
					     priv->tx_lpi_timer);

		pr_info("Energy-Efficient Ethernet initialized\n");

		ret = true;
	}

	return ret;
}

static void sxgbe_eee_adjust(const struct sxgbe_priv_data *priv)
{
	struct net_device *ndev = priv->dev;

	/* When the EEE has been already initialised we have to
	 * modify the PLS bit in the LPI ctrl & status reg according
	 * to the PHY link status. For this reason.
	 */
	if (priv->eee_enabled)
		priv->hw->mac->set_eee_pls(priv->ioaddr, ndev->phydev->link);
}

/**
 * sxgbe_clk_csr_set - dynamically set the MDC clock
 * @priv: driver private structure
 * Description: this is to dynamically set the MDC clock according to the csr
 * clock input.
 */
static void sxgbe_clk_csr_set(struct sxgbe_priv_data *priv)
{
	u32 clk_rate = clk_get_rate(priv->sxgbe_clk);

	/* assign the proper divider, this will be used during
	 * mdio communication
	 */
	if (clk_rate < SXGBE_CSR_F_150M)
		priv->clk_csr = SXGBE_CSR_100_150M;
	else if (clk_rate <= SXGBE_CSR_F_250M)
		priv->clk_csr = SXGBE_CSR_150_250M;
	else if (clk_rate <= SXGBE_CSR_F_300M)
		priv->clk_csr = SXGBE_CSR_250_300M;
	else if (clk_rate <= SXGBE_CSR_F_350M)
		priv->clk_csr = SXGBE_CSR_300_350M;
	else if (clk_rate <= SXGBE_CSR_F_400M)
		priv->clk_csr = SXGBE_CSR_350_400M;
	else if (clk_rate <= SXGBE_CSR_F_500M)
		priv->clk_csr = SXGBE_CSR_400_500M;
}

/* minimum number of free TX descriptors required to wake up TX process */
#define SXGBE_TX_THRESH(x)	(x->dma_tx_size/4)

static inline u32 sxgbe_tx_avail(struct sxgbe_tx_queue *queue, int tx_qsize)
{
	return queue->dirty_tx + tx_qsize - queue->cur_tx - 1;
}

/**
 * sxgbe_adjust_link
 * @dev: net device structure
 * Description: it adjusts the link parameters.
 */
static void sxgbe_adjust_link(struct net_device *dev)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	struct phy_device *phydev = dev->phydev;
	u8 new_state = 0;
	u8 speed = 0xff;

	if (!phydev)
		return;

	/* SXGBE is not supporting auto-negotiation and
	 * half duplex mode. so, not handling duplex change
	 * in this function. only handling speed and link status
	 */
	if (phydev->link) {
		if (phydev->speed != priv->speed) {
			new_state = 1;
			switch (phydev->speed) {
			case SPEED_10000:
				speed = SXGBE_SPEED_10G;
				break;
			case SPEED_2500:
				speed = SXGBE_SPEED_2_5G;
				break;
			case SPEED_1000:
				speed = SXGBE_SPEED_1G;
				break;
			default:
				netif_err(priv, link, dev,
					  "Speed (%d) not supported\n",
					  phydev->speed);
			}

			priv->speed = phydev->speed;
			priv->hw->mac->set_speed(priv->ioaddr, speed);
		}

		if (!priv->oldlink) {
			new_state = 1;
			priv->oldlink = 1;
		}
	} else if (priv->oldlink) {
		new_state = 1;
		priv->oldlink = 0;
		priv->speed = SPEED_UNKNOWN;
	}

	if (new_state & netif_msg_link(priv))
		phy_print_status(phydev);

	/* Alter the MAC settings for EEE */
	sxgbe_eee_adjust(priv);
}

/**
 * sxgbe_init_phy - PHY initialization
 * @ndev: net device structure
 * Description: it initializes the driver's PHY state, and attaches the PHY
 * to the mac driver.
 *  Return value:
 *  0 on success
 */
static int sxgbe_init_phy(struct net_device *ndev)
{
	char phy_id_fmt[MII_BUS_ID_SIZE + 3];
	char bus_id[MII_BUS_ID_SIZE];
	struct phy_device *phydev;
	struct sxgbe_priv_data *priv = netdev_priv(ndev);
	int phy_iface = priv->plat->interface;

	/* assign default link status */
	priv->oldlink = 0;
	priv->speed = SPEED_UNKNOWN;
	priv->oldduplex = DUPLEX_UNKNOWN;

	if (priv->plat->phy_bus_name)
		snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
			 priv->plat->phy_bus_name, priv->plat->bus_id);
	else
		snprintf(bus_id, MII_BUS_ID_SIZE, "sxgbe-%x",
			 priv->plat->bus_id);

	snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
		 priv->plat->phy_addr);
	netdev_dbg(ndev, "%s: trying to attach to %s\n", __func__, phy_id_fmt);

	phydev = phy_connect(ndev, phy_id_fmt, &sxgbe_adjust_link, phy_iface);

	if (IS_ERR(phydev)) {
		netdev_err(ndev, "Could not attach to PHY\n");
		return PTR_ERR(phydev);
	}

	/* Stop Advertising 1000BASE Capability if interface is not GMII */
	if ((phy_iface == PHY_INTERFACE_MODE_MII) ||
	    (phy_iface == PHY_INTERFACE_MODE_RMII))
		phy_set_max_speed(phydev, SPEED_1000);

	if (phydev->phy_id == 0) {
		phy_disconnect(phydev);
		return -ENODEV;
	}

	netdev_dbg(ndev, "%s: attached to PHY (UID 0x%x) Link = %d\n",
		   __func__, phydev->phy_id, phydev->link);

	return 0;
}

/**
 * sxgbe_clear_descriptors: clear descriptors
 * @priv: driver private structure
 * Description: this function is called to clear the tx and rx descriptors
 * in case of both basic and extended descriptors are used.
 */
static void sxgbe_clear_descriptors(struct sxgbe_priv_data *priv)
{
	int i, j;
	unsigned int txsize = priv->dma_tx_size;
	unsigned int rxsize = priv->dma_rx_size;

	/* Clear the Rx/Tx descriptors */
	for (j = 0; j < SXGBE_RX_QUEUES; j++) {
		for (i = 0; i < rxsize; i++)
			priv->hw->desc->init_rx_desc(&priv->rxq[j]->dma_rx[i],
						     priv->use_riwt, priv->mode,
						     (i == rxsize - 1));
	}

	for (j = 0; j < SXGBE_TX_QUEUES; j++) {
		for (i = 0; i < txsize; i++)
			priv->hw->desc->init_tx_desc(&priv->txq[j]->dma_tx[i]);
	}
}

static int sxgbe_init_rx_buffers(struct net_device *dev,
				 struct sxgbe_rx_norm_desc *p, int i,
				 unsigned int dma_buf_sz,
				 struct sxgbe_rx_queue *rx_ring)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	struct sk_buff *skb;

	skb = __netdev_alloc_skb_ip_align(dev, dma_buf_sz, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	rx_ring->rx_skbuff[i] = skb;
	rx_ring->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
						   dma_buf_sz, DMA_FROM_DEVICE);

	if (dma_mapping_error(priv->device, rx_ring->rx_skbuff_dma[i])) {
		netdev_err(dev, "%s: DMA mapping error\n", __func__);
		dev_kfree_skb_any(skb);
		return -EINVAL;
	}

	p->rdes23.rx_rd_des23.buf2_addr = rx_ring->rx_skbuff_dma[i];

	return 0;
}

/**
 * sxgbe_free_rx_buffers - free what sxgbe_init_rx_buffers() allocated
 * @dev: net device structure
 * @p: dec pointer
 * @i: index
 * @dma_buf_sz: size
 * @rx_ring: ring to be freed
 *
 * Description:  this function initializes the DMA RX descriptor
 */
static void sxgbe_free_rx_buffers(struct net_device *dev,
				  struct sxgbe_rx_norm_desc *p, int i,
				  unsigned int dma_buf_sz,
				  struct sxgbe_rx_queue *rx_ring)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);

	kfree_skb(rx_ring->rx_skbuff[i]);
	dma_unmap_single(priv->device, rx_ring->rx_skbuff_dma[i],
			 dma_buf_sz, DMA_FROM_DEVICE);
}

/**
 * init_tx_ring - init the TX descriptor ring
 * @dev: net device structure
 * @queue_no: queue
 * @tx_ring: ring to be initialised
 * @tx_rsize: ring size
 * Description:  this function initializes the DMA TX descriptor
 */
static int init_tx_ring(struct device *dev, u8 queue_no,
			struct sxgbe_tx_queue *tx_ring,	int tx_rsize)
{
	/* TX ring is not allcoated */
	if (!tx_ring) {
		dev_err(dev, "No memory for TX queue of SXGBE\n");
		return -ENOMEM;
	}

	/* allocate memory for TX descriptors */
	tx_ring->dma_tx = dma_alloc_coherent(dev,
					     tx_rsize * sizeof(struct sxgbe_tx_norm_desc),
					     &tx_ring->dma_tx_phy, GFP_KERNEL);
	if (!tx_ring->dma_tx)
		return -ENOMEM;

	/* allocate memory for TX skbuff array */
	tx_ring->tx_skbuff_dma = devm_kcalloc(dev, tx_rsize,
					      sizeof(dma_addr_t), GFP_KERNEL);
	if (!tx_ring->tx_skbuff_dma)
		goto dmamem_err;

	tx_ring->tx_skbuff = devm_kcalloc(dev, tx_rsize,
					  sizeof(struct sk_buff *), GFP_KERNEL);

	if (!tx_ring->tx_skbuff)
		goto dmamem_err;

	/* assign queue number */
	tx_ring->queue_no = queue_no;

	/* initialise counters */
	tx_ring->dirty_tx = 0;
	tx_ring->cur_tx = 0;

	return 0;

dmamem_err:
	dma_free_coherent(dev, tx_rsize * sizeof(struct sxgbe_tx_norm_desc),
			  tx_ring->dma_tx, tx_ring->dma_tx_phy);
	return -ENOMEM;
}

/**
 * free_rx_ring - free the RX descriptor ring
 * @dev: net device structure
 * @rx_ring: ring to be initialised
 * @rx_rsize: ring size
 * Description:  this function initializes the DMA RX descriptor
 */
static void free_rx_ring(struct device *dev, struct sxgbe_rx_queue *rx_ring,
			 int rx_rsize)
{
	dma_free_coherent(dev, rx_rsize * sizeof(struct sxgbe_rx_norm_desc),
			  rx_ring->dma_rx, rx_ring->dma_rx_phy);
	kfree(rx_ring->rx_skbuff_dma);
	kfree(rx_ring->rx_skbuff);
}

/**
 * init_rx_ring - init the RX descriptor ring
 * @dev: net device structure
 * @queue_no: queue
 * @rx_ring: ring to be initialised
 * @rx_rsize: ring size
 * Description:  this function initializes the DMA RX descriptor
 */
static int init_rx_ring(struct net_device *dev, u8 queue_no,
			struct sxgbe_rx_queue *rx_ring,	int rx_rsize)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	int desc_index;
	unsigned int bfsize = 0;
	unsigned int ret = 0;

	/* Set the max buffer size according to the MTU. */
	bfsize = ALIGN(dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN, 8);

	netif_dbg(priv, probe, dev, "%s: bfsize %d\n", __func__, bfsize);

	/* RX ring is not allcoated */
	if (rx_ring == NULL) {
		netdev_err(dev, "No memory for RX queue\n");
		return -ENOMEM;
	}

	/* assign queue number */
	rx_ring->queue_no = queue_no;

	/* allocate memory for RX descriptors */
	rx_ring->dma_rx = dma_alloc_coherent(priv->device,
					     rx_rsize * sizeof(struct sxgbe_rx_norm_desc),
					     &rx_ring->dma_rx_phy, GFP_KERNEL);

	if (rx_ring->dma_rx == NULL)
		return -ENOMEM;

	/* allocate memory for RX skbuff array */
	rx_ring->rx_skbuff_dma = kmalloc_array(rx_rsize,
					       sizeof(dma_addr_t), GFP_KERNEL);
	if (!rx_ring->rx_skbuff_dma) {
		ret = -ENOMEM;
		goto err_free_dma_rx;
	}

	rx_ring->rx_skbuff = kmalloc_array(rx_rsize,
					   sizeof(struct sk_buff *), GFP_KERNEL);
	if (!rx_ring->rx_skbuff) {
		ret = -ENOMEM;
		goto err_free_skbuff_dma;
	}

	/* initialise the buffers */
	for (desc_index = 0; desc_index < rx_rsize; desc_index++) {
		struct sxgbe_rx_norm_desc *p;
		p = rx_ring->dma_rx + desc_index;
		ret = sxgbe_init_rx_buffers(dev, p, desc_index,
					    bfsize, rx_ring);
		if (ret)
			goto err_free_rx_buffers;
	}

	/* initialise counters */
	rx_ring->cur_rx = 0;
	rx_ring->dirty_rx = (unsigned int)(desc_index - rx_rsize);
	priv->dma_buf_sz = bfsize;

	return 0;

err_free_rx_buffers:
	while (--desc_index >= 0) {
		struct sxgbe_rx_norm_desc *p;

		p = rx_ring->dma_rx + desc_index;
		sxgbe_free_rx_buffers(dev, p, desc_index, bfsize, rx_ring);
	}
	kfree(rx_ring->rx_skbuff);
err_free_skbuff_dma:
	kfree(rx_ring->rx_skbuff_dma);
err_free_dma_rx:
	dma_free_coherent(priv->device,
			  rx_rsize * sizeof(struct sxgbe_rx_norm_desc),
			  rx_ring->dma_rx, rx_ring->dma_rx_phy);

	return ret;
}
/**
 * free_tx_ring - free the TX descriptor ring
 * @dev: net device structure
 * @tx_ring: ring to be initialised
 * @tx_rsize: ring size
 * Description:  this function initializes the DMA TX descriptor
 */
static void free_tx_ring(struct device *dev, struct sxgbe_tx_queue *tx_ring,
			 int tx_rsize)
{
	dma_free_coherent(dev, tx_rsize * sizeof(struct sxgbe_tx_norm_desc),
			  tx_ring->dma_tx, tx_ring->dma_tx_phy);
}

/**
 * init_dma_desc_rings - init the RX/TX descriptor rings
 * @netd: net device structure
 * Description:  this function initializes the DMA RX/TX descriptors
 * and allocates the socket buffers. It suppors the chained and ring
 * modes.
 */
static int init_dma_desc_rings(struct net_device *netd)
{
	int queue_num, ret;
	struct sxgbe_priv_data *priv = netdev_priv(netd);
	int tx_rsize = priv->dma_tx_size;
	int rx_rsize = priv->dma_rx_size;

	/* Allocate memory for queue structures and TX descs */
	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		ret = init_tx_ring(priv->device, queue_num,
				   priv->txq[queue_num], tx_rsize);
		if (ret) {
			dev_err(&netd->dev, "TX DMA ring allocation failed!\n");
			goto txalloc_err;
		}

		/* save private pointer in each ring this
		 * pointer is needed during cleaing TX queue
		 */
		priv->txq[queue_num]->priv_ptr = priv;
	}

	/* Allocate memory for queue structures and RX descs */
	SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) {
		ret = init_rx_ring(netd, queue_num,
				   priv->rxq[queue_num], rx_rsize);
		if (ret) {
			netdev_err(netd, "RX DMA ring allocation failed!!\n");
			goto rxalloc_err;
		}

		/* save private pointer in each ring this
		 * pointer is needed during cleaing TX queue
		 */
		priv->rxq[queue_num]->priv_ptr = priv;
	}

	sxgbe_clear_descriptors(priv);

	return 0;

txalloc_err:
	while (queue_num--)
		free_tx_ring(priv->device, priv->txq[queue_num], tx_rsize);
	return ret;

rxalloc_err:
	while (queue_num--)
		free_rx_ring(priv->device, priv->rxq[queue_num], rx_rsize);
	return ret;
}

static void tx_free_ring_skbufs(struct sxgbe_tx_queue *txqueue)
{
	int dma_desc;
	struct sxgbe_priv_data *priv = txqueue->priv_ptr;
	int tx_rsize = priv->dma_tx_size;

	for (dma_desc = 0; dma_desc < tx_rsize; dma_desc++) {
		struct sxgbe_tx_norm_desc *tdesc = txqueue->dma_tx + dma_desc;

		if (txqueue->tx_skbuff_dma[dma_desc])
			dma_unmap_single(priv->device,
					 txqueue->tx_skbuff_dma[dma_desc],
					 priv->hw->desc->get_tx_len(tdesc),
					 DMA_TO_DEVICE);

		dev_kfree_skb_any(txqueue->tx_skbuff[dma_desc]);
		txqueue->tx_skbuff[dma_desc] = NULL;
		txqueue->tx_skbuff_dma[dma_desc] = 0;
	}
}


static void dma_free_tx_skbufs(struct sxgbe_priv_data *priv)
{
	int queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		struct sxgbe_tx_queue *tqueue = priv->txq[queue_num];
		tx_free_ring_skbufs(tqueue);
	}
}

static void free_dma_desc_resources(struct sxgbe_priv_data *priv)
{
	int queue_num;
	int tx_rsize = priv->dma_tx_size;
	int rx_rsize = priv->dma_rx_size;

	/* Release the DMA TX buffers */
	dma_free_tx_skbufs(priv);

	/* Release the TX ring memory also */
	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		free_tx_ring(priv->device, priv->txq[queue_num], tx_rsize);
	}

	/* Release the RX ring memory also */
	SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) {
		free_rx_ring(priv->device, priv->rxq[queue_num], rx_rsize);
	}
}

static int txring_mem_alloc(struct sxgbe_priv_data *priv)
{
	int queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		priv->txq[queue_num] = devm_kmalloc(priv->device,
						    sizeof(struct sxgbe_tx_queue), GFP_KERNEL);
		if (!priv->txq[queue_num])
			return -ENOMEM;
	}

	return 0;
}

static int rxring_mem_alloc(struct sxgbe_priv_data *priv)
{
	int queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) {
		priv->rxq[queue_num] = devm_kmalloc(priv->device,
						    sizeof(struct sxgbe_rx_queue), GFP_KERNEL);
		if (!priv->rxq[queue_num])
			return -ENOMEM;
	}

	return 0;
}

/**
 *  sxgbe_mtl_operation_mode - HW MTL operation mode
 *  @priv: driver private structure
 *  Description: it sets the MTL operation mode: tx/rx MTL thresholds
 *  or Store-And-Forward capability.
 */
static void sxgbe_mtl_operation_mode(struct sxgbe_priv_data *priv)
{
	int queue_num;

	/* TX/RX threshold control */
	if (likely(priv->plat->force_sf_dma_mode)) {
		/* set TC mode for TX QUEUES */
		SXGBE_FOR_EACH_QUEUE(priv->hw_cap.tx_mtl_queues, queue_num)
			priv->hw->mtl->set_tx_mtl_mode(priv->ioaddr, queue_num,
						       SXGBE_MTL_SFMODE);
		priv->tx_tc = SXGBE_MTL_SFMODE;

		/* set TC mode for RX QUEUES */
		SXGBE_FOR_EACH_QUEUE(priv->hw_cap.rx_mtl_queues, queue_num)
			priv->hw->mtl->set_rx_mtl_mode(priv->ioaddr, queue_num,
						       SXGBE_MTL_SFMODE);
		priv->rx_tc = SXGBE_MTL_SFMODE;
	} else if (unlikely(priv->plat->force_thresh_dma_mode)) {
		/* set TC mode for TX QUEUES */
		SXGBE_FOR_EACH_QUEUE(priv->hw_cap.tx_mtl_queues, queue_num)
			priv->hw->mtl->set_tx_mtl_mode(priv->ioaddr, queue_num,
						       priv->tx_tc);
		/* set TC mode for RX QUEUES */
		SXGBE_FOR_EACH_QUEUE(priv->hw_cap.rx_mtl_queues, queue_num)
			priv->hw->mtl->set_rx_mtl_mode(priv->ioaddr, queue_num,
						       priv->rx_tc);
	} else {
		pr_err("ERROR: %s: Invalid TX threshold mode\n", __func__);
	}
}

/**
 * sxgbe_tx_queue_clean:
 * @tqueue: queue pointer
 * Description: it reclaims resources after transmission completes.
 */
static void sxgbe_tx_queue_clean(struct sxgbe_tx_queue *tqueue)
{
	struct sxgbe_priv_data *priv = tqueue->priv_ptr;
	unsigned int tx_rsize = priv->dma_tx_size;
	struct netdev_queue *dev_txq;
	u8 queue_no = tqueue->queue_no;

	dev_txq = netdev_get_tx_queue(priv->dev, queue_no);

	__netif_tx_lock(dev_txq, smp_processor_id());

	priv->xstats.tx_clean++;
	while (tqueue->dirty_tx != tqueue->cur_tx) {
		unsigned int entry = tqueue->dirty_tx % tx_rsize;
		struct sk_buff *skb = tqueue->tx_skbuff[entry];
		struct sxgbe_tx_norm_desc *p;

		p = tqueue->dma_tx + entry;

		/* Check if the descriptor is owned by the DMA. */
		if (priv->hw->desc->get_tx_owner(p))
			break;

		if (netif_msg_tx_done(priv))
			pr_debug("%s: curr %d, dirty %d\n",
				 __func__, tqueue->cur_tx, tqueue->dirty_tx);

		if (likely(tqueue->tx_skbuff_dma[entry])) {
			dma_unmap_single(priv->device,
					 tqueue->tx_skbuff_dma[entry],
					 priv->hw->desc->get_tx_len(p),
					 DMA_TO_DEVICE);
			tqueue->tx_skbuff_dma[entry] = 0;
		}

		if (likely(skb)) {
			dev_kfree_skb(skb);
			tqueue->tx_skbuff[entry] = NULL;
		}

		priv->hw->desc->release_tx_desc(p);

		tqueue->dirty_tx++;
	}

	/* wake up queue */
	if (unlikely(netif_tx_queue_stopped(dev_txq) &&
	    sxgbe_tx_avail(tqueue, tx_rsize) > SXGBE_TX_THRESH(priv))) {
		if (netif_msg_tx_done(priv))
			pr_debug("%s: restart transmit\n", __func__);
		netif_tx_wake_queue(dev_txq);
	}

	__netif_tx_unlock(dev_txq);
}

/**
 * sxgbe_tx_all_clean:
 * @priv: driver private structure
 * Description: it reclaims resources after transmission completes.
 */
static void sxgbe_tx_all_clean(struct sxgbe_priv_data * const priv)
{
	u8 queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		struct sxgbe_tx_queue *tqueue = priv->txq[queue_num];

		sxgbe_tx_queue_clean(tqueue);
	}

	if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
		sxgbe_enable_eee_mode(priv);
		mod_timer(&priv->eee_ctrl_timer, SXGBE_LPI_TIMER(eee_timer));
	}
}

/**
 * sxgbe_restart_tx_queue: irq tx error mng function
 * @priv: driver private structure
 * @queue_num: queue number
 * Description: it cleans the descriptors and restarts the transmission
 * in case of errors.
 */
static void sxgbe_restart_tx_queue(struct sxgbe_priv_data *priv, int queue_num)
{
	struct sxgbe_tx_queue *tx_ring = priv->txq[queue_num];
	struct netdev_queue *dev_txq = netdev_get_tx_queue(priv->dev,
							   queue_num);

	/* stop the queue */
	netif_tx_stop_queue(dev_txq);

	/* stop the tx dma */
	priv->hw->dma->stop_tx_queue(priv->ioaddr, queue_num);

	/* free the skbuffs of the ring */
	tx_free_ring_skbufs(tx_ring);

	/* initialise counters */
	tx_ring->cur_tx = 0;
	tx_ring->dirty_tx = 0;

	/* start the tx dma */
	priv->hw->dma->start_tx_queue(priv->ioaddr, queue_num);

	priv->dev->stats.tx_errors++;

	/* wakeup the queue */
	netif_tx_wake_queue(dev_txq);
}

/**
 * sxgbe_reset_all_tx_queues: irq tx error mng function
 * @priv: driver private structure
 * Description: it cleans all the descriptors and
 * restarts the transmission on all queues in case of errors.
 */
static void sxgbe_reset_all_tx_queues(struct sxgbe_priv_data *priv)
{
	int queue_num;

	/* On TX timeout of net device, resetting of all queues
	 * may not be proper way, revisit this later if needed
	 */
	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num)
		sxgbe_restart_tx_queue(priv, queue_num);
}

/**
 * sxgbe_get_hw_features: get XMAC capabilities from the HW cap. register.
 * @priv: driver private structure
 * Description:
 *  new GMAC chip generations have a new register to indicate the
 *  presence of the optional feature/functions.
 *  This can be also used to override the value passed through the
 *  platform and necessary for old MAC10/100 and GMAC chips.
 */
static int sxgbe_get_hw_features(struct sxgbe_priv_data * const priv)
{
	int rval = 0;
	struct sxgbe_hw_features *features = &priv->hw_cap;

	/* Read First Capability Register CAP[0] */
	rval = priv->hw->mac->get_hw_feature(priv->ioaddr, 0);
	if (rval) {
		features->pmt_remote_wake_up =
			SXGBE_HW_FEAT_PMT_TEMOTE_WOP(rval);
		features->pmt_magic_frame = SXGBE_HW_FEAT_PMT_MAGIC_PKT(rval);
		features->atime_stamp = SXGBE_HW_FEAT_IEEE1500_2008(rval);
		features->tx_csum_offload =
			SXGBE_HW_FEAT_TX_CSUM_OFFLOAD(rval);
		features->rx_csum_offload =
			SXGBE_HW_FEAT_RX_CSUM_OFFLOAD(rval);
		features->multi_macaddr = SXGBE_HW_FEAT_MACADDR_COUNT(rval);
		features->tstamp_srcselect = SXGBE_HW_FEAT_TSTMAP_SRC(rval);
		features->sa_vlan_insert = SXGBE_HW_FEAT_SRCADDR_VLAN(rval);
		features->eee = SXGBE_HW_FEAT_EEE(rval);
	}

	/* Read First Capability Register CAP[1] */
	rval = priv->hw->mac->get_hw_feature(priv->ioaddr, 1);
	if (rval) {
		features->rxfifo_size = SXGBE_HW_FEAT_RX_FIFO_SIZE(rval);
		features->txfifo_size = SXGBE_HW_FEAT_TX_FIFO_SIZE(rval);
		features->atstmap_hword = SXGBE_HW_FEAT_TX_FIFO_SIZE(rval);
		features->dcb_enable = SXGBE_HW_FEAT_DCB(rval);
		features->splithead_enable = SXGBE_HW_FEAT_SPLIT_HDR(rval);
		features->tcpseg_offload = SXGBE_HW_FEAT_TSO(rval);
		features->debug_mem = SXGBE_HW_FEAT_DEBUG_MEM_IFACE(rval);
		features->rss_enable = SXGBE_HW_FEAT_RSS(rval);
		features->hash_tsize = SXGBE_HW_FEAT_HASH_TABLE_SIZE(rval);
		features->l3l4_filer_size = SXGBE_HW_FEAT_L3L4_FILTER_NUM(rval);
	}

	/* Read First Capability Register CAP[2] */
	rval = priv->hw->mac->get_hw_feature(priv->ioaddr, 2);
	if (rval) {
		features->rx_mtl_queues = SXGBE_HW_FEAT_RX_MTL_QUEUES(rval);
		features->tx_mtl_queues = SXGBE_HW_FEAT_TX_MTL_QUEUES(rval);
		features->rx_dma_channels = SXGBE_HW_FEAT_RX_DMA_CHANNELS(rval);
		features->tx_dma_channels = SXGBE_HW_FEAT_TX_DMA_CHANNELS(rval);
		features->pps_output_count = SXGBE_HW_FEAT_PPS_OUTPUTS(rval);
		features->aux_input_count = SXGBE_HW_FEAT_AUX_SNAPSHOTS(rval);
	}

	return rval;
}

/**
 * sxgbe_check_ether_addr: check if the MAC addr is valid
 * @priv: driver private structure
 * Description:
 * it is to verify if the MAC address is valid, in case of failures it
 * generates a random MAC address
 */
static void sxgbe_check_ether_addr(struct sxgbe_priv_data *priv)
{
	if (!is_valid_ether_addr(priv->dev->dev_addr)) {
		priv->hw->mac->get_umac_addr((void __iomem *)
					     priv->ioaddr,
					     priv->dev->dev_addr, 0);
		if (!is_valid_ether_addr(priv->dev->dev_addr))
			eth_hw_addr_random(priv->dev);
	}
	dev_info(priv->device, "device MAC address %pM\n",
		 priv->dev->dev_addr);
}

/**
 * sxgbe_init_dma_engine: DMA init.
 * @priv: driver private structure
 * Description:
 * It inits the DMA invoking the specific SXGBE callback.
 * Some DMA parameters can be passed from the platform;
 * in case of these are not passed a default is kept for the MAC or GMAC.
 */
static int sxgbe_init_dma_engine(struct sxgbe_priv_data *priv)
{
	int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_map = 0;
	int queue_num;

	if (priv->plat->dma_cfg) {
		pbl = priv->plat->dma_cfg->pbl;
		fixed_burst = priv->plat->dma_cfg->fixed_burst;
		burst_map = priv->plat->dma_cfg->burst_map;
	}

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num)
		priv->hw->dma->cha_init(priv->ioaddr, queue_num,
					fixed_burst, pbl,
					(priv->txq[queue_num])->dma_tx_phy,
					(priv->rxq[queue_num])->dma_rx_phy,
					priv->dma_tx_size, priv->dma_rx_size);

	return priv->hw->dma->init(priv->ioaddr, fixed_burst, burst_map);
}

/**
 * sxgbe_init_mtl_engine: MTL init.
 * @priv: driver private structure
 * Description:
 * It inits the MTL invoking the specific SXGBE callback.
 */
static void sxgbe_init_mtl_engine(struct sxgbe_priv_data *priv)
{
	int queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		priv->hw->mtl->mtl_set_txfifosize(priv->ioaddr, queue_num,
						  priv->hw_cap.tx_mtl_qsize);
		priv->hw->mtl->mtl_enable_txqueue(priv->ioaddr, queue_num);
	}
}

/**
 * sxgbe_disable_mtl_engine: MTL disable.
 * @priv: driver private structure
 * Description:
 * It disables the MTL queues by invoking the specific SXGBE callback.
 */
static void sxgbe_disable_mtl_engine(struct sxgbe_priv_data *priv)
{
	int queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num)
		priv->hw->mtl->mtl_disable_txqueue(priv->ioaddr, queue_num);
}


/**
 * sxgbe_tx_timer: mitigation sw timer for tx.
 * @t: timer pointer
 * Description:
 * This is the timer handler to directly invoke the sxgbe_tx_clean.
 */
static void sxgbe_tx_timer(struct timer_list *t)
{
	struct sxgbe_tx_queue *p = from_timer(p, t, txtimer);
	sxgbe_tx_queue_clean(p);
}

/**
 * sxgbe_tx_init_coalesce: init tx mitigation options.
 * @priv: driver private structure
 * Description:
 * This inits the transmit coalesce parameters: i.e. timer rate,
 * timer handler and default threshold used for enabling the
 * interrupt on completion bit.
 */
static void sxgbe_tx_init_coalesce(struct sxgbe_priv_data *priv)
{
	u8 queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		struct sxgbe_tx_queue *p = priv->txq[queue_num];
		p->tx_coal_frames =  SXGBE_TX_FRAMES;
		p->tx_coal_timer = SXGBE_COAL_TX_TIMER;
		timer_setup(&p->txtimer, sxgbe_tx_timer, 0);
		p->txtimer.expires = SXGBE_COAL_TIMER(p->tx_coal_timer);
		add_timer(&p->txtimer);
	}
}

static void sxgbe_tx_del_timer(struct sxgbe_priv_data *priv)
{
	u8 queue_num;

	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		struct sxgbe_tx_queue *p = priv->txq[queue_num];
		del_timer_sync(&p->txtimer);
	}
}

/**
 *  sxgbe_open - open entry point of the driver
 *  @dev : pointer to the device structure.
 *  Description:
 *  This function is the open entry point of the driver.
 *  Return value:
 *  0 on success and an appropriate (-)ve integer as defined in errno.h
 *  file on failure.
 */
static int sxgbe_open(struct net_device *dev)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	int ret, queue_num;

	clk_prepare_enable(priv->sxgbe_clk);

	sxgbe_check_ether_addr(priv);

	/* Init the phy */
	ret = sxgbe_init_phy(dev);
	if (ret) {
		netdev_err(dev, "%s: Cannot attach to PHY (error: %d)\n",
			   __func__, ret);
		goto phy_error;
	}

	/* Create and initialize the TX/RX descriptors chains. */
	priv->dma_tx_size = SXGBE_ALIGN(DMA_TX_SIZE);
	priv->dma_rx_size = SXGBE_ALIGN(DMA_RX_SIZE);
	priv->dma_buf_sz = SXGBE_ALIGN(DMA_BUFFER_SIZE);
	priv->tx_tc = TC_DEFAULT;
	priv->rx_tc = TC_DEFAULT;
	init_dma_desc_rings(dev);

	/* DMA initialization and SW reset */
	ret = sxgbe_init_dma_engine(priv);
	if (ret < 0) {
		netdev_err(dev, "%s: DMA initialization failed\n", __func__);
		goto init_error;
	}

	/*  MTL initialization */
	sxgbe_init_mtl_engine(priv);

	/* Copy the MAC addr into the HW  */
	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);

	/* Initialize the MAC Core */
	priv->hw->mac->core_init(priv->ioaddr);
	SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) {
		priv->hw->mac->enable_rxqueue(priv->ioaddr, queue_num);
	}

	/* Request the IRQ lines */
	ret = devm_request_irq(priv->device, priv->irq, sxgbe_common_interrupt,
			       IRQF_SHARED, dev->name, dev);
	if (unlikely(ret < 0)) {
		netdev_err(dev, "%s: ERROR: allocating the IRQ %d (error: %d)\n",
			   __func__, priv->irq, ret);
		goto init_error;
	}

	/* If the LPI irq is different from the mac irq
	 * register a dedicated handler
	 */
	if (priv->lpi_irq != dev->irq) {
		ret = devm_request_irq(priv->device, priv->lpi_irq,
				       sxgbe_common_interrupt,
				       IRQF_SHARED, dev->name, dev);
		if (unlikely(ret < 0)) {
			netdev_err(dev, "%s: ERROR: allocating the LPI IRQ %d (%d)\n",
				   __func__, priv->lpi_irq, ret);
			goto init_error;
		}
	}

	/* Request TX DMA irq lines */
	SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
		ret = devm_request_irq(priv->device,
				       (priv->txq[queue_num])->irq_no,
				       sxgbe_tx_interrupt, 0,
				       dev->name, priv->txq[queue_num]);
		if (unlikely(ret < 0)) {
			netdev_err(dev, "%s: ERROR: allocating TX IRQ %d (error: %d)\n",
				   __func__, priv->irq, ret);
			goto init_error;
		}
	}

	/* Request RX DMA irq lines */
	SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) {
		ret = devm_request_irq(priv->device,
				       (priv->rxq[queue_num])->irq_no,
				       sxgbe_rx_interrupt, 0,
				       dev->name, priv->rxq[queue_num]);
		if (unlikely(ret < 0)) {
			netdev_err(dev, "%s: ERROR: allocating TX IRQ %d (error: %d)\n",
				   __func__, priv->irq, ret);
			goto init_error;
		}
	}

	/* Enable the MAC Rx/Tx */
	priv->hw->mac->enable_tx(priv->ioaddr, true);
	priv->hw->mac->enable_rx(priv->ioaddr, true);

	/* Set the HW DMA mode and the COE */
	sxgbe_mtl_operation_mode(priv);

	/* Extra statistics */
	memset(&priv->xstats, 0, sizeof(struct sxgbe_extra_stats));

	priv->xstats.tx_threshold = priv->tx_tc;
	priv->xstats.rx_threshold = priv->rx_tc;

	/* Start the ball rolling... */
	netdev_dbg(dev, "DMA RX/TX processes started...\n");
	priv->hw->dma->start_tx(priv->ioaddr, SXGBE_TX_QUEUES);
	priv->hw->dma->start_rx(priv->ioaddr, SXGBE_RX_QUEUES);

	if (dev->phydev)
		phy_start(dev->phydev);

	/* initialise TX coalesce parameters */
	sxgbe_tx_init_coalesce(priv);

	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
		priv->rx_riwt = SXGBE_MAX_DMA_RIWT;
		priv->hw->dma->rx_watchdog(priv->ioaddr, SXGBE_MAX_DMA_RIWT);
	}

	priv->tx_lpi_timer = SXGBE_DEFAULT_LPI_TIMER;
	priv->eee_enabled = sxgbe_eee_init(priv);

	napi_enable(&priv->napi);
	netif_start_queue(dev);

	return 0;

init_error:
	free_dma_desc_resources(priv);
	if (dev->phydev)
		phy_disconnect(dev->phydev);
phy_error:
	clk_disable_unprepare(priv->sxgbe_clk);

	return ret;
}

/**
 *  sxgbe_release - close entry point of the driver
 *  @dev : device pointer.
 *  Description:
 *  This is the stop entry point of the driver.
 */
static int sxgbe_release(struct net_device *dev)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);

	if (priv->eee_enabled)
		del_timer_sync(&priv->eee_ctrl_timer);

	/* Stop and disconnect the PHY */
	if (dev->phydev) {
		phy_stop(dev->phydev);
		phy_disconnect(dev->phydev);
	}

	netif_tx_stop_all_queues(dev);

	napi_disable(&priv->napi);

	/* delete TX timers */
	sxgbe_tx_del_timer(priv);

	/* Stop TX/RX DMA and clear the descriptors */
	priv->hw->dma->stop_tx(priv->ioaddr, SXGBE_TX_QUEUES);
	priv->hw->dma->stop_rx(priv->ioaddr, SXGBE_RX_QUEUES);

	/* disable MTL queue */
	sxgbe_disable_mtl_engine(priv);

	/* Release and free the Rx/Tx resources */
	free_dma_desc_resources(priv);

	/* Disable the MAC Rx/Tx */
	priv->hw->mac->enable_tx(priv->ioaddr, false);
	priv->hw->mac->enable_rx(priv->ioaddr, false);

	clk_disable_unprepare(priv->sxgbe_clk);

	return 0;
}
/* Prepare first Tx descriptor for doing TSO operation */
static void sxgbe_tso_prepare(struct sxgbe_priv_data *priv,
			      struct sxgbe_tx_norm_desc *first_desc,
			      struct sk_buff *skb)
{
	unsigned int total_hdr_len, tcp_hdr_len;

	/* Write first Tx descriptor with appropriate value */
	tcp_hdr_len = tcp_hdrlen(skb);
	total_hdr_len = skb_transport_offset(skb) + tcp_hdr_len;

	first_desc->tdes01 = dma_map_single(priv->device, skb->data,
					    total_hdr_len, DMA_TO_DEVICE);
	if (dma_mapping_error(priv->device, first_desc->tdes01))
		pr_err("%s: TX dma mapping failed!!\n", __func__);

	first_desc->tdes23.tx_rd_des23.first_desc = 1;
	priv->hw->desc->tx_desc_enable_tse(first_desc, 1, total_hdr_len,
					   tcp_hdr_len,
					   skb->len - total_hdr_len);
}

/**
 *  sxgbe_xmit: Tx entry point of the driver
 *  @skb : the socket buffer
 *  @dev : device pointer
 *  Description : this is the tx entry point of the driver.
 *  It programs the chain or the ring and supports oversized frames
 *  and SG feature.
 */
static netdev_tx_t sxgbe_xmit(struct sk_buff *skb, struct net_device *dev)
{
	unsigned int entry, frag_num;
	int cksum_flag = 0;
	struct netdev_queue *dev_txq;
	unsigned txq_index = skb_get_queue_mapping(skb);
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	unsigned int tx_rsize = priv->dma_tx_size;
	struct sxgbe_tx_queue *tqueue = priv->txq[txq_index];
	struct sxgbe_tx_norm_desc *tx_desc, *first_desc;
	struct sxgbe_tx_ctxt_desc *ctxt_desc = NULL;
	int nr_frags = skb_shinfo(skb)->nr_frags;
	int no_pagedlen = skb_headlen(skb);
	int is_jumbo = 0;
	u16 cur_mss = skb_shinfo(skb)->gso_size;
	u32 ctxt_desc_req = 0;

	/* get the TX queue handle */
	dev_txq = netdev_get_tx_queue(dev, txq_index);

	if (unlikely(skb_is_gso(skb) && tqueue->prev_mss != cur_mss))
		ctxt_desc_req = 1;

	if (unlikely(skb_vlan_tag_present(skb) ||
		     ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
		      tqueue->hwts_tx_en)))
		ctxt_desc_req = 1;

	if (priv->tx_path_in_lpi_mode)
		sxgbe_disable_eee_mode(priv);

	if (unlikely(sxgbe_tx_avail(tqueue, tx_rsize) < nr_frags + 1)) {
		if (!netif_tx_queue_stopped(dev_txq)) {
			netif_tx_stop_queue(dev_txq);
			netdev_err(dev, "%s: Tx Ring is full when %d queue is awake\n",
				   __func__, txq_index);
		}
		return NETDEV_TX_BUSY;
	}

	entry = tqueue->cur_tx % tx_rsize;
	tx_desc = tqueue->dma_tx + entry;

	first_desc = tx_desc;
	if (ctxt_desc_req)
		ctxt_desc = (struct sxgbe_tx_ctxt_desc *)first_desc;

	/* save the skb address */
	tqueue->tx_skbuff[entry] = skb;

	if (!is_jumbo) {
		if (likely(skb_is_gso(skb))) {
			/* TSO support */
			if (unlikely(tqueue->prev_mss != cur_mss)) {
				priv->hw->desc->tx_ctxt_desc_set_mss(
						ctxt_desc, cur_mss);
				priv->hw->desc->tx_ctxt_desc_set_tcmssv(
						ctxt_desc);
				priv->hw->desc->tx_ctxt_desc_reset_ostc(
						ctxt_desc);
				priv->hw->desc->tx_ctxt_desc_set_ctxt(
						ctxt_desc);
				priv->hw->desc->tx_ctxt_desc_set_owner(
						ctxt_desc);

				entry = (++tqueue->cur_tx) % tx_rsize;
				first_desc = tqueue->dma_tx + entry;

				tqueue->prev_mss = cur_mss;
			}
			sxgbe_tso_prepare(priv, first_desc, skb);
		} else {
			tx_desc->tdes01 = dma_map_single(priv->device,
							 skb->data, no_pagedlen, DMA_TO_DEVICE);
			if (dma_mapping_error(priv->device, tx_desc->tdes01))
				netdev_err(dev, "%s: TX dma mapping failed!!\n",
					   __func__);

			priv->hw->desc->prepare_tx_desc(tx_desc, 1, no_pagedlen,
							no_pagedlen, cksum_flag);
		}
	}

	for (frag_num = 0; frag_num < nr_frags; frag_num++) {
		const skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_num];
		int len = skb_frag_size(frag);

		entry = (++tqueue->cur_tx) % tx_rsize;
		tx_desc = tqueue->dma_tx + entry;
		tx_desc->tdes01 = skb_frag_dma_map(priv->device, frag, 0, len,
						   DMA_TO_DEVICE);

		tqueue->tx_skbuff_dma[entry] = tx_desc->tdes01;
		tqueue->tx_skbuff[entry] = NULL;

		/* prepare the descriptor */
		priv->hw->desc->prepare_tx_desc(tx_desc, 0, len,
						len, cksum_flag);
		/* memory barrier to flush descriptor */
		wmb();

		/* set the owner */
		priv->hw->desc->set_tx_owner(tx_desc);
	}

	/* close the descriptors */
	priv->hw->desc->close_tx_desc(tx_desc);

	/* memory barrier to flush descriptor */
	wmb();

	tqueue->tx_count_frames += nr_frags + 1;
	if (tqueue->tx_count_frames > tqueue->tx_coal_frames) {
		priv->hw->desc->clear_tx_ic(tx_desc);
		priv->xstats.tx_reset_ic_bit++;
		mod_timer(&tqueue->txtimer,
			  SXGBE_COAL_TIMER(tqueue->tx_coal_timer));
	} else {
		tqueue->tx_count_frames = 0;
	}

	/* set owner for first desc */
	priv->hw->desc->set_tx_owner(first_desc);

	/* memory barrier to flush descriptor */
	wmb();

	tqueue->cur_tx++;

	/* display current ring */
	netif_dbg(priv, pktdata, dev, "%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d\n",
		  __func__, tqueue->cur_tx % tx_rsize,
		  tqueue->dirty_tx % tx_rsize, entry,
		  first_desc, nr_frags);

	if (unlikely(sxgbe_tx_avail(tqueue, tx_rsize) <= (MAX_SKB_FRAGS + 1))) {
		netif_dbg(priv, hw, dev, "%s: stop transmitted packets\n",
			  __func__);
		netif_tx_stop_queue(dev_txq);
	}

	dev->stats.tx_bytes += skb->len;

	if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
		     tqueue->hwts_tx_en)) {
		/* declare that device is doing timestamping */
		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
		priv->hw->desc->tx_enable_tstamp(first_desc);
	}

	skb_tx_timestamp(skb);

	priv->hw->dma->enable_dma_transmission(priv->ioaddr, txq_index);

	return NETDEV_TX_OK;
}

/**
 * sxgbe_rx_refill: refill used skb preallocated buffers
 * @priv: driver private structure
 * Description : this is to reallocate the skb for the reception process
 * that is based on zero-copy.
 */
static void sxgbe_rx_refill(struct sxgbe_priv_data *priv)
{
	unsigned int rxsize = priv->dma_rx_size;
	int bfsize = priv->dma_buf_sz;
	u8 qnum = priv->cur_rx_qnum;

	for (; priv->rxq[qnum]->cur_rx - priv->rxq[qnum]->dirty_rx > 0;
	     priv->rxq[qnum]->dirty_rx++) {
		unsigned int entry = priv->rxq[qnum]->dirty_rx % rxsize;
		struct sxgbe_rx_norm_desc *p;

		p = priv->rxq[qnum]->dma_rx + entry;

		if (likely(priv->rxq[qnum]->rx_skbuff[entry] == NULL)) {
			struct sk_buff *skb;

			skb = netdev_alloc_skb_ip_align(priv->dev, bfsize);

			if (unlikely(skb == NULL))
				break;

			priv->rxq[qnum]->rx_skbuff[entry] = skb;
			priv->rxq[qnum]->rx_skbuff_dma[entry] =
				dma_map_single(priv->device, skb->data, bfsize,
					       DMA_FROM_DEVICE);

			p->rdes23.rx_rd_des23.buf2_addr =
				priv->rxq[qnum]->rx_skbuff_dma[entry];
		}

		/* Added memory barrier for RX descriptor modification */
		wmb();
		priv->hw->desc->set_rx_owner(p);
		priv->hw->desc->set_rx_int_on_com(p);
		/* Added memory barrier for RX descriptor modification */
		wmb();
	}
}

/**
 * sxgbe_rx: receive the frames from the remote host
 * @priv: driver private structure
 * @limit: napi bugget.
 * Description :  this the function called by the napi poll method.
 * It gets all the frames inside the ring.
 */
static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit)
{
	u8 qnum = priv->cur_rx_qnum;
	unsigned int rxsize = priv->dma_rx_size;
	unsigned int entry = priv->rxq[qnum]->cur_rx;
	unsigned int next_entry = 0;
	unsigned int count = 0;
	int checksum;
	int status;

	while (count < limit) {
		struct sxgbe_rx_norm_desc *p;
		struct sk_buff *skb;
		int frame_len;

		p = priv->rxq[qnum]->dma_rx + entry;

		if (priv->hw->desc->get_rx_owner(p))
			break;

		count++;

		next_entry = (++priv->rxq[qnum]->cur_rx) % rxsize;
		prefetch(priv->rxq[qnum]->dma_rx + next_entry);

		/* Read the status of the incoming frame and also get checksum
		 * value based on whether it is enabled in SXGBE hardware or
		 * not.
		 */
		status = priv->hw->desc->rx_wbstatus(p, &priv->xstats,
						     &checksum);
		if (unlikely(status < 0)) {
			entry = next_entry;
			continue;
		}
		if (unlikely(!priv->rxcsum_insertion))
			checksum = CHECKSUM_NONE;

		skb = priv->rxq[qnum]->rx_skbuff[entry];

		if (unlikely(!skb))
			netdev_err(priv->dev, "rx descriptor is not consistent\n");

		prefetch(skb->data - NET_IP_ALIGN);
		priv->rxq[qnum]->rx_skbuff[entry] = NULL;

		frame_len = priv->hw->desc->get_rx_frame_len(p);

		skb_put(skb, frame_len);

		skb->ip_summed = checksum;
		if (checksum == CHECKSUM_NONE)
			netif_receive_skb(skb);
		else
			napi_gro_receive(&priv->napi, skb);

		entry = next_entry;
	}

	sxgbe_rx_refill(priv);

	return count;
}

/**
 *  sxgbe_poll - sxgbe poll method (NAPI)
 *  @napi : pointer to the napi structure.
 *  @budget : maximum number of packets that the current CPU can receive from
 *	      all interfaces.
 *  Description :
 *  To look at the incoming frames and clear the tx resources.
 */
static int sxgbe_poll(struct napi_struct *napi, int budget)
{
	struct sxgbe_priv_data *priv = container_of(napi,
						    struct sxgbe_priv_data, napi);
	int work_done = 0;
	u8 qnum = priv->cur_rx_qnum;

	priv->xstats.napi_poll++;
	/* first, clean the tx queues */
	sxgbe_tx_all_clean(priv);

	work_done = sxgbe_rx(priv, budget);
	if (work_done < budget) {
		napi_complete_done(napi, work_done);
		priv->hw->dma->enable_dma_irq(priv->ioaddr, qnum);
	}

	return work_done;
}

/**
 *  sxgbe_tx_timeout
 *  @dev : Pointer to net device structure
 *  @txqueue: index of the hanging queue
 *  Description: this function is called when a packet transmission fails to
 *   complete within a reasonable time. The driver will mark the error in the
 *   netdev structure and arrange for the device to be reset to a sane state
 *   in order to transmit a new packet.
 */
static void sxgbe_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);

	sxgbe_reset_all_tx_queues(priv);
}

/**
 *  sxgbe_common_interrupt - main ISR
 *  @irq: interrupt number.
 *  @dev_id: to pass the net device pointer.
 *  Description: this is the main driver interrupt service routine.
 *  It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI
 *  interrupts.
 */
static irqreturn_t sxgbe_common_interrupt(int irq, void *dev_id)
{
	struct net_device *netdev = (struct net_device *)dev_id;
	struct sxgbe_priv_data *priv = netdev_priv(netdev);
	int status;

	status = priv->hw->mac->host_irq_status(priv->ioaddr, &priv->xstats);
	/* For LPI we need to save the tx status */
	if (status & TX_ENTRY_LPI_MODE) {
		priv->xstats.tx_lpi_entry_n++;
		priv->tx_path_in_lpi_mode = true;
	}
	if (status & TX_EXIT_LPI_MODE) {
		priv->xstats.tx_lpi_exit_n++;
		priv->tx_path_in_lpi_mode = false;
	}
	if (status & RX_ENTRY_LPI_MODE)
		priv->xstats.rx_lpi_entry_n++;
	if (status & RX_EXIT_LPI_MODE)
		priv->xstats.rx_lpi_exit_n++;

	return IRQ_HANDLED;
}

/**
 *  sxgbe_tx_interrupt - TX DMA ISR
 *  @irq: interrupt number.
 *  @dev_id: to pass the net device pointer.
 *  Description: this is the tx dma interrupt service routine.
 */
static irqreturn_t sxgbe_tx_interrupt(int irq, void *dev_id)
{
	int status;
	struct sxgbe_tx_queue *txq = (struct sxgbe_tx_queue *)dev_id;
	struct sxgbe_priv_data *priv = txq->priv_ptr;

	/* get the channel status */
	status = priv->hw->dma->tx_dma_int_status(priv->ioaddr, txq->queue_no,
						  &priv->xstats);
	/* check for normal path */
	if (likely((status & handle_tx)))
		napi_schedule(&priv->napi);

	/* check for unrecoverable error */
	if (unlikely((status & tx_hard_error)))
		sxgbe_restart_tx_queue(priv, txq->queue_no);

	/* check for TC configuration change */
	if (unlikely((status & tx_bump_tc) &&
		     (priv->tx_tc != SXGBE_MTL_SFMODE) &&
		     (priv->tx_tc < 512))) {
		/* step of TX TC is 32 till 128, otherwise 64 */
		priv->tx_tc += (priv->tx_tc < 128) ? 32 : 64;
		priv->hw->mtl->set_tx_mtl_mode(priv->ioaddr,
					       txq->queue_no, priv->tx_tc);
		priv->xstats.tx_threshold = priv->tx_tc;
	}

	return IRQ_HANDLED;
}

/**
 *  sxgbe_rx_interrupt - RX DMA ISR
 *  @irq: interrupt number.
 *  @dev_id: to pass the net device pointer.
 *  Description: this is the rx dma interrupt service routine.
 */
static irqreturn_t sxgbe_rx_interrupt(int irq, void *dev_id)
{
	int status;
	struct sxgbe_rx_queue *rxq = (struct sxgbe_rx_queue *)dev_id;
	struct sxgbe_priv_data *priv = rxq->priv_ptr;

	/* get the channel status */
	status = priv->hw->dma->rx_dma_int_status(priv->ioaddr, rxq->queue_no,
						  &priv->xstats);

	if (likely((status & handle_rx) && (napi_schedule_prep(&priv->napi)))) {
		priv->hw->dma->disable_dma_irq(priv->ioaddr, rxq->queue_no);
		__napi_schedule(&priv->napi);
	}

	/* check for TC configuration change */
	if (unlikely((status & rx_bump_tc) &&
		     (priv->rx_tc != SXGBE_MTL_SFMODE) &&
		     (priv->rx_tc < 128))) {
		/* step of TC is 32 */
		priv->rx_tc += 32;
		priv->hw->mtl->set_rx_mtl_mode(priv->ioaddr,
					       rxq->queue_no, priv->rx_tc);
		priv->xstats.rx_threshold = priv->rx_tc;
	}

	return IRQ_HANDLED;
}

static inline u64 sxgbe_get_stat64(void __iomem *ioaddr, int reg_lo, int reg_hi)
{
	u64 val = readl(ioaddr + reg_lo);

	val |= ((u64)readl(ioaddr + reg_hi)) << 32;

	return val;
}


/*  sxgbe_get_stats64 - entry point to see statistical information of device
 *  @dev : device pointer.
 *  @stats : pointer to hold all the statistical information of device.
 *  Description:
 *  This function is a driver entry point whenever ifconfig command gets
 *  executed to see device statistics. Statistics are number of
 *  bytes sent or received, errors occurred etc.
 */
static void sxgbe_get_stats64(struct net_device *dev,
			      struct rtnl_link_stats64 *stats)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	void __iomem *ioaddr = priv->ioaddr;
	u64 count;

	spin_lock(&priv->stats_lock);
	/* Freeze the counter registers before reading value otherwise it may
	 * get updated by hardware while we are reading them
	 */
	writel(SXGBE_MMC_CTRL_CNT_FRZ, ioaddr + SXGBE_MMC_CTL_REG);

	stats->rx_bytes = sxgbe_get_stat64(ioaddr,
					   SXGBE_MMC_RXOCTETLO_GCNT_REG,
					   SXGBE_MMC_RXOCTETHI_GCNT_REG);

	stats->rx_packets = sxgbe_get_stat64(ioaddr,
					     SXGBE_MMC_RXFRAMELO_GBCNT_REG,
					     SXGBE_MMC_RXFRAMEHI_GBCNT_REG);

	stats->multicast = sxgbe_get_stat64(ioaddr,
					    SXGBE_MMC_RXMULTILO_GCNT_REG,
					    SXGBE_MMC_RXMULTIHI_GCNT_REG);

	stats->rx_crc_errors = sxgbe_get_stat64(ioaddr,
						SXGBE_MMC_RXCRCERRLO_REG,
						SXGBE_MMC_RXCRCERRHI_REG);

	stats->rx_length_errors = sxgbe_get_stat64(ioaddr,
						  SXGBE_MMC_RXLENERRLO_REG,
						  SXGBE_MMC_RXLENERRHI_REG);

	stats->rx_missed_errors = sxgbe_get_stat64(ioaddr,
						   SXGBE_MMC_RXFIFOOVERFLOWLO_GBCNT_REG,
						   SXGBE_MMC_RXFIFOOVERFLOWHI_GBCNT_REG);

	stats->tx_bytes = sxgbe_get_stat64(ioaddr,
					   SXGBE_MMC_TXOCTETLO_GCNT_REG,
					   SXGBE_MMC_TXOCTETHI_GCNT_REG);

	count = sxgbe_get_stat64(ioaddr, SXGBE_MMC_TXFRAMELO_GBCNT_REG,
				 SXGBE_MMC_TXFRAMEHI_GBCNT_REG);

	stats->tx_errors = sxgbe_get_stat64(ioaddr, SXGBE_MMC_TXFRAMELO_GCNT_REG,
					    SXGBE_MMC_TXFRAMEHI_GCNT_REG);
	stats->tx_errors = count - stats->tx_errors;
	stats->tx_packets = count;
	stats->tx_fifo_errors = sxgbe_get_stat64(ioaddr, SXGBE_MMC_TXUFLWLO_GBCNT_REG,
						 SXGBE_MMC_TXUFLWHI_GBCNT_REG);
	writel(0, ioaddr + SXGBE_MMC_CTL_REG);
	spin_unlock(&priv->stats_lock);
}

/*  sxgbe_set_features - entry point to set offload features of the device.
 *  @dev : device pointer.
 *  @features : features which are required to be set.
 *  Description:
 *  This function is a driver entry point and called by Linux kernel whenever
 *  any device features are set or reset by user.
 *  Return value:
 *  This function returns 0 after setting or resetting device features.
 */
static int sxgbe_set_features(struct net_device *dev,
			      netdev_features_t features)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	netdev_features_t changed = dev->features ^ features;

	if (changed & NETIF_F_RXCSUM) {
		if (features & NETIF_F_RXCSUM) {
			priv->hw->mac->enable_rx_csum(priv->ioaddr);
			priv->rxcsum_insertion = true;
		} else {
			priv->hw->mac->disable_rx_csum(priv->ioaddr);
			priv->rxcsum_insertion = false;
		}
	}

	return 0;
}

/*  sxgbe_change_mtu - entry point to change MTU size for the device.
 *  @dev : device pointer.
 *  @new_mtu : the new MTU size for the device.
 *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
 *  to drive packet transmission. Ethernet has an MTU of 1500 octets
 *  (ETH_DATA_LEN). This value can be changed with ifconfig.
 *  Return value:
 *  0 on success and an appropriate (-)ve integer as defined in errno.h
 *  file on failure.
 */
static int sxgbe_change_mtu(struct net_device *dev, int new_mtu)
{
	dev->mtu = new_mtu;

	if (!netif_running(dev))
		return 0;

	/* Recevice ring buffer size is needed to be set based on MTU. If MTU is
	 * changed then reinitilisation of the receive ring buffers need to be
	 * done. Hence bring interface down and bring interface back up
	 */
	sxgbe_release(dev);
	return sxgbe_open(dev);
}

static void sxgbe_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
				unsigned int reg_n)
{
	unsigned long data;

	data = (addr[5] << 8) | addr[4];
	/* For MAC Addr registers se have to set the Address Enable (AE)
	 * bit that has no effect on the High Reg 0 where the bit 31 (MO)
	 * is RO.
	 */
	writel(data | SXGBE_HI_REG_AE, ioaddr + SXGBE_ADDR_HIGH(reg_n));
	data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
	writel(data, ioaddr + SXGBE_ADDR_LOW(reg_n));
}

/**
 * sxgbe_set_rx_mode - entry point for setting different receive mode of
 * a device. unicast, multicast addressing
 * @dev : pointer to the device structure
 * Description:
 * This function is a driver entry point which gets called by the kernel
 * whenever different receive mode like unicast, multicast and promiscuous
 * must be enabled/disabled.
 * Return value:
 * void.
 */
static void sxgbe_set_rx_mode(struct net_device *dev)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);
	void __iomem *ioaddr = (void __iomem *)priv->ioaddr;
	unsigned int value = 0;
	u32 mc_filter[2];
	struct netdev_hw_addr *ha;
	int reg = 1;

	netdev_dbg(dev, "%s: # mcasts %d, # unicast %d\n",
		   __func__, netdev_mc_count(dev), netdev_uc_count(dev));

	if (dev->flags & IFF_PROMISC) {
		value = SXGBE_FRAME_FILTER_PR;

	} else if ((netdev_mc_count(dev) > SXGBE_HASH_TABLE_SIZE) ||
		   (dev->flags & IFF_ALLMULTI)) {
		value = SXGBE_FRAME_FILTER_PM;	/* pass all multi */
		writel(0xffffffff, ioaddr + SXGBE_HASH_HIGH);
		writel(0xffffffff, ioaddr + SXGBE_HASH_LOW);

	} else if (!netdev_mc_empty(dev)) {
		/* Hash filter for multicast */
		value = SXGBE_FRAME_FILTER_HMC;

		memset(mc_filter, 0, sizeof(mc_filter));
		netdev_for_each_mc_addr(ha, dev) {
			/* The upper 6 bits of the calculated CRC are used to
			 * index the contens of the hash table
			 */
			int bit_nr = bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26;

			/* The most significant bit determines the register to
			 * use (H/L) while the other 5 bits determine the bit
			 * within the register.
			 */
			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
		}
		writel(mc_filter[0], ioaddr + SXGBE_HASH_LOW);
		writel(mc_filter[1], ioaddr + SXGBE_HASH_HIGH);
	}

	/* Handle multiple unicast addresses (perfect filtering) */
	if (netdev_uc_count(dev) > SXGBE_MAX_PERFECT_ADDRESSES)
		/* Switch to promiscuous mode if more than 16 addrs
		 * are required
		 */
		value |= SXGBE_FRAME_FILTER_PR;
	else {
		netdev_for_each_uc_addr(ha, dev) {
			sxgbe_set_umac_addr(ioaddr, ha->addr, reg);
			reg++;
		}
	}
#ifdef FRAME_FILTER_DEBUG
	/* Enable Receive all mode (to debug filtering_fail errors) */
	value |= SXGBE_FRAME_FILTER_RA;
#endif
	writel(value, ioaddr + SXGBE_FRAME_FILTER);

	netdev_dbg(dev, "Filter: 0x%08x\n\tHash: HI 0x%08x, LO 0x%08x\n",
		   readl(ioaddr + SXGBE_FRAME_FILTER),
		   readl(ioaddr + SXGBE_HASH_HIGH),
		   readl(ioaddr + SXGBE_HASH_LOW));
}

#ifdef CONFIG_NET_POLL_CONTROLLER
/**
 * sxgbe_poll_controller - entry point for polling receive by device
 * @dev : pointer to the device structure
 * Description:
 * This function is used by NETCONSOLE and other diagnostic tools
 * to allow network I/O with interrupts disabled.
 * Return value:
 * Void.
 */
static void sxgbe_poll_controller(struct net_device *dev)
{
	struct sxgbe_priv_data *priv = netdev_priv(dev);

	disable_irq(priv->irq);
	sxgbe_rx_interrupt(priv->irq, dev);
	enable_irq(priv->irq);
}
#endif

/*  sxgbe_ioctl - Entry point for the Ioctl
 *  @dev: Device pointer.
 *  @rq: An IOCTL specefic structure, that can contain a pointer to
 *  a proprietary structure used to pass information to the driver.
 *  @cmd: IOCTL command
 *  Description:
 *  Currently it supports the phy_mii_ioctl(...) and HW time stamping.
 */
static int sxgbe_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
	int ret = -EOPNOTSUPP;

	if (!netif_running(dev))
		return -EINVAL;

	switch (cmd) {
	case SIOCGMIIPHY:
	case SIOCGMIIREG:
	case SIOCSMIIREG:
		ret = phy_do_ioctl(dev, rq, cmd);
		break;
	default:
		break;
	}

	return ret;
}

static const struct net_device_ops sxgbe_netdev_ops = {
	.ndo_open		= sxgbe_open,
	.ndo_start_xmit		= sxgbe_xmit,
	.ndo_stop		= sxgbe_release,
	.ndo_get_stats64	= sxgbe_get_stats64,
	.ndo_change_mtu		= sxgbe_change_mtu,
	.ndo_set_features	= sxgbe_set_features,
	.ndo_set_rx_mode	= sxgbe_set_rx_mode,
	.ndo_tx_timeout		= sxgbe_tx_timeout,
	.ndo_eth_ioctl		= sxgbe_ioctl,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= sxgbe_poll_controller,
#endif
	.ndo_set_mac_address	= eth_mac_addr,
};

/* Get the hardware ops */
static void sxgbe_get_ops(struct sxgbe_ops * const ops_ptr)
{
	ops_ptr->mac		= sxgbe_get_core_ops();
	ops_ptr->desc		= sxgbe_get_desc_ops();
	ops_ptr->dma		= sxgbe_get_dma_ops();
	ops_ptr->mtl		= sxgbe_get_mtl_ops();

	/* set the MDIO communication Address/Data regisers */
	ops_ptr->mii.addr	= SXGBE_MDIO_SCMD_ADD_REG;
	ops_ptr->mii.data	= SXGBE_MDIO_SCMD_DATA_REG;

	/* Assigning the default link settings
	 * no SXGBE defined default values to be set in registers,
	 * so assigning as 0 for port and duplex
	 */
	ops_ptr->link.port	= 0;
	ops_ptr->link.duplex	= 0;
	ops_ptr->link.speed	= SXGBE_SPEED_10G;
}

/**
 *  sxgbe_hw_init - Init the GMAC device
 *  @priv: driver private structure
 *  Description: this function checks the HW capability
 *  (if supported) and sets the driver's features.
 */
static int sxgbe_hw_init(struct sxgbe_priv_data * const priv)
{
	u32 ctrl_ids;

	priv->hw = kmalloc(sizeof(*priv->hw), GFP_KERNEL);
	if(!priv->hw)
		return -ENOMEM;

	/* get the hardware ops */
	sxgbe_get_ops(priv->hw);

	/* get the controller id */
	ctrl_ids = priv->hw->mac->get_controller_version(priv->ioaddr);
	priv->hw->ctrl_uid = (ctrl_ids & 0x00ff0000) >> 16;
	priv->hw->ctrl_id = (ctrl_ids & 0x000000ff);
	pr_info("user ID: 0x%x, Controller ID: 0x%x\n",
		priv->hw->ctrl_uid, priv->hw->ctrl_id);

	/* get the H/W features */
	if (!sxgbe_get_hw_features(priv))
		pr_info("Hardware features not found\n");

	if (priv->hw_cap.tx_csum_offload)
		pr_info("TX Checksum offload supported\n");

	if (priv->hw_cap.rx_csum_offload)
		pr_info("RX Checksum offload supported\n");

	return 0;
}

static int sxgbe_sw_reset(void __iomem *addr)
{
	int retry_count = 10;

	writel(SXGBE_DMA_SOFT_RESET, addr + SXGBE_DMA_MODE_REG);
	while (retry_count--) {
		if (!(readl(addr + SXGBE_DMA_MODE_REG) &
		      SXGBE_DMA_SOFT_RESET))
			break;
		mdelay(10);
	}

	if (retry_count < 0)
		return -EBUSY;

	return 0;
}

/**
 * sxgbe_drv_probe
 * @device: device pointer
 * @plat_dat: platform data pointer
 * @addr: iobase memory address
 * Description: this is the main probe function used to
 * call the alloc_etherdev, allocate the priv structure.
 */
struct sxgbe_priv_data *sxgbe_drv_probe(struct device *device,
					struct sxgbe_plat_data *plat_dat,
					void __iomem *addr)
{
	struct sxgbe_priv_data *priv;
	struct net_device *ndev;
	int ret;
	u8 queue_num;

	ndev = alloc_etherdev_mqs(sizeof(struct sxgbe_priv_data),
				  SXGBE_TX_QUEUES, SXGBE_RX_QUEUES);
	if (!ndev)
		return NULL;

	SET_NETDEV_DEV(ndev, device);

	priv = netdev_priv(ndev);
	priv->device = device;
	priv->dev = ndev;

	sxgbe_set_ethtool_ops(ndev);
	priv->plat = plat_dat;
	priv->ioaddr = addr;

	ret = sxgbe_sw_reset(priv->ioaddr);
	if (ret)
		goto error_free_netdev;

	/* Verify driver arguments */
	sxgbe_verify_args();

	/* Init MAC and get the capabilities */
	ret = sxgbe_hw_init(priv);
	if (ret)
		goto error_free_netdev;

	/* allocate memory resources for Descriptor rings */
	ret = txring_mem_alloc(priv);
	if (ret)
		goto error_free_hw;

	ret = rxring_mem_alloc(priv);
	if (ret)
		goto error_free_hw;

	ndev->netdev_ops = &sxgbe_netdev_ops;

	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
		NETIF_F_RXCSUM | NETIF_F_TSO | NETIF_F_TSO6 |
		NETIF_F_GRO;
	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
	ndev->watchdog_timeo = msecs_to_jiffies(TX_TIMEO);

	/* assign filtering support */
	ndev->priv_flags |= IFF_UNICAST_FLT;

	/* MTU range: 68 - 9000 */
	ndev->min_mtu = MIN_MTU;
	ndev->max_mtu = MAX_MTU;

	priv->msg_enable = netif_msg_init(debug, default_msg_level);

	/* Enable TCP segmentation offload for all DMA channels */
	if (priv->hw_cap.tcpseg_offload) {
		SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
			priv->hw->dma->enable_tso(priv->ioaddr, queue_num);
		}
	}

	/* Enable Rx checksum offload */
	if (priv->hw_cap.rx_csum_offload) {
		priv->hw->mac->enable_rx_csum(priv->ioaddr);
		priv->rxcsum_insertion = true;
	}

	/* Initialise pause frame settings */
	priv->rx_pause = 1;
	priv->tx_pause = 1;

	/* Rx Watchdog is available, enable depend on platform data */
	if (!priv->plat->riwt_off) {
		priv->use_riwt = 1;
		pr_info("Enable RX Mitigation via HW Watchdog Timer\n");
	}

	netif_napi_add(ndev, &priv->napi, sxgbe_poll, 64);

	spin_lock_init(&priv->stats_lock);

	priv->sxgbe_clk = clk_get(priv->device, SXGBE_RESOURCE_NAME);
	if (IS_ERR(priv->sxgbe_clk)) {
		netdev_warn(ndev, "%s: warning: cannot get CSR clock\n",
			    __func__);
		goto error_napi_del;
	}

	/* If a specific clk_csr value is passed from the platform
	 * this means that the CSR Clock Range selection cannot be
	 * changed at run-time and it is fixed. Viceversa the driver'll try to
	 * set the MDC clock dynamically according to the csr actual
	 * clock input.
	 */
	if (!priv->plat->clk_csr)
		sxgbe_clk_csr_set(priv);
	else
		priv->clk_csr = priv->plat->clk_csr;

	/* MDIO bus Registration */
	ret = sxgbe_mdio_register(ndev);
	if (ret < 0) {
		netdev_dbg(ndev, "%s: MDIO bus (id: %d) registration failed\n",
			   __func__, priv->plat->bus_id);
		goto error_clk_put;
	}

	ret = register_netdev(ndev);
	if (ret) {
		pr_err("%s: ERROR %i registering the device\n", __func__, ret);
		goto error_mdio_unregister;
	}

	sxgbe_check_ether_addr(priv);

	return priv;

error_mdio_unregister:
	sxgbe_mdio_unregister(ndev);
error_clk_put:
	clk_put(priv->sxgbe_clk);
error_napi_del:
	netif_napi_del(&priv->napi);
error_free_hw:
	kfree(priv->hw);
error_free_netdev:
	free_netdev(ndev);

	return NULL;
}

/**
 * sxgbe_drv_remove
 * @ndev: net device pointer
 * Description: this function resets the TX/RX processes, disables the MAC RX/TX
 * changes the link status, releases the DMA descriptor rings.
 */
int sxgbe_drv_remove(struct net_device *ndev)
{
	struct sxgbe_priv_data *priv = netdev_priv(ndev);
	u8 queue_num;

	netdev_info(ndev, "%s: removing driver\n", __func__);

	SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) {
		priv->hw->mac->disable_rxqueue(priv->ioaddr, queue_num);
	}

	priv->hw->dma->stop_rx(priv->ioaddr, SXGBE_RX_QUEUES);
	priv->hw->dma->stop_tx(priv->ioaddr, SXGBE_TX_QUEUES);

	priv->hw->mac->enable_tx(priv->ioaddr, false);
	priv->hw->mac->enable_rx(priv->ioaddr, false);

	unregister_netdev(ndev);

	sxgbe_mdio_unregister(ndev);

	clk_put(priv->sxgbe_clk);

	netif_napi_del(&priv->napi);

	kfree(priv->hw);

	free_netdev(ndev);

	return 0;
}

#ifdef CONFIG_PM
int sxgbe_suspend(struct net_device *ndev)
{
	return 0;
}

int sxgbe_resume(struct net_device *ndev)
{
	return 0;
}

int sxgbe_freeze(struct net_device *ndev)
{
	return -ENOSYS;
}

int sxgbe_restore(struct net_device *ndev)
{
	return -ENOSYS;
}
#endif /* CONFIG_PM */

/* Driver is configured as Platform driver */
static int __init sxgbe_init(void)
{
	int ret;

	ret = sxgbe_register_platform();
	if (ret)
		goto err;
	return 0;
err:
	pr_err("driver registration failed\n");
	return ret;
}

static void __exit sxgbe_exit(void)
{
	sxgbe_unregister_platform();
}

module_init(sxgbe_init);
module_exit(sxgbe_exit);

#ifndef MODULE
static int __init sxgbe_cmdline_opt(char *str)
{
	char *opt;

	if (!str || !*str)
		return -EINVAL;
	while ((opt = strsep(&str, ",")) != NULL) {
		if (!strncmp(opt, "eee_timer:", 10)) {
			if (kstrtoint(opt + 10, 0, &eee_timer))
				goto err;
		}
	}
	return 0;

err:
	pr_err("%s: ERROR broken module parameter conversion\n", __func__);
	return -EINVAL;
}

__setup("sxgbeeth=", sxgbe_cmdline_opt);
#endif /* MODULE */



MODULE_DESCRIPTION("Samsung 10G/2.5G/1G Ethernet PLATFORM driver");

MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)");
MODULE_PARM_DESC(eee_timer, "EEE-LPI Default LS timer value");

MODULE_AUTHOR("Siva Reddy Kallam <siva.kallam@samsung.com>");
MODULE_AUTHOR("ByungHo An <bh74.an@samsung.com>");
MODULE_AUTHOR("Girish K S <ks.giri@samsung.com>");
MODULE_AUTHOR("Vipul Pandya <vipul.pandya@samsung.com>");

MODULE_LICENSE("GPL");
