/*
 * Copyright (c) 2014, 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 <config.h>
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <command.h>
#include <asm/io.h>
#include <asm/addrspace.h>
#include <asm/types.h>

#ifdef CONFIG_ATH_NAND_BR
#include <nand.h>
#endif

#include <atheros.h>
#include "qca-eth-955x.h"
#include "qca-eth-955x_phy.h"
#define SGMII_LINK_WAR_MAX_TRY 10

#if (CONFIG_COMMANDS & CFG_CMD_MII)
#include <miiphy.h>
#endif
#define ath_gmac_unit2mac(_unit)     ath_gmac_macs[(_unit)]
#define ath_gmac_name2mac(name)	   is_drqfn() ? ath_gmac_unit2mac(1):strcmp(name,"eth0") ? ath_gmac_unit2mac(1) : ath_gmac_unit2mac(0)

int ath_gmac_miiphy_read(char *devname, uint32_t phaddr, uint8_t reg, uint16_t *data);
int ath_gmac_miiphy_write(char *devname, uint32_t phaddr, uint8_t reg, uint16_t data);

#ifndef CFG_ATH_GMAC_NMACS
#define CFG_ATH_GMAC_NMACS	1
#endif /* CFG_ATH_GMAC_NMACS */

ath_gmac_mac_t *ath_gmac_macs[CFG_ATH_GMAC_NMACS];


#ifdef CONFIG_VIR_PHY
extern int athr_vir_phy_setup(int unit);
extern int athr_vir_phy_is_up(int unit);
extern int athr_vir_phy_is_fdx(int unit);
extern int athr_vir_phy_speed(int unit);
extern void athr_vir_reg_init(void);
#endif

#ifdef  CONFIG_ATHRS17_PHY
extern void athrs17_reg_init(void);
extern void athrs17_reg_init_wan(void);
#endif


#ifdef CONFIG_ATHR_8033_PHY
extern int athrs_ar8033_reg_init(void *arg);
extern int athrs_ar8033_phy_setup(void  *arg);
extern int athrs_ar8033_phy_is_fdx(int ethUnit);
extern int athrs_ar8033_phy_is_link_alive(int phyUnit);
extern int athrs_ar8033_phy_is_up(int ethUnit);
extern int athrs_ar8033_phy_speed(int ethUnit,int phyUnit);
#endif

#ifdef CONFIG_ATH_NAND_BR

#define ATH_ETH_MAC_READ_SIZE 4096
extern unsigned long long
ath_nand_get_cal_offset(const char *ba);
#endif

static int
ath_gmac_send(struct eth_device *dev, volatile void *packet, int length)
{
	int i;

	ath_gmac_mac_t *mac = (ath_gmac_mac_t *)dev->priv;

	ath_gmac_desc_t *f = mac->fifo_tx[mac->next_tx];

	f->pkt_size = length;
	f->res1 = 0;
	f->pkt_start_addr = virt_to_phys(packet);

	ath_gmac_tx_give_to_dma(f);
	flush_cache((u32) packet, length);
	ath_gmac_reg_wr(mac, ATH_DMA_TX_DESC, virt_to_phys(f));
	ath_gmac_reg_wr(mac, ATH_DMA_TX_CTRL, ATH_TXE);

	for (i = 0; i < MAX_WAIT; i++) {
		udelay(10);
		if (!ath_gmac_tx_owned_by_dma(f))
			break;
	}
	if (i == MAX_WAIT)
		printf("Tx Timed out\n");

	f->pkt_start_addr = 0;
	f->pkt_size = 0;

	if (++mac->next_tx >= NO_OF_TX_FIFOS)
		mac->next_tx = 0;

	return (0);
}

static int ath_gmac_recv(struct eth_device *dev)
{
	int length;
	ath_gmac_desc_t *f;
	ath_gmac_mac_t *mac;
	volatile int dmaed_pkt=0;
	int count = 0;

	mac = (ath_gmac_mac_t *)dev->priv;

	for (;;) {
		f = mac->fifo_rx[mac->next_rx];
		if (ath_gmac_rx_owned_by_dma(f)) {
		/* check if the current Descriptor is_empty is 1,But the DMAed count is not-zero
		then move to desciprot where the packet is available */
			dmaed_pkt = (ath_gmac_reg_rd(mac, 0x194) >> 16);
			if (!dmaed_pkt) {
				break ;
			} else {
				if (f->is_empty == 1) {
					while ( count < NO_OF_RX_FIFOS ) {
						if (++mac->next_rx >= NO_OF_RX_FIFOS) {
							mac->next_rx = 0;
						}
						f = mac->fifo_rx[mac->next_rx];
						/*
						 * Break on valid data in the desc by checking
						 *  empty bit.
						 */
						if (!f->is_empty){
							count = 0;
							break;
						}
						count++;
					}
				}
			}
		}

		length = f->pkt_size;

		net_process_received_packet(net_rx_packets[mac->next_rx] , length - 4);
		flush_cache((u32) net_rx_packets[mac->next_rx] , PKTSIZE_ALIGN);

		ath_gmac_reg_wr(mac,0x194,1);
		ath_gmac_rx_give_to_dma(f);

		if (++mac->next_rx >= NO_OF_RX_FIFOS)
			mac->next_rx = 0;
	}

	if (!(ath_gmac_reg_rd(mac, ATH_DMA_RX_CTRL))) {
		ath_gmac_reg_wr(mac, ATH_DMA_RX_DESC, virt_to_phys(f));
		ath_gmac_reg_wr(mac, ATH_DMA_RX_CTRL, 1);
	}

	return (0);
}

