/*
 * comcerto_gem.c
 * Mindspeed Comcerto GEMAC driver
 *
 * From TSEC.c 
 *
 * This software may be used and distributed according to the
 * terms of the GNU Public License, Version 2, incorporated
 * herein by reference.
 *
 * Copyright 2004 Freescale Semiconductor.
 * (C) Copyright 2003, Motorola, Inc.
 * author Andy Fleming
 *
 */

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

#if defined(CONFIG_COMCERTO_GEMAC)
#include "comcerto_gem.h"

DECLARE_GLOBAL_DATA_PTR;

static struct gemac_info_struct gemac_info[] = {
#if defined(CONFIG_COMCERTO_900) || defined(CONFIG_COMCERTO_100)
	{GEMAC_BASEADDR, MMGEM0_START, GEMAC0_PHY_ADDR, GEMAC0_CONFIG, GEMAC0_MODE, GEMAC0_PHY_FLAGS, GEMAC0_PHYIDX},
#elif defined(CONFIG_COMCERTO_1000)
	{GEMAC_BASEADDR, GEMAC0_PHY_ADDR, GEMAC0_CONFIG, GEMAC0_MODE, GEMAC0_PHY_FLAGS, GEMAC0_PHYIDX},
#else
	{0, 0, 0},
#endif
#if defined(CONFIG_COMCERTO_100)
	{GEMAC1_BASEADDR, MMGEM1_START, GEMAC1_PHY_ADDR, GEMAC1_CONFIG, GEMAC1_MODE, GEMAC1_PHY_FLAGS, GEMAC1_PHYIDX},
#elif defined(CONFIG_COMCERTO_1000)
	{GEMAC1_BASEADDR, GEMAC1_PHY_ADDR, GEMAC1_CONFIG, GEMAC1_MODE, GEMAC1_PHY_FLAGS, GEMAC1_PHYIDX},
#else
	{0, 0, 0},
#endif
};

#define MAX_GEMACS	2

static struct gemac_dev *gemac_list[MAX_GEMACS];

#define NUM_RX_DESC		16
#define MAX_RX_BUFF_SIZE	2048

static u32 rx_next;

#if defined(CONFIG_COMCERTO_100)
static u8 rx_ring_data_buff[NUM_RX_DESC * MAX_RX_BUFF_SIZE] __attribute((aligned(4)));
static struct fdesc rx_ring[NUM_RX_DESC] __attribute((aligned(16)));
static struct fdesc tx_fdesc __attribute((aligned(16)));
#else
static u8 rx_ring_data_buff[NUM_RX_DESC * MAX_RX_BUFF_SIZE] __attribute((aligned(16)));
static struct rx_desc rx_ring[NUM_RX_DESC] __attribute((aligned(16)));
static struct tx_desc tx_fdesc[2] __attribute((aligned(8)));
#endif

/* Initialize device structure. Returns success if PHY
 * initialization succeeded (i.e. if it recognizes the PHY)
 */

static void default_speed_duplex(struct gemac_dev *gemac, int *speed, int *duplex)
{
	switch (gemac->mode & GEM_CONF_SPEED_MASK) {
	case GEM_CONF_SPEED_GEM_10M:
		*speed = _10BASET;
		break;

	case GEM_CONF_SPEED_GEM_100M:
		*speed = _100BASET;
		break;

	case GEM_CONF_SPEED_GEM_1G:
	default:
		*speed = _1000BASET;
		break;
	}

	if (gemac->mode & GEM_CONF_DUPLEX_GEM_FULL)
		*duplex = FULL;
	else
		*duplex = HALF;
}

static void gemt_reinit(struct gemac_dev *gemac, int speed, int duplex)
{
	switch (speed) {
	case _1000BASET:
		printf("PHY 1000Mbit ");
		gem_set_speed(gemac, SPEED_1000M);
		break;

	case _100BASET:
		printf("PHY 100Mbit ");
		gem_set_speed(gemac, SPEED_100M);
		break;

	default:
	case _10BASET:
		printf("PHY 10Mbit ");
		gem_set_speed(gemac, SPEED_10M);
		break;
	}

	switch (duplex) {
	case FULL:
		printf("FD\n");
		gem_full_duplex(gemac);
		break;

	default:
	case HALF:
		printf("HD\n");
		gem_half_duplex(gemac);
		break;
	}
}

