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