/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include <common.h>
#include <net.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <phy.h>
#include <net.h>
#include <asm/global_data.h>
#include "ipq_phy.h"
#include <asm/arch-ipq5018/ipq5018_gmac.h>

DECLARE_GLOBAL_DATA_PTR;

#define ipq_info        printf
#define ipq_dbg         printf
#define DESC_SIZE       (sizeof(ipq_gmac_desc_t))
#define DESC_FLUSH_SIZE (((DESC_SIZE + (CONFIG_SYS_CACHELINE_SIZE - 1)) \
                        / CONFIG_SYS_CACHELINE_SIZE) * \
                        (CONFIG_SYS_CACHELINE_SIZE))

static struct ipq_eth_dev *ipq_gmac_macs[IPQ5018_GMAC_PORT];

uchar ipq_def_enetaddr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
phy_info_t *phy_info[IPQ5018_PHY_MAX] = {0};

extern int ipq_mdio_read(int mii_id, int regnum, ushort *data);
extern int ipq_mdio_write(int mii_id, int regnum, u16 value);
extern int ipq5018_mdio_write(int mii_id, int regnum, u16 value);
extern int ipq5018_mdio_read(int mii_id, int regnum, ushort *data);
extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id);
extern int ipq_qca8081_phy_init(struct phy_ops **ops, u32 phy_id);
extern int ipq_gephy_phy_init(struct phy_ops **ops, u32 phy_id);
extern int ipq_sw_mdio_init(const char *);
extern int ipq5018_sw_mdio_init(const char *);
extern void ppe_uniphy_mode_set(uint32_t mode);
extern int ipq_athrs17_init(ipq_gmac_board_cfg_t *gmac_cfg);

static int ipq_eth_wr_macaddr(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = (struct eth_mac_regs *)priv->mac_regs_p;
	u32 macid_lo, macid_hi;
	u8 *mac_id = &dev->enetaddr[0];

	macid_lo = mac_id[0] + (mac_id[1] << 8) +
		   (mac_id[2] << 16) + (mac_id[3] << 24);
	macid_hi = mac_id[4] + (mac_id[5] << 8);

	writel(macid_hi, &mac_p->macaddr0hi);
	writel(macid_lo, &mac_p->macaddr0lo);

	return 0;
}

static void ipq_mac_reset(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
	u32 val;

	writel(DMAMAC_SRST, &dma_reg->busmode);
	do {
		udelay(10);
		val = readl(&dma_reg->busmode);
	} while (val & DMAMAC_SRST);

}

static void ipq_eth_mac_cfg(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_reg = (struct eth_mac_regs *)priv->mac_regs_p;
	uint speed = 0;
	uint ipq_mac_cfg = 0;
	uint ipq_mac_framefilter = 0;

	ipq_mac_framefilter = PROMISCUOUS_MODE_ON;

	if (priv->mac_unit) {
		if (priv->phy_type == QCA8081_1_1_PHY || priv->phy_type == QCA8033_PHY)
			speed = priv->speed;

		ipq_mac_cfg |= (FRAME_BURST_ENABLE | JUMBO_FRAME_ENABLE | JABBER_DISABLE |
				TX_ENABLE | RX_ENABLE | FULL_DUPLEX_ENABLE | speed);

		writel(ipq_mac_cfg, &mac_reg->conf);
	} else {
		ipq_mac_cfg |= (priv->speed | FULL_DUPLEX_ENABLE | FRAME_BURST_ENABLE |
				TX_ENABLE | RX_ENABLE);
		writel(ipq_mac_cfg, &mac_reg->conf);
	}

	writel(ipq_mac_framefilter, &mac_reg->framefilt);

}

static void ipq_eth_dma_cfg(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
	uint ipq_dma_bus_mode;
	uint ipq_dma_op_mode;

	ipq_dma_op_mode = DmaStoreAndForward | DmaRxThreshCtrl128 |
				DmaTxSecondFrame;
	ipq_dma_bus_mode = DmaFixedBurstEnable | DmaBurstLength16 |
				DmaDescriptorSkip0 | DmaDescriptor8Words |
				DmaArbitPr;

	writel(ipq_dma_bus_mode, &dma_reg->busmode);
	writel(ipq_dma_op_mode, &dma_reg->opmode);
}

