/*
 * INCA-IP internal switch ethernet driver.
 *
 * (C) Copyright 2003-2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */


#include <common.h>

#include <malloc.h>
#include <net.h>
#include <netdev.h>
#include <asm/inca-ip.h>
#include <asm/addrspace.h>


#define NUM_RX_DESC	PKTBUFSRX
#define NUM_TX_DESC	3
#define TOUT_LOOP	1000000


#define DELAY	udelay(10000)
  /* Sometimes the store word instruction hangs while writing to one
   * of the Switch registers. Moving the instruction into a separate
   * function somehow makes the problem go away.
   */
static void SWORD(volatile u32 * reg, u32 value)
{
	*reg = value;
}

#define DMA_WRITE_REG(reg, value) *((volatile u32 *)reg) = (u32)value;
#define DMA_READ_REG(reg, value)    value = (u32)*((volatile u32*)reg)
#define SW_WRITE_REG(reg, value)   \
	SWORD(reg, value);\
	DELAY;\
	SWORD(reg, value);

#define SW_READ_REG(reg, value)	   \
	value = (u32)*((volatile u32*)reg);\
	DELAY;\
	value = (u32)*((volatile u32*)reg);

#define INCA_DMA_TX_POLLING_TIME	0x07
#define INCA_DMA_RX_POLLING_TIME	0x07

#define INCA_DMA_TX_HOLD		0x80000000
#define INCA_DMA_TX_EOP			0x40000000
#define INCA_DMA_TX_SOP			0x20000000
#define INCA_DMA_TX_ICPT		0x10000000
#define INCA_DMA_TX_IEOP		0x08000000

#define INCA_DMA_RX_C			0x80000000
#define INCA_DMA_RX_SOP			0x40000000
#define INCA_DMA_RX_EOP			0x20000000

#define INCA_SWITCH_PHY_SPEED_10H	0x1
#define INCA_SWITCH_PHY_SPEED_10F	0x5
#define INCA_SWITCH_PHY_SPEED_100H	0x2
#define INCA_SWITCH_PHY_SPEED_100F	0x6

/************************ Auto MDIX settings ************************/
#define INCA_IP_AUTO_MDIX_LAN_PORTS_DIR		INCA_IP_Ports_P1_DIR
#define INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL	INCA_IP_Ports_P1_ALTSEL
#define INCA_IP_AUTO_MDIX_LAN_PORTS_OUT		INCA_IP_Ports_P1_OUT
#define INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX	16

#define WAIT_SIGNAL_RETRIES			100
#define WAIT_LINK_RETRIES			100
#define LINK_RETRY_DELAY			2000  /* ms */
/********************************************************************/

typedef struct
{
	union {
		struct {
			volatile u32 HOLD		:1;
			volatile u32 ICpt		:1;
			volatile u32 IEop		:1;
			volatile u32 offset		:3;
			volatile u32 reserved0		:4;
			volatile u32 NFB		:22;
		}field;

		volatile u32 word;
	}params;

	volatile u32 nextRxDescPtr;

	volatile u32 RxDataPtr;

	union {
		struct {
			volatile u32 C			:1;
			volatile u32 Sop		:1;
			volatile u32 Eop		:1;
			volatile u32 reserved3		:12;
			volatile u32 NBT		:17;
		}field;

		volatile u32 word;
	}status;

} inca_rx_descriptor_t;


typedef struct
{
	union {
		struct {
			volatile u32 HOLD		:1;
			volatile u32 Eop		:1;
			volatile u32 Sop		:1;
			volatile u32 ICpt		:1;
			volatile u32 IEop		:1;
			volatile u32 reserved0		:5;
			volatile u32 NBA		:22;
		}field;

		volatile u32 word;
	}params;

	volatile u32 nextTxDescPtr;

	volatile u32 TxDataPtr;

	volatile u32 C			:1;
	volatile u32 reserved3		:31;

} inca_tx_descriptor_t;


static inca_rx_descriptor_t rx_ring[NUM_RX_DESC] __attribute__ ((aligned(16)));
static inca_tx_descriptor_t tx_ring[NUM_TX_DESC] __attribute__ ((aligned(16)));

static int tx_new, rx_new, tx_hold, rx_hold;
static int tx_old_hold = -1;
static int initialized	= 0;


static int inca_switch_init(struct eth_device *dev, bd_t * bis);
static int inca_switch_send(struct eth_device *dev, void *packet, int length);
static int inca_switch_recv(struct eth_device *dev);
static void inca_switch_halt(struct eth_device *dev);
static void inca_init_switch_chip(void);
static void inca_dma_init(void);
static int inca_amdix(void);