#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)

static int gemt_PHY_timeout(struct gemac_dev *gemac, int timeout)
{
	while (!gem_phy_man_idle(gemac)) {

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

		udelay(1);
	}

	return 0;
}

static struct gemac_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;
}

static int comcerto_miiphy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
{
	struct gemac_dev *gemac = get_gemac(devname);

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

	if ((addr > 31) || (reg > 31))
		return -1;

	gem_phy_man_wr(gemac, addr, reg, value);
	if (gemt_PHY_timeout(gemac, MDIO_TIMEOUT))
		return -1;

	return 0;
}

static int comcerto_miiphy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
{
	struct gemac_dev *gemac = get_gemac(devname);

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

	if ((addr > 31) || (reg > 31))
		return -1;

	gem_phy_man_rd(gemac, addr, reg);
	if (gemt_PHY_timeout(gemac, MDIO_TIMEOUT))
		return -1;

	*value = gem_phy_man_data(gemac);

	return 0;
}

/*=============================================================================
 *
 * NAME: gemt_config_PHY
 * 
 * PARAMETERS:   
 *   net_device *dev    -INOUT
 *
 * DESCRIPTION   
 *   Reconfigure PHY
 *   This function will set up the PHY device.  This is a required external
 *   support routine.
 *   The parameters set up the maximum desired advertised ability for the 
 *   device.
 *   TODO - read back negotiated ability and set MAC appropriately.
 *          duplex configuration to be done.
 *
 * ASSUMPTIONS
 *   None
 *
 * SIDE EFFECTS / STATIC DATA USE
 *   None
 *
 * RETURNS:      
 *   int        0       -successful
 *              <0      -failed
 *
 *===========================================================================*/
static int gemt_config_PHY(struct gemac_dev *gemac, int phy_addr, MAC_SPEED speed, u8 duplex)
{
	unsigned short anar, bmcr, btcr;

	if (gemac->phyflags & GEMAC_M88E1111_PHY_RGMII_ADD_DELAY) {
		unsigned short tmp;

		if (!miiphy_read(gemac->dev->name, phy_addr, 20, &tmp)) {
			tmp |= 0x82;
			miiphy_write(gemac->dev->name, phy_addr, 20, tmp);
		}
	}

	if (miiphy_reset(gemac->dev->name, gemac->phyaddr))
		return -1;

	switch (speed) {
	case _10BASET:
		if (duplex == FULL) {
			anar = PHY_ANAR_10FD | PHY_ANAR_10;
			btcr = 0x0;
			bmcr = PHY_BMCR_DPLX | PHY_BMCR_10_MBPS;
		} else {
			anar = PHY_ANAR_10;
			btcr = 0x0;
			bmcr = PHY_BMCR_10_MBPS;
		}

		break;

	case _100BASET:
	default:
		if (duplex == FULL) {
			anar = PHY_ANAR_TXFD | PHY_ANAR_TX | PHY_ANAR_10FD | PHY_ANAR_10;
			btcr = 0x0;
			bmcr = PHY_BMCR_DPLX | PHY_BMCR_100_MBPS;
		} else {
			anar = PHY_ANAR_TX | PHY_ANAR_10;
			btcr = 0x0;
			bmcr = PHY_BMCR_100_MBPS;
		}

		break;

	case _1000BASET:
		if (duplex == FULL) {
			anar = PHY_ANAR_TXFD | PHY_ANAR_TX | PHY_ANAR_10FD | PHY_ANAR_10;
			btcr = PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD;
			bmcr = PHY_BMCR_DPLX | PHY_BMCR_1000_MBPS;
		} else {
			anar = PHY_ANAR_TX | PHY_ANAR_10;
			btcr = PHY_1000BTCR_1000HD;
			bmcr = PHY_BMCR_1000_MBPS;
		}

		break;
	}

	if (gemac->phyflags & GEMAC_PHY_AUTONEG) {
		if (miiphy_write(gemac->dev->name, phy_addr, PHY_ANAR, anar | PHY_ANAR_PSB_802_3))
			return -1;

		if (miiphy_supports_1000base_t(gemac->dev->name, phy_addr)) {
			if (miiphy_write(gemac->dev->name, phy_addr, PHY_1000BTCR, btcr))
				return -1;
		}

		if (miiphy_write(gemac->dev->name, phy_addr, PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG | bmcr))
			return -1;
	} else {
		if (miiphy_write(gemac->dev->name, phy_addr, PHY_BMCR, bmcr))
			return -1;
	}

	return 0;
}

