#include <common.h>
#include <config.h>
#include <asm/arch/hardware.h>
#include <asm/byteorder.h>
//#include <malloc.h>
#include <net.h>
#include <command.h>
#include <miiphy.h>
#include <asm/arch/clkcore_c2000.h>
#include <asm/arch/gpio_c2000.h>
#include "c2000_eth.h"
#ifdef CONFIG_AR8328_SWITCH
#include "ar8328.h"
#endif

struct gemac_s gem_info[] = {
        /* PORT_0 configuration */
        {
                /* GEMAC config */
                .gemac_mode = RGMII,
                .gemac_speed = SPEED_1000M,
                .gemac_duplex = DUPLEX_FULL,
                .flags = EMAC0_FLAGS,

                /* phy iface */
                .phy_reg_index = EMAC_PORT_0,
                .phy_address = EMAC0_PHY_ADDR,
        },
        /* PORT_1 configuration */
        {
                /* GEMAC config */
                .gemac_mode = RGMII,
                .gemac_speed = SPEED_1000M,
                .gemac_duplex = DUPLEX_FULL,
                .flags = EMAC1_FLAGS,

                /* phy iface */
                .phy_reg_index = EMAC_PORT_0,
                .phy_address = EMAC1_PHY_ADDR,
        },

        /* PORT_2 configuration */
        {
                /* GEMAC config */
                .gemac_mode = RGMII,
                .gemac_speed = SPEED_1000M,
                .gemac_duplex = DUPLEX_FULL,
                .flags = EMAC2_FLAGS,

                /* phy iface */
                .phy_reg_index = EMAC_PORT_0,
                .phy_address = 0,
        },
};

#define MAX_GEMACS      3

static struct c2000_eth_dev *gemac_list[MAX_GEMACS];

/********************************************************************
 * Helper functions for phy read/write
 *******************************************************************/

/* Max MII register/address (we support) */
#define MII_REGISTER_MAX  31
#define MII_ADDRESS_MAX   31

#define MDIO_TIMEOUT    5000

/********************************************************************
 * gem_phy_man_rd :
 *      Performs phy management read operation.
 *******************************************************************/
static int gem_phy_man_rd(struct c2000_eth_dev *priv, u32 phy_addr, u32 phy_reg)
{
        u32 write_data;

        write_data = 0x60020000 | ( (phy_addr & (u32) 0x1f) << 23) | ( (phy_reg & (u32) 0x1f) << 18); // read_op
        writel(write_data, priv->phyregisters + EMAC_PHY_MANAGEMENT);

        return 0;
}

static int gem_phy_man_wr(struct c2000_eth_dev *priv, u32 phy_addr, u32 phy_reg, u32 val)
{
        u32 write_data;

        write_data =  0x50020000 | ( (phy_addr & (u32) 0x1f) << 23) | ( (phy_reg & (u32) 0x1f) << 18) | (val & (u32) 0xffff); // write_op
        writel(write_data, priv->phyregisters + EMAC_PHY_MANAGEMENT);

        return 0;
}

/** gem_phy_man_data
 *      Read the data section of phy management register.
 *    After a successful read opeeration the data will be stored in
 *    in this register in lower 16bits.
 */
static u32 gem_phy_man_data(struct c2000_eth_dev *priv)
{
        u32 value;

        value = readl(priv->phyregisters + EMAC_PHY_MANAGEMENT) & 0xFFFF;
        return value;
}

#define EMAC_PHY_IDLE   (1 << 2)

static int gem_phy_man_idle(struct c2000_eth_dev *priv)
{
        u32 value;

        value = readl(priv->phyregisters + EMAC_NETWORK_STATUS);
        return ((value & EMAC_PHY_IDLE) == EMAC_PHY_IDLE);
}

static int gem_phy_timeout(struct c2000_eth_dev *priv, int timeout)
{
        while(!gem_phy_man_idle(priv)) {

                if (timeout-- <= 0) {
                        printf("Phy MDIO read/write timeout\n");
                        return -1;
                }

                //udelay(1);
        }
        return 0;
}

static struct c2000_eth_dev* get_gemac(char *devname)
{
        int i;

        for (i = 0; i < MAX_GEMACS; i++) {
                if (!strcmp(gemac_list[i]->dev->name, devname))
                        return gemac_list[i];
        }

        return NULL;
}