int inca_switch_initialize(bd_t * bis)
{
	struct eth_device *dev;

#if 0
	printf("Entered inca_switch_initialize()\n");
#endif

	if (!(dev = (struct eth_device *) malloc (sizeof *dev))) {
		printf("Failed to allocate memory\n");
		return 0;
	}
	memset(dev, 0, sizeof(*dev));

	inca_dma_init();

	inca_init_switch_chip();

#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
	inca_amdix();
#endif

	sprintf(dev->name, "INCA-IP Switch");
	dev->init = inca_switch_init;
	dev->halt = inca_switch_halt;
	dev->send = inca_switch_send;
	dev->recv = inca_switch_recv;

	eth_register(dev);

#if 0
	printf("Leaving inca_switch_initialize()\n");
#endif

	return 0;
}


static int inca_switch_init(struct eth_device *dev, bd_t * bis)
{
	int i;
	u32 v, regValue;
	u16 wTmp;

#if 0
	printf("Entering inca_switch_init()\n");
#endif

	/* Set MAC address.
	 */
	wTmp = (u16)dev->enetaddr[0];
	regValue = (wTmp << 8) | dev->enetaddr[1];

	SW_WRITE_REG(INCA_IP_Switch_PMAC_SA1, regValue);

	wTmp = (u16)dev->enetaddr[2];
	regValue = (wTmp << 8) | dev->enetaddr[3];
	regValue = regValue << 16;
	wTmp = (u16)dev->enetaddr[4];
	regValue |= (wTmp<<8) | dev->enetaddr[5];

	SW_WRITE_REG(INCA_IP_Switch_PMAC_SA2, regValue);

	/* Initialize the descriptor rings.
	 */
	for (i = 0; i < NUM_RX_DESC; i++) {
		inca_rx_descriptor_t * rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[i]);
		memset(rx_desc, 0, sizeof(rx_ring[i]));

		/* Set maximum size of receive buffer.
		 */
		rx_desc->params.field.NFB = PKTSIZE_ALIGN;

		/* Set the offset of the receive buffer. Zero means
		 * that the offset mechanism is not used.
		 */
		rx_desc->params.field.offset = 0;

		/* Check if it is the last descriptor.
		 */
		if (i == (NUM_RX_DESC - 1)) {
			/* Let the last descriptor point to the first
			 * one.
			 */
			rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(rx_ring);
		} else {
			/* Set the address of the next descriptor.
			 */
			rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(&rx_ring[i+1]);
		}

		rx_desc->RxDataPtr = (u32)CKSEG1ADDR(NetRxPackets[i]);
	}

#if 0
	printf("rx_ring = 0x%08X 0x%08X\n", (u32)rx_ring, (u32)&rx_ring[0]);
	printf("tx_ring = 0x%08X 0x%08X\n", (u32)tx_ring, (u32)&tx_ring[0]);
#endif

	for (i = 0; i < NUM_TX_DESC; i++) {
		inca_tx_descriptor_t * tx_desc = (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[i]);

		memset(tx_desc, 0, sizeof(tx_ring[i]));

		tx_desc->params.word	   = 0;
		tx_desc->params.field.HOLD = 1;
		tx_desc->C		   = 1;

			/* Check if it is the last descriptor.
			 */
		if (i == (NUM_TX_DESC - 1)) {
				/* Let the last descriptor point to the
				 * first one.
				 */
			tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(tx_ring);
		} else {
				/* Set the address of the next descriptor.
				 */
			tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(&tx_ring[i+1]);
		}
	}

	/* Initialize RxDMA.
	 */
	DMA_READ_REG(INCA_IP_DMA_DMA_RXISR, v);
	debug("RX status = 0x%08X\n", v);

	/* Writing to the FRDA of CHANNEL.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXFRDA0, (u32)rx_ring);

	/* Writing to the COMMAND REG.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_INIT);

	/* Initialize TxDMA.
	 */
	DMA_READ_REG(INCA_IP_DMA_DMA_TXISR, v);
	debug("TX status = 0x%08X\n", v);

	/* Writing to the FRDA of CHANNEL.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXFRDA0, (u32)tx_ring);

	tx_new = rx_new = 0;

	tx_hold = NUM_TX_DESC - 1;
	rx_hold = NUM_RX_DESC - 1;

#if 0
	rx_ring[rx_hold].params.field.HOLD = 1;
#endif
	/* enable spanning tree forwarding, enable the CPU port */
	/* ST_PT:
	 *	CPS (CPU port status)	0x3 (forwarding)
	 *	LPS (LAN port status)	0x3 (forwarding)
	 *	PPS (PC port status)	0x3 (forwarding)
	 */
	SW_WRITE_REG(INCA_IP_Switch_ST_PT,0x3f);