#endif /* defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) */

/*=============================================================================
 *
 * NAME: gemt_reset_gem
 * 
 * PARAMETERS:   
 *   net_device *dev    -INOUT
 *
 * DESCRIPTION   
 *   Reset MAC hardware
 *   This function will reset MAC hardware after stop the MAC for both 
 *   transmission and reception.
 *
 * ASSUMPTIONS
 *   None
 *
 * SIDE EFFECTS / STATIC DATA USE
 *   None
 *
 * RETURNS:      
 *   None
 *
 *===========================================================================*/
static void gemt_reset_gem(struct gemac_dev *gemac)
{
	gem_abort_tx(gemac);
	gem_disable_rx(gemac);

	gem_mask_irq(gemac, GEM_IRQ_ALL);
	gem_get_irq_stat(gemac);

	if (gem_reset(gemac) != 0)
		printf("Failed to reset device!\n");
}

#if defined(CONFIG_COMCERTO_100)
static void gemac_rx_ring_init(struct gemac_dev *gemac)
{
	u32 i;
	u8 *pU8 = rx_ring_data_buff;

	for (i = 0; i < NUM_RX_DESC - 1; i++) {
		rx_ring[i].next = (void *)(__cpu_to_le32((u32)&(rx_ring[i + 1])));
		rx_ring[i].system = __cpu_to_le32(i);
		rx_ring[i].fstatus = __cpu_to_le32(0);
		rx_ring[i].fcontrol = __cpu_to_le32(IDMA_FCONTROL_FREADY);
		rx_ring[i].bdesc.bptr = (volatile u8 *)(__cpu_to_le32((u32)pU8));
		rx_ring[i].bdesc.bcontrol = __cpu_to_le32(0);
		pU8 += MAX_RX_BUFF_SIZE;
	}

	rx_ring[i].next = (void *)(__cpu_to_le32((u32)&(rx_ring[0])));
	rx_ring[i].system = __cpu_to_le32(i);
	rx_ring[i].fstatus = __cpu_to_le32(0);
	rx_ring[i].fcontrol = __cpu_to_le32(0);
	rx_ring[i].bdesc.bptr = (volatile u8 *)(__cpu_to_le32((u32)pU8));
	rx_ring[i].bdesc.bcontrol = __cpu_to_le32(0);

	rx_next = 0;
}

static int gemac_send(struct eth_device *dev, volatile void *packet, int length)
{
	struct gemac_dev *gemac = (struct gemac_dev *)dev->priv;
	int i;

	if (length <= 0) {
		printf("Comcerto_Emac: bad packet size: %d\n", length);
		return (-1);
	}

	memset(&tx_fdesc, 0, sizeof(struct fdesc));

	// build the tx frame descriptor here
	tx_fdesc.fcontrol = __cpu_to_le32(IDMA_FCONTROL_FREADY | IDMA_FCONTROL_FLAST);
	tx_fdesc.fstatus = __cpu_to_le32(0);
	tx_fdesc.bdesc.bptr = (volatile u8 *)(__cpu_to_le32((u32)((u8 *)packet)));
	tx_fdesc.bdesc.bcontrol = __cpu_to_le32(length | IDMA_BCONTROL_BLAST);

	// Check if DMA Stopped
	if (!(*(volatile u32 *)(gemac->idma_baseaddr + MMEM_START) & __cpu_to_le32(IDMA_START))) {
		*(volatile u32 *)(gemac->idma_baseaddr + MMEM_HEAD) = __cpu_to_le32((u32) &tx_fdesc);
		*(volatile u32 *)(gemac->idma_baseaddr + MMEM_START) |= __cpu_to_le32(IDMA_START);
	} else {
		printf("Emac: tx EDMA busy!\n");
		return (-1);
	}

	i = 0;
	while ((tx_fdesc.fstatus & __cpu_to_le32(IDMA_FSTATUS_FRAME_DONE_MASK)) == 0) {
		udelay(100);
		i++;
		if (i == 50000) {
			printf("Emac: tx timed out!\n");
			return (-1);
		}
	}

	if (*(volatile u32 *)(gemac->idma_baseaddr + MMEM_START) & __cpu_to_le32(IDMA_START)) {
		printf("Error! Emac: tx did not stop after sending a packet!\n");
	}

	return (length);
}

