// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
/*
 * Copyright (c) 2003-2012 Broadcom Corporation
 * All Rights Reserved
 */

#include <linux/phy.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/smp.h>
#include <linux/ethtool.h>
#include <linux/module.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>

#include <asm/mipsregs.h>
/*
 * fmn.h - For FMN credit configuration and registering fmn_handler.
 * FMN is communication mechanism that allows processing agents within
 * XLR/XLS to communicate each other.
 */
#include <asm/netlogic/xlr/fmn.h>

#include "platform_net.h"
#include "xlr_net.h"

/*
 * The readl/writel implementation byteswaps on XLR/XLS, so
 * we need to use __raw_ IO to read the NAE registers
 * because they are in the big-endian MMIO area on the SoC.
 */
static inline void xlr_nae_wreg(u32 __iomem *base, unsigned int reg, u32 val)
{
	__raw_writel(val, base + reg);
}

static inline u32 xlr_nae_rdreg(u32 __iomem *base, unsigned int reg)
{
	return __raw_readl(base + reg);
}

static inline void xlr_reg_update(u32 *base_addr, u32 off, u32 val, u32 mask)
{
	u32 tmp;

	tmp = xlr_nae_rdreg(base_addr, off);
	xlr_nae_wreg(base_addr, off, (tmp & ~mask) | (val & mask));
}

#define MAC_SKB_BACK_PTR_SIZE SMP_CACHE_BYTES

static int send_to_rfr_fifo(struct xlr_net_priv *priv, void *addr)
{
	struct nlm_fmn_msg msg;
	int ret = 0, num_try = 0, stnid;
	unsigned long paddr, mflags;

	paddr = virt_to_bus(addr);
	msg.msg0 = (u64)paddr & 0xffffffffe0ULL;
	msg.msg1 = 0;
	msg.msg2 = 0;
	msg.msg3 = 0;
	stnid = priv->nd->rfr_station;
	do {
		mflags = nlm_cop2_enable_irqsave();
		ret = nlm_fmn_send(1, 0, stnid, &msg);
		nlm_cop2_disable_irqrestore(mflags);
		if (ret == 0)
			return 0;
	} while (++num_try < 10000);

	netdev_err(priv->ndev, "Send to RFR failed in RX path\n");
	return ret;
}

static inline unsigned char *xlr_alloc_skb(void)
{
	struct sk_buff *skb;
	int buf_len = sizeof(struct sk_buff *);
	unsigned char *skb_data;

	/* skb->data is cache aligned */
	skb = alloc_skb(XLR_RX_BUF_SIZE, GFP_ATOMIC);
	if (!skb)
		return NULL;
	skb_data = skb->data;
	skb_put(skb, MAC_SKB_BACK_PTR_SIZE);
	skb_pull(skb, MAC_SKB_BACK_PTR_SIZE);
	memcpy(skb_data, &skb, buf_len);

	return skb->data;
}

static void xlr_net_fmn_handler(int bkt, int src_stnid, int size, int code,
				struct nlm_fmn_msg *msg, void *arg)
{
	struct sk_buff *skb;
	void *skb_data = NULL;
	struct net_device *ndev;
	struct xlr_net_priv *priv;
	u32 port, length;
	unsigned char *addr;
	struct xlr_adapter *adapter = arg;

	length = (msg->msg0 >> 40) & 0x3fff;
	if (length == 0) {
		addr = bus_to_virt(msg->msg0 & 0xffffffffffULL);
		addr = addr - MAC_SKB_BACK_PTR_SIZE;
		skb = (struct sk_buff *)(*(unsigned long *)addr);
		dev_kfree_skb_any((struct sk_buff *)addr);
	} else {
		addr = (unsigned char *)
			bus_to_virt(msg->msg0 & 0xffffffffe0ULL);
		length = length - BYTE_OFFSET - MAC_CRC_LEN;
		port = ((int)msg->msg0) & 0x0f;
		addr = addr - MAC_SKB_BACK_PTR_SIZE;
		skb = (struct sk_buff *)(*(unsigned long *)addr);
		skb->dev = adapter->netdev[port];
		if (!skb->dev)
			return;
		ndev = skb->dev;
		priv = netdev_priv(ndev);

		/* 16 byte IP header align */
		skb_reserve(skb, BYTE_OFFSET);
		skb_put(skb, length);
		skb->protocol = eth_type_trans(skb, skb->dev);
		netif_rx(skb);
		/* Fill rx ring */
		skb_data = xlr_alloc_skb();
		if (skb_data)
			send_to_rfr_fifo(priv, skb_data);
	}
}

static struct phy_device *xlr_get_phydev(struct xlr_net_priv *priv)
{
	return mdiobus_get_phy(priv->mii_bus, priv->phy_addr);
}

/*
 * Ethtool operation
 */
static int xlr_get_link_ksettings(struct net_device *ndev,
				  struct ethtool_link_ksettings *ecmd)
{
	struct xlr_net_priv *priv = netdev_priv(ndev);
	struct phy_device *phydev = xlr_get_phydev(priv);

	if (!phydev)
		return -ENODEV;

	phy_ethtool_ksettings_get(phydev, ecmd);

	return 0;
}