#if 0
	printf("Leaving inca_switch_init()\n");
#endif

	return 0;
}


static int inca_switch_send(struct eth_device *dev, void *packet, int length)
{
	int		       i;
	int		       res	= -1;
	u32		       command;
	u32		       regValue;
	inca_tx_descriptor_t * tx_desc	= (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_new]);

#if 0
	printf("Entered inca_switch_send()\n");
#endif

	if (length <= 0) {
		printf ("%s: bad packet size: %d\n", dev->name, length);
		goto Done;
	}

	for(i = 0; tx_desc->C == 0; i++) {
		if (i >= TOUT_LOOP) {
			printf("%s: tx error buffer not ready\n", dev->name);
			goto Done;
		}
	}

	if (tx_old_hold >= 0) {
		((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_old_hold]))->params.field.HOLD = 1;
	}
	tx_old_hold = tx_hold;

	tx_desc->params.word =
			(INCA_DMA_TX_SOP | INCA_DMA_TX_EOP | INCA_DMA_TX_HOLD);

	tx_desc->C = 0;
	tx_desc->TxDataPtr = (u32)packet;
	tx_desc->params.field.NBA = length;

	((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->params.field.HOLD = 0;

	tx_hold = tx_new;
	tx_new	= (tx_new + 1) % NUM_TX_DESC;


	if (! initialized) {
		command = INCA_IP_DMA_DMA_TXCCR0_INIT;
		initialized = 1;
	} else {
		command = INCA_IP_DMA_DMA_TXCCR0_HR;
	}

	DMA_READ_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
	regValue |= command;
#if 0
	printf("regValue = 0x%x\n", regValue);
#endif
	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);

#if 1
	for(i = 0; ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->C == 0; i++) {
		if (i >= TOUT_LOOP) {
			printf("%s: tx buffer not ready\n", dev->name);
			goto Done;
		}
	}
#endif
	res = length;
Done:
#if 0
	printf("Leaving inca_switch_send()\n");
#endif
	return res;
}


static int inca_switch_recv(struct eth_device *dev)
{
	int		       length  = 0;
	inca_rx_descriptor_t * rx_desc;

#if 0
	printf("Entered inca_switch_recv()\n");
#endif

	for (;;) {
		rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_new]);

		if (rx_desc->status.field.C == 0) {
			break;
		}

#if 0
		rx_ring[rx_new].params.field.HOLD = 1;
#endif

		if (! rx_desc->status.field.Eop) {
			printf("Partly received packet!!!\n");
			break;
		}

		length = rx_desc->status.field.NBT;
		rx_desc->status.word &=
			 ~(INCA_DMA_RX_EOP | INCA_DMA_RX_SOP | INCA_DMA_RX_C);
#if 0
{
  int i;
  for (i=0;i<length - 4;i++) {
    if (i % 16 == 0) printf("\n%04x: ", i);
    printf("%02X ", NetRxPackets[rx_new][i]);
  }
  printf("\n");
}
#endif

		if (length) {
#if 0
			printf("Received %d bytes\n", length);
#endif
			NetReceive((void*)CKSEG1ADDR(NetRxPackets[rx_new]), length - 4);
		} else {
#if 1
			printf("Zero length!!!\n");
#endif
		}


		((inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_hold]))->params.field.HOLD = 0;

		rx_hold = rx_new;

		rx_new = (rx_new + 1) % NUM_RX_DESC;
	}

#if 0
	printf("Leaving inca_switch_recv()\n");
#endif

	return length;
}


static void inca_switch_halt(struct eth_device *dev)
{
#if 0
	printf("Entered inca_switch_halt()\n");
#endif

#if 1
	initialized = 0;
#endif
#if 1
	/* Disable forwarding to the CPU port.
	 */
	SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);

	/* Close RxDMA channel.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);

	/* Close TxDMA channel.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_TXCCR0_OFF);


#endif
#if 0
	printf("Leaving inca_switch_halt()\n");
#endif
}


static void inca_init_switch_chip(void)
{
	u32 regValue;

	/* To workaround a problem with collision counter
	 * (see Errata sheet).
	 */
	SW_WRITE_REG(INCA_IP_Switch_PC_TX_CTL, 0x00000001);
	SW_WRITE_REG(INCA_IP_Switch_LAN_TX_CTL, 0x00000001);

