/*
 * INCA-IP internal switch ethernet driver.
 *
 * (C) Copyright 2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */


#include <common.h>

#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
	&& defined(CONFIG_INCA_IP_SWITCH)

#include <malloc.h>
#include <net.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)

#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)   \
	 *((volatile u32*)reg) = (u32)value;\
	 DELAY;\
	 *((volatile u32*)reg) = (u32)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


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, volatile 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);


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();

	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 1;
}


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 = KSEG1ADDR(&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 = KSEG1ADDR((u32)rx_ring);
		}
		else
		{
				/* Set the address of the next descriptor.
				 */
			rx_desc->nextRxDescPtr = (u32)KSEG1ADDR(&rx_ring[i+1]);
		}

		rx_desc->RxDataPtr = (u32)KSEG1ADDR(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 = KSEG1ADDR(&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 = KSEG1ADDR((u32)tx_ring);
		}
		else
		{
				/* Set the address of the next descriptor.
				 */
			tx_desc->nextTxDescPtr = (u32)KSEG1ADDR(&tx_ring[i+1]);
		}
	}

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

		/* 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);
#if 0
	printf("TX status = 0x%08X\n", v);
#endif

		/* 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, volatile void *packet,
						  int length)
{
	int                    i;
	int                    res         = -1;
	u32                    command;
	u32                    regValue;
	inca_tx_descriptor_t * tx_desc     = KSEG1ADDR(&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)
	{
		KSEG1ADDR(&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;

	KSEG1ADDR(&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; KSEG1ADDR(&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 = KSEG1ADDR(&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*)KSEG1ADDR(NetRxPackets[rx_new]),
				    length - 4);
		}
		else
		{
#if 1
			printf("Zero length!!!\n");
#endif
		}


		KSEG1ADDR(&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)  - disable
				      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, 0xc0a08000);

	   /* 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)  - disable
				      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, 0xc0c08000);
#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);
}

#endif