static int xlr_set_link_ksettings(struct net_device *ndev,
				  const struct ethtool_link_ksettings *ecmd)
{
	struct xlr_net_priv *priv = netdev_priv(ndev);
	struct phy_device *phydev = xlr_get_phydev(priv);

	if (!phydev)
		return -ENODEV;
	return phy_ethtool_ksettings_set(phydev, ecmd);
}

static const struct ethtool_ops xlr_ethtool_ops = {
	.get_link_ksettings = xlr_get_link_ksettings,
	.set_link_ksettings = xlr_set_link_ksettings,
};

/*
 * Net operations
 */
static int xlr_net_fill_rx_ring(struct net_device *ndev)
{
	void *skb_data;
	struct xlr_net_priv *priv = netdev_priv(ndev);
	int i;

	for (i = 0; i < MAX_FRIN_SPILL / 4; i++) {
		skb_data = xlr_alloc_skb();
		if (!skb_data) {
			netdev_err(ndev, "SKB allocation failed\n");
			return -ENOMEM;
		}
		send_to_rfr_fifo(priv, skb_data);
	}
	netdev_info(ndev, "Rx ring setup done\n");
	return 0;
}

static int xlr_net_open(struct net_device *ndev)
{
	u32 err;
	struct xlr_net_priv *priv = netdev_priv(ndev);
	struct phy_device *phydev = xlr_get_phydev(priv);

	/* schedule a link state check */
	phy_start(phydev);

	err = phy_start_aneg(phydev);
	if (err) {
		pr_err("Autoneg failed\n");
		return err;
	}
	/* Setup the speed from PHY to internal reg*/
	xlr_set_gmac_speed(priv);

	netif_tx_start_all_queues(ndev);

	return 0;
}

static int xlr_net_stop(struct net_device *ndev)
{
	struct xlr_net_priv *priv = netdev_priv(ndev);
	struct phy_device *phydev = xlr_get_phydev(priv);

	phy_stop(phydev);
	netif_tx_stop_all_queues(ndev);
	return 0;
}

static void xlr_make_tx_desc(struct nlm_fmn_msg *msg, unsigned long addr,
			     struct sk_buff *skb)
{
	unsigned long physkb = virt_to_phys(skb);
	int cpu_core = nlm_core_id();
	int fr_stn_id = cpu_core * 8 + XLR_FB_STN;	/* FB to 6th bucket */

	msg->msg0 = (((u64)1 << 63)	|	/* End of packet descriptor */
		((u64)127 << 54)	|	/* No Free back */
		(u64)skb->len << 40	|	/* Length of data */
		((u64)addr));
	msg->msg1 = (((u64)1 << 63)	|
		((u64)fr_stn_id << 54)	|	/* Free back id */
		(u64)0 << 40		|	/* Set len to 0 */
		((u64)physkb  & 0xffffffff));	/* 32bit address */
	msg->msg2 = 0;
	msg->msg3 = 0;
}

static netdev_tx_t xlr_net_start_xmit(struct sk_buff *skb,
				      struct net_device *ndev)
{
	struct nlm_fmn_msg msg;
	struct xlr_net_priv *priv = netdev_priv(ndev);
	int ret;
	u32 flags;

	xlr_make_tx_desc(&msg, virt_to_phys(skb->data), skb);
	flags = nlm_cop2_enable_irqsave();
	ret = nlm_fmn_send(2, 0, priv->tx_stnid, &msg);
	nlm_cop2_disable_irqrestore(flags);
	if (ret)
		dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
}

static void xlr_hw_set_mac_addr(struct net_device *ndev)
{
	struct xlr_net_priv *priv = netdev_priv(ndev);

	/* set mac station address */
	xlr_nae_wreg(priv->base_addr, R_MAC_ADDR0,
		     ((ndev->dev_addr[5] << 24) | (ndev->dev_addr[4] << 16) |
		     (ndev->dev_addr[3] << 8) | (ndev->dev_addr[2])));
	xlr_nae_wreg(priv->base_addr, R_MAC_ADDR0 + 1,
		     ((ndev->dev_addr[1] << 24) | (ndev->dev_addr[0] << 16)));

	xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK2, 0xffffffff);
	xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK2 + 1, 0xffffffff);
	xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK3, 0xffffffff);
	xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK3 + 1, 0xffffffff);

	xlr_nae_wreg(priv->base_addr, R_MAC_FILTER_CONFIG,
		     (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) |
		     (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) |
		     (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID));

	if (priv->nd->phy_interface == PHY_INTERFACE_MODE_RGMII ||
	    priv->nd->phy_interface == PHY_INTERFACE_MODE_SGMII)
		xlr_reg_update(priv->base_addr, R_IPG_IFG, MAC_B2B_IPG, 0x7f);
}

static int xlr_net_set_mac_addr(struct net_device *ndev, void *data)
{
	int err;

	err = eth_mac_addr(ndev, data);
	if (err)
		return err;
	xlr_hw_set_mac_addr(ndev);
	return 0;
}