#if 1
	/* init MDIO configuration:
	 *	MDS (Poll speed):	0x01 (4ms)
	 *	PHY_LAN_ADDR:		0x06
	 *	PHY_PC_ADDR:		0x05
	 *	UEP (Use External PHY): 0x00 (Internal PHY is used)
	 *	PS (Port Select):	0x00 (PT/UMM for LAN)
	 *	PT (PHY Test):		0x00 (no test mode)
	 *	UMM (Use MDIO Mode):	0x00 (state machine is disabled)
	 */
	SW_WRITE_REG(INCA_IP_Switch_MDIO_CFG, 0x4c50);

	/* init PHY:
	 *	SL (Auto Neg. Speed for LAN)
	 *	SP (Auto Neg. Speed for PC)
	 *	LL (Link Status for LAN)
	 *	LP (Link Status for PC)
	 *	DL (Duplex Status for LAN)
	 *	DP (Duplex Status for PC)
	 *	PL (Auto Neg. Pause Status for LAN)
	 *	PP (Auto Neg. Pause Status for PC)
	 */
	SW_WRITE_REG (INCA_IP_Switch_EPHY, 0xff);

	/* MDIO_ACC:
	 *	RA (Request/Ack)  0x01 (Request)
	 *	RW (Read/Write)	  0x01 (Write)
	 *	PHY_ADDR	  0x05 (PC)
	 *	REG_ADDR	  0x00 (PHY_BCR: basic control register)
	 *	PHY_DATA	  0x8000
	 *		      Reset		      - software reset
	 *		      LB (loop back)	      - normal
	 *		      SS (speed select)	      - 10 Mbit/s
	 *		      ANE (auto neg. enable)  - enable
	 *		      PD (power down)	      - normal
	 *		      ISO (isolate)	      - normal
	 *		      RAN (restart auto neg.) - normal
	 *		      DM (duplex mode)	      - half duplex
	 *		      CT (collision test)     - enable
	 */
	SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0a09000);

	/* MDIO_ACC:
	 *	RA (Request/Ack)  0x01 (Request)
	 *	RW (Read/Write)	  0x01 (Write)
	 *	PHY_ADDR	  0x06 (LAN)
	 *	REG_ADDR	  0x00 (PHY_BCR: basic control register)
	 *	PHY_DATA	  0x8000
	 *		      Reset		      - software reset
	 *		      LB (loop back)	      - normal
	 *		      SS (speed select)	      - 10 Mbit/s
	 *		      ANE (auto neg. enable)  - enable
	 *		      PD (power down)	      - normal
	 *		      ISO (isolate)	      - normal
	 *		      RAN (restart auto neg.) - normal
	 *		      DM (duplex mode)	      - half duplex
	 *		      CT (collision test)     - enable
	 */
	SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0c09000);

#endif

	/* Make sure the CPU port is disabled for now. We
	 * don't want packets to get stacked for us until
	 * we enable DMA and are prepared to receive them.
	 */
	SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);

	SW_READ_REG(INCA_IP_Switch_ARL_CTL, regValue);

	/* CRC GEN is enabled.
	 */
	regValue |= 0x00000200;
	SW_WRITE_REG(INCA_IP_Switch_ARL_CTL, regValue);

	/* ADD TAG is disabled.
	 */
	SW_READ_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
	regValue &= ~0x00000002;
	SW_WRITE_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
}


static void inca_dma_init(void)
{
	/* Switch off all DMA channels.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR1, INCA_IP_DMA_DMA_RXCCR1_OFF);

	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR1, INCA_IP_DMA_DMA_TXCCR1_OFF);
	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR2, INCA_IP_DMA_DMA_TXCCR2_OFF);

	/* Setup TX channel polling time.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXPOLL, INCA_DMA_TX_POLLING_TIME);

	/* Setup RX channel polling time.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXPOLL, INCA_DMA_RX_POLLING_TIME);

	/* ERRATA: write reset value into the DMA RX IMR register.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXIMR, 0xFFFFFFFF);

	/* Just in case: disable all transmit interrupts also.
	 */
	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXIMR, 0xFFFFFFFF);

	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXISR, 0xFFFFFFFF);
	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXISR, 0xFFFFFFFF);
}

#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
static int inca_amdix(void)
{
	u32 phyReg1 = 0;
	u32 phyReg4 = 0;
	u32 phyReg5 = 0;
	u32 phyReg6 = 0;
	u32 phyReg31 = 0;
	u32 regEphy = 0;
	int mdi_flag;
	int retries;

	/* Setup GPIO pins.
	 */
	*INCA_IP_AUTO_MDIX_LAN_PORTS_DIR    |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
	*INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);

