/*
 * Copyright (c) 2012 - 2013, 2016-2017 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 <miiphy.h>
#include <linux/compat.h>
#include <fdtdec.h>
#include <asm/arch-ipq806x/clk.h>
#include <asm/arch-ipq806x/ipq_gmac.h>
#include <asm/arch-ipq806x/msm_ipq806x_gmac.h>
#include <asm/arch-qca-common/gpio.h>
#include <dt-bindings/qcom/gpio-ipq806x.h>

#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))

uchar ipq_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xAB, 0xBD, 0xDA};

static struct ipq_eth_dev *ipq_gmac_macs[CONFIG_IPQ_NO_MACS];
static int (*ipq_switch_init)(ipq_gmac_board_cfg_t *cfg);
static struct ipq_forced_mode get_params;
static struct bitbang_nodes *bb_nodes[CONFIG_IPQ_NO_MACS];
static void ipq_gmac_mii_clk_init(struct ipq_eth_dev *priv, uint clk_div,
				ipq_gmac_board_cfg_t *gmac_cfg);

extern ipq_gmac_board_cfg_t gmac_cfg[];

DECLARE_GLOBAL_DATA_PTR;

void ipq_register_switch(int(*sw_init)(ipq_gmac_board_cfg_t *cfg))
{
	ipq_switch_init = sw_init;
}

static void config_auto_neg(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	u8  phy_addr;

	if (priv->forced_params->is_forced) {
		if (priv->forced_params->miiwrite_done) {
			phy_addr = priv->forced_params->phy_addr;
			if (priv->forced_params->speed == SPEED_10M) {
				miiphy_write(priv->phy_name, phy_addr,
					PHY_CONTROL_REG, FORCE_RATE_10);
			} else if (priv->forced_params->speed == SPEED_100M) {
				miiphy_write(priv->phy_name, phy_addr,
					PHY_CONTROL_REG, FORCE_RATE_100);
			} else if (priv->forced_params->speed == SPEED_1000M) {
				miiphy_write(priv->phy_name, phy_addr,
					PHY_CONTROL_REG, AUTO_NEG_ENABLE);
			}
			priv->forced_params->miiwrite_done = 0;
			mdelay(200);
		}
	} else {
		miiphy_write(priv->phy_name, priv->phy_address[0],
			PHY_CONTROL_REG, AUTO_NEG_ENABLE);
	}
}

static int ipq_phy_link_status(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	int port_status;
	ushort phy_status;
	uint i;

	udelay(1000);

	for (i = 0; i < priv->no_of_phys; i++) {

		miiphy_read(priv->phy_name, priv->phy_address[i],
				PHY_SPECIFIC_STATUS_REG, &phy_status);

		port_status = ((phy_status & Mii_phy_status_link_up) >>
				(MII_PHY_STAT_SHIFT));
		if (port_status == 1)
			return 0;
	}

	return -1;
}

static void get_phy_speed_duplexity(struct eth_device *dev)
{
	struct ipq_eth_dev *priv = dev->priv;
	uint phy_status;
	uint start;
	const uint timeout = 2000;

	start = get_timer(0);
	while (get_timer(start) < timeout) {

		phy_status = readl(QSGMII_REG_BASE +
				PCS_QSGMII_MAC_STAT);

		if (PCS_QSGMII_MAC_LINK(phy_status, priv->mac_unit)) {

			priv->speed =
			PCS_QSGMII_MAC_SPEED(phy_status,
			priv->mac_unit);

			priv->duplex =
			PCS_QSGMII_MAC_DUPLEX(phy_status,
			priv->mac_unit);

			if (priv->duplex)
				ipq_info("Full duplex link\n");
			else
				ipq_info("Half duplex link\n");

			ipq_info("Link %x up, Phy_status = %x\n",
			priv->mac_unit,phy_status);

			break;
		}

		udelay(10);
	}
}

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 ipq_mac_cfg;

	if (priv->mac_unit > GMAC_UNIT1) {
		ipq_mac_cfg = (priv->mac_ps | FULL_DUPLEX_ENABLE);
	} else {
		ipq_mac_cfg = (GMII_PORT_SELECT | FULL_DUPLEX_ENABLE);
	}

	ipq_mac_cfg |= (FRAME_BURST_ENABLE | TX_ENABLE | RX_ENABLE);

	writel(ipq_mac_cfg, &mac_reg->conf);
}

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 int ipq_eth_update(struct eth_device *dev, bd_t *this)
{
	struct ipq_eth_dev *priv = dev->priv;
	uint clk_div_val;
	uint phy_status;
	uint cur_speed;
	uint cur_duplex;

	phy_status = readl(QSGMII_REG_BASE +
				PCS_QSGMII_MAC_STAT);

	if (PCS_QSGMII_MAC_LINK(phy_status, priv->mac_unit)) {
		cur_speed = PCS_QSGMII_MAC_SPEED(phy_status,
				priv->mac_unit);
		cur_duplex = PCS_QSGMII_MAC_DUPLEX(phy_status,
				priv->mac_unit);

		if (cur_speed != priv->speed || cur_duplex != priv->duplex) {
			ipq_info("Link %x status changed\n", priv->mac_unit);
			if (priv->duplex)
				ipq_info("Full duplex link\n");
			else
				ipq_info("Half duplex link\n");

			ipq_info("Link %x up, Phy_status = %x\n",
					priv->mac_unit, phy_status);

			switch (cur_speed) {
			case SPEED_1000M:
				ipq_info("Port:%d speed 1000Mbps\n",
					priv->mac_unit);
				priv->mac_ps = GMII_PORT_SELECT;
				clk_div_val = (CLK_DIV_SGMII_1000M - 1);
				break;

			case SPEED_100M:
				ipq_info("Port:%d speed 100Mbps\n",
					priv->mac_unit);
				priv->mac_ps = MII_PORT_SELECT;
				clk_div_val = (CLK_DIV_SGMII_100M - 1);
				break;

			case SPEED_10M:
				ipq_info("Port:%d speed 10Mbps\n",
					priv->mac_unit);
				priv->mac_ps = MII_PORT_SELECT;
				clk_div_val = (CLK_DIV_SGMII_10M - 1);
				break;

			default:
				ipq_info("Port speed unknown\n");
				return -1;
			}

			priv->speed = cur_speed;
			priv->duplex = cur_duplex;

			ipq_gmac_mii_clk_init(priv, clk_div_val,
				priv->gmac_board_cfg);
		}
	} else {
		return -1;
	}

	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 (!(priv->forced_params->is_forced && (priv->mac_unit == GMAC_UNIT2 ||
						 priv->mac_unit == GMAC_UNIT3))) {
		if (ipq_phy_link_status(dev) != 0) {
			ipq_info("Mac%x unit failed\n", priv->mac_unit);
			return -1;
		}

		if (priv->gmac_board_cfg->mac_conn_to_phy) {
			/* Check the current speed and duplex mode and change
			   the MAC settings according to it */
			if (ipq_eth_update(dev, this) != 0) {
				ipq_info("Mac%x settings update failed\n",
					priv->mac_unit);
				return -1;
			}
		}
	}

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

	ipq_mac_reset(dev);

	if ((priv->mac_unit == GMAC_UNIT2) || (priv->mac_unit == GMAC_UNIT3))
		config_auto_neg(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 void
gmac_sgmii_clk_init(uint mac_unit, uint clk_div, ipq_gmac_board_cfg_t *gmac_cfg)
{
	uint gmac_ctl_val;
	uint nss_eth_clk_gate_val;

	gmac_ctl_val = (NSS_ETH_GMAC_PHY_INTF_SEL |
			NSS_ETH_GMAC_PHY_IFG_LIMIT |
			NSS_ETH_GMAC_PHY_IFG);


	nss_eth_clk_gate_val = (GMACn_GMII_RX_CLK(mac_unit) |
				GMACn_GMII_TX_CLK(mac_unit) |
				GMACn_PTP_CLK(mac_unit));

	writel(gmac_ctl_val, (NSS_REG_BASE + NSS_GMACn_CTL(mac_unit)));

	if (gmac_cfg->phy == PHY_INTERFACE_MODE_QSGMII) {
		nss_eth_clk_gate_val = GMACn_GMII_RX_CLK(mac_unit) |
					GMACn_GMII_TX_CLK(mac_unit);
		clrbits_le32((NSS_REG_BASE + NSS_ETH_CLK_SRC_CTL),
				(1 << mac_unit));
		writel(NSS_QSGMII_CLK_CTL_CLR_MSK,
				(NSS_REG_BASE + NSS_QSGMII_CLK_CTL));
		setbits_le32((NSS_REG_BASE + NSS_ETH_CLK_DIV0),
				GMACn_CLK_DIV(mac_unit, 1));
	}

	switch (mac_unit) {
	case GMAC_UNIT0:
	case GMAC_UNIT1:
		setbits_le32((QSGMII_REG_BASE + PCS_ALL_CH_CTL),
				PCS_CHn_FORCE_SPEED(mac_unit));
		clrbits_le32((QSGMII_REG_BASE + PCS_ALL_CH_CTL),
				PCS_CHn_SPEED_MASK(mac_unit));
		setbits_le32((QSGMII_REG_BASE + PCS_ALL_CH_CTL),
				PCS_CHn_SPEED(mac_unit,
					PCS_CH_SPEED_1000));
		setbits_le32((NSS_REG_BASE + NSS_ETH_CLK_GATE_CTL),
			nss_eth_clk_gate_val);
		break;
	case GMAC_UNIT2:
	case GMAC_UNIT3:
		setbits_le32((NSS_REG_BASE + NSS_ETH_CLK_SRC_CTL),
			(1 << mac_unit));
		if (gmac_cfg->mac_conn_to_phy) {

			setbits_le32((QSGMII_REG_BASE + PCS_ALL_CH_CTL),
				(PCS_CHn_SPEED_FORCE_OUTSIDE(mac_unit) |
				PCS_DEBUG_SELECT));


			if (clk_div == 0) {
				clrbits_le32((NSS_REG_BASE +
					NSS_ETH_CLK_DIV0),
					(NSS_ETH_CLK_DIV(
					NSS_ETH_CLK_DIV_MASK,
					mac_unit)));
			} else {
				clrsetbits_le32((NSS_REG_BASE +
					NSS_ETH_CLK_DIV0),
					(NSS_ETH_CLK_DIV(
					NSS_ETH_CLK_DIV_MASK,
					mac_unit)),
					(NSS_ETH_CLK_DIV(clk_div,
					mac_unit)));
			}
			setbits_le32((NSS_REG_BASE + NSS_ETH_CLK_GATE_CTL),
					nss_eth_clk_gate_val);
		} else {
			/* this part of code forces the speed of MAC 2 to
			 * 1000Mbps disabling the Autoneg in case
			 * of AP148/DB147 since it is connected to switch
			 */
			setbits_le32((QSGMII_REG_BASE + PCS_ALL_CH_CTL),
				PCS_CHn_FORCE_SPEED(mac_unit));

			clrbits_le32((QSGMII_REG_BASE + PCS_ALL_CH_CTL),
				PCS_CHn_SPEED_MASK(mac_unit));

			setbits_le32((QSGMII_REG_BASE + PCS_ALL_CH_CTL),
				PCS_CHn_SPEED(mac_unit,
					PCS_CH_SPEED_1000));

			setbits_le32((NSS_REG_BASE + NSS_ETH_CLK_GATE_CTL),
				nss_eth_clk_gate_val);
		}
		break;
	}
}

static void ipq_gmac_mii_clk_init(struct ipq_eth_dev *priv, uint clk_div,
				ipq_gmac_board_cfg_t *gmac_cfg)
{
	u32 nss_gmac_ctl_val;
	u32 nss_eth_clk_gate_ctl_val;
	int gmac_idx = priv->mac_unit;
	u32 interface = priv->interface;

	switch (interface) {
	case PHY_INTERFACE_MODE_RGMII:
		nss_gmac_ctl_val = (GMAC_PHY_RGMII | GMAC_IFG |
				GMAC_IFG_LIMIT(GMAC_IFG));
		nss_eth_clk_gate_ctl_val =
			(GMACn_RGMII_RX_CLK(gmac_idx) |
			 GMACn_RGMII_TX_CLK(gmac_idx) |
			 GMACn_PTP_CLK(gmac_idx));
		setbits_le32((NSS_REG_BASE + NSS_GMACn_CTL(gmac_idx)),
				nss_gmac_ctl_val);
		setbits_le32((NSS_REG_BASE + NSS_ETH_CLK_GATE_CTL),
				nss_eth_clk_gate_ctl_val);
		setbits_le32((NSS_REG_BASE + NSS_ETH_CLK_SRC_CTL),
				(0x1 << gmac_idx));
		writel((NSS_ETH_CLK_DIV(1, gmac_idx)),
				(NSS_REG_BASE + NSS_ETH_CLK_DIV0));
		break;
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
		gmac_sgmii_clk_init(gmac_idx, clk_div, gmac_cfg);
		break;
	default :
		ipq_info(" default : no rgmii sgmii for gmac %d  \n", gmac_idx);
		return;
	}
}

int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
{
	static int sw_init_done = 0;
	struct eth_device *dev[CONFIG_IPQ_NO_MACS];
	uint clk_div_val;
	uchar enet_addr[CONFIG_IPQ_NO_MACS * 6];
	uchar *mac_addr;
	char ethaddr[32] = "ethaddr";
	char mac[64];
	int i, phy_idx;
	int ret;
	int gmac_gpio_node = 0, ar8033_gpio_node = 0, offset = 0;
	memset(enet_addr, 0, sizeof(enet_addr));

	/* 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 failed;

		ipq_gmac_macs[i] = malloc(sizeof(struct ipq_eth_dev));
		if (ipq_gmac_macs[i] == NULL)
			goto 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];

		snprintf(dev[i]->name, sizeof(dev[i]->name), "eth%d", 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] = gmac_cfg->unit & 0xff;
		} else {
			memcpy(&dev[i]->enetaddr[0], &enet_addr[i * 6], 6);

			/*
			 * Populate the environment with these MAC addresses.
			 * U-Boot uses these to patch the 'local-mac-address'
			 * dts entry for the ethernet entries, which in turn
			 * will be picked up by the HLOS driver
			 */
			snprintf(mac, sizeof(mac), "%x:%x:%x:%x:%x:%x",
					dev[i]->enetaddr[0], dev[i]->enetaddr[1],
					dev[i]->enetaddr[2], dev[i]->enetaddr[3],
					dev[i]->enetaddr[4], dev[i]->enetaddr[5]);

			setenv(ethaddr, mac);

		}

		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(ethaddr, sizeof(ethaddr), "eth%daddr", (i + 1));

		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]->interface = gmac_cfg->phy;
		ipq_gmac_macs[i]->phy_address = gmac_cfg->phy_addr.addr;
		ipq_gmac_macs[i]->no_of_phys = gmac_cfg->phy_addr.count;
		ipq_gmac_macs[i]->gmac_board_cfg = gmac_cfg;

		if (get_params.gmac_port == gmac_cfg->unit) {
			ipq_gmac_macs[i]->forced_params = &get_params;
		}
		/* tx/rx Descriptor initialization */
		if (ipq_gmac_tx_rx_desc_ring(dev[i]->priv) == -1)
			goto failed;

		if ((gmac_cfg->unit == GMAC_UNIT2 ||
		    gmac_cfg->unit == GMAC_UNIT3) &&
		    (gmac_cfg->mac_conn_to_phy)) {
			if (ipq_gmac_macs[i]->forced_params->is_forced) {
				ipq_gmac_macs[i]->speed = ipq_gmac_macs[i]->forced_params->speed;
			} else {
				get_phy_speed_duplexity(dev[i]);
			}
			switch (ipq_gmac_macs[i]->speed) {
			case SPEED_1000M:
				ipq_info("Port:%d speed 1000Mbps\n",
					gmac_cfg->unit);
				ipq_gmac_macs[i]->mac_ps = GMII_PORT_SELECT;
				clk_div_val = (CLK_DIV_SGMII_1000M - 1);
				break;
			case SPEED_100M:
				ipq_info("Port:%d speed 100Mbps\n",
					gmac_cfg->unit);
				ipq_gmac_macs[i]->mac_ps = MII_PORT_SELECT;
				clk_div_val = (CLK_DIV_SGMII_100M - 1);
				break;
			case SPEED_10M:
				ipq_info("Port:%d speed 10Mbps\n",
					gmac_cfg->unit);
				ipq_gmac_macs[i]->mac_ps = MII_PORT_SELECT;
				clk_div_val = (CLK_DIV_SGMII_10M - 1);
				break;
			default:
				ipq_info("Port speed unknown\n");
				goto failed;
			}
		} else {
			/* Force it to zero for GMAC 0 & 1 */
			clk_div_val = 0;
		}

		ipq_gmac_mii_clk_init(ipq_gmac_macs[i], clk_div_val, gmac_cfg);

		strlcpy((char *)ipq_gmac_macs[i]->phy_name, gmac_cfg->phy_name,
					sizeof(ipq_gmac_macs[i]->phy_name));
		bb_nodes[i] = malloc(sizeof(struct bitbang_nodes));
		if (bb_nodes[i] == NULL)
			goto failed;
		memset(bb_nodes[i], 0, sizeof(struct bitbang_nodes));

		gmac_gpio_node = fdt_path_offset(gd->fdt_blob, "gmac_gpio");
		if (gmac_gpio_node >= 0) {
			offset = fdt_first_subnode(gd->fdt_blob, gmac_gpio_node);
			bb_nodes[i]->mdio = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);

			offset = fdt_next_subnode(gd->fdt_blob, offset);
			bb_nodes[i]->mdc = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
			bb_miiphy_buses[i].priv = bb_nodes[i];
			strncpy(bb_miiphy_buses[i].name, gmac_cfg->phy_name,
						sizeof(bb_miiphy_buses[i].name));
			miiphy_register(bb_miiphy_buses[i].name, bb_miiphy_read, bb_miiphy_write);
			for (phy_idx = 0; phy_idx < ipq_gmac_macs[i]->no_of_phys; phy_idx++) {
				miiphy_write(bb_miiphy_buses[i].name,
						ipq_gmac_macs[i]->phy_address[phy_idx], PHY_CONTROL_REG,
						BMCR_RESET | AUTO_NEG_ENABLE);
				mdelay(100);
			}
		}

		eth_register(dev[i]);

		if (!sw_init_done && ipq_switch_init) {
			if (ipq_switch_init(gmac_cfg) == 0) {
				sw_init_done = 1;
			} else {
				ipq_info("Switch inits failed\n");
				goto failed;
			}
		}
	}

	ar8033_gpio_node = fdt_path_offset(gd->fdt_blob, "/ar8033_gpio");

	if (ar8033_gpio_node >= 0) {
		bb_nodes[i] = malloc(sizeof(struct bitbang_nodes));
		memset(bb_nodes[i], 0, sizeof(struct bitbang_nodes));

		offset = fdt_first_subnode(gd->fdt_blob, ar8033_gpio_node);
		bb_nodes[i]->mdio = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);

		offset = fdt_next_subnode(gd->fdt_blob, offset);
		bb_nodes[i]->mdc = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);

		bb_miiphy_buses[i].priv = bb_nodes[i];
		strlcpy(bb_miiphy_buses[i].name, "8033",
				sizeof(bb_miiphy_buses[i].name));
		miiphy_register(bb_miiphy_buses[i].name, bb_miiphy_read, bb_miiphy_write);
	}

	/* set the mac address in environment for unconfigured GMAC */
	if (ret >= 0) {
		for (; i < CONFIG_IPQ_NO_MACS; i++) {
			mac_addr = &enet_addr[i * 6];
			if (is_valid_ethaddr(mac_addr)) {
				/*
				 * U-Boot uses these to patch the 'local-mac-address'
				 * dts entry for the ethernet entries, which in turn
				 * will be picked up by the HLOS driver
				 */
				sprintf(mac, "%x:%x:%x:%x:%x:%x",
						mac_addr[0], mac_addr[1],
						mac_addr[2], mac_addr[3],
						mac_addr[4], mac_addr[5]);
				setenv(ethaddr, mac);
			}
			sprintf(ethaddr, "eth%daddr", (i + 1));
		}
	}

	return 0;

