/*
 * ks8695eth.c -- KS8695 ethernet driver
 *
 * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
 *
 * 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>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <asm/arch/platform.h>

/****************************************************************************/

/*
 * Hardware register access to the KS8695 LAN ethernet port
 * (well, it is the 4 port switch really).
 */
#define	ks8695_read(a)    *((volatile unsigned long *) (KS8695_IO_BASE + (a)))
#define	ks8695_write(a,v) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) = (v)

/****************************************************************************/

/*
 * Define the descriptor in-memory data structures.
 */
struct ks8695_txdesc {
	uint32_t	owner;
	uint32_t	ctrl;
	uint32_t	addr;
	uint32_t	next;
};

struct ks8695_rxdesc {
	uint32_t	status;
	uint32_t	ctrl;
	uint32_t	addr;
	uint32_t	next;
};

/****************************************************************************/

/*
 * Allocate local data structures to use for receiving and sending
 * packets. Just to keep it all nice and simple.
 */

#define	TXDESCS		4
#define	RXDESCS		4
#define	BUFSIZE		2048

volatile struct ks8695_txdesc ks8695_tx[TXDESCS] __attribute__((aligned(256)));
volatile struct ks8695_rxdesc ks8695_rx[RXDESCS] __attribute__((aligned(256)));
volatile uint8_t ks8695_bufs[BUFSIZE*(TXDESCS+RXDESCS)] __attribute__((aligned(2048)));;

/****************************************************************************/

/*
 *	Ideally we want to use the MAC address stored in flash.
 *	But we do some sanity checks in case they are not present
 *	first.
 */
unsigned char eth_mac[] = {
	0x00, 0x13, 0xc6, 0x00, 0x00, 0x00
};

void ks8695_getmac(void)
{
	unsigned char *fp;
	int i;

	/* Check if flash MAC is valid */
	fp = (unsigned char *) 0x0201c000;
	for (i = 0; (i < 6); i++) {
		if ((fp[i] != 0) && (fp[i] != 0xff))
			break;
	}

	/* If we found a valid looking MAC address then use it */
	if (i < 6)
		memcpy(&eth_mac[0], fp, 6);
}

/****************************************************************************/

void eth_reset(bd_t *bd)
{
	int i;

	debug ("%s(%d): eth_reset()\n", __FILE__, __LINE__);

	/* Reset the ethernet engines first */
	ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
	ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);

	ks8695_getmac();

	/* Set MAC address */
	ks8695_write(KS8695_LAN_MAC_LOW, (eth_mac[5] | (eth_mac[4] << 8) |
		(eth_mac[3] << 16) | (eth_mac[2] << 24)));
	ks8695_write(KS8695_LAN_MAC_HIGH, (eth_mac[1] | (eth_mac[0] << 8)));

	/* Turn the 4 port switch on */
	i = ks8695_read(KS8695_SWITCH_CTRL0);
	ks8695_write(KS8695_SWITCH_CTRL0, (i | 0x1));
	/* ks8695_write(KS8695_WAN_CONTROL, 0x3f000066); */

	/* Initialize descriptor rings */
	for (i = 0; (i < TXDESCS); i++) {
		ks8695_tx[i].owner = 0;
		ks8695_tx[i].ctrl = 0;
		ks8695_tx[i].addr = (uint32_t) &ks8695_bufs[i*BUFSIZE];
		ks8695_tx[i].next = (uint32_t) &ks8695_tx[i+1];
	}
	ks8695_tx[TXDESCS-1].ctrl = 0x02000000;
	ks8695_tx[TXDESCS-1].next = (uint32_t) &ks8695_tx[0];

	for (i = 0; (i < RXDESCS); i++) {
		ks8695_rx[i].status = 0x80000000;
		ks8695_rx[i].ctrl = BUFSIZE - 4;
		ks8695_rx[i].addr = (uint32_t) &ks8695_bufs[(i+TXDESCS)*BUFSIZE];
		ks8695_rx[i].next = (uint32_t) &ks8695_rx[i+1];
	}
	ks8695_rx[RXDESCS-1].ctrl |= 0x00080000;
	ks8695_rx[RXDESCS-1].next = (uint32_t) &ks8695_rx[0];

	/* The KS8695 is pretty slow reseting the ethernets... */
	udelay(2000000);

	/* Enable the ethernet engine */
	ks8695_write(KS8695_LAN_TX_LIST, (uint32_t) &ks8695_tx[0]);
	ks8695_write(KS8695_LAN_RX_LIST, (uint32_t) &ks8695_rx[0]);
	ks8695_write(KS8695_LAN_DMA_TX, 0x3);
	ks8695_write(KS8695_LAN_DMA_RX, 0x71);
	ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);

	printf("KS8695 ETHERNET: %pM\n", eth_mac);
}

/****************************************************************************/

int eth_init(bd_t *bd)
{
	debug ("%s(%d): eth_init()\n", __FILE__, __LINE__);

	eth_reset(bd);
	return 0;
}

/****************************************************************************/

void eth_halt(void)
{
	debug ("%s(%d): eth_halt()\n", __FILE__, __LINE__);

	/* Reset the ethernet engines */
	ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
	ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
}

/****************************************************************************/

int eth_rx(void)
{
	volatile struct ks8695_rxdesc *dp;
	int i, len = 0;

	debug ("%s(%d): eth_rx()\n", __FILE__, __LINE__);

	for (i = 0; (i < RXDESCS); i++) {
		dp= &ks8695_rx[i];
		if ((dp->status & 0x80000000) == 0) {
			len = (dp->status & 0x7ff) - 4;
			NetReceive((void *) dp->addr, len);
			dp->status = 0x80000000;
			ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
			break;
		}
	}

	return len;
}

/****************************************************************************/

int eth_send(volatile void *packet, int len)
{
	volatile struct ks8695_txdesc *dp;
	static int next = 0;

	debug ("%s(%d): eth_send(packet=%x,len=%d)\n", __FILE__, __LINE__,
		packet, len);

	dp = &ks8695_tx[next];
	memcpy((void *) dp->addr, (void *) packet, len);

	if (len < 64) {
		memset((void *) (dp->addr + len), 0, 64-len);
		len = 64;
	}

	dp->ctrl = len | 0xe0000000;
	dp->owner = 0x80000000;

	ks8695_write(KS8695_LAN_DMA_TX, 0x3);
	ks8695_write(KS8695_LAN_DMA_TX_START, 0x1);

	if (++next >= TXDESCS)
		next = 0;

	return len;
}
