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