failed:
	for (i = 0; i < CONFIG_IPQ_NO_MACS; i++) {
		if (bb_nodes[i])
			free(bb_nodes[i]);
		if (dev[i]) {
			eth_unregister(dev[i]);
			free(dev[i]);
		}
		if (ipq_gmac_macs[i])
			free(ipq_gmac_macs[i]);
	}

	return -ENOMEM;
}



static void ipq_gmac_core_reset(ipq_gmac_board_cfg_t *gmac_cfg)
{
	for (; gmac_cfg_is_valid(gmac_cfg); gmac_cfg++) {
		writel(0, GMAC_CORE_RESET(gmac_cfg->unit));
		if (gmac_cfg->is_macsec)
			writel(0, GMACSEC_CORE_RESET(gmac_cfg->unit));
	}

	writel(0, (void *)GMAC_AHB_RESET);
}

void ipq_gmac_common_init(ipq_gmac_board_cfg_t *gmac_cfg)
{
	uint pcs_qsgmii_ctl_val;
	uint pcs_mode_ctl_val;
	uint i;
	ipq_gmac_board_cfg_t *gmac_tmp_cfg = gmac_cfg;

	pcs_mode_ctl_val = (PCS_CHn_ANEG_EN(GMAC_UNIT1) |
			PCS_CHn_ANEG_EN(GMAC_UNIT2) |
			PCS_CHn_ANEG_EN(GMAC_UNIT3) |
			PCS_CHn_ANEG_EN(GMAC_UNIT0) |
			PCS_SGMII_MAC);

	pcs_qsgmii_ctl_val = (PCS_QSGMII_ATHR_CSCO_AUTONEG |
			PCS_QSGMII_SW_VER_1_7 |
			PCS_QSGMII_SHORT_THRESH |
			PCS_QSGMII_SHORT_LATENCY |
			PCS_QSGMII_DEPTH_THRESH(1) |
			PCS_CHn_SERDES_SN_DETECT(0) |
			PCS_CHn_SERDES_SN_DETECT(1) |
			PCS_CHn_SERDES_SN_DETECT(2) |
			PCS_CHn_SERDES_SN_DETECT(3) |
			PCS_CHn_SERDES_SN_DETECT_2(0) |
			PCS_CHn_SERDES_SN_DETECT_2(1) |
			PCS_CHn_SERDES_SN_DETECT_2(2) |
			PCS_CHn_SERDES_SN_DETECT_2(3));

	for (i = 0; gmac_cfg_is_valid(gmac_tmp_cfg); gmac_tmp_cfg++, i++) {
		switch(gmac_tmp_cfg->phy) {
		case PHY_INTERFACE_MODE_SGMII:
			writel(QSGMII_PHY_MODE_SGMII,
				(QSGMII_REG_BASE + QSGMII_PHY_MODE_CTL));
			writel(PCS_QSGMII_MODE_SGMII,
				(QSGMII_REG_BASE + PCS_QSGMII_SGMII_MODE));
			break;
		case PHY_INTERFACE_MODE_QSGMII:
			pcs_mode_ctl_val = (PCS_SGMII_MAC);
			writel(QSGMII_PHY_MODE_QSGMII,
				(QSGMII_REG_BASE + QSGMII_PHY_MODE_CTL));
			writel(PCS_QSGMII_MODE_QSGMII,
				(QSGMII_REG_BASE + PCS_QSGMII_SGMII_MODE));
			clrbits_le32((QSGMII_REG_BASE + QSGMII_PHY_QSGMII_CTL),
				QSGMII_TX_SLC_CTL(3));
			break;
		default:
			break;
		}
	}

	writel(MACSEC_BYPASS_EXT_EN, (NSS_REG_BASE + NSS_MACSEC_CTL));
	writel(pcs_mode_ctl_val, (QSGMII_REG_BASE + NSS_PCS_MODE_CTL));
	writel(pcs_qsgmii_ctl_val, (QSGMII_REG_BASE + PCS_QSGMII_CTL));

	/*
	 * MDIO lines for all the MACs are connected through MAC0.
	 * Regardless of MAC 0 being used or not, it has to be pulled
	 * out of reset. Else, MDIO writes to configure other MACs
	 * will fail.
	 */
	writel(0, GMAC_CORE_RESET(0));

	/*
	 * Pull out of reset the MACs that are applicable to the
	 * current board.
	 */
	ipq_gmac_core_reset(gmac_cfg);
}