static int gemac_recv(struct eth_device *dev)
{
	struct gemac_dev *gemac = (struct gemac_dev *)dev->priv;
	int rx_prev;
	int length;
	int total_length = 0;

	// loop thru rx FDescs
	while (1) {
		if ((rx_ring[rx_next].fstatus & __cpu_to_le32(IDMA_FSTATUS_FRAME_DONE_MASK)) == 0)
			break;

		// mark rx_next not usable
		rx_ring[rx_next].fcontrol = __cpu_to_le32(0);

		length = __le32_to_cpu(rx_ring[rx_next].bdesc.bcontrol) & 0x0000ffff;
		if (length > MAX_RX_BUFF_SIZE) {
			printf("Comcerto_Emac: frame too big (%d bytes)!\n", length);
			length = MAX_RX_BUFF_SIZE;
		}

		// Pass the packet up to the protocol layers.
                NetReceive((volatile uchar *)(__le32_to_cpu((u32)(rx_ring[rx_next].bdesc.bptr))), length);
		total_length += length;

		// rx_prev can be used now
		if (rx_next == 0)
			rx_prev = NUM_RX_DESC - 1;
		else
			rx_prev = rx_next - 1;

		rx_ring[rx_prev].fstatus = __cpu_to_le32(0);
		rx_ring[rx_prev].fcontrol = __cpu_to_le32(IDMA_FCONTROL_FREADY);

		rx_next++;
		if (rx_next == NUM_RX_DESC)
			rx_next = 0;
	}

	// Check if DMA Stopped
	// if RX is stopped, restart
	if (!(*(volatile u32 *)(gemac->idma_baseaddr + EMMM_START) & __cpu_to_le32(IDMA_START))) {
		*(volatile u32 *)(gemac->idma_baseaddr + EMMM_HEAD) = __cpu_to_le32((u32) (&(rx_ring[rx_next])));
		*(volatile u32 *)(gemac->idma_baseaddr + EMMM_START) |= __cpu_to_le32(IDMA_START);
	}

	return (total_length);
}

/* Stop the interface */
static void gemac_halt(struct eth_device *dev)
{
	struct gemac_dev *gemac = (struct gemac_dev *)dev->priv;

	*(volatile u32 *)(gemac->idma_baseaddr + MMEM_SOFT_RESET) = __cpu_to_le32(1);
	*(volatile u32 *)(gemac->idma_baseaddr + EMMM_SOFT_RESET) = __cpu_to_le32(1);

	gem_stop_tx(gemac);
	gem_disable_rx(gemac);
}

#else
static void gemac_rx_ring_init(struct gemac_dev *gemac)
{
	u8 *pU8;
	int i;

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

	memset(rx_ring, 0, NUM_RX_DESC * sizeof(struct rx_desc));
	pU8 = rx_ring_data_buff;

	for (i = 0; i < NUM_RX_DESC - 1; i++) {
		rx_ring[i].data = (volatile u8 *)(__cpu_to_le32((u32)pU8));
		pU8 += MAX_RX_BUFF_SIZE;
	}

	rx_ring[i].data = (volatile u8 *)(__cpu_to_le32((u32)pU8));
	rx_ring[i].status |= __cpu_to_le32(GEMRX_WRAP);	// last descriptor in the list
	rx_next = 0;
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_RX_QPTR) = __cpu_to_le32((u32)rx_ring);
}

