/*
 * (C) Copyright 2004
 * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de)
 *
 * Support for the Elmeg VoVPN Gateway Module
 * ------------------------------------------
 * Initialize Marvell M88E6060 Switch
 *
 * 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 <ioports.h>
#include <mpc8260.h>
#include <asm/m8260_pci.h>
#include <net.h>
#include <miiphy.h>

#include "m88e6060.h"

#if defined(CONFIG_CMD_NET)
static int		prtTab[M88X_PRT_CNT] = { 8, 9, 10, 11, 12, 13 };
static int		phyTab[M88X_PHY_CNT] = { 0, 1, 2, 3, 4 };

static m88x_regCfg_t	prtCfg0[] = {
	{  4, 0x3e7c, 0x8000 },
	{  4, 0x3e7c, 0x8003 },
	{  6, 0x0fc0, 0x001e },
	{ -1, 0xffff, 0x0000 }
};

static m88x_regCfg_t	prtCfg1[] = {
	{  4, 0x3e7c, 0x8000 },
	{  4, 0x3e7c, 0x8003 },
	{  6, 0x0fc0, 0x001d },
	{ -1, 0xffff, 0x0000 }
};

static m88x_regCfg_t	prtCfg2[] = {
	{  4, 0x3e7c, 0x8000 },
	{  4, 0x3e7c, 0x8003 },
	{  6, 0x0fc0, 0x001b },
	{ -1, 0xffff, 0x0000 }
};

static m88x_regCfg_t	prtCfg3[] = {
	{  4, 0x3e7c, 0x8000 },
	{  4, 0x3e7c, 0x8003 },
	{  6, 0x0fc0, 0x0017 },
	{ -1, 0xffff, 0x0000 }
};

static m88x_regCfg_t	prtCfg4[] = {
	{  4, 0x3e7c, 0x8000 },
	{  4, 0x3e7c, 0x8003 },
	{  6, 0x0fc0, 0x000f },
	{ -1, 0xffff, 0x0000 }
};

static m88x_regCfg_t	*prtCfg[M88X_PRT_CNT] = {
	prtCfg0,prtCfg1,prtCfg2,prtCfg3,prtCfg4,NULL
};

static m88x_regCfg_t	phyCfgX[] = {
	{  4, 0xfa1f, 0x01e0 },
	{  0, 0x213f, 0x1200 },
	{ 24, 0x81ff, 0x1200 },
	{ -1, 0xffff, 0x0000 }
};

static m88x_regCfg_t	*phyCfg[M88X_PHY_CNT] = {
	phyCfgX,phyCfgX,phyCfgX,phyCfgX,NULL
};

#if 0
static void
m88e6060_dump( int devAddr )
{
	int		i, j;
	unsigned short	val[6];

	printf( "M88E6060 Register Dump\n" );
	printf( "====================================\n" );
	printf( "PortNo    0    1    2    3    4    5\n" );
	for (i=0; i<6; i++)
		miiphy_read( devAddr+prtTab[i],M88X_PRT_STAT,&val[i] );
	printf( "STAT   %04hx %04hx %04hx %04hx %04hx %04hx\n",
		val[0],val[1],val[2],val[3],val[4],val[5] );

	for (i=0; i<6; i++)
		miiphy_read( devAddr+prtTab[i],M88X_PRT_ID,&val[i] );
	printf( "ID     %04hx %04hx %04hx %04hx %04hx %04hx\n",
		val[0],val[1],val[2],val[3],val[4],val[5] );

	for (i=0; i<6; i++)
		miiphy_read( devAddr+prtTab[i],M88X_PRT_CNTL,&val[i] );
	printf( "CNTL   %04hx %04hx %04hx %04hx %04hx %04hx\n",
		val[0],val[1],val[2],val[3],val[4],val[5] );

	for (i=0; i<6; i++)
		miiphy_read( devAddr+prtTab[i],M88X_PRT_VLAN,&val[i] );
	printf( "VLAN   %04hx %04hx %04hx %04hx %04hx %04hx\n",
		val[0],val[1],val[2],val[3],val[4],val[5] );

	for (i=0; i<6; i++)
		miiphy_read( devAddr+prtTab[i],M88X_PRT_PAV,&val[i] );
	printf( "PAV    %04hx %04hx %04hx %04hx %04hx %04hx\n",
		val[0],val[1],val[2],val[3],val[4],val[5] );

	for (i=0; i<6; i++)
		miiphy_read( devAddr+prtTab[i],M88X_PRT_RX,&val[i] );
	printf( "RX     %04hx %04hx %04hx %04hx %04hx %04hx\n",
		val[0],val[1],val[2],val[3],val[4],val[5] );

	for (i=0; i<6; i++)
		miiphy_read( devAddr+prtTab[i],M88X_PRT_TX,&val[i] );
	printf( "TX     %04hx %04hx %04hx %04hx %04hx %04hx\n",
		val[0],val[1],val[2],val[3],val[4],val[5] );

	printf( "------------------------------------\n" );
	printf( "PhyNo     0    1    2    3    4\n" );
	for (i=0; i<9; i++) {
		for (j=0; j<5; j++) {
			miiphy_read( devAddr+phyTab[j],i,&val[j] );
		}
		printf( "0x%02x   %04hx %04hx %04hx %04hx %04hx\n",
			i,val[0],val[1],val[2],val[3],val[4] );
	}
	for (i=0x10; i<0x1d; i++) {
		for (j=0; j<5; j++) {
			miiphy_read( devAddr+phyTab[j],i,&val[j] );
		}
		printf( "0x%02x   %04hx %04hx %04hx %04hx %04hx\n",
			i,val[0],val[1],val[2],val[3],val[4] );
	}
}
#endif

int
m88e6060_initialize( int devAddr )
{
	static char	*_f = "m88e6060_initialize:";
	m88x_regCfg_t	*p;
	int		err;
	int		i;
	unsigned short	val;

	/*** reset all phys into powerdown ************************************/
	for (i=0, err=0; i<M88X_PHY_CNT; i++) {
		err += bb_miiphy_read(NULL, devAddr+phyTab[i],M88X_PHY_CNTL,&val );
		/* keep SpeedLSB, Duplex */
		val &= 0x2100;
		/* set SWReset, AnegEn, PwrDwn, RestartAneg */
		val |= 0x9a00;
		err += bb_miiphy_write(NULL, devAddr+phyTab[i],M88X_PHY_CNTL,val );
	}
	if (err) {
		printf( "%s [ERR] reset phys\n",_f );
		return( -1 );
	}

	/*** disable all ports ************************************************/
	for (i=0, err=0; i<M88X_PRT_CNT; i++) {
		err += bb_miiphy_read(NULL, devAddr+prtTab[i],M88X_PRT_CNTL,&val );
		val &= 0xfffc;
		err += bb_miiphy_write(NULL, devAddr+prtTab[i],M88X_PRT_CNTL,val );
	}
	if (err) {
		printf( "%s [ERR] disable ports\n",_f );
		return( -1 );
	}

	/*** initialize switch ************************************************/
	/* set switch mac addr */
