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 | * |
Wolfgang Denk | d79de1d | 2013-07-08 09:37:19 +0200 | [diff] [blame^] | 9 | * SPDX-License-Identifier: GPL-2.0+ |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <common.h> |
| 13 | #include <ioports.h> |
| 14 | #include <mpc8260.h> |
| 15 | #include <asm/m8260_pci.h> |
| 16 | #include <net.h> |
| 17 | #include <miiphy.h> |
| 18 | |
| 19 | #include "m88e6060.h" |
| 20 | |
Jon Loeliger | 96892a9 | 2007-07-09 18:31:28 -0500 | [diff] [blame] | 21 | #if defined(CONFIG_CMD_NET) |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 22 | static int prtTab[M88X_PRT_CNT] = { 8, 9, 10, 11, 12, 13 }; |
| 23 | static int phyTab[M88X_PHY_CNT] = { 0, 1, 2, 3, 4 }; |
| 24 | |
| 25 | static m88x_regCfg_t prtCfg0[] = { |
| 26 | { 4, 0x3e7c, 0x8000 }, |
| 27 | { 4, 0x3e7c, 0x8003 }, |
| 28 | { 6, 0x0fc0, 0x001e }, |
| 29 | { -1, 0xffff, 0x0000 } |
| 30 | }; |
| 31 | |
| 32 | static m88x_regCfg_t prtCfg1[] = { |
| 33 | { 4, 0x3e7c, 0x8000 }, |
| 34 | { 4, 0x3e7c, 0x8003 }, |
| 35 | { 6, 0x0fc0, 0x001d }, |
| 36 | { -1, 0xffff, 0x0000 } |
| 37 | }; |
| 38 | |
| 39 | static m88x_regCfg_t prtCfg2[] = { |
| 40 | { 4, 0x3e7c, 0x8000 }, |
| 41 | { 4, 0x3e7c, 0x8003 }, |
| 42 | { 6, 0x0fc0, 0x001b }, |
| 43 | { -1, 0xffff, 0x0000 } |
| 44 | }; |
| 45 | |
| 46 | static m88x_regCfg_t prtCfg3[] = { |
| 47 | { 4, 0x3e7c, 0x8000 }, |
| 48 | { 4, 0x3e7c, 0x8003 }, |
| 49 | { 6, 0x0fc0, 0x0017 }, |
| 50 | { -1, 0xffff, 0x0000 } |
| 51 | }; |
| 52 | |
| 53 | static m88x_regCfg_t prtCfg4[] = { |
| 54 | { 4, 0x3e7c, 0x8000 }, |
| 55 | { 4, 0x3e7c, 0x8003 }, |
| 56 | { 6, 0x0fc0, 0x000f }, |
| 57 | { -1, 0xffff, 0x0000 } |
| 58 | }; |
| 59 | |
| 60 | static m88x_regCfg_t *prtCfg[M88X_PRT_CNT] = { |
| 61 | prtCfg0,prtCfg1,prtCfg2,prtCfg3,prtCfg4,NULL |
| 62 | }; |
| 63 | |
| 64 | static m88x_regCfg_t phyCfgX[] = { |
| 65 | { 4, 0xfa1f, 0x01e0 }, |
| 66 | { 0, 0x213f, 0x1200 }, |
| 67 | { 24, 0x81ff, 0x1200 }, |
| 68 | { -1, 0xffff, 0x0000 } |
| 69 | }; |
| 70 | |
| 71 | static m88x_regCfg_t *phyCfg[M88X_PHY_CNT] = { |
| 72 | phyCfgX,phyCfgX,phyCfgX,phyCfgX,NULL |
| 73 | }; |
| 74 | |
| 75 | #if 0 |
| 76 | static void |
| 77 | m88e6060_dump( int devAddr ) |
| 78 | { |
| 79 | int i, j; |
| 80 | unsigned short val[6]; |
| 81 | |
| 82 | printf( "M88E6060 Register Dump\n" ); |
| 83 | printf( "====================================\n" ); |
| 84 | printf( "PortNo 0 1 2 3 4 5\n" ); |
| 85 | for (i=0; i<6; i++) |
| 86 | miiphy_read( devAddr+prtTab[i],M88X_PRT_STAT,&val[i] ); |
| 87 | printf( "STAT %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 88 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 89 | |
| 90 | for (i=0; i<6; i++) |
| 91 | miiphy_read( devAddr+prtTab[i],M88X_PRT_ID,&val[i] ); |
| 92 | printf( "ID %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 93 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 94 | |
| 95 | for (i=0; i<6; i++) |
| 96 | miiphy_read( devAddr+prtTab[i],M88X_PRT_CNTL,&val[i] ); |
| 97 | printf( "CNTL %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 98 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 99 | |
| 100 | for (i=0; i<6; i++) |
| 101 | miiphy_read( devAddr+prtTab[i],M88X_PRT_VLAN,&val[i] ); |
| 102 | printf( "VLAN %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 103 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 104 | |
| 105 | for (i=0; i<6; i++) |
| 106 | miiphy_read( devAddr+prtTab[i],M88X_PRT_PAV,&val[i] ); |
| 107 | printf( "PAV %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 108 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 109 | |
| 110 | for (i=0; i<6; i++) |
| 111 | miiphy_read( devAddr+prtTab[i],M88X_PRT_RX,&val[i] ); |
| 112 | printf( "RX %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 113 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 114 | |
| 115 | for (i=0; i<6; i++) |
| 116 | miiphy_read( devAddr+prtTab[i],M88X_PRT_TX,&val[i] ); |
| 117 | printf( "TX %04hx %04hx %04hx %04hx %04hx %04hx\n", |
| 118 | val[0],val[1],val[2],val[3],val[4],val[5] ); |
| 119 | |
| 120 | printf( "------------------------------------\n" ); |
| 121 | printf( "PhyNo 0 1 2 3 4\n" ); |
| 122 | for (i=0; i<9; i++) { |
| 123 | for (j=0; j<5; j++) { |
| 124 | miiphy_read( devAddr+phyTab[j],i,&val[j] ); |
| 125 | } |
| 126 | printf( "0x%02x %04hx %04hx %04hx %04hx %04hx\n", |
| 127 | i,val[0],val[1],val[2],val[3],val[4] ); |
| 128 | } |
| 129 | for (i=0x10; i<0x1d; i++) { |
| 130 | for (j=0; j<5; j++) { |
| 131 | miiphy_read( devAddr+phyTab[j],i,&val[j] ); |
| 132 | } |
| 133 | printf( "0x%02x %04hx %04hx %04hx %04hx %04hx\n", |
| 134 | i,val[0],val[1],val[2],val[3],val[4] ); |
| 135 | } |
| 136 | } |
| 137 | #endif |
| 138 | |
| 139 | int |
| 140 | m88e6060_initialize( int devAddr ) |
| 141 | { |
| 142 | static char *_f = "m88e6060_initialize:"; |
| 143 | m88x_regCfg_t *p; |
| 144 | int err; |
| 145 | int i; |
| 146 | unsigned short val; |
| 147 | |
| 148 | /*** reset all phys into powerdown ************************************/ |
| 149 | for (i=0, err=0; i<M88X_PHY_CNT; i++) { |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 150 | err += bb_miiphy_read(NULL, devAddr+phyTab[i],M88X_PHY_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 151 | /* keep SpeedLSB, Duplex */ |
| 152 | val &= 0x2100; |
| 153 | /* set SWReset, AnegEn, PwrDwn, RestartAneg */ |
| 154 | val |= 0x9a00; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 155 | err += bb_miiphy_write(NULL, devAddr+phyTab[i],M88X_PHY_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 156 | } |
| 157 | if (err) { |
| 158 | printf( "%s [ERR] reset phys\n",_f ); |
| 159 | return( -1 ); |
| 160 | } |
| 161 | |
| 162 | /*** disable all ports ************************************************/ |
| 163 | for (i=0, err=0; i<M88X_PRT_CNT; i++) { |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 164 | err += bb_miiphy_read(NULL, devAddr+prtTab[i],M88X_PRT_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 165 | val &= 0xfffc; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 166 | err += bb_miiphy_write(NULL, devAddr+prtTab[i],M88X_PRT_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 167 | } |
| 168 | if (err) { |
| 169 | printf( "%s [ERR] disable ports\n",_f ); |
| 170 | return( -1 ); |
| 171 | } |
| 172 | |
| 173 | /*** initialize switch ************************************************/ |
| 174 | /* set switch mac addr */ |
| 175 | #define ea eth_get_dev()->enetaddr |
| 176 | val = (ea[4] << 8) | ea[5]; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 177 | err = bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC45,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 178 | val = (ea[2] << 8) | ea[3]; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 179 | err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC23,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 180 | val = (ea[0] << 8) | ea[1]; |
| 181 | #undef ea |
| 182 | val &= 0xfeff; /* clear DiffAddr */ |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 183 | err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_MAC01,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 184 | if (err) { |
| 185 | printf( "%s [ERR] switch mac address register\n",_f ); |
| 186 | return( -1 ); |
| 187 | } |
| 188 | |
| 189 | /* !DiscardExcessive, MaxFrameSize, CtrMode */ |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 190 | err = bb_miiphy_read(NULL, devAddr+15,M88X_GLB_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 191 | val &= 0xd870; |
| 192 | val |= 0x0500; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 193 | err += bb_miiphy_write(NULL, devAddr+15,M88X_GLB_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 194 | if (err) { |
| 195 | printf( "%s [ERR] switch global control register\n",_f ); |
| 196 | return( -1 ); |
| 197 | } |
| 198 | |
| 199 | /* LernDis off, ATUSize 1024, AgeTime 5min */ |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 200 | err = bb_miiphy_read(NULL, devAddr+15,M88X_ATU_CNTL,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 201 | val &= 0x000f; |
| 202 | val |= 0x2130; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 203 | err += bb_miiphy_write(NULL, devAddr+15,M88X_ATU_CNTL,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 204 | if (err) { |
| 205 | printf( "%s [ERR] atu control register\n",_f ); |
| 206 | return( -1 ); |
| 207 | } |
| 208 | |
| 209 | /*** initialize ports *************************************************/ |
| 210 | for (i=0; i<M88X_PRT_CNT; i++) { |
| 211 | if ((p = prtCfg[i]) == NULL) { |
| 212 | continue; |
| 213 | } |
| 214 | while (p->reg != -1) { |
| 215 | err = 0; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 216 | err += bb_miiphy_read(NULL, devAddr+prtTab[i],p->reg,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 217 | val &= p->msk; |
| 218 | val |= p->val; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 219 | err += bb_miiphy_write(NULL, devAddr+prtTab[i],p->reg,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 220 | if (err) { |
| 221 | printf( "%s [ERR] config port %d register %d\n",_f,i,p->reg ); |
| 222 | /* XXX what todo */ |
| 223 | } |
| 224 | p++; |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | /*** initialize phys **************************************************/ |
| 229 | for (i=0; i<M88X_PHY_CNT; i++) { |
| 230 | if ((p = phyCfg[i]) == NULL) { |
| 231 | continue; |
| 232 | } |
| 233 | while (p->reg != -1) { |
| 234 | err = 0; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 235 | err += bb_miiphy_read(NULL, devAddr+phyTab[i],p->reg,&val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 236 | val &= p->msk; |
| 237 | val |= p->val; |
Marian Balakowicz | aab8c49 | 2005-10-28 22:30:33 +0200 | [diff] [blame] | 238 | err += bb_miiphy_write(NULL, devAddr+phyTab[i],p->reg,val ); |
wdenk | c28149c | 2005-05-30 23:55:42 +0000 | [diff] [blame] | 239 | if (err) { |
| 240 | printf( "%s [ERR] config phy %d register %d\n",_f,i,p->reg ); |
| 241 | /* XXX what todo */ |
| 242 | } |
| 243 | p++; |
| 244 | } |
| 245 | } |
| 246 | udelay(100000); |
| 247 | return( 0 ); |
| 248 | } |
| 249 | #endif |