static int gemac_send(struct eth_device *dev, volatile void *packet, int length)
{
	struct gemac_dev *gemac = (struct gemac_dev *)dev->priv;
	int i, rc = -1;

	if (length <= 0) {
		printf("Comcerto_Emac: bad packet size: %d\n", length);
		return (-1);
	}

	// build the tx frame descriptor here
	memset(&tx_fdesc, 0, 2 * sizeof(struct tx_desc));

	tx_fdesc[0].ctl |= __cpu_to_le32(TX_DESC_WORD1_LAST | TX_DESC_WORD1_FCS);
	tx_fdesc[0].data = (volatile u8 *)(__cpu_to_le32((u32)packet));
	tx_fdesc[0].ctl |= __cpu_to_le32(length & TX_DESC_WORD1_LEGTH_MASK);
	tx_fdesc[1].ctl |= __cpu_to_le32(TX_DESC_WORD1_WRAP | TX_DESC_WORD1_USED);

	// just enable queue0, let the other queues uninitialized
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_QUEUE_BASE0) = __cpu_to_le32((u32)&tx_fdesc[0]);

	gem_start_tx(gemac);
	// Notify scheduler
	*(volatile u32 *)(gemac->baseaddr + GEM_SCH_PKT_QUEUED) = __cpu_to_le32((u32) length);

	i = 0;
	while ((tx_fdesc[0].ctl & __cpu_to_le32(TX_DESC_WORD1_USED)) == 0) {
		udelay(100);
		i++;
		if (i == 50000) {
			printf("Emac: tx timed out!\n");
			goto out;
		}
	}

	rc = length;
//      printf("gemac_send done \n");
out:

	return rc;
}

static int gemac_recv(struct eth_device *dev)
{
	int length = 0;
	int total_length = 0;
	u32 rx_status;
	u32 rx_data;
	u32 rx_extstatus;

	// loop thru rx FDescs
	while (1) {

		rx_extstatus = rx_ring[rx_next].extstatus;
		if (((rx_extstatus & __cpu_to_le32(GEMRX_OWN)) == 0)) {
//			printf("done %d index %d\n",total_length, rx_next); 
			break;
		}

		rx_data = __le32_to_cpu(rx_ring[rx_next].data);
		rx_status = __le32_to_cpu(rx_ring[rx_next].status);
		length = (rx_status & RX_STA_LEN_MASK) /*>>RX_STA_LEN_POS */ ;

		// Pass the packet up to the protocol layers.
		if (!(rx_status & RX_CHECK_ERROR)) {
			NetReceive((u8 *)rx_data, length);
			total_length += length;
		}

		//clear bits... the buffer can be reused
		rx_ring[rx_next].status &= __cpu_to_le32(GEMRX_WRAP);
		rx_ring[rx_next].extstatus = __cpu_to_le32(0);
		length = 0;

		rx_next++;
		if (rx_next == NUM_RX_DESC)
			rx_next = 0;
	}

	return (total_length);
}

/* Stop the interface */
static void gemac_halt(struct eth_device *dev)
{
	struct gemac_dev *gemac = (struct gemac_dev *)dev->priv;

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

	gem_stop_tx(gemac);
	gem_abort_tx(gemac);
	gem_disable_rx(gemac);
}
#endif

/* Initializes data structures and registers for the controller,
 * and brings the interface up.	 Returns the link status, meaning
 * that it returns success if the link is up, failure otherwise.
 * This allows u-boot to find the first active controller. */
static int gemac_init(struct eth_device *dev, bd_t * bd)
{
	struct gemac_dev *gemac = (struct gemac_dev *)dev->priv;
	MAC_ADDR enet_addr;
	int speed = _1000BASET, duplex = FULL;

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

	/* Make sure the controller is stopped */
	gemac_halt(dev);

	default_speed_duplex(gemac, &speed, &duplex);

#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
	if (!(gemac->phyflags & GEMAC_NO_PHY))
		if (miiphy_speed_duplex(gemac->dev->name, gemac->phyaddr, &speed, &duplex))
			return -1;
#endif /* defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) */

	gemt_reinit(gemac, speed, duplex);

	gem_disable_copy_all(gemac);
	gem_allow_broadcast(gemac);
	gem_enable_unicast(gemac);
	gem_disable_multicast(gemac);
	gem_disable_fcs_rx(gemac);

	gem_enet_addr_byte_mac(dev->enetaddr, &enet_addr);
	gem_set_laddr1(gemac, &enet_addr);

	gemac_rx_ring_init(gemac);

	/* Ready the device for tx/rx */
	gem_start_tx(gemac);
	gem_enable_rx(gemac);

	return (1);
}