static void ipq_eth_flw_cntl_cfg(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_reg = (struct eth_mac_regs *)priv->mac_regs_p;
	struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
	uint ipq_dma_flw_cntl;
	uint ipq_mac_flw_cntl;

	ipq_dma_flw_cntl = DmaRxFlowCtrlAct3K | DmaRxFlowCtrlDeact4K |
				DmaEnHwFlowCtrl;
	ipq_mac_flw_cntl = GmacRxFlowControl | GmacTxFlowControl | 0xFFFF0000;

	setbits_le32(&dma_reg->opmode, ipq_dma_flw_cntl);
	setbits_le32(&mac_reg->flowcontrol, ipq_mac_flw_cntl);
}

static int ipq_gmac_alloc_fifo(int ndesc, ipq_gmac_desc_t **fifo)
{
	int i;
	void *addr;

	addr = memalign((CONFIG_SYS_CACHELINE_SIZE),
			(ndesc * DESC_FLUSH_SIZE));

	for (i = 0; i < ndesc; i++) {
		fifo[i] = (ipq_gmac_desc_t *)((unsigned long)addr +
			  (i * DESC_FLUSH_SIZE));
		if (fifo[i] == NULL) {
			ipq_info("Can't allocate desc fifos\n");
			return -1;
		}
	}
	return 0;
}

static int ipq_gmac_rx_desc_setup(struct ipq_eth_dev  *priv)
{
	struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
	ipq_gmac_desc_t *rxdesc;
	int i;

	for (i = 0; i < NO_OF_RX_DESC; i++) {
		rxdesc = priv->desc_rx[i];
		rxdesc->length |= ((ETH_MAX_FRAME_LEN << DescSize1Shift) &
					DescSize1Mask);
		rxdesc->buffer1 = virt_to_phys(net_rx_packets[i]);
		rxdesc->data1 = (unsigned long)priv->desc_rx[(i + 1) %
				NO_OF_RX_DESC];

		rxdesc->extstatus = 0;
		rxdesc->reserved1 = 0;
		rxdesc->timestamplow = 0;
		rxdesc->timestamphigh = 0;
		rxdesc->status = DescOwnByDma;


		flush_dcache_range((unsigned long)rxdesc,
			(unsigned long)rxdesc + DESC_SIZE);

	}
	/* Assign Descriptor base address to dmadesclist addr reg */
	writel((uint)priv->desc_rx[0], &dma_reg->rxdesclistaddr);

	return 0;
}

static int ipq_gmac_tx_rx_desc_ring(struct ipq_eth_dev  *priv)
{
	int i;
	ipq_gmac_desc_t *desc;

	if (ipq_gmac_alloc_fifo(NO_OF_TX_DESC, priv->desc_tx))
		return -1;

	for (i = 0; i < NO_OF_TX_DESC; i++) {
		desc = priv->desc_tx[i];
		memset(desc, 0, DESC_SIZE);

		desc->status =
		(i == (NO_OF_TX_DESC - 1)) ? TxDescEndOfRing : 0;

		desc->status |= TxDescChain;

		desc->data1 = (unsigned long)priv->desc_tx[(i + 1) %
				NO_OF_TX_DESC ];

		flush_dcache_range((unsigned long)desc,
			(unsigned long)desc + DESC_SIZE);

	}

	if (ipq_gmac_alloc_fifo(NO_OF_RX_DESC, priv->desc_rx))
		return -1;

	for (i = 0; i < NO_OF_RX_DESC; i++) {
		desc = priv->desc_rx[i];
		memset(desc, 0, DESC_SIZE);
		desc->length =
		(i == (NO_OF_RX_DESC - 1)) ? RxDescEndOfRing : 0;
		desc->length |= RxDescChain;

		desc->data1 = (unsigned long)priv->desc_rx[(i + 1) %
				NO_OF_RX_DESC];

		flush_dcache_range((unsigned long)desc,
			(unsigned long)desc + DESC_SIZE);

	}

	priv->next_tx = 0;
	priv->next_rx = 0;

	return 0;
}

static inline void ipq_gmac_give_to_dma(ipq_gmac_desc_t *fr)
{
	fr->status |= DescOwnByDma;
}

static inline u32 ipq_gmac_owned_by_dma(ipq_gmac_desc_t *fr)
{
	return (fr->status & DescOwnByDma);
}

static inline u32 ipq_gmac_is_desc_empty(ipq_gmac_desc_t *fr)
{
	return ((fr->length & DescSize1Mask) == 0);
}