/** PHY read function
 * Reads a 16bit value from a MII register
 *
 * @param[in] mdev              Pointer to MII device structure
 * @param[in] phy_addr
 * @param[in] phy_reg
 *
 * @return  16bit value on success, a negivie value (-1) on error
 */
static int c2000_phy_read(char *devname, unsigned char phy_addr, unsigned char phy_reg, unsigned short *value)
{
        struct c2000_eth_dev *priv = get_gemac(devname);

        if (!priv) {
                printf("Unknown device %s\n", devname);
                return -1;
        }

        if ((phy_addr > MII_ADDRESS_MAX) || (phy_reg > MII_REGISTER_MAX))
                return -1;

        gem_phy_man_rd(priv, phy_addr, phy_reg);
        if (gem_phy_timeout(priv, MDIO_TIMEOUT))
                return -1;

        *value = gem_phy_man_data(priv);

        dprint("%s: Addr: %d, Reg: %d, Val: 0x%x\n",
                                              __func__, phy_addr, phy_reg, *value);

        return 0;
}

/** PHY write function
 * Writes a 16bit value to a MII register
 *
 * @param[in] mdev              Pointer to MII device structure
 * @param[in] phy_addr
 * @param[in] phy_reg
 * @param[in] value     Value to be written to Phy
 *
 * @return              On success returns 0, a negative value (-1) on error
 */
static int c2000_phy_write(char *devname, unsigned char phy_addr, unsigned char phy_reg, unsigned short value)
{
        struct c2000_eth_dev *priv = get_gemac(devname);

        if (!priv) {
                printf("Unknown device %s\n", devname);
                return -1;
        }
        if ((phy_addr > MII_ADDRESS_MAX) || (phy_reg > MII_REGISTER_MAX))
                return -1;

        gem_phy_man_wr(priv, phy_addr, phy_reg, value);
        if (gem_phy_timeout(priv, MDIO_TIMEOUT))
                return -1;

        dprint("%s: Addr: %d, Reg: %d, Val: 0x%x\n",
                                              __func__, phy_addr, phy_reg, value);

        return 0;
}

/** MAC Address converter
 * Convert standard byte style ethernet address to format compatible with MAC.
 *
 * @param[in] enet_byte_addr    Pointer to the mac address in byte format
 * @param[out] Pointer to MAC_ADDR structure
 *
 * @return      0 on success, -1 on failure
 */
int gemac_enet_addr_byte_mac(u8 *enet_byte_addr, MAC_ADDR *enet_addr)
{
    if ((enet_byte_addr == NULL) || (enet_addr == NULL))
    {
        return -1;
    }
    else
    {
        enet_addr->bottom = enet_byte_addr[0] |
                            (enet_byte_addr[1] << 8) |
                            (enet_byte_addr[2] << 16) |
                            (enet_byte_addr[3] << 24);
        enet_addr->top = enet_byte_addr[4] |
                         (enet_byte_addr[5] << 8);
        return 0;
    }
}

/** Configures ethernet address to GEMAC ADDR1 location.
 *
 * @param[in] edev      Pointer to the eth device structure
 * @param[in] addr      Pointer to ethernet address in byte order
 *
 * @return  0 on success (always success)
 */
static int c2000_set_ethaddr(struct eth_device *dev, u8 *enet_byte_addr)
{
        struct c2000_eth_dev *priv = (struct c2000_eth_dev *)dev->priv;
        MAC_ADDR enet_address = {0x0, 0x0};


        gemac_enet_addr_byte_mac(enet_byte_addr, &enet_address);
        gemac_set_laddr1(priv->gem->gemac_base, &enet_address);

        return 0;
}

/** Get/Read configured ethernet mac address from GEMAC.
 *
 * @param[in] edev      Pointer to eth device structure
 * @param[out] addr     Pointer to ethernet address to be copied
 *
 * @return      0 on success, always success.
 */
static int c2000_get_ethaddr(struct eth_device *edev, unsigned char *addr)
{
        struct c2000_eth_dev *priv = (struct c2000_eth_dev *)edev->priv;
        MAC_ADDR enet_address = {0x0, 0x0};
        u16 *p = (u16 *)addr;

        enet_address = gem_get_laddr1(priv->gem->gemac_base);
        p[0] = enet_address.bottom & 0xffff;
        p[1] = (enet_address.bottom >> 16) & 0xffff;
        p[2] = enet_address.top & 0xffff;

        return 0;
}


/** Stops or Disables GEMAC pointing to this eth iface.
 *
 * @param[in]   edev    Pointer to eth device structure.
 *
 * @return      none
 */