static void xlr_set_rx_mode(struct net_device *ndev)
{
	struct xlr_net_priv *priv = netdev_priv(ndev);
	u32 regval;

	regval = xlr_nae_rdreg(priv->base_addr, R_MAC_FILTER_CONFIG);

	if (ndev->flags & IFF_PROMISC) {
		regval |= (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) |
		(1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) |
		(1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) |
		(1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN);
	} else {
		regval &= ~((1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) |
		(1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN));
	}

	xlr_nae_wreg(priv->base_addr, R_MAC_FILTER_CONFIG, regval);
}

static void xlr_stats(struct net_device *ndev, struct rtnl_link_stats64 *stats)
{
	struct xlr_net_priv *priv = netdev_priv(ndev);

	stats->rx_packets = xlr_nae_rdreg(priv->base_addr, RX_PACKET_COUNTER);
	stats->tx_packets = xlr_nae_rdreg(priv->base_addr, TX_PACKET_COUNTER);
	stats->rx_bytes = xlr_nae_rdreg(priv->base_addr, RX_BYTE_COUNTER);
	stats->tx_bytes = xlr_nae_rdreg(priv->base_addr, TX_BYTE_COUNTER);
	stats->tx_errors = xlr_nae_rdreg(priv->base_addr, TX_FCS_ERROR_COUNTER);
	stats->rx_dropped = xlr_nae_rdreg(priv->base_addr,
					  RX_DROP_PACKET_COUNTER);
	stats->tx_dropped = xlr_nae_rdreg(priv->base_addr,
					  TX_DROP_FRAME_COUNTER);

	stats->multicast = xlr_nae_rdreg(priv->base_addr,
					 RX_MULTICAST_PACKET_COUNTER);
	stats->collisions = xlr_nae_rdreg(priv->base_addr,
					  TX_TOTAL_COLLISION_COUNTER);

	stats->rx_length_errors = xlr_nae_rdreg(priv->base_addr,
						RX_FRAME_LENGTH_ERROR_COUNTER);
	stats->rx_over_errors = xlr_nae_rdreg(priv->base_addr,
					      RX_DROP_PACKET_COUNTER);
	stats->rx_crc_errors = xlr_nae_rdreg(priv->base_addr,
					     RX_FCS_ERROR_COUNTER);
	stats->rx_frame_errors = xlr_nae_rdreg(priv->base_addr,
					       RX_ALIGNMENT_ERROR_COUNTER);

	stats->rx_fifo_errors = xlr_nae_rdreg(priv->base_addr,
					      RX_DROP_PACKET_COUNTER);
	stats->rx_missed_errors = xlr_nae_rdreg(priv->base_addr,
						RX_CARRIER_SENSE_ERROR_COUNTER);

	stats->rx_errors = (stats->rx_over_errors + stats->rx_crc_errors +
			    stats->rx_frame_errors + stats->rx_fifo_errors +
			    stats->rx_missed_errors);

	stats->tx_aborted_errors = xlr_nae_rdreg(priv->base_addr,
			TX_EXCESSIVE_COLLISION_PACKET_COUNTER);
	stats->tx_carrier_errors = xlr_nae_rdreg(priv->base_addr,
						 TX_DROP_FRAME_COUNTER);
	stats->tx_fifo_errors = xlr_nae_rdreg(priv->base_addr,
					      TX_DROP_FRAME_COUNTER);
}

static const struct net_device_ops xlr_netdev_ops = {
	.ndo_open = xlr_net_open,
	.ndo_stop = xlr_net_stop,
	.ndo_start_xmit = xlr_net_start_xmit,
	.ndo_select_queue = dev_pick_tx_cpu_id,
	.ndo_set_mac_address = xlr_net_set_mac_addr,
	.ndo_set_rx_mode = xlr_set_rx_mode,
	.ndo_get_stats64 = xlr_stats,
};

/*
 * Gmac init
 */
static void *xlr_config_spill(struct xlr_net_priv *priv, int reg_start_0,
			      int reg_start_1, int reg_size, int size)
{
	void *spill;
	u32 *base;
	unsigned long phys_addr;
	u32 spill_size;

	base = priv->base_addr;
	spill_size = size;
	spill = kmalloc(spill_size + SMP_CACHE_BYTES, GFP_ATOMIC);
	if (!spill) {
		pr_err("Unable to allocate memory for spill area!\n");
		return ZERO_SIZE_PTR;
	}

	spill = PTR_ALIGN(spill, SMP_CACHE_BYTES);
	phys_addr = virt_to_phys(spill);
	dev_dbg(&priv->ndev->dev, "Allocated spill %d bytes at %lx\n",
		size, phys_addr);
	xlr_nae_wreg(base, reg_start_0, (phys_addr >> 5) & 0xffffffff);
	xlr_nae_wreg(base, reg_start_1, ((u64)phys_addr >> 37) & 0x07);
	xlr_nae_wreg(base, reg_size, spill_size);

	return spill;
}

/*
 * Configure the 6 FIFO's that are used by the network accelarator to
 * communicate with the rest of the XLx device. 4 of the FIFO's are for
 * packets from NA --> cpu (called Class FIFO's) and 2 are for feeding
 * the NA with free descriptors.
 */