static void ipq5018_gmac0_speed_clock_set(int speed_clock1,
	int speed_clock2, int gmacid)
{
	int iTxRx;
	uint32_t reg_value;
	/*
	 * iTxRx indicates Tx and RX register
	 * 0 = Rx and 1 = Tx
	 */
	for (iTxRx = 0; iTxRx < 2; ++iTxRx){
		/* gcc port first clock divider */
		reg_value = 0;
		reg_value = readl(GCC_GMAC0_RX_CFG_RCGR +
				(iTxRx * 8) + (gmacid * 0x10));
		reg_value &= ~0x1f;
		reg_value |= speed_clock1;
		writel(reg_value, GCC_GMAC0_RX_CFG_RCGR +
				(iTxRx * 8) + (gmacid * 0x10));
		/* gcc port second clock divider */
		reg_value = 0;
		reg_value = readl(GCC_GMAC0_RX_MISC +
				(iTxRx * 4) + (gmacid * 0x10));
		reg_value &= ~0xf;
		reg_value |= speed_clock2;
		writel(reg_value, GCC_GMAC0_RX_MISC +
				(iTxRx * 4) + (gmacid * 0x10));
		/* update above clock configuration */
		reg_value = 0;
		reg_value = readl(GCC_GMAC0_RX_CMD_RCGR +
				(iTxRx * 8) + (gmacid * 0x10));
		reg_value &= ~0x1;
		reg_value |= 0x1;
		writel(reg_value, GCC_GMAC0_RX_CMD_RCGR +
				(iTxRx * 8) + (gmacid * 0x10));
	}
}

static void ipq5018_enable_gephy(void)
{
	uint32_t reg_val;

	reg_val = readl(GCC_GEPHY_RX_CBCR);
	reg_val |= GCC_CBCR_CLK_ENABLE;
	writel(reg_val, GCC_GEPHY_RX_CBCR);
	mdelay(20);

	reg_val = readl(GCC_GEPHY_TX_CBCR);
	reg_val |= GCC_CBCR_CLK_ENABLE;
	writel(reg_val, GCC_GEPHY_TX_CBCR);
	mdelay(20);
}

static int ipq5018_s17c_Link_Update(struct ipq_eth_dev *priv)
{
	uint16_t phy_data;
	int status = 1;
        int i;

	for(i = 0;
		i < priv->gmac_board_cfg->switch_port_count; ++i){
		phy_data = ipq_mdio_read(
			priv->gmac_board_cfg->switch_port_phy_address[i],
			0x11,
			NULL);

		if (phy_data == 0x50)
			continue;

		/* Atleast one port should be link up*/
		if (phy_data & LINK_UP)
			status = 0;

		printf("Port%d %s ", i + 1, LINK(phy_data));

		switch(SPEED(phy_data)){
		case SPEED_1000M:
			printf("Speed :1000M ");
			break;
		case SPEED_100M:
			printf("Speed :100M ");
			break;
		default:
			printf("Speed :10M ");
		}

		printf ("%s \n", DUPLEX(phy_data));
	}
	return status;
}