#if 0
	/* Wait for signal.
	 */
	retries = WAIT_SIGNAL_RETRIES;
	while (--retries) {
		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
				(0x1 << 31) |	/* RA		*/
				(0x0 << 30) |	/* Read		*/
				(0x6 << 21) |	/* LAN		*/
				(17  << 16));	/* PHY_MCSR	*/
		do {
			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
		} while (phyReg1 & (1 << 31));

		if (phyReg1 & (1 << 1)) {
			/* Signal detected */
			break;
		}
	}

	if (!retries)
		goto Fail;
#endif

	/* Set MDI mode.
	 */
	*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
	mdi_flag = 1;

	/* Wait for link.
	 */
	retries = WAIT_LINK_RETRIES;
	while (--retries) {
		udelay(LINK_RETRY_DELAY * 1000);
		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
				(0x1 << 31) |	/* RA		*/
				(0x0 << 30) |	/* Read		*/
				(0x6 << 21) |	/* LAN		*/
				(1   << 16));	/* PHY_BSR	*/
		do {
			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
		} while (phyReg1 & (1 << 31));

		if (phyReg1 & (1 << 2)) {
			/* Link is up */
			break;
		} else if (mdi_flag) {
			/* Set MDIX mode */
			*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
			mdi_flag = 0;
		} else {
			/* Set MDI mode */
			*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
			mdi_flag = 1;
		}
	}

	if (!retries) {
		goto Fail;
	} else {
		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
				(0x1 << 31) |	/* RA		*/
				(0x0 << 30) |	/* Read		*/
				(0x6 << 21) |	/* LAN		*/
				(1   << 16));	/* PHY_BSR	*/
		do {
			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
		} while (phyReg1 & (1 << 31));

		/* Auto-negotiation / Parallel detection complete
		 */
		if (phyReg1 & (1 << 5)) {
			SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
				(0x1 << 31) |	/* RA		*/
				(0x0 << 30) |	/* Read		*/
				(0x6 << 21) |	/* LAN		*/
				(31  << 16));	/* PHY_SCSR	*/
			do {
				SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg31);
			} while (phyReg31 & (1 << 31));

			switch ((phyReg31 >> 2) & 0x7) {
			case INCA_SWITCH_PHY_SPEED_10H:
				/* 10Base-T Half-duplex */
				regEphy = 0;
				break;
			case INCA_SWITCH_PHY_SPEED_10F:
				/* 10Base-T Full-duplex */
				regEphy = INCA_IP_Switch_EPHY_DL;
				break;
			case INCA_SWITCH_PHY_SPEED_100H:
				/* 100Base-TX Half-duplex */
				regEphy = INCA_IP_Switch_EPHY_SL;
				break;
			case INCA_SWITCH_PHY_SPEED_100F:
				/* 100Base-TX Full-duplex */
				regEphy = INCA_IP_Switch_EPHY_SL | INCA_IP_Switch_EPHY_DL;
				break;
			}

			/* In case of Auto-negotiation,
			 * update the negotiated PAUSE support status
			 */
			if (phyReg1 & (1 << 3)) {
				SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
					(0x1 << 31) |	/* RA		*/
					(0x0 << 30) |	/* Read		*/
					(0x6 << 21) |	/* LAN		*/
					(6   << 16));	/* MII_EXPANSION	*/
				do {
					SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg6);
				} while (phyReg6 & (1 << 31));

				/* We are Autoneg-able.
				 * Is Link partner also able to autoneg?
				 */
				if (phyReg6 & (1 << 0)) {
					SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
						(0x1 << 31) |	/* RA		*/
						(0x0 << 30) |	/* Read		*/
						(0x6 << 21) |	/* LAN		*/
						(4   << 16));	/* MII_ADVERTISE	*/
					do {
						SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg4);
					} while (phyReg4 & (1 << 31));

					/* We advertise PAUSE capab.
					 * Does link partner also advertise it?
					 */
					if (phyReg4 & (1 << 10)) {
						SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
							(0x1 << 31) |	/* RA		*/
							(0x0 << 30) |	/* Read		*/
							(0x6 << 21) |	/* LAN		*/
							(5   << 16));	/* MII_LPA	*/
						do {
							SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg5);
						} while (phyReg5 & (1 << 31));

						/* Link partner is PAUSE capab.
						 */
						if (phyReg5 & (1 << 10)) {
							regEphy |= INCA_IP_Switch_EPHY_PL;
						}
					}
				}

			}

			/* Link is up */
			regEphy |= INCA_IP_Switch_EPHY_LL;

			SW_WRITE_REG(INCA_IP_Switch_EPHY, regEphy);
		}
	}

	return 0;

Fail:
	printf("No Link on LAN port\n");
	return -1;
}
#endif /* CONFIG_INCA_IP_SWITCH_AMDIX */
