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