static int ipq5018_phy_link_update(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	u8 status = 1;
	struct phy_ops *phy_get_ops;
	fal_port_speed_t speed;
	fal_port_duplex_t duplex;
	char *lstatus[] = {"up", "Down"};
	char *dp[] = {"Half", "Full"};
	int speed_clock1 = 0, speed_clock2 = 0;
	int mode = PORT_WRAPPER_SGMII0_RGMII4;

	phy_get_ops = priv->ops;

	if (priv->ipq_swith) {
		speed_clock1 = 1;
		speed_clock2 = 0;
		status = ipq5018_s17c_Link_Update(priv);
	}

	if (phy_get_ops != NULL &&
		phy_get_ops->phy_get_link_status != NULL &&
		phy_get_ops->phy_get_speed != NULL &&
		phy_get_ops->phy_get_duplex != NULL){

		status = phy_get_ops->phy_get_link_status(priv->mac_unit,
				priv->phy_address);
		phy_get_ops->phy_get_speed(priv->mac_unit,
				priv->phy_address, &speed);
		phy_get_ops->phy_get_duplex(priv->mac_unit,
				priv->phy_address, &duplex);

		switch (speed) {
		case FAL_SPEED_10:
			speed_clock1 = 9;
			speed_clock2 = 9;
			priv->speed = MII_PORT_SELECT;
			printf ("eth%d  %s Speed :%d %s duplex\n",
					priv->mac_unit,
					lstatus[status], speed,
					dp[duplex]);
			break;
		case FAL_SPEED_100:
			priv->speed = MII_PORT_SELECT | FES_PORT_SPEED;
			speed_clock1 = 9;
			speed_clock2 = 0;
			printf ("eth%d %s Speed :%d %s duplex\n",
					priv->mac_unit,
					lstatus[status], speed,
					dp[duplex]);
			break;
		case FAL_SPEED_1000:
			priv->speed = SGMII_PORT_SELECT;
			speed_clock1 = 1;
			speed_clock2 = 0;
			printf ("eth%d %s Speed :%d %s duplex\n",
					priv->mac_unit,
					lstatus[status], speed,
					dp[duplex]);
			break;
		case FAL_SPEED_2500:
			priv->speed = SGMII_PORT_SELECT;
			mode = PORT_WRAPPER_SGMII_PLUS;
			speed_clock1 = 1;
			speed_clock2 = 0;
			printf ("eth%d %s Speed :%d %s duplex\n",
					priv->mac_unit,
					lstatus[status], speed,
					dp[duplex]);
			break;
		default:
			printf("Unknown speed\n");
			break;
		}
	}

	if (status) {
		/* No PHY link is alive */
		if (priv->ipq_swith == 0 && phy_get_ops == NULL)
			printf("Link status/Get speed/Get duplex not mapped\n");
		return -1;
	}

	if (priv->mac_unit){
		ppe_uniphy_mode_set(mode);
	} else {
		ipq5018_enable_gephy();
	}

	ipq5018_gmac0_speed_clock_set(speed_clock1, speed_clock2, priv->mac_unit);

	return 0;
}

int ipq_eth_init(struct eth_device *dev, bd_t *this)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
	u32 data;

	if(ipq5018_phy_link_update(dev) < 0) {
		return -1;
	}

	priv->next_rx = 0;
	priv->next_tx = 0;

	ipq_mac_reset(dev);
	ipq_eth_wr_macaddr(dev);

	/* DMA, MAC configuration for Synopsys GMAC */
	ipq_eth_dma_cfg(dev);
	ipq_eth_mac_cfg(dev);
	ipq_eth_flw_cntl_cfg(dev);

	/* clear all pending interrupts if any */
	data = readl(&dma_reg->status);
	writel(data, &dma_reg->status);

	/* Setup Rx fifos and assign base address to */
	ipq_gmac_rx_desc_setup(priv);

	writel((uint)priv->desc_tx[0], &dma_reg->txdesclistaddr);
	setbits_le32(&dma_reg->opmode, (RXSTART));
	setbits_le32(&dma_reg->opmode, (TXSTART));

	return 1;
}

static int ipq_eth_send(struct eth_device *dev, void *packet, int length)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_p = (struct eth_dma_regs *)priv->dma_regs_p;
	ipq_gmac_desc_t *txdesc = priv->desc_tx[priv->next_tx];
	int i;

	invalidate_dcache_range((unsigned long)txdesc,
		       (unsigned long)txdesc + DESC_FLUSH_SIZE);

	/* Check if the dma descriptor is still owned by DMA */
	if (ipq_gmac_owned_by_dma(txdesc)) {
		ipq_info("BUG: Tx descriptor is owned by DMA %p\n", txdesc);
		return NETDEV_TX_BUSY;
	}

	txdesc->length |= ((length <<DescSize1Shift) & DescSize1Mask);
	txdesc->status |= (DescTxFirst | DescTxLast | DescTxIntEnable);
	txdesc->buffer1 = virt_to_phys(packet);
	ipq_gmac_give_to_dma(txdesc);

	flush_dcache_range((unsigned long)txdesc,
			(unsigned long)txdesc + DESC_SIZE);

	flush_dcache_range((unsigned long)(txdesc->buffer1),
		(unsigned long)(txdesc->buffer1) + PKTSIZE_ALIGN);

	/* Start the transmission */
	writel(POLL_DATA, &dma_p->txpolldemand);

	for (i = 0; i < MAX_WAIT; i++) {

		udelay(10);

		invalidate_dcache_range((unsigned long)txdesc,
		(unsigned long)txdesc + DESC_FLUSH_SIZE);

		if (!ipq_gmac_owned_by_dma(txdesc))
			break;
	}

	if (i == MAX_WAIT) {
		ipq_info("Tx Timed out\n");
	}

	/* reset the descriptors */
	txdesc->status = (priv->next_tx == (NO_OF_TX_DESC - 1)) ?
	TxDescEndOfRing : 0;
	txdesc->status |= TxDescChain;
	txdesc->length = 0;
	txdesc->buffer1 = 0;

	priv->next_tx = (priv->next_tx + 1) % NO_OF_TX_DESC;

	txdesc->data1 = (unsigned long)priv->desc_tx[priv->next_tx];


	flush_dcache_range((unsigned long)txdesc,
			(unsigned long)txdesc + DESC_SIZE);

	return 0;
}