static void xlr_config_fifo_spill_area(struct xlr_net_priv *priv)
{
	priv->frin_spill = xlr_config_spill(priv,
					    R_REG_FRIN_SPILL_MEM_START_0,
					    R_REG_FRIN_SPILL_MEM_START_1,
					    R_REG_FRIN_SPILL_MEM_SIZE,
					    MAX_FRIN_SPILL * sizeof(u64));
	priv->frout_spill = xlr_config_spill(priv,
					     R_FROUT_SPILL_MEM_START_0,
					     R_FROUT_SPILL_MEM_START_1,
					     R_FROUT_SPILL_MEM_SIZE,
					     MAX_FROUT_SPILL * sizeof(u64));
	priv->class_0_spill = xlr_config_spill(priv,
					       R_CLASS0_SPILL_MEM_START_0,
					       R_CLASS0_SPILL_MEM_START_1,
					       R_CLASS0_SPILL_MEM_SIZE,
					       MAX_CLASS_0_SPILL * sizeof(u64));
	priv->class_1_spill = xlr_config_spill(priv,
					       R_CLASS1_SPILL_MEM_START_0,
					       R_CLASS1_SPILL_MEM_START_1,
					       R_CLASS1_SPILL_MEM_SIZE,
					       MAX_CLASS_1_SPILL * sizeof(u64));
	priv->class_2_spill = xlr_config_spill(priv,
					       R_CLASS2_SPILL_MEM_START_0,
					       R_CLASS2_SPILL_MEM_START_1,
					       R_CLASS2_SPILL_MEM_SIZE,
					       MAX_CLASS_2_SPILL * sizeof(u64));
	priv->class_3_spill = xlr_config_spill(priv,
					       R_CLASS3_SPILL_MEM_START_0,
					       R_CLASS3_SPILL_MEM_START_1,
					       R_CLASS3_SPILL_MEM_SIZE,
					       MAX_CLASS_3_SPILL * sizeof(u64));
}

/*
 * Configure PDE to Round-Robin distribution of packets to the
 * available cpu
 */
static void xlr_config_pde(struct xlr_net_priv *priv)
{
	int i = 0;
	u64 bkt_map = 0;

	/* Each core has 8 buckets(station) */
	for (i = 0; i < hweight32(priv->nd->cpu_mask); i++)
		bkt_map |= (0xff << (i * 8));

	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_0, (bkt_map & 0xffffffff));
	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_0 + 1,
		     ((bkt_map >> 32) & 0xffffffff));

	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_1, (bkt_map & 0xffffffff));
	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_1 + 1,
		     ((bkt_map >> 32) & 0xffffffff));

	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_2, (bkt_map & 0xffffffff));
	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_2 + 1,
		     ((bkt_map >> 32) & 0xffffffff));

	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_3, (bkt_map & 0xffffffff));
	xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_3 + 1,
		     ((bkt_map >> 32) & 0xffffffff));
}

/*
 * Setup the Message ring credits, bucket size and other
 * common configuration
 */
static int xlr_config_common(struct xlr_net_priv *priv)
{
	struct xlr_fmn_info *gmac = priv->nd->gmac_fmn_info;
	int start_stn_id = gmac->start_stn_id;
	int end_stn_id = gmac->end_stn_id;
	int *bucket_size = priv->nd->bucket_size;
	int i, j, err;

	/* Setting non-core MsgBktSize(0x321 - 0x325) */
	for (i = start_stn_id; i <= end_stn_id; i++) {
		xlr_nae_wreg(priv->base_addr,
			     R_GMAC_RFR0_BUCKET_SIZE + i - start_stn_id,
			     bucket_size[i]);
	}

	/*
	 * Setting non-core Credit counter register
	 * Distributing Gmac's credit to CPU's
	 */
	for (i = 0; i < 8; i++) {
		for (j = 0; j < 8; j++)
			xlr_nae_wreg(priv->base_addr,
				     (R_CC_CPU0_0 + (i * 8)) + j,
				     gmac->credit_config[(i * 8) + j]);
	}

	xlr_nae_wreg(priv->base_addr, R_MSG_TX_THRESHOLD, 3);
	xlr_nae_wreg(priv->base_addr, R_DMACR0, 0xffffffff);
	xlr_nae_wreg(priv->base_addr, R_DMACR1, 0xffffffff);
	xlr_nae_wreg(priv->base_addr, R_DMACR2, 0xffffffff);
	xlr_nae_wreg(priv->base_addr, R_DMACR3, 0xffffffff);
	xlr_nae_wreg(priv->base_addr, R_FREEQCARVE, 0);

	err = xlr_net_fill_rx_ring(priv->ndev);
	if (err)
		return err;
	nlm_register_fmn_handler(start_stn_id, end_stn_id, xlr_net_fmn_handler,
				 priv->adapter);
	return 0;
}