int comcerto_gemac_initialize(bd_t * bis, int index, char *devname)
{
	struct eth_device *dev;
	struct gemac_dev *gemac;
	int i;

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

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

	gemac = (struct gemac_dev *)malloc(sizeof(struct gemac_dev));
	if (!gemac)
		return -1;

	gemac_list[index] = gemac;
	gemac->baseaddr = (void *)gemac_info[index].baseaddr;
	gemac->registers = (void *)(gemac_info[index].baseaddr + GEM_IP);
	gemac->phyregisters = (void *)(gemac_info[gemac_info[index].phyregidx].baseaddr + GEM_IP);
	gemac->phyaddr = gemac_info[index].phyaddr;
	gemac->mode = gemac_info[index].mode;

#if defined(CONFIG_COMCERTO_100)
	gemac->idma_baseaddr = (void *)(gemac_info[index].idma_baseaddr);
#endif
	gemac->phyflags = gemac_info[index].phyflags;
	sprintf(dev->name, devname);
	dev->iobase = 0;
	dev->priv = gemac;
	gemac->dev = dev;
	dev->init = gemac_init;
	dev->halt = gemac_halt;
	dev->send = gemac_send;
	dev->recv = gemac_recv;

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

	eth_register(dev);

	/* put gemac out of reset */
#if defined(CONFIG_COMCERTO_100)
	{
// TODO: please cleanup need centralize the reset bock
		volatile int delay_count;

		// get GEMAC out of reset
		*(volatile u32 *)(BLOCK_RESET_REG) |= __cpu_to_le32(GEMAC0_RST << index);
		// 20 ops delay
		delay_count = 20;
		while (delay_count--) ;
	}
#else
	{
		// TODO: please cleanup need centralize the reset bock
		volatile int delay_count;

		// get GEMAC out of reset
		*(volatile u32 *)(CLKCORE_BLK_RESET) |=
		    __cpu_to_le32((BLK_RESET_GEMAC0_AHB_RESET_N << index) | (BLK_RESET_GEMAC0_REF_RESET_N << index));
		// 20 ops delay
		delay_count = 20;
		while (delay_count--) ;
	}
#endif

#if !defined(CONFIG_COMCERTO_MII_CFG_BOOTSTRAP)
	// software config
	switch (gemac_info[index].gemacconfig) {
	case CONFIG_COMCERTO_USE_GMII:
		*(volatile u32 *)(gemac->baseaddr + GEM_CFG) = __cpu_to_le32(gemac->mode | GEM_CONF_MODE_SEL_GEM | GEM_CONF_MODE_GEM_GMII);
		break;
	case CONFIG_COMCERTO_USE_RGMII:
		*(volatile u32 *)(gemac->baseaddr + GEM_CFG) = __cpu_to_le32(gemac->mode | GEM_CONF_MODE_SEL_GEM | GEM_CONF_MODE_GEM_RGMII);
		break;
	case CONFIG_COMCERTO_USE_RMII:
		*(volatile u32 *)(gemac->baseaddr + GEM_CFG) = __cpu_to_le32(gemac->mode | GEM_CONF_MODE_SEL_GEM | GEM_CONF_MODE_GEM_RMII);
		break;
	case CONFIG_COMCERTO_USE_MII:
		*(volatile u32 *)(gemac->baseaddr + GEM_CFG) = __cpu_to_le32(gemac->mode | GEM_CONF_MODE_SEL_GEM | GEM_CONF_MODE_GEM_MII);
		break;
	default:
		printf("comcerto gemac software config requires one MII mode defined %d\n");
		return (-1);
	}
#else
	*(volatile u32 *)(gemac->baseaddr + GEM_CFG) = __cpu_to_le32(gemac->mode);
#endif

#if defined(CONFIG_COMCERTO_1000)
	if ((gemac->phyflags & GEMAC_GEM_DELAY_DISABLE))
		*(volatile u32 *)(gemac->baseaddr + GEM_DELAY_ELEMENT_CTRL) = __cpu_to_le32(0);
#endif

#if defined(CONFIG_COMCERTO_100)
	*(volatile u32 *)(gemac->baseaddr + GEM_TX_CTRL) = __cpu_to_le32(GEM_TXCTRL_DMAIF_EN | GEM_TXCTRL_CRC_EN | GEM_TXCTRL_RETR_EN);
	*(volatile u32 *)(gemac->baseaddr + GEM_RX_CTRL) = __cpu_to_le32(GEM_RXCTRL_DMAIF_EN);
	*(volatile u32 *)(gemac->baseaddr + GEM_RX_STAT_PKTSIZE) = __cpu_to_le32(0x100);
	*(volatile u32 *)(gemac->baseaddr + GEM_ARM_FIFO_CTRL) = __cpu_to_le32(ARM_FIFO_RXDREQWE | ARM_FIFO_TXDREQRE);
	*(volatile u32 *)(gemac->baseaddr + GEM_ARM_RX_FIFO_HIGH) = __cpu_to_le32(0x1D0);
	*(volatile u32 *)(gemac->baseaddr + GEM_ARM_RX_FIFO_LOW) = __cpu_to_le32(0x180);
	*(volatile u32 *)(gemac->baseaddr + GEM_RX_FIFO_HIGH) = __cpu_to_le32(0x1CD);
	*(volatile u32 *)(gemac->baseaddr + GEM_FIFO_CTRL) = __cpu_to_le32(GEM_FIFO_CTRL_TXFF_EN | GEM_FIFO_CTRL_HBTXRQ_EN | GEM_FIFO_CTRL_RXFF_EN | GEM_FIFO_CTRL_HBRXRQ_EN);
#else
	/* configure DMA register */
	/* enable scheduler */
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) |= __cpu_to_le32((1UL << 31));

	/* Master enable scheduler block*/
	*(volatile u32 *)(gemac->baseaddr + GEM_SCH_CTL) |= __cpu_to_le32(1UL);

	/* enable 16 bytes aligned bursts */
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) |= __cpu_to_le32((1UL << 27));

	/* enable software buffer allocation (legacy mode) */
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) |= __cpu_to_le32((1UL << 26));
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) |= __cpu_to_le32((1UL << 25));

	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) &= __cpu_to_le32(~(0x00FF001F));

	/* set buffer size to 2048 bytes */
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) |= __cpu_to_le32(0x00200000);

	/* attempt to use INCR16 AHB bursts */
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) |= __cpu_to_le32(0x00000010);

	/* disable admittance manager */
	*(volatile u32 *)(gemac->baseaddr + GEM_IP + GEM_DMA_CONFIG) &= __cpu_to_le32(~(1UL << 12));

 	/* disable admittance master config bit */
 	*(volatile u32 *)(gemac->baseaddr + ADMITTANCE + ADM_CFG) &= ~(1UL);