static int ipq_eth_recv(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_p = (struct eth_dma_regs *)priv->dma_regs_p;
	int length = 0;
	ipq_gmac_desc_t *rxdesc = priv->desc_rx[priv->next_rx];
	uint status;

	invalidate_dcache_range((unsigned long)(priv->desc_rx[0]),
			(unsigned long)(priv->desc_rx[NO_OF_RX_DESC - 1]) +
			DESC_FLUSH_SIZE);

	for (rxdesc = priv->desc_rx[priv->next_rx];
		!ipq_gmac_owned_by_dma(rxdesc);
		rxdesc = priv->desc_rx[priv->next_rx]) {

		status = rxdesc->status;
		length = ((status & DescFrameLengthMask) >>
				DescFrameLengthShift);

		invalidate_dcache_range(
			(unsigned long)(net_rx_packets[priv->next_rx]),
			(unsigned long)(net_rx_packets[priv->next_rx]) +
			PKTSIZE_ALIGN);
		net_process_received_packet(net_rx_packets[priv->next_rx], length - 4);

		rxdesc->length = ((ETH_MAX_FRAME_LEN << DescSize1Shift) &
				   DescSize1Mask);

		rxdesc->length |= (priv->next_rx == (NO_OF_RX_DESC - 1)) ?
					RxDescEndOfRing : 0;
		rxdesc->length |= RxDescChain;

		rxdesc->buffer1 = virt_to_phys(net_rx_packets[priv->next_rx]);

		priv->next_rx = (priv->next_rx + 1) % NO_OF_RX_DESC;

		rxdesc->data1 = (unsigned long)priv->desc_rx[priv->next_rx];

		rxdesc->extstatus = 0;
		rxdesc->reserved1 = 0;
		rxdesc->timestamplow = 0;
		rxdesc->timestamphigh = 0;
		rxdesc->status = DescOwnByDma;

		flush_dcache_range((unsigned long)rxdesc,
			(unsigned long)rxdesc + DESC_SIZE);

		writel(POLL_DATA, &dma_p->rxpolldemand);
	}

	return length;
}

static void ipq_eth_halt(struct eth_device *dev)
{
	if (dev->state != ETH_STATE_ACTIVE)
		return;
	/* reset the mac */
	ipq_mac_reset(dev);
}

static int QCA8337_switch_init(ipq_gmac_board_cfg_t *gmac_cfg)
{
        int port;

	for (port = 0;
		port < gmac_cfg->switch_port_count;
		++port) {
		u32 phy_val;
		/* phy powerdown */
		ipq_mdio_write(
			gmac_cfg->switch_port_phy_address[port],
			0x0,
			0x0800
			);
		phy_val = ipq_mdio_read(
				gmac_cfg->switch_port_phy_address[port],
				0x3d,
				NULL
				);
		phy_val &= ~0x0040;
		ipq_mdio_write(
			gmac_cfg->switch_port_phy_address[port],
			0x3d,
			phy_val
			);
		/*
		* PHY will stop the tx clock for a while when link is down
		* en_anychange  debug port 0xb bit13 = 0  //speed up link down tx_clk
		* sel_rst_80us  debug port 0xb bit10 = 0  //speed up speed mode change to 2'b10 tx_clk
		*/
		phy_val = ipq_mdio_read(
				gmac_cfg->switch_port_phy_address[port],
				0xb,
				NULL
				);
		phy_val &= ~0x2400;
		ipq_mdio_write(
			gmac_cfg->switch_port_phy_address[port],
			0xb,
			phy_val
			);
		mdelay(100);
	}
	if (ipq_athrs17_init(gmac_cfg) != 0){
		printf("QCA_8337 switch init failed \n");
		return 0;
	}
	for (port = 0;
		port < gmac_cfg->switch_port_count;
		++port) {
		ipq_mdio_write(
			gmac_cfg->switch_port_phy_address[port],
			MII_ADVERTISE,
			ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM
			);
		/* phy reg 0x9, b10,1 = Prefer multi-port device (master) */
		ipq_mdio_write(
			gmac_cfg->switch_port_phy_address[port],
			MII_CTRL1000,
			(0x0400|ADVERTISE_1000FULL)
			);
		ipq_mdio_write(
			gmac_cfg->switch_port_phy_address[port],
			MII_BMCR,
			BMCR_RESET | BMCR_ANENABLE
			);
		mdelay(100);
	}
	return 1;
}

