/*
 * (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 (CONFIG_COMMANDS & CFG_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 += miiphy_read( devAddr+phyTab[i],M88X_PHY_CNTL,&val );
		/* keep SpeedLSB, Duplex */
		val &= 0x2100;
		/* set SWReset, AnegEn, PwrDwn, RestartAneg */
		val |= 0x9a00;
		err += miiphy_write( 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 += miiphy_read( devAddr+prtTab[i],M88X_PRT_CNTL,&val );
		val &= 0xfffc;
		err += miiphy_write( 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 = miiphy_write( devAddr+15,M88X_GLB_MAC45,val );
	val = (ea[2] <<  8) | ea[3];
	err += miiphy_write( devAddr+15,M88X_GLB_MAC23,val );
	val = (ea[0] <<  8) | ea[1];
#undef ea
	val &= 0xfeff;		/* clear DiffAddr */
	err += miiphy_write( devAddr+15,M88X_GLB_MAC01,val );
	if (err) {
		printf( "%s [ERR] switch mac address register\n",_f );
		return( -1 );
	}

	/* !DiscardExcessive, MaxFrameSize, CtrMode */
	err = miiphy_read( devAddr+15,M88X_GLB_CNTL,&val );
	val &= 0xd870;
	val |= 0x0500;
	err += miiphy_write( 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 = miiphy_read( devAddr+15,M88X_ATU_CNTL,&val );
	val &= 0x000f;
	val |= 0x2130;
	err += miiphy_write( 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 += miiphy_read( devAddr+prtTab[i],p->reg,&val );
			val &= p->msk;
			val |= p->val;
			err += miiphy_write( 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 += miiphy_read( devAddr+phyTab[i],p->reg,&val );
			val &= p->msk;
			val |= p->val;
			err += miiphy_write( 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