static void xlr_config_translate_table(struct xlr_net_priv *priv)
{
	u32 cpu_mask;
	u32 val;
	int bkts[32]; /* one bucket is assumed for each cpu */
	int b1, b2, c1, c2, i, j, k;
	int use_bkt;

	use_bkt = 0;
	cpu_mask = priv->nd->cpu_mask;

	pr_info("Using %s-based distribution\n",
		(use_bkt) ? "bucket" : "class");
	j = 0;
	for (i = 0; i < 32; i++) {
		if ((1 << i) & cpu_mask) {
			/* for each cpu, mark the 4+threadid bucket */
			bkts[j] = ((i / 4) * 8) + (i % 4);
			j++;
		}
	}

	/*configure the 128 * 9 Translation table to send to available buckets*/
	k = 0;
	c1 = 3;
	c2 = 0;
	for (i = 0; i < 64; i++) {
		/*
		 * On use_bkt set the b0, b1 are used, else
		 * the 4 classes are used, here implemented
		 * a logic to distribute the packets to the
		 * buckets equally or based on the class
		 */
		c1 = (c1 + 1) & 3;
		c2 = (c1 + 1) & 3;
		b1 = bkts[k];
		k = (k + 1) % j;
		b2 = bkts[k];
		k = (k + 1) % j;

		val = ((c1 << 23) | (b1 << 17) | (use_bkt << 16) |
				(c2 << 7) | (b2 << 1) | (use_bkt << 0));
		dev_dbg(&priv->ndev->dev, "Table[%d] b1=%d b2=%d c1=%d c2=%d\n",
			i, b1, b2, c1, c2);
		xlr_nae_wreg(priv->base_addr, R_TRANSLATETABLE + i, val);
		c1 = c2;
	}
}

static void xlr_config_parser(struct xlr_net_priv *priv)
{
	u32 val;

	/* Mark it as ETHERNET type */
	xlr_nae_wreg(priv->base_addr, R_L2TYPE_0, 0x01);

	/* Use 7bit CRChash for flow classification with 127 as CRC polynomial*/
	xlr_nae_wreg(priv->base_addr, R_PARSERCONFIGREG,
		     ((0x7f << 8) | (1 << 1)));

	/* configure the parser : L2 Type is configured in the bootloader */
	/* extract IP: src, dest protocol */
	xlr_nae_wreg(priv->base_addr, R_L3CTABLE,
		     (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) |
		     (0x0800 << 0));
	xlr_nae_wreg(priv->base_addr, R_L3CTABLE + 1,
		     (9 << 25) | (1 << 21) | (12 << 14) | (4 << 10) |
		     (16 << 4) | 4);

	/* Configure to extract SRC port and Dest port for TCP and UDP pkts */
	xlr_nae_wreg(priv->base_addr, R_L4CTABLE, 6);
	xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 2, 17);
	val = ((0 << 21) | (2 << 17) | (2 << 11) | (2 << 7));
	xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 1, val);
	xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 3, val);

	xlr_config_translate_table(priv);
}

static int xlr_phy_write(u32 *base_addr, int phy_addr, int regnum, u16 val)
{
	unsigned long timeout, stoptime, checktime;
	int timedout;

	/* 100ms timeout*/
	timeout = msecs_to_jiffies(100);
	stoptime = jiffies + timeout;
	timedout = 0;

	xlr_nae_wreg(base_addr, R_MII_MGMT_ADDRESS, (phy_addr << 8) | regnum);

	/* Write the data which starts the write cycle */
	xlr_nae_wreg(base_addr, R_MII_MGMT_WRITE_DATA, (u32)val);

	/* poll for the read cycle to complete */
	while (!timedout) {
		checktime = jiffies;
		if (xlr_nae_rdreg(base_addr, R_MII_MGMT_INDICATORS) == 0)
			break;
		timedout = time_after(checktime, stoptime);
	}
	if (timedout) {
		pr_info("Phy device write err: device busy");
		return -EBUSY;
	}

	return 0;
}

static int xlr_phy_read(u32 *base_addr, int phy_addr, int regnum)
{
	unsigned long timeout, stoptime, checktime;
	int timedout;

	/* 100ms timeout*/
	timeout = msecs_to_jiffies(100);
	stoptime = jiffies + timeout;
	timedout = 0;

	/* setup the phy reg to be used */
	xlr_nae_wreg(base_addr, R_MII_MGMT_ADDRESS,
		     (phy_addr << 8) | (regnum << 0));

	/* Issue the read command */
	xlr_nae_wreg(base_addr, R_MII_MGMT_COMMAND,
		     (1 << O_MII_MGMT_COMMAND__rstat));

	/* poll for the read cycle to complete */
	while (!timedout) {
		checktime = jiffies;
		if (xlr_nae_rdreg(base_addr, R_MII_MGMT_INDICATORS) == 0)
			break;
		timedout = time_after(checktime, stoptime);
	}
	if (timedout) {
		pr_info("Phy device read err: device busy");
		return -EBUSY;
	}

	/* clear the read cycle */
	xlr_nae_wreg(base_addr, R_MII_MGMT_COMMAND, 0);

	/* Read the data */
	return xlr_nae_rdreg(base_addr, R_MII_MGMT_STATUS);
}

static int xlr_mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 val)
{
	struct xlr_net_priv *priv = bus->priv;
	int ret;

	ret = xlr_phy_write(priv->mii_addr, phy_addr, regnum, val);
	dev_dbg(&priv->ndev->dev, "mii_write phy %d : %d <- %x [%x]\n",
		phy_addr, regnum, val, ret);
	return ret;
}

