1 /* 2 * (C) Copyright 2000-2004 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * (C) Copyright 2007 Freescale Semiconductor, Inc. 6 * TsiChung Liew (Tsi-Chung.Liew@freescale.com) 7 * 8 * See file CREDITS for list of people who contributed to this 9 * project. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License as 13 * published by the Free Software Foundation; either version 2 of 14 * the License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24 * MA 02111-1307 USA 25 */ 26 27 #include <common.h> 28 #include <malloc.h> 29 30 #include <command.h> 31 #include <net.h> 32 #include <netdev.h> 33 #include <miiphy.h> 34 35 #include <asm/fec.h> 36 #include <asm/immap.h> 37 38 #undef ET_DEBUG 39 #undef MII_DEBUG 40 41 /* Ethernet Transmit and Receive Buffers */ 42 #define DBUF_LENGTH 1520 43 #define TX_BUF_CNT 2 44 #define PKT_MAXBUF_SIZE 1518 45 #define PKT_MINBUF_SIZE 64 46 #define PKT_MAXBLR_SIZE 1520 47 #define LAST_PKTBUFSRX PKTBUFSRX - 1 48 #define BD_ENET_RX_W_E (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY) 49 #define BD_ENET_TX_RDY_LST (BD_ENET_TX_READY | BD_ENET_TX_LAST) 50 51 DECLARE_GLOBAL_DATA_PTR; 52 53 struct fec_info_s fec_info[] = { 54 #ifdef CONFIG_SYS_FEC0_IOBASE 55 { 56 0, /* index */ 57 CONFIG_SYS_FEC0_IOBASE, /* io base */ 58 CONFIG_SYS_FEC0_PINMUX, /* gpio pin muxing */ 59 CONFIG_SYS_FEC0_MIIBASE, /* mii base */ 60 -1, /* phy_addr */ 61 0, /* duplex and speed */ 62 0, /* phy name */ 63 0, /* phyname init */ 64 0, /* RX BD */ 65 0, /* TX BD */ 66 0, /* rx Index */ 67 0, /* tx Index */ 68 0, /* tx buffer */ 69 0, /* initialized flag */ 70 (struct fec_info_s *)-1, 71 }, 72 #endif 73 #ifdef CONFIG_SYS_FEC1_IOBASE 74 { 75 1, /* index */ 76 CONFIG_SYS_FEC1_IOBASE, /* io base */ 77 CONFIG_SYS_FEC1_PINMUX, /* gpio pin muxing */ 78 CONFIG_SYS_FEC1_MIIBASE, /* mii base */ 79 -1, /* phy_addr */ 80 0, /* duplex and speed */ 81 0, /* phy name */ 82 0, /* phy name init */ 83 #ifdef CONFIG_SYS_FEC_BUF_USE_SRAM 84 (cbd_t *)DBUF_LENGTH, /* RX BD */ 85 #else 86 0, /* RX BD */ 87 #endif 88 0, /* TX BD */ 89 0, /* rx Index */ 90 0, /* tx Index */ 91 0, /* tx buffer */ 92 0, /* initialized flag */ 93 (struct fec_info_s *)-1, 94 } 95 #endif 96 }; 97 98 int fec_send(struct eth_device *dev, volatile void *packet, int length); 99 int fec_recv(struct eth_device *dev); 100 int fec_init(struct eth_device *dev, bd_t * bd); 101 void fec_halt(struct eth_device *dev); 102 void fec_reset(struct eth_device *dev); 103 104 void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd) 105 { 106 if ((dup_spd >> 16) == FULL) { 107 /* Set maximum frame length */ 108 fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE | 109 FEC_RCR_PROM | 0x100; 110 fecp->tcr = FEC_TCR_FDEN; 111 } else { 112 /* Half duplex mode */ 113 fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | 114 FEC_RCR_MII_MODE | FEC_RCR_DRT; 115 fecp->tcr &= ~FEC_TCR_FDEN; 116 } 117 118 if ((dup_spd & 0xFFFF) == _100BASET) { 119 #ifdef CONFIG_MCF5445x 120 fecp->rcr &= ~0x200; /* disabled 10T base */ 121 #endif 122 #ifdef MII_DEBUG 123 printf("100Mbps\n"); 124 #endif 125 bd->bi_ethspeed = 100; 126 } else { 127 #ifdef CONFIG_MCF5445x 128 fecp->rcr |= 0x200; /* enabled 10T base */ 129 #endif 130 #ifdef MII_DEBUG 131 printf("10Mbps\n"); 132 #endif 133 bd->bi_ethspeed = 10; 134 } 135 } 136 137 int fec_send(struct eth_device *dev, volatile void *packet, int length) 138 { 139 struct fec_info_s *info = dev->priv; 140 volatile fec_t *fecp = (fec_t *) (info->iobase); 141 int j, rc; 142 u16 phyStatus; 143 144 miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phyStatus); 145 146 /* section 16.9.23.3 147 * Wait for ready 148 */ 149 j = 0; 150 while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) && 151 (j < MCFFEC_TOUT_LOOP)) { 152 udelay(1); 153 j++; 154 } 155 if (j >= MCFFEC_TOUT_LOOP) { 156 printf("TX not ready\n"); 157 } 158 159 info->txbd[info->txIdx].cbd_bufaddr = (uint) packet; 160 info->txbd[info->txIdx].cbd_datlen = length; 161 info->txbd[info->txIdx].cbd_sc |= BD_ENET_TX_RDY_LST; 162 163 /* Activate transmit Buffer Descriptor polling */ 164 fecp->tdar = 0x01000000; /* Descriptor polling active */ 165 166 #ifndef CONFIG_SYS_FEC_BUF_USE_SRAM 167 /* 168 * FEC unable to initial transmit data packet. 169 * A nop will ensure the descriptor polling active completed. 170 * CF Internal RAM has shorter cycle access than DRAM. If use 171 * DRAM as Buffer descriptor and data, a nop is a must. 172 * Affect only V2 and V3. 173 */ 174 __asm__ ("nop"); 175 176 #endif 177 178 #ifdef CONFIG_SYS_UNIFY_CACHE 179 icache_invalid(); 180 #endif 181 182 j = 0; 183 while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) && 184 (j < MCFFEC_TOUT_LOOP)) { 185 udelay(1); 186 j++; 187 } 188 if (j >= MCFFEC_TOUT_LOOP) { 189 printf("TX timeout\n"); 190 } 191 192 #ifdef ET_DEBUG 193 printf("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n", 194 __FILE__, __LINE__, __FUNCTION__, j, 195 info->txbd[info->txIdx].cbd_sc, 196 (info->txbd[info->txIdx].cbd_sc & 0x003C) >> 2); 197 #endif 198 199 /* return only status bits */ 200 rc = (info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS); 201 info->txIdx = (info->txIdx + 1) % TX_BUF_CNT; 202 203 return rc; 204 } 205 206 int fec_recv(struct eth_device *dev) 207 { 208 struct fec_info_s *info = dev->priv; 209 volatile fec_t *fecp = (fec_t *) (info->iobase); 210 int length; 211 212 for (;;) { 213 #ifndef CONFIG_SYS_FEC_BUF_USE_SRAM 214 #endif 215 #ifdef CONFIG_SYS_UNIFY_CACHE 216 icache_invalid(); 217 #endif 218 /* section 16.9.23.2 */ 219 if (info->rxbd[info->rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { 220 length = -1; 221 break; /* nothing received - leave for() loop */ 222 } 223 224 length = info->rxbd[info->rxIdx].cbd_datlen; 225 226 if (info->rxbd[info->rxIdx].cbd_sc & 0x003f) { 227 printf("%s[%d] err: %x\n", 228 __FUNCTION__, __LINE__, 229 info->rxbd[info->rxIdx].cbd_sc); 230 #ifdef ET_DEBUG 231 printf("%s[%d] err: %x\n", 232 __FUNCTION__, __LINE__, 233 info->rxbd[info->rxIdx].cbd_sc); 234 #endif 235 } else { 236 237 length -= 4; 238 /* Pass the packet up to the protocol layers. */ 239 NetReceive(NetRxPackets[info->rxIdx], length); 240 241 fecp->eir |= FEC_EIR_RXF; 242 } 243 244 /* Give the buffer back to the FEC. */ 245 info->rxbd[info->rxIdx].cbd_datlen = 0; 246 247 /* wrap around buffer index when necessary */ 248 if (info->rxIdx == LAST_PKTBUFSRX) { 249 info->rxbd[PKTBUFSRX - 1].cbd_sc = BD_ENET_RX_W_E; 250 info->rxIdx = 0; 251 } else { 252 info->rxbd[info->rxIdx].cbd_sc = BD_ENET_RX_EMPTY; 253 info->rxIdx++; 254 } 255 256 /* Try to fill Buffer Descriptors */ 257 fecp->rdar = 0x01000000; /* Descriptor polling active */ 258 } 259 260 return length; 261 } 262 263 #ifdef ET_DEBUG 264 void dbgFecRegs(struct eth_device *dev) 265 { 266 struct fec_info_s *info = dev->priv; 267 volatile fec_t *fecp = (fec_t *) (info->iobase); 268 269 printf("=====\n"); 270 printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir); 271 printf("imask %x - %x\n", (int)&fecp->eimr, fecp->eimr); 272 printf("r_des_active %x - %x\n", (int)&fecp->rdar, fecp->rdar); 273 printf("x_des_active %x - %x\n", (int)&fecp->tdar, fecp->tdar); 274 printf("ecntrl %x - %x\n", (int)&fecp->ecr, fecp->ecr); 275 printf("mii_mframe %x - %x\n", (int)&fecp->mmfr, fecp->mmfr); 276 printf("mii_speed %x - %x\n", (int)&fecp->mscr, fecp->mscr); 277 printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc); 278 printf("r_cntrl %x - %x\n", (int)&fecp->rcr, fecp->rcr); 279 printf("x_cntrl %x - %x\n", (int)&fecp->tcr, fecp->tcr); 280 printf("padr_l %x - %x\n", (int)&fecp->palr, fecp->palr); 281 printf("padr_u %x - %x\n", (int)&fecp->paur, fecp->paur); 282 printf("op_pause %x - %x\n", (int)&fecp->opd, fecp->opd); 283 printf("iadr_u %x - %x\n", (int)&fecp->iaur, fecp->iaur); 284 printf("iadr_l %x - %x\n", (int)&fecp->ialr, fecp->ialr); 285 printf("gadr_u %x - %x\n", (int)&fecp->gaur, fecp->gaur); 286 printf("gadr_l %x - %x\n", (int)&fecp->galr, fecp->galr); 287 printf("x_wmrk %x - %x\n", (int)&fecp->tfwr, fecp->tfwr); 288 printf("r_bound %x - %x\n", (int)&fecp->frbr, fecp->frbr); 289 printf("r_fstart %x - %x\n", (int)&fecp->frsr, fecp->frsr); 290 printf("r_drng %x - %x\n", (int)&fecp->erdsr, fecp->erdsr); 291 printf("x_drng %x - %x\n", (int)&fecp->etdsr, fecp->etdsr); 292 printf("r_bufsz %x - %x\n", (int)&fecp->emrbr, fecp->emrbr); 293 294 printf("\n"); 295 printf("rmon_t_drop %x - %x\n", (int)&fecp->rmon_t_drop, 296 fecp->rmon_t_drop); 297 printf("rmon_t_packets %x - %x\n", (int)&fecp->rmon_t_packets, 298 fecp->rmon_t_packets); 299 printf("rmon_t_bc_pkt %x - %x\n", (int)&fecp->rmon_t_bc_pkt, 300 fecp->rmon_t_bc_pkt); 301 printf("rmon_t_mc_pkt %x - %x\n", (int)&fecp->rmon_t_mc_pkt, 302 fecp->rmon_t_mc_pkt); 303 printf("rmon_t_crc_align %x - %x\n", (int)&fecp->rmon_t_crc_align, 304 fecp->rmon_t_crc_align); 305 printf("rmon_t_undersize %x - %x\n", (int)&fecp->rmon_t_undersize, 306 fecp->rmon_t_undersize); 307 printf("rmon_t_oversize %x - %x\n", (int)&fecp->rmon_t_oversize, 308 fecp->rmon_t_oversize); 309 printf("rmon_t_frag %x - %x\n", (int)&fecp->rmon_t_frag, 310 fecp->rmon_t_frag); 311 printf("rmon_t_jab %x - %x\n", (int)&fecp->rmon_t_jab, 312 fecp->rmon_t_jab); 313 printf("rmon_t_col %x - %x\n", (int)&fecp->rmon_t_col, 314 fecp->rmon_t_col); 315 printf("rmon_t_p64 %x - %x\n", (int)&fecp->rmon_t_p64, 316 fecp->rmon_t_p64); 317 printf("rmon_t_p65to127 %x - %x\n", (int)&fecp->rmon_t_p65to127, 318 fecp->rmon_t_p65to127); 319 printf("rmon_t_p128to255 %x - %x\n", (int)&fecp->rmon_t_p128to255, 320 fecp->rmon_t_p128to255); 321 printf("rmon_t_p256to511 %x - %x\n", (int)&fecp->rmon_t_p256to511, 322 fecp->rmon_t_p256to511); 323 printf("rmon_t_p512to1023 %x - %x\n", (int)&fecp->rmon_t_p512to1023, 324 fecp->rmon_t_p512to1023); 325 printf("rmon_t_p1024to2047 %x - %x\n", (int)&fecp->rmon_t_p1024to2047, 326 fecp->rmon_t_p1024to2047); 327 printf("rmon_t_p_gte2048 %x - %x\n", (int)&fecp->rmon_t_p_gte2048, 328 fecp->rmon_t_p_gte2048); 329 printf("rmon_t_octets %x - %x\n", (int)&fecp->rmon_t_octets, 330 fecp->rmon_t_octets); 331 332 printf("\n"); 333 printf("ieee_t_drop %x - %x\n", (int)&fecp->ieee_t_drop, 334 fecp->ieee_t_drop); 335 printf("ieee_t_frame_ok %x - %x\n", (int)&fecp->ieee_t_frame_ok, 336 fecp->ieee_t_frame_ok); 337 printf("ieee_t_1col %x - %x\n", (int)&fecp->ieee_t_1col, 338 fecp->ieee_t_1col); 339 printf("ieee_t_mcol %x - %x\n", (int)&fecp->ieee_t_mcol, 340 fecp->ieee_t_mcol); 341 printf("ieee_t_def %x - %x\n", (int)&fecp->ieee_t_def, 342 fecp->ieee_t_def); 343 printf("ieee_t_lcol %x - %x\n", (int)&fecp->ieee_t_lcol, 344 fecp->ieee_t_lcol); 345 printf("ieee_t_excol %x - %x\n", (int)&fecp->ieee_t_excol, 346 fecp->ieee_t_excol); 347 printf("ieee_t_macerr %x - %x\n", (int)&fecp->ieee_t_macerr, 348 fecp->ieee_t_macerr); 349 printf("ieee_t_cserr %x - %x\n", (int)&fecp->ieee_t_cserr, 350 fecp->ieee_t_cserr); 351 printf("ieee_t_sqe %x - %x\n", (int)&fecp->ieee_t_sqe, 352 fecp->ieee_t_sqe); 353 printf("ieee_t_fdxfc %x - %x\n", (int)&fecp->ieee_t_fdxfc, 354 fecp->ieee_t_fdxfc); 355 printf("ieee_t_octets_ok %x - %x\n", (int)&fecp->ieee_t_octets_ok, 356 fecp->ieee_t_octets_ok); 357 358 printf("\n"); 359 printf("rmon_r_drop %x - %x\n", (int)&fecp->rmon_r_drop, 360 fecp->rmon_r_drop); 361 printf("rmon_r_packets %x - %x\n", (int)&fecp->rmon_r_packets, 362 fecp->rmon_r_packets); 363 printf("rmon_r_bc_pkt %x - %x\n", (int)&fecp->rmon_r_bc_pkt, 364 fecp->rmon_r_bc_pkt); 365 printf("rmon_r_mc_pkt %x - %x\n", (int)&fecp->rmon_r_mc_pkt, 366 fecp->rmon_r_mc_pkt); 367 printf("rmon_r_crc_align %x - %x\n", (int)&fecp->rmon_r_crc_align, 368 fecp->rmon_r_crc_align); 369 printf("rmon_r_undersize %x - %x\n", (int)&fecp->rmon_r_undersize, 370 fecp->rmon_r_undersize); 371 printf("rmon_r_oversize %x - %x\n", (int)&fecp->rmon_r_oversize, 372 fecp->rmon_r_oversize); 373 printf("rmon_r_frag %x - %x\n", (int)&fecp->rmon_r_frag, 374 fecp->rmon_r_frag); 375 printf("rmon_r_jab %x - %x\n", (int)&fecp->rmon_r_jab, 376 fecp->rmon_r_jab); 377 printf("rmon_r_p64 %x - %x\n", (int)&fecp->rmon_r_p64, 378 fecp->rmon_r_p64); 379 printf("rmon_r_p65to127 %x - %x\n", (int)&fecp->rmon_r_p65to127, 380 fecp->rmon_r_p65to127); 381 printf("rmon_r_p128to255 %x - %x\n", (int)&fecp->rmon_r_p128to255, 382 fecp->rmon_r_p128to255); 383 printf("rmon_r_p256to511 %x - %x\n", (int)&fecp->rmon_r_p256to511, 384 fecp->rmon_r_p256to511); 385 printf("rmon_r_p512to1023 %x - %x\n", (int)&fecp->rmon_r_p512to1023, 386 fecp->rmon_r_p512to1023); 387 printf("rmon_r_p1024to2047 %x - %x\n", (int)&fecp->rmon_r_p1024to2047, 388 fecp->rmon_r_p1024to2047); 389 printf("rmon_r_p_gte2048 %x - %x\n", (int)&fecp->rmon_r_p_gte2048, 390 fecp->rmon_r_p_gte2048); 391 printf("rmon_r_octets %x - %x\n", (int)&fecp->rmon_r_octets, 392 fecp->rmon_r_octets); 393 394 printf("\n"); 395 printf("ieee_r_drop %x - %x\n", (int)&fecp->ieee_r_drop, 396 fecp->ieee_r_drop); 397 printf("ieee_r_frame_ok %x - %x\n", (int)&fecp->ieee_r_frame_ok, 398 fecp->ieee_r_frame_ok); 399 printf("ieee_r_crc %x - %x\n", (int)&fecp->ieee_r_crc, 400 fecp->ieee_r_crc); 401 printf("ieee_r_align %x - %x\n", (int)&fecp->ieee_r_align, 402 fecp->ieee_r_align); 403 printf("ieee_r_macerr %x - %x\n", (int)&fecp->ieee_r_macerr, 404 fecp->ieee_r_macerr); 405 printf("ieee_r_fdxfc %x - %x\n", (int)&fecp->ieee_r_fdxfc, 406 fecp->ieee_r_fdxfc); 407 printf("ieee_r_octets_ok %x - %x\n", (int)&fecp->ieee_r_octets_ok, 408 fecp->ieee_r_octets_ok); 409 410 printf("\n\n\n"); 411 } 412 #endif 413 414 int fec_init(struct eth_device *dev, bd_t * bd) 415 { 416 struct fec_info_s *info = dev->priv; 417 volatile fec_t *fecp = (fec_t *) (info->iobase); 418 int i; 419 uchar ea[6]; 420 421 fecpin_setclear(dev, 1); 422 423 fec_reset(dev); 424 425 #if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \ 426 defined (CONFIG_SYS_DISCOVER_PHY) 427 428 mii_init(); 429 430 setFecDuplexSpeed(fecp, bd, info->dup_spd); 431 #else 432 #ifndef CONFIG_SYS_DISCOVER_PHY 433 setFecDuplexSpeed(fecp, bd, (FECDUPLEX << 16) | FECSPEED); 434 #endif /* ifndef CONFIG_SYS_DISCOVER_PHY */ 435 #endif /* CONFIG_CMD_MII || CONFIG_MII */ 436 437 /* We use strictly polling mode only */ 438 fecp->eimr = 0; 439 440 /* Clear any pending interrupt */ 441 fecp->eir = 0xffffffff; 442 443 /* Set station address */ 444 if ((u32) fecp == CONFIG_SYS_FEC0_IOBASE) { 445 #ifdef CONFIG_SYS_FEC1_IOBASE 446 volatile fec_t *fecp1 = (fec_t *) (CONFIG_SYS_FEC1_IOBASE); 447 eth_getenv_enetaddr("eth1addr", ea); 448 fecp1->palr = 449 (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); 450 fecp1->paur = (ea[4] << 24) | (ea[5] << 16); 451 #endif 452 eth_getenv_enetaddr("ethaddr", ea); 453 fecp->palr = 454 (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); 455 fecp->paur = (ea[4] << 24) | (ea[5] << 16); 456 } else { 457 #ifdef CONFIG_SYS_FEC0_IOBASE 458 volatile fec_t *fecp0 = (fec_t *) (CONFIG_SYS_FEC0_IOBASE); 459 eth_getenv_enetaddr("ethaddr", ea); 460 fecp0->palr = 461 (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); 462 fecp0->paur = (ea[4] << 24) | (ea[5] << 16); 463 #endif 464 #ifdef CONFIG_SYS_FEC1_IOBASE 465 eth_getenv_enetaddr("eth1addr", ea); 466 fecp->palr = 467 (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); 468 fecp->paur = (ea[4] << 24) | (ea[5] << 16); 469 #endif 470 } 471 472 /* Clear unicast address hash table */ 473 fecp->iaur = 0; 474 fecp->ialr = 0; 475 476 /* Clear multicast address hash table */ 477 fecp->gaur = 0; 478 fecp->galr = 0; 479 480 /* Set maximum receive buffer size. */ 481 fecp->emrbr = PKT_MAXBLR_SIZE; 482 483 /* 484 * Setup Buffers and Buffer Desriptors 485 */ 486 info->rxIdx = 0; 487 info->txIdx = 0; 488 489 /* 490 * Setup Receiver Buffer Descriptors (13.14.24.18) 491 * Settings: 492 * Empty, Wrap 493 */ 494 for (i = 0; i < PKTBUFSRX; i++) { 495 info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; 496 info->rxbd[i].cbd_datlen = 0; /* Reset */ 497 info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; 498 } 499 info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; 500 501 /* 502 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) 503 * Settings: 504 * Last, Tx CRC 505 */ 506 for (i = 0; i < TX_BUF_CNT; i++) { 507 info->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC; 508 info->txbd[i].cbd_datlen = 0; /* Reset */ 509 info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]); 510 } 511 info->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; 512 513 /* Set receive and transmit descriptor base */ 514 fecp->erdsr = (unsigned int)(&info->rxbd[0]); 515 fecp->etdsr = (unsigned int)(&info->txbd[0]); 516 517 /* Now enable the transmit and receive processing */ 518 fecp->ecr |= FEC_ECR_ETHER_EN; 519 520 /* And last, try to fill Rx Buffer Descriptors */ 521 fecp->rdar = 0x01000000; /* Descriptor polling active */ 522 523 return 1; 524 } 525 526 void fec_reset(struct eth_device *dev) 527 { 528 struct fec_info_s *info = dev->priv; 529 volatile fec_t *fecp = (fec_t *) (info->iobase); 530 int i; 531 532 fecp->ecr = FEC_ECR_RESET; 533 for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { 534 udelay(1); 535 } 536 if (i == FEC_RESET_DELAY) { 537 printf("FEC_RESET_DELAY timeout\n"); 538 } 539 } 540 541 void fec_halt(struct eth_device *dev) 542 { 543 struct fec_info_s *info = dev->priv; 544 545 fec_reset(dev); 546 547 fecpin_setclear(dev, 0); 548 549 info->rxIdx = info->txIdx = 0; 550 memset(info->rxbd, 0, PKTBUFSRX * sizeof(cbd_t)); 551 memset(info->txbd, 0, TX_BUF_CNT * sizeof(cbd_t)); 552 memset(info->txbuf, 0, DBUF_LENGTH); 553 } 554 555 int mcffec_initialize(bd_t * bis) 556 { 557 struct eth_device *dev; 558 int i; 559 #ifdef CONFIG_SYS_FEC_BUF_USE_SRAM 560 u32 tmp = CONFIG_SYS_INIT_RAM_ADDR + 0x1000; 561 #endif 562 563 for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); i++) { 564 565 dev = 566 (struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE, 567 sizeof *dev); 568 if (dev == NULL) 569 hang(); 570 571 memset(dev, 0, sizeof(*dev)); 572 573 sprintf(dev->name, "FEC%d", fec_info[i].index); 574 575 dev->priv = &fec_info[i]; 576 dev->init = fec_init; 577 dev->halt = fec_halt; 578 dev->send = fec_send; 579 dev->recv = fec_recv; 580 581 /* setup Receive and Transmit buffer descriptor */ 582 #ifdef CONFIG_SYS_FEC_BUF_USE_SRAM 583 fec_info[i].rxbd = (cbd_t *)((u32)fec_info[i].rxbd + tmp); 584 tmp = (u32)fec_info[i].rxbd; 585 fec_info[i].txbd = 586 (cbd_t *)((u32)fec_info[i].txbd + tmp + 587 (PKTBUFSRX * sizeof(cbd_t))); 588 tmp = (u32)fec_info[i].txbd; 589 fec_info[i].txbuf = 590 (char *)((u32)fec_info[i].txbuf + tmp + 591 (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t))); 592 tmp = (u32)fec_info[i].txbuf; 593 #else 594 fec_info[i].rxbd = 595 (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE, 596 (PKTBUFSRX * sizeof(cbd_t))); 597 fec_info[i].txbd = 598 (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE, 599 (TX_BUF_CNT * sizeof(cbd_t))); 600 fec_info[i].txbuf = 601 (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH); 602 #endif 603 604 #ifdef ET_DEBUG 605 printf("rxbd %x txbd %x\n", 606 (int)fec_info[i].rxbd, (int)fec_info[i].txbd); 607 #endif 608 609 fec_info[i].phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32); 610 611 eth_register(dev); 612 613 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 614 miiphy_register(dev->name, 615 mcffec_miiphy_read, mcffec_miiphy_write); 616 #endif 617 if (i > 0) 618 fec_info[i - 1].next = &fec_info[i]; 619 } 620 fec_info[i - 1].next = &fec_info[0]; 621 622 /* default speed */ 623 bis->bi_ethspeed = 10; 624 625 return 0; 626 } 627