void ath_gmac_mii_setup(ath_gmac_mac_t *mac)
{
	u32 mgmt_cfg_val;

	ath_reg_wr(SWITCH_CLOCK_SPARE_ADDRESS, 0x520);

	if ((is_s17()  && mac->mac_unit == 0) || is_drqfn()) {
		printf("Scorpion  ----> S17 PHY *\n");
		mgmt_cfg_val = 7;
#ifndef ATH_RGMII_CAL
		ath_reg_wr(ATH_ETH_CFG, ETH_CFG_ETH_RXDV_DELAY_SET(3) |
					ETH_CFG_ETH_RXD_DELAY_SET(3)|
					ETH_CFG_RGMII_GE0_SET(1));

		ath_reg_wr(ETH_XMII_ADDRESS, ETH_XMII_TX_INVERT_SET(1) |
					ETH_XMII_RX_DELAY_SET(2) |
					ETH_XMII_TX_DELAY_SET(1) |
					ETH_XMII_GIGE_SET(1));
#else
		rgmii_cal_alg()
#endif
		udelay(1000);
		ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
		ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, mgmt_cfg_val);
		return;
	}

	if (is_ar8033 () && mac->mac_unit == 1) {
		printf("Scorpion ---->8033 PHY*\n");
		mgmt_cfg_val = 7;
		ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
		ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, mgmt_cfg_val);
		return;
	}

	if (is_vir_phy()) {
		printf("Scorpion ---->VIR PHY*\n");
		ath_reg_wr(ATH_ETH_CFG, ETH_CFG_ETH_RXDV_DELAY_SET(3) |
					ETH_CFG_ETH_RXD_DELAY_SET(3)|
					ETH_CFG_RGMII_GE0_SET(1));
		ath_reg_wr(ETH_XMII_ADDRESS, ETH_XMII_TX_INVERT_SET(1) |
				ETH_XMII_RX_DELAY_SET(2)  |
				ETH_XMII_TX_DELAY_SET(1)  |
				ETH_XMII_GIGE_SET(1));
		udelay(1000);
		ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31));
		ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, mgmt_cfg_val);

		return;
	}
}