static int xlr_mii_read(struct mii_bus *bus, int phy_addr, int regnum)
{
	struct xlr_net_priv *priv = bus->priv;
	int ret;

	ret =  xlr_phy_read(priv->mii_addr, phy_addr, regnum);
	dev_dbg(&priv->ndev->dev, "mii_read phy %d : %d [%x]\n",
		phy_addr, regnum, ret);
	return ret;
}

/*
 * XLR ports are RGMII. XLS ports are SGMII mostly except the port0,
 * which can be configured either SGMII or RGMII, considered SGMII
 * by default, if board setup to RGMII the port_type need to set
 * accordingly.Serdes and PCS layer need to configured for SGMII
 */
static void xlr_sgmii_init(struct xlr_net_priv *priv)
{
	int phy;

	xlr_phy_write(priv->serdes_addr, 26, 0, 0x6DB0);
	xlr_phy_write(priv->serdes_addr, 26, 1, 0xFFFF);
	xlr_phy_write(priv->serdes_addr, 26, 2, 0xB6D0);
	xlr_phy_write(priv->serdes_addr, 26, 3, 0x00FF);
	xlr_phy_write(priv->serdes_addr, 26, 4, 0x0000);
	xlr_phy_write(priv->serdes_addr, 26, 5, 0x0000);
	xlr_phy_write(priv->serdes_addr, 26, 6, 0x0005);
	xlr_phy_write(priv->serdes_addr, 26, 7, 0x0001);
	xlr_phy_write(priv->serdes_addr, 26, 8, 0x0000);
	xlr_phy_write(priv->serdes_addr, 26, 9, 0x0000);
	xlr_phy_write(priv->serdes_addr, 26, 10, 0x0000);

	/* program  GPIO values for serdes init parameters */
	xlr_nae_wreg(priv->gpio_addr, 0x20, 0x7e6802);
	xlr_nae_wreg(priv->gpio_addr, 0x10, 0x7104);

	xlr_nae_wreg(priv->gpio_addr, 0x22, 0x7e6802);
	xlr_nae_wreg(priv->gpio_addr, 0x21, 0x7104);

	/* enable autoneg - more magic */
	phy = priv->phy_addr % 4 + 27;
	xlr_phy_write(priv->pcs_addr, phy, 0, 0x1000);
	xlr_phy_write(priv->pcs_addr, phy, 0, 0x0200);
}

void xlr_set_gmac_speed(struct xlr_net_priv *priv)
{
	struct phy_device *phydev = xlr_get_phydev(priv);
	int speed;

	if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
		xlr_sgmii_init(priv);

	if (phydev->speed != priv->phy_speed) {
		speed = phydev->speed;
		if (speed == SPEED_1000) {
			/* Set interface to Byte mode */
			xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7217);
			priv->phy_speed = speed;
		} else if (speed == SPEED_100 || speed == SPEED_10) {
			/* Set interface to Nibble mode */
			xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7117);
			priv->phy_speed = speed;
		}
		/* Set SGMII speed in Interface control reg */
		if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
			if (speed == SPEED_10)
				xlr_nae_wreg(priv->base_addr,
					     R_INTERFACE_CONTROL,
					     SGMII_SPEED_10);
			if (speed == SPEED_100)
				xlr_nae_wreg(priv->base_addr,
					     R_INTERFACE_CONTROL,
					     SGMII_SPEED_100);
			if (speed == SPEED_1000)
				xlr_nae_wreg(priv->base_addr,
					     R_INTERFACE_CONTROL,
					     SGMII_SPEED_1000);
		}
		if (speed == SPEED_10)
			xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x2);
		if (speed == SPEED_100)
			xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x1);
		if (speed == SPEED_1000)
			xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x0);
	}
	pr_info("gmac%d : %dMbps\n", priv->port_id, priv->phy_speed);
}

static void xlr_gmac_link_adjust(struct net_device *ndev)
{
	struct xlr_net_priv *priv = netdev_priv(ndev);
	struct phy_device *phydev = xlr_get_phydev(priv);
	u32 intreg;

	intreg = xlr_nae_rdreg(priv->base_addr, R_INTREG);
	if (phydev->link) {
		if (phydev->speed != priv->phy_speed) {
			xlr_set_gmac_speed(priv);
			pr_info("gmac%d : Link up\n", priv->port_id);
		}
	} else {
		xlr_set_gmac_speed(priv);
		pr_info("gmac%d : Link down\n", priv->port_id);
	}
}

static int xlr_mii_probe(struct xlr_net_priv *priv)
{
	struct phy_device *phydev = xlr_get_phydev(priv);

	if (!phydev) {
		pr_err("no PHY found on phy_addr %d\n", priv->phy_addr);
		return -ENODEV;
	}

	/* Attach MAC to PHY */
	phydev = phy_connect(priv->ndev, phydev_name(phydev),
			     xlr_gmac_link_adjust, priv->nd->phy_interface);

	if (IS_ERR(phydev)) {
		pr_err("could not attach PHY\n");
		return PTR_ERR(phydev);
	}
	phydev->supported &= (ADVERTISED_10baseT_Full
				| ADVERTISED_10baseT_Half
				| ADVERTISED_100baseT_Full
				| ADVERTISED_100baseT_Half
				| ADVERTISED_1000baseT_Full
				| ADVERTISED_Autoneg
				| ADVERTISED_MII);

	phydev->advertising = phydev->supported;
	phy_attached_info(phydev);
	return 0;
}