#define ea eth_get_dev()->enetaddr
	val = (ea[4] <<  8) | ea[5];
	err = bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC45,val );
	val = (ea[2] <<  8) | ea[3];
	err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC23,val );
	val = (ea[0] <<  8) | ea[1];
#undef ea
	val &= 0xfeff;		/* clear DiffAddr */
	err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC01,val );
	if (err) {
		printf( "%s [ERR] switch mac address register\n",_f );
		return( -1 );
	}

	/* !DiscardExcessive, MaxFrameSize, CtrMode */
	err = bb_miiphy_read(NULL, devAddr+15,M88X_GLB_CNTL,&val );
	val &= 0xd870;
	val |= 0x0500;
	err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_CNTL,val );
	if (err) {
		printf( "%s [ERR] switch global control register\n",_f );
		return( -1 );
	}

	/* LernDis off, ATUSize 1024, AgeTime 5min */
	err = bb_miiphy_read(NULL, devAddr+15,M88X_ATU_CNTL,&val );
	val &= 0x000f;
	val |= 0x2130;
	err += bb_miiphy_write(NULL, devAddr+15,M88X_ATU_CNTL,val );
	if (err) {
		printf( "%s [ERR] atu control register\n",_f );
		return( -1 );
	}

	/*** initialize ports *************************************************/
	for (i=0; i<M88X_PRT_CNT; i++) {
		if ((p = prtCfg[i]) == NULL) {
			continue;
		}
		while (p->reg != -1) {
			err = 0;
			err += bb_miiphy_read(NULL, devAddr+prtTab[i],p->reg,&val );
			val &= p->msk;
			val |= p->val;
			err += bb_miiphy_write(NULL, devAddr+prtTab[i],p->reg,val );
			if (err) {
				printf( "%s [ERR] config port %d register %d\n",_f,i,p->reg );
				/* XXX what todo */
			}
			p++;
		}
	}

	/*** initialize phys **************************************************/
	for (i=0; i<M88X_PHY_CNT; i++) {
		if ((p = phyCfg[i]) == NULL) {
			continue;
		}
		while (p->reg != -1) {
			err = 0;
			err += bb_miiphy_read(NULL, devAddr+phyTab[i],p->reg,&val );
			val &= p->msk;
			val |= p->val;
			err += bb_miiphy_write(NULL, devAddr+phyTab[i],p->reg,val );
			if (err) {
				printf( "%s [ERR] config phy %d register %d\n",_f,i,p->reg );
				/* XXX what todo */
			}
			p++;
		}
	}
	udelay(100000);
	return( 0 );
}
#endif