static void gephy_mdac_edac_config(ipq_gmac_board_cfg_t *gmac_cfg)
{
	uint16_t phy_data;
	uint32_t phy_dac = PHY_DAC(0x10);
	uint32_t C45_id = QCA808X_REG_C45_ADDRESS(MPGE_PHY_MMD1_NUM,
				MPGE_PHY_MMD1_DAC);
	/*set mdac value*/
	phy_data = ipq5018_mdio_read(
			gmac_cfg->phy_addr,
			C45_id,
			NULL
			);
	phy_data &= ~(MPGE_PHY_MMD1_DAC_MASK);
	ipq5018_mdio_write(
		gmac_cfg->phy_addr,
		C45_id,
		(phy_data | phy_dac)
		);
	mdelay(1);
	/*set edac value*/
	phy_data = ipq5018_mdio_read(
			gmac_cfg->phy_addr,
			MPGE_PHY_DEBUG_EDAC,
			NULL
			);
	phy_data &= ~(MPGE_PHY_MMD1_DAC_MASK);
	ipq5018_mdio_write(
		gmac_cfg->phy_addr,
		MPGE_PHY_DEBUG_EDAC,
		(phy_data | phy_dac)
		);
	mdelay(1);
}

static void mdio_init(void)
{
	if(ipq5018_sw_mdio_init("IPQ MDIO0"))
		printf("MDIO Failed to init for GMAC0\n");

	if(ipq_sw_mdio_init("IPQ MDIO1"))
		printf("MDIO Failed to init for GMAC1\n");
}