static int ipq_eth_bb_init(struct bb_miiphy_bus *bus)
{
	return 0;
}

static int ipq_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
{
	struct bitbang_nodes *bb_node = bus->priv;
	struct qca_gpio_config gmac_gpio_config = {0};

	gmac_gpio_config.gpio = bb_node->mdio;
	gmac_gpio_config.func = 0;
	gmac_gpio_config.out = GPIO_OUTPUT;
	gmac_gpio_config.pull = GPIO_NO_PULL;
	gmac_gpio_config.drvstr = GPIO_8MA;
	gmac_gpio_config.oe = 1;

	gpio_tlmm_config(&gmac_gpio_config);

	gmac_gpio_config.gpio = bb_node->mdc;

	gpio_tlmm_config(&gmac_gpio_config);

	return 0;
}

static int ipq_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
{
	struct bitbang_nodes *bb_node = bus->priv;
	struct qca_gpio_config gmac_gpio_config = {0};

	gmac_gpio_config.gpio = bb_node->mdio;
	gmac_gpio_config.func = 0;
	gmac_gpio_config.out = GPIO_INPUT;
	gmac_gpio_config.pull = GPIO_NO_PULL;
	gmac_gpio_config.drvstr = GPIO_8MA;
	gmac_gpio_config.oe = 0;

	gpio_tlmm_config(&gmac_gpio_config);


	gmac_gpio_config.gpio = bb_node->mdc;
	gmac_gpio_config.out = GPIO_OUTPUT;
	gmac_gpio_config.oe = 1;

	gpio_tlmm_config(&gmac_gpio_config);
	return 0;
}