void
athrs_sgmii_res_cal(void)
{
	unsigned int read_data, read_data_otp, otp_value, otp_per_val, rbias_per;
	unsigned int read_data_spi;
	unsigned int *address_spi = (unsigned int *)0xbffffffc;
	unsigned int rbias_pos_or_neg, res_cal_val;
	unsigned int sgmii_pos, sgmii_res_cal_value;
	unsigned int reversed_sgmii_value, use_value;

	ath_reg_wr(OTP_INTF2_ADDRESS, 0x7d);
	ath_reg_wr(OTP_LDO_CONTROL_ADDRESS, 0x0);

	while (ath_reg_rd(OTP_LDO_STATUS_ADDRESS) & OTP_LDO_STATUS_POWER_ON_MASK);

	read_data = ath_reg_rd(OTP_MEM_0_ADDRESS + 4);

	while (!(ath_reg_rd(OTP_STATUS0_ADDRESS) & OTP_STATUS0_EFUSE_READ_DATA_VALID_MASK));

	read_data_otp = ath_reg_rd(OTP_STATUS1_ADDRESS);

	if (read_data_otp & 0x1fff) {
		read_data = read_data_otp;
	} else {
		read_data_spi = *(address_spi);
		if ((read_data_spi & 0xffff0000) == 0x5ca10000) {
			read_data = read_data_spi;
		} else {
			read_data = read_data_otp;
		}
	}

	if (read_data & 0x00001000) {
		otp_value = (read_data & 0xfc0) >> 6;
	} else {
		otp_value = read_data & 0x3f;
	}

	if (otp_value > 31) {
		otp_per_val = 63 - otp_value;
		rbias_pos_or_neg = 1;
	} else {
		otp_per_val = otp_value;
		rbias_pos_or_neg = 0;
	}

	rbias_per = otp_per_val * 15;

	if (rbias_pos_or_neg == 1) {
		res_cal_val = (rbias_per + 34) / 21;
		sgmii_pos = 1;
	} else {
		if (rbias_per > 34) {
			res_cal_val = (rbias_per - 34) / 21;
			sgmii_pos = 0;
		} else {
			res_cal_val = (34 - rbias_per) / 21;
			sgmii_pos = 1;
		}
	}

	if (sgmii_pos == 1) {
		sgmii_res_cal_value = 8 + res_cal_val;
	} else {
		sgmii_res_cal_value = 8 - res_cal_val;
	}

	reversed_sgmii_value = 0;
	use_value = 0x8;
	reversed_sgmii_value = reversed_sgmii_value | ((sgmii_res_cal_value & use_value) >> 3);
	use_value = 0x4;
	reversed_sgmii_value = reversed_sgmii_value | ((sgmii_res_cal_value & use_value) >> 1);
	use_value = 0x2;
	reversed_sgmii_value = reversed_sgmii_value | ((sgmii_res_cal_value & use_value) << 1);
	use_value = 0x1;
	reversed_sgmii_value = reversed_sgmii_value | ((sgmii_res_cal_value & use_value) << 3);

	reversed_sgmii_value &= 0xf;

	printf("%s: cal value = 0x%x\n", __func__, reversed_sgmii_value);

	// To Check the locking of the SGMII PLL

	read_data = (ath_reg_rd(SGMII_SERDES_ADDRESS) &
				~SGMII_SERDES_RES_CALIBRATION_MASK) |
			SGMII_SERDES_RES_CALIBRATION_SET(reversed_sgmii_value);

	ath_reg_wr(SGMII_SERDES_ADDRESS, read_data);


	ath_reg_wr(ETH_SGMII_SERDES_ADDRESS,
			ETH_SGMII_SERDES_EN_LOCK_DETECT_MASK |
			ETH_SGMII_SERDES_PLL_REFCLK_SEL_MASK |
			ETH_SGMII_SERDES_EN_PLL_MASK);

	ath_reg_rmw_set(SGMII_SERDES_ADDRESS,
			SGMII_SERDES_CDR_BW_SET(3) |
			SGMII_SERDES_TX_DR_CTRL_SET(1) |
			SGMII_SERDES_PLL_BW_SET(1) |
			SGMII_SERDES_EN_SIGNAL_DETECT_SET(1) |
			SGMII_SERDES_FIBER_SDO_SET(1) |
			SGMII_SERDES_VCO_REG_SET(3));

	ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_ETH_SGMII_ARESET_MASK);
	udelay(25);
	ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_ETH_SGMII_RESET_MASK);

	while (!(ath_reg_rd(SGMII_SERDES_ADDRESS) & SGMII_SERDES_LOCK_DETECT_STATUS_MASK));
}


static void athr_gmac_sgmii_setup()
{
	int status = 0, count = 0;

#ifdef ATH_SGMII_FORCED_MODE
        ath_reg_wr(MR_AN_CONTROL_ADDRESS, MR_AN_CONTROL_SPEED_SEL1_SET(1) |
					MR_AN_CONTROL_PHY_RESET_SET(1)  |
					MR_AN_CONTROL_DUPLEX_MODE_SET(1));
	udelay(10);

	ath_reg_wr(SGMII_CONFIG_ADDRESS, SGMII_CONFIG_MODE_CTRL_SET(2)   |
					SGMII_CONFIG_FORCE_SPEED_SET(1) |
					SGMII_CONFIG_SPEED_SET(2));

	printf ("SGMII in forced mode\n");
#else

	ath_reg_wr(SGMII_CONFIG_ADDRESS, SGMII_CONFIG_MODE_CTRL_SET(2));

	ath_reg_wr(MR_AN_CONTROL_ADDRESS, MR_AN_CONTROL_AN_ENABLE_SET(1) |
					MR_AN_CONTROL_PHY_RESET_SET(1));

	ath_reg_wr(MR_AN_CONTROL_ADDRESS, MR_AN_CONTROL_AN_ENABLE_SET(1));
#endif

	/*
	 * SGMII reset sequence suggested by systems team.
	 */

	ath_reg_wr(SGMII_RESET_ADDRESS, SGMII_RESET_RX_CLK_N_RESET);

	ath_reg_wr(SGMII_RESET_ADDRESS, SGMII_RESET_HW_RX_125M_N_SET(1));

	ath_reg_wr(SGMII_RESET_ADDRESS, SGMII_RESET_HW_RX_125M_N_SET(1) |
					SGMII_RESET_RX_125M_N_SET(1));

	ath_reg_wr(SGMII_RESET_ADDRESS, SGMII_RESET_HW_RX_125M_N_SET(1) |
					SGMII_RESET_TX_125M_N_SET(1)	|
					SGMII_RESET_RX_125M_N_SET(1));

	ath_reg_wr(SGMII_RESET_ADDRESS, SGMII_RESET_HW_RX_125M_N_SET(1) |
					SGMII_RESET_TX_125M_N_SET(1)	|
					SGMII_RESET_RX_125M_N_SET(1)	|
					SGMII_RESET_RX_CLK_N_SET(1));

	ath_reg_wr(SGMII_RESET_ADDRESS, SGMII_RESET_HW_RX_125M_N_SET(1) |
					SGMII_RESET_TX_125M_N_SET(1)	|
					SGMII_RESET_RX_125M_N_SET(1)	|
					SGMII_RESET_RX_CLK_N_SET(1)	|
					SGMII_RESET_TX_CLK_N_SET(1));

	ath_reg_rmw_clear(MR_AN_CONTROL_ADDRESS, MR_AN_CONTROL_PHY_RESET_SET(1));

	/*
	 * WAR::Across resets SGMII link status goes to weird
	 * state.
	 * if 0xb8070058 (SGMII_DEBUG register) reads other then 0x1f or 0x10
	 * for sure we are in bad  state.
	 * Issue a PHY reset in MR_AN_CONTROL_ADDRESS to keep going.
	 */
	status = (ath_reg_rd(SGMII_DEBUG_ADDRESS) & 0xff);
	while (!(status == 0xf || status == 0x10)) {

		ath_reg_rmw_set(MR_AN_CONTROL_ADDRESS, MR_AN_CONTROL_PHY_RESET_SET(1));
		udelay(100);
		ath_reg_rmw_clear(MR_AN_CONTROL_ADDRESS, MR_AN_CONTROL_PHY_RESET_SET(1));
		if (count++ == SGMII_LINK_WAR_MAX_TRY) {
			printf ("Max resets limit reached exiting...\n");
			break;
		}
		status = (ath_reg_rd(SGMII_DEBUG_ADDRESS) & 0xff);
	}

	printf("%s SGMII done\n",__func__);

}