static void c2000_eth_halt(struct eth_device *edev)
{
        struct c2000_eth_dev *priv = (struct c2000_eth_dev *)edev->priv;

//        printf("%s:\n",__func__);

        gemac_disable(priv->gem->gemac_base);

        gpi_disable(priv->gem->egpi_base);

        return;
}

#ifdef CONFIG_BOARD_C2KASIC
int c2000_eth_board_init(char *devname, int eth_port)
{
        //eth0 port is chosen as criteria for bringingup out of reset because
        //all MDIO access can happen through EMAC0 and without bringing eth0 first
        //no PHY configuration can happen and no point in removing reset without eth0
        if(eth_port != 0)
                return 0;

//        printf("%s: Bringing PHY out of reset\n",__func__);
        //Bring all PHYs out of reset. The correct way is to assert, deassert and re-assert the GPIO reset signal
        //with delay in between
        writel(readl(COMCERTO_GPIO_OE_REG) | GPIO_3, COMCERTO_GPIO_OE_REG);

        writel(readl(COMCERTO_GPIO_OUTPUT_REG) | GPIO_3, COMCERTO_GPIO_OUTPUT_REG);
        udelay(100000);
        writel(readl(COMCERTO_GPIO_OUTPUT_REG) & ~GPIO_3, COMCERTO_GPIO_OUTPUT_REG);
        udelay(100000);
        writel(readl(COMCERTO_GPIO_OUTPUT_REG) | GPIO_3, COMCERTO_GPIO_OUTPUT_REG);
        udelay(100000);

}
#else
int c2000_eth_board_init(char *devname, int eth_port)
{
        //eth0 port is chosen as criteria for bringingup out of reset because
        //all MDIO access can happen through EMAC0 and without bringing eth0 first
        //no Switch/PHY configuration can happen and no point in removing reset without eth0
        if(eth_port == 0)
        {

                //Bring AR8327 switch out of reset. Toggle reset
                writel(readl(COMCERTO_GPIO_OE_REG) | GPIO_27, COMCERTO_GPIO_OE_REG);
                writel(readl(COMCERTO_GPIO_OUTPUT_REG) | GPIO_27, COMCERTO_GPIO_OUTPUT_REG);
                udelay(10000);
                writel(readl(COMCERTO_GPIO_OUTPUT_REG) & ~GPIO_27, COMCERTO_GPIO_OUTPUT_REG);
                udelay(10000);
                writel(readl(COMCERTO_GPIO_OUTPUT_REG) | GPIO_27, COMCERTO_GPIO_OUTPUT_REG);
                udelay(10000);


                //AR8327 Switch init
                athrs17_init(devname);

                //AR8327 WAN PHY4 init
                athrs17_phy_setup(devname,EMAC0_PHY_ADDR);
        }
        else
        {
                //AR8327 LAN PHYs init
                athrs17_phy_setup(devname,EMAC1_PHY_ADDR);
        }

}
#endif

static int c2000_eth_init(struct eth_device *dev, bd_t * bd)
{
        struct c2000_eth_dev *priv = (struct c2000_eth_dev *)dev->priv;
        struct gemac_s *gem = priv->gem;
	u32 phyaddr;

//	printf("## %s\n",__func__);

        /* GEMAC init */
        pfe_gemac_init(gem->gemac_base, gem->gemac_mode, gem->gemac_speed, gem->gemac_duplex);

        /* set ethernet mac address */
        c2000_set_ethaddr(dev, dev->enetaddr);

	phyaddr = gem_info[priv->gemac_port].phy_address;

        if (!(gem->flags & GEMAC_NO_PHY) && (gem->gemac_mode == RGMII) )
        {
                miiphy_enable_rgmii_rx_delay(dev->name, phyaddr);
                miiphy_enable_rgmii_tx_delay(dev->name, phyaddr);
        }


        /* Re-negotiate speed and duplex */
        if (!(gem->flags & GEMAC_NO_PHY))
        {
                int speed = gem->gemac_speed;
                int duplex = gem->gemac_duplex;

		miiphy_speed_duplex(dev->name, phyaddr, &speed, &duplex);

                switch (speed)
                {
                        case _10BASET:
                                speed = SPEED_10M;
                                break;

                        case _100BASET:
                                speed = SPEED_100M;
                                break;

                        case _1000BASET:
                                speed = SPEED_1000M;
                                break;
                }

                duplex = (duplex == HALF) ? DUPLEX_HALF:DUPLEX_FULL;
                gemac_set_speed(gem->gemac_base, speed);
                gemac_set_duplex(gem->gemac_base, duplex);
        }

        /* Enable GPI */
        gpi_enable(priv->gem->egpi_base);

        /* Enable GEMAC for tx and rx */
        gemac_enable(priv->gem->gemac_base);
	
        return 0;
}