static int ipq_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
{
	struct bitbang_nodes *bb_node = bus->priv;

	gpio_set_value(bb_node->mdio, v);

	return 0;
}

static int ipq_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
{
	struct bitbang_nodes *bb_node = bus->priv;

	*v = gpio_get_value(bb_node->mdio);

	return 0;
}

static int ipq_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
{
	struct bitbang_nodes *bb_node = bus->priv;

	gpio_set_value(bb_node->mdc, v);

	return 0;
}

static int ipq_eth_bb_delay(struct bb_miiphy_bus *bus)
{
	ndelay(350);

	return 0;
}

struct bb_miiphy_bus bb_miiphy_buses[] = {
	{
		.init		= ipq_eth_bb_init,
		.mdio_active	= ipq_eth_bb_mdio_active,
		.mdio_tristate	= ipq_eth_bb_mdio_tristate,
		.set_mdio	= ipq_eth_bb_set_mdio,
		.get_mdio	= ipq_eth_bb_get_mdio,
		.set_mdc	= ipq_eth_bb_set_mdc,
		.delay		= ipq_eth_bb_delay,
	},
	{
		.init		= ipq_eth_bb_init,
		.mdio_active	= ipq_eth_bb_mdio_active,
		.mdio_tristate	= ipq_eth_bb_mdio_tristate,
		.set_mdio	= ipq_eth_bb_set_mdio,
		.get_mdio	= ipq_eth_bb_get_mdio,
		.set_mdc	= ipq_eth_bb_set_mdc,
		.delay		= ipq_eth_bb_delay,
	},
	{
		.init		= ipq_eth_bb_init,
		.mdio_active	= ipq_eth_bb_mdio_active,
		.mdio_tristate	= ipq_eth_bb_mdio_tristate,
		.set_mdio	= ipq_eth_bb_set_mdio,
		.get_mdio	= ipq_eth_bb_get_mdio,
		.set_mdc	= ipq_eth_bb_set_mdc,
		.delay		= ipq_eth_bb_delay,
	},
	{
		.init		= ipq_eth_bb_init,
		.mdio_active	= ipq_eth_bb_mdio_active,
		.mdio_tristate	= ipq_eth_bb_mdio_tristate,
		.set_mdio	= ipq_eth_bb_set_mdio,
		.get_mdio	= ipq_eth_bb_get_mdio,
		.set_mdc	= ipq_eth_bb_set_mdc,
		.delay		= ipq_eth_bb_delay,
	},
};
int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);

