// 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_reserve(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)
			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_KERNEL);
	if (!spill)
		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;
		priv->base_addr = devm_platform_ioremap_resource(pdev, port);
		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");
