wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 1 | /* |
| 2 | * (C) Copyright 2004 |
| 3 | * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de) |
| 4 | * |
| 5 | * Support for the Elmeg VoVPN Gateway Module |
| 6 | * ------------------------------------------ |
| 7 | * Initialize Marvell M88E6060 Switch |
| 8 | * |
| 9 | * This program is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU General Public License as |
| 11 | * published by the Free Software Foundation; either version 2 of |
| 12 | * the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | * GNU General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU General Public License |
| 20 | * along with this program; if not, write to the Free Software |
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| 22 | * MA 02111-1307 USA |
| 23 | */ |
| 24 | |
| 25 | #include <common.h> |
| 26 | #include <ioports.h> |
| 27 | #include <mpc8260.h> |
| 28 | #include <asm/m8260_pci.h> |
| 29 | #include <net.h> |
| 30 | #include <miiphy.h> |
| 31 | |
| 32 | #include "m88e6060.h" |
| 33 | |
| 34 | #if (CONFIG_COMMANDS & CFG_CMD_NET) |
| 35 | static int prtTab[M88X_PRT_CNT] = { 8, 9, 10, 11, 12, 13 }; |
| 36 | static int phyTab[M88X_PHY_CNT] = { 0, 1, 2, 3, 4 }; |
| 37 | |
| 38 | static m88x_regCfg_t prtCfg0[] = { |
| 39 | { 4, 0x3e7c, 0x8000 }, |
| 40 | { 4, 0x3e7c, 0x8003 }, |
| 41 | { 6, 0x0fc0, 0x001e }, |
| 42 | { -1, 0xffff, 0x0000 } |
| 43 | }; |
| 44 | |
| 45 | static m88x_regCfg_t prtCfg1[] = { |
| 46 | { 4, 0x3e7c, 0x8000 }, |
| 47 | { 4, 0x3e7c, 0x8003 }, |
| 48 | { 6, 0x0fc0, 0x001d }, |
| 49 | { -1, 0xffff, 0x0000 } |
| 50 | }; |
| 51 | |
| 52 | static m88x_regCfg_t prtCfg2[] = { |
| 53 | { 4, 0x3e7c, 0x8000 }, |
| 54 | { 4, 0x3e7c, 0x8003 }, |
| 55 | { 6, 0x0fc0, 0x001b }, |
| 56 | { -1, 0xffff, 0x0000 } |
| 57 | }; |
| 58 | |
| 59 | static m88x_regCfg_t prtCfg3[] = { |
| 60 | { 4, 0x3e7c, 0x8000 }, |
| 61 | { 4, 0x3e7c, 0x8003 }, |
| 62 | { 6, 0x0fc0, 0x0017 }, |
| 63 | { -1, 0xffff, 0x0000 } |
| 64 | }; |
| 65 | |
| 66 | static m88x_regCfg_t prtCfg4[] = { |
| 67 | { 4, 0x3e7c, 0x8000 }, |
| 68 | { 4, 0x3e7c, 0x8003 }, |
| 69 | { 6, 0x0fc0, 0x000f }, |
| 70 | { -1, 0xffff, 0x0000 } |
| 71 | }; |
| 72 | |
| 73 | static m88x_regCfg_t *prtCfg[M88X_PRT_CNT] = { |
| 74 | prtCfg0,prtCfg1,prtCfg2,prtCfg3,prtCfg4,NULL |
| 75 | }; |
| 76 | |
| 77 | static m88x_regCfg_t phyCfgX[] = { |
| 78 | { 4, 0xfa1f, 0x01e0 }, |
| 79 | { 0, 0x213f, 0x1200 }, |
| 80 | { 24, 0x81ff, 0x1200 }, |
| 81 | { -1, 0xffff, 0x0000 } |
| 82 | }; |
| 83 | |
| 84 | static m88x_regCfg_t *phyCfg[M88X_PHY_CNT] = { |
| 85 | phyCfgX,phyCfgX,phyCfgX,phyCfgX,NULL |
| 86 | }; |
| 87 | |
| 88 | #if 0 |
| 89 | static void |
| 90 | m88e6060_dump( int devAddr ) |
| 91 | { |
| 92 | int i, j; |
| 93 | unsigned short val[6]; |
| 94 | |
| 95 | printf( "M88E6060 Register Dump\n" ); |
| 96 | printf( "====================================\n" ); |
| 97 | printf( "PortNo 0 1 2 3 4 5\n" ); |
| 98 | for (i=0; i<6; i++) |
| 99 | miiphy_read( devAddr+prtTab[i],M88X_PRT_STAT,&val[i] ); |
| 100 | printf( "STAT %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 101 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 102 | |
| 103 | for (i=0; i<6; i++) |
| 104 | miiphy_read( devAddr+prtTab[i],M88X_PRT_ID,&val[i] ); |
| 105 | printf( "ID %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 106 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 107 | |
| 108 | for (i=0; i<6; i++) |
| 109 | miiphy_read( devAddr+prtTab[i],M88X_PRT_CNTL,&val[i] ); |
| 110 | printf( "CNTL %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 111 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 112 | |
| 113 | for (i=0; i<6; i++) |
| 114 | miiphy_read( devAddr+prtTab[i],M88X_PRT_VLAN,&val[i] ); |
| 115 | printf( "VLAN %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 116 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 117 | |
| 118 | for (i=0; i<6; i++) |
| 119 | miiphy_read( devAddr+prtTab[i],M88X_PRT_PAV,&val[i] ); |
| 120 | printf( "PAV %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 121 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 122 | |
| 123 | for (i=0; i<6; i++) |
| 124 | miiphy_read( devAddr+prtTab[i],M88X_PRT_RX,&val[i] ); |
| 125 | printf( "RX %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 126 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 127 | |
| 128 | for (i=0; i<6; i++) |
| 129 | miiphy_read( devAddr+prtTab[i],M88X_PRT_TX,&val[i] ); |
| 130 | printf( "TX %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 131 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 132 | |
| 133 | printf( "------------------------------------\n" ); |
| 134 | printf( "PhyNo 0 1 2 3 4\n" ); |
| 135 | for (i=0; i<9; i++) { |
| 136 | for (j=0; j<5; j++) { |
| 137 | miiphy_read( devAddr+phyTab[j],i,&val[j] ); |
| 138 | } |
| 139 | printf( "0x%02x %04hx %04hx %04hx %04hx %04hx\n", |
| 140 | i,val[0],val[1],val[2],val[3],val[4] ); |
| 141 | } |
| 142 | for (i=0x10; i<0x1d; i++) { |
| 143 | for (j=0; j<5; j++) { |
| 144 | miiphy_read( devAddr+phyTab[j],i,&val[j] ); |
| 145 | } |
| 146 | printf( "0x%02x %04hx %04hx %04hx %04hx %04hx\n", |
| 147 | i,val[0],val[1],val[2],val[3],val[4] ); |
| 148 | } |
| 149 | } |
| 150 | #endif |
| 151 | |
| 152 | int |
| 153 | m88e6060_initialize( int devAddr ) |
| 154 | { |
| 155 | static char *_f = "m88e6060_initialize:"; |
| 156 | m88x_regCfg_t *p; |
| 157 | int err; |
| 158 | int i; |
| 159 | unsigned short val; |
| 160 | |
| 161 | /*** reset all phys into powerdown ************************************/ |
| 162 | for (i=0, err=0; i<M88X_PHY_CNT; i++) { |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 163 | err += bb_miiphy_read(NULL, devAddr+phyTab[i],M88X_PHY_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 164 | /* keep SpeedLSB, Duplex */ |
| 165 | val &= 0x2100; |
| 166 | /* set SWReset, AnegEn, PwrDwn, RestartAneg */ |
| 167 | val |= 0x9a00; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 168 | err += bb_miiphy_write(NULL, devAddr+phyTab[i],M88X_PHY_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 169 | } |
| 170 | if (err) { |
| 171 | printf( "%s [ERR] reset phys\n",_f ); |
| 172 | return( -1 ); |
| 173 | } |
| 174 | |
| 175 | /*** disable all ports ************************************************/ |
| 176 | for (i=0, err=0; i<M88X_PRT_CNT; i++) { |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 177 | err += bb_miiphy_read(NULL, devAddr+prtTab[i],M88X_PRT_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 178 | val &= 0xfffc; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 179 | err += bb_miiphy_write(NULL, devAddr+prtTab[i],M88X_PRT_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 180 | } |
| 181 | if (err) { |
| 182 | printf( "%s [ERR] disable ports\n",_f ); |
| 183 | return( -1 ); |
| 184 | } |
| 185 | |
| 186 | /*** initialize switch ************************************************/ |
| 187 | /* set switch mac addr */ |
| 188 | #define ea eth_get_dev()->enetaddr |
| 189 | val = (ea[4] << 8) | ea[5]; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 190 | err = bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC45,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 191 | val = (ea[2] << 8) | ea[3]; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 192 | err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC23,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 193 | val = (ea[0] << 8) | ea[1]; |
| 194 | #undef ea |
| 195 | val &= 0xfeff; /* clear DiffAddr */ |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 196 | err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC01,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 197 | if (err) { |
| 198 | printf( "%s [ERR] switch mac address register\n",_f ); |
| 199 | return( -1 ); |
| 200 | } |
| 201 | |
| 202 | /* !DiscardExcessive, MaxFrameSize, CtrMode */ |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 203 | err = bb_miiphy_read(NULL, devAddr+15,M88X_GLB_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 204 | val &= 0xd870; |
| 205 | val |= 0x0500; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 206 | err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 207 | if (err) { |
| 208 | printf( "%s [ERR] switch global control register\n",_f ); |
| 209 | return( -1 ); |
| 210 | } |
| 211 | |
| 212 | /* LernDis off, ATUSize 1024, AgeTime 5min */ |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 213 | err = bb_miiphy_read(NULL, devAddr+15,M88X_ATU_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 214 | val &= 0x000f; |
| 215 | val |= 0x2130; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 216 | err += bb_miiphy_write(NULL, devAddr+15,M88X_ATU_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 217 | if (err) { |
| 218 | printf( "%s [ERR] atu control register\n",_f ); |
| 219 | return( -1 ); |
| 220 | } |
| 221 | |
| 222 | /*** initialize ports *************************************************/ |
| 223 | for (i=0; i<M88X_PRT_CNT; i++) { |
| 224 | if ((p = prtCfg[i]) == NULL) { |
| 225 | continue; |
| 226 | } |
| 227 | while (p->reg != -1) { |
| 228 | err = 0; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 229 | err += bb_miiphy_read(NULL, devAddr+prtTab[i],p->reg,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 230 | val &= p->msk; |
| 231 | val |= p->val; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 232 | err += bb_miiphy_write(NULL, devAddr+prtTab[i],p->reg,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 233 | if (err) { |
| 234 | printf( "%s [ERR] config port %d register %d\n",_f,i,p->reg ); |
| 235 | /* XXX what todo */ |
| 236 | } |
| 237 | p++; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | /*** initialize phys **************************************************/ |
| 242 | for (i=0; i<M88X_PHY_CNT; i++) { |
| 243 | if ((p = phyCfg[i]) == NULL) { |
| 244 | continue; |
| 245 | } |
| 246 | while (p->reg != -1) { |
| 247 | err = 0; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 248 | err += bb_miiphy_read(NULL, devAddr+phyTab[i],p->reg,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 249 | val &= p->msk; |
| 250 | val |= p->val; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 251 | err += bb_miiphy_write(NULL, devAddr+phyTab[i],p->reg,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 252 | if (err) { |
| 253 | printf( "%s [ERR] config phy %d register %d\n",_f,i,p->reg ); |
| 254 | /* XXX what todo */ |
| 255 | } |
| 256 | p++; |
| 257 | } |
| 258 | } |
| 259 | udelay(100000); |
| 260 | return( 0 ); |
| 261 | } |
| 262 | #endif |