static void ath_gmac_hw_start(ath_gmac_mac_t *mac)
{


#ifndef ATH_RGMII_CAL /* Moved after mii_setup since these registers are touched in RGMII cal code */
	if(mac->mac_unit)
	{
		ath_gmac_reg_rmw_set(mac, ATH_MAC_CFG2, (ATH_MAC_CFG2_PAD_CRC_EN |
					ATH_MAC_CFG2_LEN_CHECK | ATH_MAC_CFG2_IF_1000));
	} else {


		ath_gmac_reg_rmw_set(mac, ATH_MAC_CFG2, (ATH_MAC_CFG2_PAD_CRC_EN |
					ATH_MAC_CFG2_LEN_CHECK | ATH_MAC_CFG2_IF_10_100));
	}
	ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_0, 0x1f00);
#endif


#ifdef ATH_RGMII_CAL
	if(mac->mac_unit)
	{
		ath_gmac_reg_rmw_set(mac, ATH_MAC_CFG2, (ATH_MAC_CFG2_PAD_CRC_EN |
					ATH_MAC_CFG2_LEN_CHECK | ATH_MAC_CFG2_IF_1000));
	} else {


		ath_gmac_reg_rmw_set(mac, ATH_MAC_CFG2, (ATH_MAC_CFG2_PAD_CRC_EN |
					ATH_MAC_CFG2_LEN_CHECK | ATH_MAC_CFG2_IF_10_100));
	}
	ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_0, 0x1f00);
#endif

	ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_1, 0x10ffff);
	ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_2, 0xAAA0555);

	ath_gmac_reg_rmw_set(mac, ATH_MAC_FIFO_CFG_4, 0x3ffff);
	/*
	 * Setting Drop CRC Errors, Pause Frames,Length Error frames
	 * and Multi/Broad cast frames.
	 */

	ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_5, 0x7eccf);

	ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_3, 0x1f00140);

	printf(": cfg1 %#x cfg2 %#x\n", ath_gmac_reg_rd(mac, ATH_MAC_CFG1),
			ath_gmac_reg_rd(mac, ATH_MAC_CFG2));


}