static int xlr_setup_mdio(struct xlr_net_priv *priv,
			  struct platform_device *pdev)
{
	int err;

	priv->mii_bus = mdiobus_alloc();
	if (!priv->mii_bus) {
		pr_err("mdiobus alloc failed\n");
		return -ENOMEM;
	}

	priv->mii_bus->priv = priv;
	priv->mii_bus->name = "xlr-mdio";
	snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d",
		 priv->mii_bus->name, priv->port_id);
	priv->mii_bus->read = xlr_mii_read;
	priv->mii_bus->write = xlr_mii_write;
	priv->mii_bus->parent = &pdev->dev;

	/* Scan only the enabled address */
	priv->mii_bus->phy_mask = ~(1 << priv->phy_addr);

	/* setting clock divisor to 54 */
	xlr_nae_wreg(priv->base_addr, R_MII_MGMT_CONFIG, 0x7);

	err = mdiobus_register(priv->mii_bus);
	if (err) {
		mdiobus_free(priv->mii_bus);
		pr_err("mdio bus registration failed\n");
		return err;
	}

	pr_info("Registered mdio bus id : %s\n", priv->mii_bus->id);
	err = xlr_mii_probe(priv);
	if (err) {
		mdiobus_free(priv->mii_bus);
		return err;
	}
	return 0;
}

static void xlr_port_enable(struct xlr_net_priv *priv)
{
	u32 prid = (read_c0_prid() & 0xf000);

	/* Setup MAC_CONFIG reg if (xls & rgmii) */
	if ((prid == 0x8000 || prid == 0x4000 || prid == 0xc000) &&
	    priv->nd->phy_interface == PHY_INTERFACE_MODE_RGMII)
		xlr_reg_update(priv->base_addr, R_RX_CONTROL,
			       (1 << O_RX_CONTROL__RGMII),
			       (1 << O_RX_CONTROL__RGMII));

	/* Rx Tx enable */
	xlr_reg_update(priv->base_addr, R_MAC_CONFIG_1,
		       ((1 << O_MAC_CONFIG_1__rxen) |
			(1 << O_MAC_CONFIG_1__txen) |
			(1 << O_MAC_CONFIG_1__rxfc) |
			(1 << O_MAC_CONFIG_1__txfc)),
		       ((1 << O_MAC_CONFIG_1__rxen) |
			(1 << O_MAC_CONFIG_1__txen) |
			(1 << O_MAC_CONFIG_1__rxfc) |
			(1 << O_MAC_CONFIG_1__txfc)));

	/* Setup tx control reg */
	xlr_reg_update(priv->base_addr, R_TX_CONTROL,
		       ((1 << O_TX_CONTROL__TXENABLE) |
		       (512 << O_TX_CONTROL__TXTHRESHOLD)), 0x3fff);

	/* Setup rx control reg */
	xlr_reg_update(priv->base_addr, R_RX_CONTROL,
		       1 << O_RX_CONTROL__RXENABLE,
		       1 << O_RX_CONTROL__RXENABLE);
}

static void xlr_port_disable(struct xlr_net_priv *priv)
{
	/* Setup MAC_CONFIG reg */
	/* Rx Tx disable*/
	xlr_reg_update(priv->base_addr, R_MAC_CONFIG_1,
		       ((1 << O_MAC_CONFIG_1__rxen) |
			(1 << O_MAC_CONFIG_1__txen) |
			(1 << O_MAC_CONFIG_1__rxfc) |
			(1 << O_MAC_CONFIG_1__txfc)), 0x0);

	/* Setup tx control reg */
	xlr_reg_update(priv->base_addr, R_TX_CONTROL,
		       ((1 << O_TX_CONTROL__TXENABLE) |
		       (512 << O_TX_CONTROL__TXTHRESHOLD)), 0);

	/* Setup rx control reg */
	xlr_reg_update(priv->base_addr, R_RX_CONTROL,
		       1 << O_RX_CONTROL__RXENABLE, 0);
}

/*
 * Initialization of gmac
 */
static int xlr_gmac_init(struct xlr_net_priv *priv,
			 struct platform_device *pdev)
{
	int ret;

	pr_info("Initializing the gmac%d\n", priv->port_id);

	xlr_port_disable(priv);

	xlr_nae_wreg(priv->base_addr, R_DESC_PACK_CTRL,
		     (1 << O_DESC_PACK_CTRL__MAXENTRY) |
		     (BYTE_OFFSET << O_DESC_PACK_CTRL__BYTEOFFSET) |
		     (1600 << O_DESC_PACK_CTRL__REGULARSIZE));

	ret = xlr_setup_mdio(priv, pdev);
	if (ret)
		return ret;
	xlr_port_enable(priv);

