|
|
|
/*
|
|
|
|
* (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 += 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
|