static int c2000_eth_send(struct eth_device *dev, volatile void *data, int length)
{
        struct c2000_eth_dev *priv = (struct c2000_eth_dev *)dev->priv;

        int rc;
        uint64_t tx_tmo;
	int i;

        rc = pfe_send(priv->gemac_port, data, length);

        if (rc < 0) {
                printf("Tx Q full\n");
                return 0;
        }

        while (1) {
                rc = pfe_tx_done();
                if (rc == 0)
                        break;
		
		udelay(100);
		i++;
		if(i == 30000)
			printf("Tx timeout, send failed\n");
			break;

	}

	return 0;
}

static int c2000_eth_recv(struct eth_device *dev)
{
        struct c2000_eth_dev *priv = (struct c2000_eth_dev *)dev->priv;
        u32 pkt_buf;
        int len;
        int phy_port;

        len = pfe_recv(&pkt_buf, &phy_port);

        if (len < 0)
                return 0; //no packet in rx

        dprint("Rx pkt: pkt_buf(%08x), phy_port(%d), len(%d)\n", pkt_buf, phy_port, len);
        if (phy_port != priv->gemac_port)  {
                printf("Rx pkt not on expected port\n");
                return 0;
        }

	// Pass the packet up to the protocol layers.
	NetReceive((unsigned char *)pkt_buf, len);


	return 0;
}

int c2000_gemac_initialize(bd_t * bis, int index, char *devname)
{
        struct eth_device *dev;
        struct c2000_eth_dev *priv;
        struct pfe *pfe;
	int i;
	
        //Bring HFE and GEMTX out of reset
        writel(0x0, HFE_RESET);
        writel(0x0, GEMTX_RESET);

        dev = (struct eth_device *)malloc(sizeof(struct eth_device));
        if (!dev)
                return -1;

        memset(dev, 0, sizeof(struct eth_device));

        priv = (struct c2000_eth_dev *)malloc(sizeof(struct c2000_eth_dev));
        if (!priv)
                return -1;

        gemac_list[index] = priv;
	priv->gemac_port = index;
        priv->gem = &gem_info[priv->gemac_port];
        priv->dev = dev;

        pfe = &priv->pfe;

        pfe->cbus_baseaddr = (void *)COMCERTO_AXI_HFE_CFG_BASE;
        pfe->ddr_baseaddr = (void *)CONFIG_DDR_BASEADDR;
        pfe->ddr_phys_baseaddr = (unsigned long)CONFIG_DDR_PHYS_BASEADDR;

	sprintf(dev->name, devname);
        dev->priv = priv;
        dev->init = c2000_eth_init;
        dev->halt = c2000_eth_halt;
        dev->send = c2000_eth_send;
        dev->recv = c2000_eth_recv;

        /* Tell u-boot to get the addr from the env */
        for (i = 0; i < 6; i++)
                dev->enetaddr[i] = 0;


        switch(priv->gemac_port)  {
                case EMAC_PORT_0:
                default:
                        priv->gem->gemac_base = EMAC1_BASE_ADDR;
                        priv->gem->egpi_base = EGPI1_BASE_ADDR;
                break;
                case EMAC_PORT_1:
                        priv->gem->gemac_base = EMAC2_BASE_ADDR;
                        priv->gem->egpi_base = EGPI2_BASE_ADDR;
                break;
                case EMAC_PORT_2:
                        priv->gem->gemac_base = EMAC3_BASE_ADDR;
                        priv->gem->egpi_base = EGPI3_BASE_ADDR;
                break;
        }

        pfe_probe(pfe);
        priv->phyregisters = (void *)gem_info[gem_info[priv->gemac_port].phy_reg_index].gemac_base;

        if(priv->gemac_port == 0)
        {
                gemac_set_mdc_div(priv->gem->gemac_base, MDC_DIV_96);
                gemac_enable_mdio(priv->gem->gemac_base);
                miiphy_register(dev->name, c2000_phy_read, c2000_phy_write);
        }

	c2000_eth_board_init(dev->name, priv->gemac_port);
	
        eth_register(dev);
}