int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
{
	struct eth_device *dev[CONFIG_IPQ_NO_MACS];
	uchar enet_addr[CONFIG_IPQ_NO_MACS * 6];
	int i;
	uint32_t phy_chip_id, phy_chip_id1, phy_chip_id2;
	int ret;
	memset(enet_addr, 0, sizeof(enet_addr));

	/* Mdio init */
	mdio_init();

	/* Getting the MAC address from ART partition */
	ret = get_eth_mac_address(enet_addr, CONFIG_IPQ_NO_MACS);

	for (i = 0; gmac_cfg_is_valid(gmac_cfg); gmac_cfg++, i++) {

		dev[i] = malloc(sizeof(struct eth_device));
		if (dev[i] == NULL)
			goto init_failed;

		ipq_gmac_macs[i] = malloc(sizeof(struct ipq_eth_dev));
		if (ipq_gmac_macs[i] == NULL)
			goto init_failed;

		memset(dev[i], 0, sizeof(struct eth_device));
		memset(ipq_gmac_macs[i], 0, sizeof(struct ipq_eth_dev));

		dev[i]->iobase = gmac_cfg->base;
		dev[i]->init = ipq_eth_init;
		dev[i]->halt = ipq_eth_halt;
		dev[i]->recv = ipq_eth_recv;
		dev[i]->send = ipq_eth_send;
		dev[i]->write_hwaddr = ipq_eth_wr_macaddr;
		dev[i]->priv = (void *) ipq_gmac_macs[i];
		/*
		 * Setting the Default MAC address
		 * if the MAC read from ART partition is invalid
		 */
		if ((ret < 0) ||
			(!is_valid_ethaddr(&enet_addr[i * 6]))) {
				memcpy(&dev[i]->enetaddr[0], ipq_def_enetaddr, 6);
				dev[i]->enetaddr[5] = dev[i]->enetaddr[5] +  i;
		} else {
			memcpy(&dev[i]->enetaddr[0], &enet_addr[i * 6], 6);
		}

		ipq_info("MAC%x addr:%x:%x:%x:%x:%x:%x\n",
			gmac_cfg->unit, dev[i]->enetaddr[0],
			dev[i]->enetaddr[1],
			dev[i]->enetaddr[2],
			dev[i]->enetaddr[3],
			dev[i]->enetaddr[4],
			dev[i]->enetaddr[5]);

		snprintf(dev[i]->name, sizeof(dev[i]->name), "eth%d", i);

		ipq_gmac_macs[i]->dev = dev[i];
		ipq_gmac_macs[i]->mac_unit = gmac_cfg->unit;
		ipq_gmac_macs[i]->mac_regs_p =
			(struct eth_mac_regs *)(gmac_cfg->base);
		ipq_gmac_macs[i]->dma_regs_p =
			(struct eth_dma_regs *)(gmac_cfg->base + DW_DMA_BASE_OFFSET);
		ipq_gmac_macs[i]->phy_address = gmac_cfg->phy_addr;
		ipq_gmac_macs[i]->gmac_board_cfg = gmac_cfg;
		ipq_gmac_macs[i]->interface = gmac_cfg->phy_interface_mode;
		ipq_gmac_macs[i]->phy_type = gmac_cfg->phy_type;
		ipq_gmac_macs[i]->phy_external_link = gmac_cfg->phy_external_link;

		snprintf((char *)ipq_gmac_macs[i]->phy_name,
				sizeof(ipq_gmac_macs[i]->phy_name), "IPQ MDIO%d", i);

		if (gmac_cfg->unit){
			phy_chip_id1 = ipq_mdio_read(
					ipq_gmac_macs[i]->phy_address,
					QCA_PHY_ID1,
					NULL);
			phy_chip_id2 = ipq_mdio_read(
					ipq_gmac_macs[i]->phy_address,
					QCA_PHY_ID2,
					NULL);
			phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
		} else {
			phy_chip_id1 = ipq5018_mdio_read(
					ipq_gmac_macs[i]->phy_address,
					QCA_PHY_ID1,
					NULL);
			phy_chip_id2 = ipq5018_mdio_read(
					ipq_gmac_macs[i]->phy_address,
					QCA_PHY_ID2,
					NULL);
			phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
		}
		switch(phy_chip_id) {
#ifdef CONFIG_QCA8081_PHY
			/* NAPA PHY For GMAC1 */
			case QCA8081_PHY:
			case QCA8081_1_1_PHY:
				ipq_gmac_macs[i]->phy_type = QCA8081_1_1_PHY;
				ipq_qca8081_phy_init(
					&ipq_gmac_macs[i]->ops,
					ipq_gmac_macs[i]->phy_address);
				break;
#endif
			/* Internel GEPHY only for GMAC0 */
			case GEPHY:
				ipq_gmac_macs[i]->phy_type = GEPHY;
				ipq_gephy_phy_init(
					&ipq_gmac_macs[i]->ops,
					ipq_gmac_macs[i]->phy_address);
				if(ipq_gmac_macs[i]->phy_external_link)
					gephy_mdac_edac_config(gmac_cfg);
				break;
#ifdef CONFIG_QCA8033_PHY
			/* 1G PHY */
			case QCA8033_PHY:
				ipq_gmac_macs[i]->phy_type = QCA8033_PHY;
				ipq_qca8033_phy_init(
					&ipq_gmac_macs[i]->ops,
					ipq_gmac_macs[i]->phy_address);
				break;
#endif
			case QCA_8337:
				if(gmac_cfg->ipq_swith){
					ipq_gmac_macs[i]->ipq_swith =
						QCA8337_switch_init(gmac_cfg);
				}
				break;
			default:
				printf("GMAC%d:Invalid PHY ID \n", i);
				break;
		}
		/* Initialize 8337 switch */
		if (gmac_cfg->ipq_swith &&
			ipq_gmac_macs[i]->phy_external_link &&
			!ipq_gmac_macs[i]->ipq_swith){
			ipq_gmac_macs[i]->ipq_swith =
				QCA8337_switch_init(gmac_cfg);
		}
		/* Tx/Rx Descriptor initialization */
		if (ipq_gmac_tx_rx_desc_ring(dev[i]->priv) == -1)
			goto init_failed;

		eth_register(dev[i]);
	}
	return 0;

init_failed:
	for (i = 0; i < IPQ5018_GMAC_PORT; i++) {
		if (dev[i]) {
			free(dev[i]);
		}
		if (ipq_gmac_macs[i])
			free(ipq_gmac_macs[i]);
	}

	return -ENOMEM;
}