static int ath_gmac_check_link(ath_gmac_mac_t *mac)
{
	int link, duplex, speed;

	ath_gmac_phy_link(mac->mac_unit, &link);
	ath_gmac_phy_duplex(mac->mac_unit, &duplex);
	ath_gmac_phy_speed(mac->mac_unit, &speed);

	mac->link = link;

	if(!mac->link) {
		printf("%s link down\n",mac->dev->name);
		return 0;
	}

	switch (speed)
	{
		case _1000BASET:
			ath_gmac_set_mac_if(mac, 1);
			ath_gmac_reg_rmw_set(mac, ATH_MAC_FIFO_CFG_5, (1 << 19));

			if (is_ar8033() && mac->mac_unit == 1) {
				ath_reg_wr(ETH_SGMII_ADDRESS, ETH_SGMII_GIGE_SET(1) |
                                           ETH_SGMII_CLK_SEL_SET(1));
			}

			break;

		case _100BASET:
			ath_gmac_set_mac_if(mac, 0);
			ath_gmac_set_mac_speed(mac, 1);
			ath_gmac_reg_rmw_clear(mac, ATH_MAC_FIFO_CFG_5, (1 << 19));

			if (is_ar8033() && mac->mac_unit == 1) {
				ath_reg_wr(ETH_SGMII_ADDRESS, ETH_SGMII_PHASE0_COUNT_SET(1) |
						ETH_SGMII_PHASE1_COUNT_SET(1));
			}

			break;

		case _10BASET:
			ath_gmac_set_mac_if(mac, 0);
			ath_gmac_set_mac_speed(mac, 0);
			ath_gmac_reg_rmw_clear(mac, ATH_MAC_FIFO_CFG_5, (1 << 19));

			if (is_ar8033() && mac->mac_unit == 1) {
				ath_reg_wr(ETH_SGMII_ADDRESS, ETH_SGMII_PHASE0_COUNT_SET(19) |
						ETH_SGMII_PHASE1_COUNT_SET(19));
			}

			break;

		default:
			printf("Invalid speed detected\n");
			return 0;
	}

	if (mac->link && (duplex == mac->duplex) && (speed == mac->speed)) {
		return 1;
	}

	mac->duplex = duplex;
	mac->speed = speed;

	printf("dup %d speed %d\n", duplex, speed);

	ath_gmac_set_mac_duplex(mac,duplex);

	return 1;
}

/*
 * For every command we re-setup the ring and start with clean h/w rx state
 */
static int ath_gmac_clean_rx(struct eth_device *dev, bd_t * bd)
{

	int i;
	ath_gmac_desc_t *fr;
	ath_gmac_mac_t *mac = (ath_gmac_mac_t*)dev->priv;

	if (!ath_gmac_check_link(mac)) {
		return -1;
	}

	mac->next_rx = 0;

	ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_0, 0x1f00);
	ath_gmac_reg_wr(mac, ATH_MAC_CFG1, (ATH_MAC_CFG1_RX_EN | ATH_MAC_CFG1_TX_EN));

	for (i = 0; i < NO_OF_RX_FIFOS; i++) {
		fr = mac->fifo_rx[i];
		fr->pkt_start_addr = virt_to_phys(net_rx_packets[i]);
		flush_cache((u32) net_rx_packets[i], PKTSIZE_ALIGN);
		ath_gmac_rx_give_to_dma(fr);
	}

	ath_gmac_reg_wr(mac, ATH_DMA_RX_DESC, virt_to_phys(mac->fifo_rx[0]));
	ath_gmac_reg_wr(mac, ATH_DMA_RX_CTRL, ATH_RXE);	/* rx start */
	udelay(1000 * 1000);


	return 1;

}

static int ath_gmac_alloc_fifo(int ndesc, ath_gmac_desc_t ** fifo)
{
	int i;
	u32 size;
	uchar *p = NULL;

	size = sizeof(ath_gmac_desc_t) * ndesc;
	size += CONFIG_SYS_CACHELINE_SIZE - 1;

	if ((p = malloc(size)) == NULL) {
		printf("Cant allocate fifos\n");
		return -1;
	}

	p = (uchar *) (((u32) p + CONFIG_SYS_CACHELINE_SIZE - 1) &
			~(CONFIG_SYS_CACHELINE_SIZE - 1));
	p = UNCACHED_SDRAM(p);

	for (i = 0; i < ndesc; i++)
		fifo[i] = (ath_gmac_desc_t *) p + i;

	return 0;
}

static int ath_gmac_setup_fifos(ath_gmac_mac_t *mac)
{
	int i;

	if (ath_gmac_alloc_fifo(NO_OF_TX_FIFOS, mac->fifo_tx))
		return 1;

	for (i = 0; i < NO_OF_TX_FIFOS; i++) {
		mac->fifo_tx[i]->next_desc = (i == NO_OF_TX_FIFOS - 1) ?
			virt_to_phys(mac->fifo_tx[0]) : virt_to_phys(mac->fifo_tx[i + 1]);
		ath_gmac_tx_own(mac->fifo_tx[i]);
	}

	if (ath_gmac_alloc_fifo(NO_OF_RX_FIFOS, mac->fifo_rx))
		return 1;

	for (i = 0; i < NO_OF_RX_FIFOS; i++) {
		mac->fifo_rx[i]->next_desc = (i == NO_OF_RX_FIFOS - 1) ?
			virt_to_phys(mac->fifo_rx[0]) : virt_to_phys(mac->fifo_rx[i + 1]);
	}

	return (1);
}