	/* Enable Full-duplex/1000Mbps/CRC */
	xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7217);
	/* speed 2.5Mhz */
	xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x02);
	/* Setup Interrupt mask reg */
	xlr_nae_wreg(priv->base_addr, R_INTMASK, (1 << O_INTMASK__TXILLEGAL) |
		     (1 << O_INTMASK__MDINT) | (1 << O_INTMASK__TXFETCHERROR) |
		     (1 << O_INTMASK__P2PSPILLECC) | (1 << O_INTMASK__TAGFULL) |
		     (1 << O_INTMASK__UNDERRUN) | (1 << O_INTMASK__ABORT));

	/* Clear all stats */
	xlr_reg_update(priv->base_addr, R_STATCTRL, 0, 1 << O_STATCTRL__CLRCNT);
	xlr_reg_update(priv->base_addr, R_STATCTRL, 1 << 2, 1 << 2);
	return 0;
}

static int xlr_net_probe(struct platform_device *pdev)
{
	struct xlr_net_priv *priv = NULL;
	struct net_device *ndev;
	struct resource *res;
	struct xlr_adapter *adapter;
	int err, port;

	pr_info("XLR/XLS Ethernet Driver controller %d\n", pdev->id);
	/*
	 * Allocate our adapter data structure and attach it to the device.
	 */
	adapter = devm_kzalloc(&pdev->dev, sizeof(*adapter), GFP_KERNEL);
	if (!adapter)
		return -ENOMEM;

	/*
	 * XLR and XLS have 1 and 2 NAE controller respectively
	 * Each controller has 4 gmac ports, mapping each controller
	 * under one parent device, 4 gmac ports under one device.
	 */
	for (port = 0; port < pdev->num_resources / 2; port++) {
		ndev = alloc_etherdev_mq(sizeof(struct xlr_net_priv), 32);
		if (!ndev) {
			dev_err(&pdev->dev,
				"Allocation of Ethernet device failed\n");
			return -ENOMEM;
		}

		priv = netdev_priv(ndev);
		priv->pdev = pdev;
		priv->ndev = ndev;
		priv->port_id = (pdev->id * 4) + port;
		priv->nd = (struct xlr_net_data *)pdev->dev.platform_data;
		res = platform_get_resource(pdev, IORESOURCE_MEM, port);
		priv->base_addr = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(priv->base_addr)) {
			err = PTR_ERR(priv->base_addr);
			goto err_gmac;
		}
		priv->adapter = adapter;
		adapter->netdev[port] = ndev;

		res = platform_get_resource(pdev, IORESOURCE_IRQ, port);
		if (!res) {
			dev_err(&pdev->dev, "No irq resource for MAC %d\n",
				priv->port_id);
			err = -ENODEV;
			goto err_gmac;
		}

		ndev->irq = res->start;

		priv->phy_addr = priv->nd->phy_addr[port];
		priv->tx_stnid = priv->nd->tx_stnid[port];
		priv->mii_addr = priv->nd->mii_addr;
		priv->serdes_addr = priv->nd->serdes_addr;
		priv->pcs_addr = priv->nd->pcs_addr;
		priv->gpio_addr = priv->nd->gpio_addr;

		ndev->netdev_ops = &xlr_netdev_ops;
		ndev->watchdog_timeo = HZ;

		/* Setup Mac address and Rx mode */
		eth_hw_addr_random(ndev);
		xlr_hw_set_mac_addr(ndev);
		xlr_set_rx_mode(ndev);

		priv->num_rx_desc += MAX_NUM_DESC_SPILL;
		ndev->ethtool_ops = &xlr_ethtool_ops;
		SET_NETDEV_DEV(ndev, &pdev->dev);

		xlr_config_fifo_spill_area(priv);
		/* Configure PDE to Round-Robin pkt distribution */
		xlr_config_pde(priv);
		xlr_config_parser(priv);

		/* Call init with respect to port */
		if (strcmp(res->name, "gmac") == 0) {
			err = xlr_gmac_init(priv, pdev);
			if (err) {
				dev_err(&pdev->dev, "gmac%d init failed\n",
					priv->port_id);
				goto err_gmac;
			}
		}

		if (priv->port_id == 0 || priv->port_id == 4) {
			err = xlr_config_common(priv);
			if (err)
				goto err_netdev;
		}

		err = register_netdev(ndev);
		if (err) {
			dev_err(&pdev->dev,
				"Registering netdev failed for gmac%d\n",
				priv->port_id);
			goto err_netdev;
		}
		platform_set_drvdata(pdev, priv);
	}

	return 0;

err_netdev:
	mdiobus_free(priv->mii_bus);
err_gmac:
	free_netdev(ndev);
	return err;
}

static int xlr_net_remove(struct platform_device *pdev)
{
	struct xlr_net_priv *priv = platform_get_drvdata(pdev);

	unregister_netdev(priv->ndev);
	mdiobus_unregister(priv->mii_bus);
	mdiobus_free(priv->mii_bus);
	free_netdev(priv->ndev);
	return 0;
}

static struct platform_driver xlr_net_driver = {
	.probe		= xlr_net_probe,
	.remove		= xlr_net_remove,
	.driver		= {
		.name	= "xlr-net",
	},
};

module_platform_driver(xlr_net_driver);

MODULE_AUTHOR("Ganesan Ramalingam <ganesanr@broadcom.com>");
MODULE_DESCRIPTION("Ethernet driver for Netlogic XLR/XLS");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("platform:xlr-net");