#endif
	/* Reset the MAC */
	gemt_reset_gem(gemac);

	if (index == 0) {
#if defined(CONFIG_COMCERTO_100)
/* todo remove this from this file */
		// set ephy divider and switch to ref clk (25Mhz)
		*(volatile u32 *)(CLKCORE_CLKDIV_CNTRL) &= __cpu_to_le32(~(0x1F << EPHY_CLKDIV_RATIO_SHIFT));
		*(volatile u32 *)(CLKCORE_CLKDIV_CNTRL) |= __cpu_to_le32(((CFG_ARM_CLOCK / 25000000) << EPHY_CLKDIV_RATIO_SHIFT));
		*(volatile u32 *)(CLKCORE_CLKDIV_CNTRL) &= __cpu_to_le32(~EPHY_CLKDIV_BYPASS);
#endif
		reset_emac0_phy(1);
	}

	if (index == 1) {
		reset_emac1_phy(1);
	}

#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
	gem_enable_MDIO(gemac);

	if (!(gemac->phyflags & GEMAC_NO_PHY)) {
		int speed, duplex;

		miiphy_register(dev->name, comcerto_miiphy_read, comcerto_miiphy_write);

		default_speed_duplex(gemac, &speed, &duplex);

		if (gemt_config_PHY(gemac, gemac->phyaddr, speed, duplex))
			return -1;
	}
#endif

	return 0;
}

#endif /* CONFIG_COMCERTO_GEMAC */