static void ath_gmac_halt(struct eth_device *dev)
{
	ath_gmac_mac_t *mac = (ath_gmac_mac_t *)dev->priv;
	ath_gmac_reg_rmw_clear(mac, ATH_MAC_CFG1,(ATH_MAC_CFG1_RX_EN | ATH_MAC_CFG1_TX_EN));
	ath_gmac_reg_wr(mac,ATH_MAC_FIFO_CFG_0,0x1f1f);
	ath_gmac_reg_wr(mac,ATH_DMA_RX_CTRL, 0);
	while (ath_gmac_reg_rd(mac, ATH_DMA_RX_CTRL));
}

#ifdef CONFIG_ATH_NAND_BR

unsigned char *
ath_eth_mac_addr(unsigned char *sectorBuff)
{
	ulong   off, size;
	nand_info_t *nand;
	unsigned char ret;

	/*
	 * caldata partition is of 128k
	 */
	nand = &nand_info[nand_curr_device];
	size = ATH_ETH_MAC_READ_SIZE; /* To read 4k setting size as 4k */

	/*
	 * Get the Offset of Caldata partition
	 */
	off = ath_nand_get_cal_offset(getenv("bootargs"));
	if(off == ATH_CAL_OFF_INVAL) {
		printf("Invalid CAL offset \n");
		return NULL;
	}
	/*
	 * Get the values from flash, and program into the MAC address
	 * registers
	 */
	ret = nand_read(nand, (loff_t)off, &size, (u_char *)sectorBuff);
	printf(" %d bytes %s: %s\n", size,
			"read", ret ? "ERROR" : "OK");
	if(ret != 0 ) {
		return NULL;
	}

	return sectorBuff;
}

#else  /* CONFIG_ATH_NAND_BR */

unsigned char *
ath_gmac_mac_addr_loc(void)
{
	extern flash_info_t flash_info[];

#ifdef BOARDCAL
	/*
	 ** BOARDCAL environmental variable has the address of the cal sector
	 */

	return ((unsigned char *)BOARDCAL);

#else
	/* MAC address is store in the 2nd 4k of last sector */
	return ((unsigned char *)
			(KSEG1ADDR(ATH_SPI_BASE) + (4 * 1024) +
			 flash_info[0].size - (64 * 1024) /* sector_size */ ));
#endif
}

#endif  /* CONFIG_ATH_NAND_BR */

static void ath_gmac_get_ethaddr(struct eth_device *dev)
{
	unsigned char *eeprom;
	unsigned char *mac = dev->enetaddr;
#ifndef CONFIG_ATH_EMULATION

#ifdef CONFIG_ATH_NAND_BR
	unsigned char sectorBuff[ATH_ETH_MAC_READ_SIZE];

	eeprom = ath_eth_mac_addr(sectorBuff);
	if(eeprom == NULL) {
		/* mac address will be set to default mac address */
		mac[0] = 0xff;
	}
	else {
#else  /* CONFIG_ATH_NAND_BR */
		eeprom = ath_gmac_mac_addr_loc();
#endif  /* CONFIG_ATH_NAND_BR */

		if (strcmp(dev->name, "eth0") == 0) {
			memcpy(mac, eeprom, 6);
		} else if (strcmp(dev->name, "eth1") == 0) {
			eeprom += 6;
			memcpy(mac, eeprom, 6);
		} else {
			printf("%s: unknown ethernet device %s\n", __func__, dev->name);
			return;
		}
#ifdef CONFIG_ATH_NAND_BR
	}
#endif  /* CONFIG_ATH_NAND_BR */
	/* Use fixed address if the above address is invalid */
	if (mac[0] != 0x00 || (mac[0] == 0xff && mac[5] == 0xff))
#else
	if (1)
#endif
	{
			mac[0] = 0x00;
			mac[1] = 0x03;
			mac[2] = 0x7f;
			mac[3] = 0x09;
			mac[4] = 0x0b;
			mac[5] = 0xad;
			printf("No valid address in Flash. Using fixed address\n");
		} else {
			printf("Fetching MAC Address from 0x%p\n", __func__, eeprom);
		}
}

void
athr_mgmt_init(void)
{

#ifdef CONFIG_MGMT_INIT
	uint32_t rddata;

	rddata = ath_reg_rd(GPIO_IN_ENABLE3_ADDRESS)&
		~GPIO_IN_ENABLE3_MII_GE1_MDI_MASK;
	rddata |= GPIO_IN_ENABLE3_MII_GE1_MDI_SET(19);
	ath_reg_wr(GPIO_IN_ENABLE3_ADDRESS, rddata);

	ath_reg_rmw_clear(GPIO_OE_ADDRESS, (1 << 19));

	ath_reg_rmw_clear(GPIO_OE_ADDRESS, (1 << 17));


	rddata = ath_reg_rd(GPIO_OUT_FUNCTION4_ADDRESS) &
		~ (GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_MASK |
		GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_MASK);

	rddata |= GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_SET(0x20) |
	GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_SET(0x21);

	ath_reg_wr(GPIO_OUT_FUNCTION4_ADDRESS, rddata);
#endif
	printf ("%s ::done\n",__func__);
}