static int ipq_eth_unregister(void)
{
	int i;
	struct eth_device *dev;

	for (i = 0; i < CONFIG_IPQ_NO_MACS; i++) {
		if (bb_nodes[i])
			free(bb_nodes[i]);
		if (ipq_gmac_macs[i]) {
			dev = ipq_gmac_macs[i]->dev;
			eth_unregister(dev);
		}
		if (ipq_gmac_macs[i])
			free(ipq_gmac_macs[i]);
	}

	return 0;
}

static int do_force_eth_speed(cmd_tbl_t *cmdtp, int flag, int argc,
				char *const argv[])
{
	int status;
	int i;
	int j;
	int phyaddrfound = 0;
	int phy_addr;

	if (argc != 3)
		return CMD_RET_USAGE;

	ipq_gmac_board_cfg_t *gmac_tmp_cfg = gmac_cfg;

	if (strict_strtoul(argv[1], 16, (unsigned long *)&phy_addr) < 0) {
		ipq_info("Invalid Phy addr configured\n");
		return CMD_RET_USAGE;
	}
	get_params.phy_addr = phy_addr;
	for (i = 0; gmac_cfg_is_valid(gmac_tmp_cfg); gmac_tmp_cfg++, i++) {
		for (j = 0; j < gmac_tmp_cfg->phy_addr.count; j++) {
			if (gmac_tmp_cfg->phy_addr.addr[j] == get_params.phy_addr) {
				get_params.gmac_port = gmac_tmp_cfg->unit;
				phyaddrfound = 1;
				break;
			}
		}
	}
	if (phyaddrfound == 0) {
		ipq_info("Invalid Phy addr configured\n");
		return CMD_RET_USAGE;
	}

	if (strcmp(argv[2], "10") == 0) {
		get_params.speed = SPEED_10M;
	} else if (strcmp(argv[2], "100") == 0) {
		get_params.speed = SPEED_100M;
	} else if (strcmp(argv[2], "autoneg") == 0) {
		get_params.speed = SPEED_1000M;
	} else {
		ipq_info("Invalid speed settings configured\n");
		return CMD_RET_USAGE;
	}

	get_params.is_forced = 1;
	get_params.miiwrite_done = 1;
	ipq_eth_unregister();
	status = ipq_gmac_init(gmac_cfg);

	return status;
}

U_BOOT_CMD(ethspeed, 3, 0, do_force_eth_speed,
	   "Force ethernet speed to 10/100/autoneg",
	   "ethspeed {phy addr} {10|100|autoneg} - Force ethernet speed to 10/100/autoneg\n");