int ath_gmac_enet_initialize(bd_t * bis)
{
	struct eth_device *dev[CFG_ATH_GMAC_NMACS];
	u32 mask, mac_h, mac_l;
	int i;

	printf("%s...\n", __func__);

	athrs_sgmii_res_cal();

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

		if ((dev[i] = (struct eth_device *) malloc(sizeof (struct eth_device))) == NULL) {
			puts("malloc failed\n");
			return 0;
		}

		if ((ath_gmac_macs[i] = (ath_gmac_mac_t *) malloc(sizeof (ath_gmac_mac_t))) == NULL) {
			puts("malloc failed\n");
			return 0;
		}

		memset(ath_gmac_macs[i], 0, sizeof(ath_gmac_mac_t));
		memset(dev[i], 0, sizeof(struct eth_device));

		sprintf(dev[i]->name, "eth%d", i);
		ath_gmac_get_ethaddr(dev[i]);

		ath_gmac_macs[i]->mac_unit = i;
		ath_gmac_macs[i]->mac_base = i ? ATH_GE1_BASE : ATH_GE0_BASE ;
		ath_gmac_macs[i]->dev = dev[i];

		dev[i]->iobase = 0;
		dev[i]->init = ath_gmac_clean_rx;
		dev[i]->halt = ath_gmac_halt;
		dev[i]->send = ath_gmac_send;
		dev[i]->recv = ath_gmac_recv;
		dev[i]->priv = (void *)ath_gmac_macs[i];
	}

#if !defined(CONFIG_ATH_NAND_BR)
	ath_reg_rmw_set(RST_RESET_ADDRESS,  RST_RESET_ETH_SGMII_ARESET_SET(1));
	udelay(1000 * 100);
	ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_ETH_SGMII_ARESET_SET(1));
	udelay(100);
#endif
	ath_reg_rmw_set(RST_RESET_ADDRESS, RST_RESET_ETH_SGMII_RESET_SET(1) | RST_RESET_EXTERNAL_RESET_SET(1));
	udelay(1000 * 100);
	ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_ETH_SGMII_RESET_SET(1) | RST_RESET_EXTERNAL_RESET_SET(1));
	udelay(1000 * 100);

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

		ath_gmac_reg_rmw_set(ath_gmac_macs[i], ATH_MAC_CFG1, ATH_MAC_CFG1_SOFT_RST
				| ATH_MAC_CFG1_RX_RST | ATH_MAC_CFG1_TX_RST);

		if(!i) {
			mask = (ATH_RESET_GE0_MAC | ATH_RESET_GE1_MAC);

			mask = mask | ATH_RESET_GE0_MDIO | ATH_RESET_GE1_MDIO;

			printf("%s: reset mask:%x \n", __func__, mask);

			ath_reg_rmw_set(RST_RESET_ADDRESS, mask);
			udelay(1000 * 100);

			ath_reg_rmw_clear(RST_RESET_ADDRESS, mask);
			udelay(1000 * 100);

			udelay(10 * 1000);
		}
#if defined(CONFIG_MGMT_INIT) && defined (CONFIG_ATHR_SWITCH_ONLY_MODE) || defined ATH_MDC_GPIO
		if (!i)
			athr_mgmt_init();

		if (ath_gmac_macs[i]->mac_unit == 0)
                        continue;
#endif
		eth_register(dev[i]);
#if(CONFIG_COMMANDS & CFG_CMD_MII)
		miiphy_register(dev[i]->name, ath_gmac_miiphy_read, ath_gmac_miiphy_write);
#endif
		ath_gmac_mii_setup(ath_gmac_macs[i]);

		/* if using header for register configuration, we have to     */
		/* configure s26 register after frame transmission is enabled */

		if (ath_gmac_macs[i]->mac_unit == 0) { /* WAN Phy */
#ifdef  CONFIG_ATHRS17_PHY
			athrs17_reg_init();
#endif

#ifdef CONFIG_VIR_PHY
			printf("VIRPhy reg init \n");
			athr_vir_reg_init();
#endif

		} else {
#ifdef CONFIG_ATHR_8033_PHY
			printf("AR8033 PHY init \n");
			athrs_ar8033_reg_init(NULL);

#endif

#if defined(CONFIG_MGMT_INIT) && defined (CONFIG_ATHR_SWITCH_ONLY_MODE)
			athrs17_reg_init();
#elif defined (CONFIG_ATHRS17_PHY) && !defined(CFG_DUAL_PHY_SUPPORT)
			athrs17_reg_init_wan();
#endif
		}
#ifdef CONFIG_ATHRS_GMAC_SGMII
	/*
	 * MAC unit 1 or drqfn package call sgmii setup.
	 */
	if (i == 1 || is_drqfn())
		athr_gmac_sgmii_setup();
#endif
		ath_gmac_hw_start(ath_gmac_macs[i]);
		ath_gmac_setup_fifos(ath_gmac_macs[i]);

		udelay(100 * 1000);

		{
			unsigned char *mac = dev[i]->enetaddr;

			printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev[i]->name,
					mac[0] & 0xff, mac[1] & 0xff, mac[2] & 0xff,
					mac[3] & 0xff, mac[4] & 0xff, mac[5] & 0xff);
		}
		mac_l = (dev[i]->enetaddr[4] << 8) | (dev[i]->enetaddr[5]);
		mac_h = (dev[i]->enetaddr[0] << 24) | (dev[i]->enetaddr[1] << 16) |
			(dev[i]->enetaddr[2] << 8) | (dev[i]->enetaddr[3] << 0);

		ath_gmac_reg_wr(ath_gmac_macs[i], ATH_GE_MAC_ADDR1, mac_l);
		ath_gmac_reg_wr(ath_gmac_macs[i], ATH_GE_MAC_ADDR2, mac_h);


	ath_gmac_phy_setup(ath_gmac_macs[i]->mac_unit);
		printf("%s up\n",dev[i]->name);
	}

	return 1;
}

#if (CONFIG_COMMANDS & CFG_CMD_MII)
int
ath_gmac_miiphy_read(char *devname, uint32_t phy_addr, uint8_t reg, uint16_t *data)
{
	ath_gmac_mac_t *mac   = ath_gmac_name2mac(devname);
	uint16_t      addr  = (phy_addr << ATH_ADDR_SHIFT) | reg, val;
	volatile int           rddata;
	uint16_t      ii = 0xFFFF;

	/*
	 * Check for previous transactions are complete. Added to avoid
	 * race condition while running at higher frequencies.
	 */
	do
	{
		udelay(5);
		rddata = ath_gmac_reg_rd(mac, ATH_MII_MGMT_IND) & 0x1;
	}while(rddata && --ii);

	if (ii == 0)
		printf("ERROR:%s:%d transaction failed\n",__func__,__LINE__);


	ath_gmac_reg_wr(mac, ATH_MII_MGMT_CMD, 0x0);
	ath_gmac_reg_wr(mac, ATH_MII_MGMT_ADDRESS, addr);
	ath_gmac_reg_wr(mac, ATH_MII_MGMT_CMD, ATH_MGMT_CMD_READ);

	do
	{
		udelay(5);
		rddata = ath_gmac_reg_rd(mac, ATH_MII_MGMT_IND) & 0x1;
	}while(rddata && --ii);

	if(ii==0)
		printf("Error!!! Leave ath_gmac_miiphy_read without polling correct status!\n");

	val = ath_gmac_reg_rd(mac, ATH_MII_MGMT_STATUS);
	ath_gmac_reg_wr(mac, ATH_MII_MGMT_CMD, 0x0);

	if (data != NULL)
		*data = val;
	return val;
}

int
ath_gmac_miiphy_write(char *devname, uint32_t phy_addr, uint8_t reg, uint16_t data)
{
	ath_gmac_mac_t *mac   = ath_gmac_name2mac(devname);
	uint16_t addr  = (phy_addr << ATH_ADDR_SHIFT) | reg;
	volatile int rddata;
	uint16_t ii = 0xFFFF;


	/*
	 * Check for previous transactions are complete. Added to avoid
	 * race condition while running at higher frequencies.
	 */
	do {
		udelay(5);
		rddata = ath_gmac_reg_rd(mac, ATH_MII_MGMT_IND) & 0x1;
	} while (rddata && --ii);

	if (ii == 0)
		printf("ERROR:%s:%d transaction failed\n",__func__,__LINE__);

	ath_gmac_reg_wr(mac, ATH_MII_MGMT_ADDRESS, addr);
	ath_gmac_reg_wr(mac, ATH_MII_MGMT_CTRL, data);

	do {
		rddata = ath_gmac_reg_rd(mac, ATH_MII_MGMT_IND) & 0x1;
	} while (rddata && --ii);

	if (ii == 0)
		printf("Error!!! Leave ath_gmac_miiphy_write without polling correct status!\n");

	return 0;
}
#endif		/* CONFIG_COMMANDS & CFG_CMD_MII */

int cpu_eth_init(bd_t *bis)
{
	ath_gmac_enet_initialize(bis);
	return 0;
}

