1 /* 2 * Copyright (C) 2005,2010-2011 Freescale Semiconductor, Inc. 3 * 4 * Author: Shlomi Gridish 5 * 6 * Description: UCC GETH Driver -- PHY handling 7 * Driver for UEC on QE 8 * Based on 8260_io/fcc_enet.c 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the 12 * Free Software Foundation; either version 2 of the License, or (at your 13 * option) any later version. 14 * 15 */ 16 17 #include "common.h" 18 #include "net.h" 19 #include "malloc.h" 20 #include "asm/errno.h" 21 #include "asm/immap_qe.h" 22 #include "asm/io.h" 23 #include "qe.h" 24 #include "uccf.h" 25 #include "uec.h" 26 #include "uec_phy.h" 27 #include "miiphy.h" 28 29 #define ugphy_printk(format, arg...) \ 30 printf(format "\n", ## arg) 31 32 #define ugphy_dbg(format, arg...) \ 33 ugphy_printk(format , ## arg) 34 #define ugphy_err(format, arg...) \ 35 ugphy_printk(format , ## arg) 36 #define ugphy_info(format, arg...) \ 37 ugphy_printk(format , ## arg) 38 #define ugphy_warn(format, arg...) \ 39 ugphy_printk(format , ## arg) 40 41 #ifdef UEC_VERBOSE_DEBUG 42 #define ugphy_vdbg ugphy_dbg 43 #else 44 #define ugphy_vdbg(ugeth, fmt, args...) do { } while (0) 45 #endif /* UEC_VERBOSE_DEBUG */ 46 47 /*--------------------------------------------------------------------+ 48 * Fixed PHY (PHY-less) support for Ethernet Ports. 49 * 50 * Copied from arch/powerpc/cpu/ppc4xx/4xx_enet.c 51 *--------------------------------------------------------------------*/ 52 53 /* 54 * Some boards do not have a PHY for each ethernet port. These ports are known 55 * as Fixed PHY (or PHY-less) ports. For such ports, set the appropriate 56 * CONFIG_SYS_UECx_PHY_ADDR equal to CONFIG_FIXED_PHY_ADDR (an unused address) 57 * When the drver tries to identify the PHYs, CONFIG_FIXED_PHY will be returned 58 * and the driver will search CONFIG_SYS_FIXED_PHY_PORTS to find what network 59 * speed and duplex should be for the port. 60 * 61 * Example board header configuration file: 62 * #define CONFIG_FIXED_PHY 0xFFFFFFFF 63 * #define CONFIG_SYS_FIXED_PHY_ADDR 0x1E (pick an unused phy address) 64 * 65 * #define CONFIG_SYS_UEC1_PHY_ADDR CONFIG_SYS_FIXED_PHY_ADDR 66 * #define CONFIG_SYS_UEC2_PHY_ADDR 0x02 67 * #define CONFIG_SYS_UEC3_PHY_ADDR CONFIG_SYS_FIXED_PHY_ADDR 68 * #define CONFIG_SYS_UEC4_PHY_ADDR 0x04 69 * 70 * #define CONFIG_SYS_FIXED_PHY_PORT(name,speed,duplex) \ 71 * {name, speed, duplex}, 72 * 73 * #define CONFIG_SYS_FIXED_PHY_PORTS \ 74 * CONFIG_SYS_FIXED_PHY_PORT("UEC0",SPEED_100,DUPLEX_FULL) \ 75 * CONFIG_SYS_FIXED_PHY_PORT("UEC2",SPEED_100,DUPLEX_HALF) 76 */ 77 78 #ifndef CONFIG_FIXED_PHY 79 #define CONFIG_FIXED_PHY 0xFFFFFFFF /* Fixed PHY (PHY-less) */ 80 #endif 81 82 #ifndef CONFIG_SYS_FIXED_PHY_PORTS 83 #define CONFIG_SYS_FIXED_PHY_PORTS /* default is an empty array */ 84 #endif 85 86 struct fixed_phy_port { 87 char name[NAMESIZE]; /* ethernet port name */ 88 unsigned int speed; /* specified speed 10,100 or 1000 */ 89 unsigned int duplex; /* specified duplex FULL or HALF */ 90 }; 91 92 static const struct fixed_phy_port fixed_phy_port[] = { 93 CONFIG_SYS_FIXED_PHY_PORTS /* defined in board configuration file */ 94 }; 95 96 /*--------------------------------------------------------------------+ 97 * BitBang MII support for ethernet ports 98 * 99 * Based from MPC8560ADS implementation 100 *--------------------------------------------------------------------*/ 101 /* 102 * Example board header file to define bitbang ethernet ports: 103 * 104 * #define CONFIG_SYS_BITBANG_PHY_PORT(name) name, 105 * #define CONFIG_SYS_BITBANG_PHY_PORTS CONFIG_SYS_BITBANG_PHY_PORT("UEC0") 106 */ 107 #ifndef CONFIG_SYS_BITBANG_PHY_PORTS 108 #define CONFIG_SYS_BITBANG_PHY_PORTS /* default is an empty array */ 109 #endif 110 111 #if defined(CONFIG_BITBANGMII) 112 static const char *bitbang_phy_port[] = { 113 CONFIG_SYS_BITBANG_PHY_PORTS /* defined in board configuration file */ 114 }; 115 #endif /* CONFIG_BITBANGMII */ 116 117 static void config_genmii_advert (struct uec_mii_info *mii_info); 118 static void genmii_setup_forced (struct uec_mii_info *mii_info); 119 static void genmii_restart_aneg (struct uec_mii_info *mii_info); 120 static int gbit_config_aneg (struct uec_mii_info *mii_info); 121 static int genmii_config_aneg (struct uec_mii_info *mii_info); 122 static int genmii_update_link (struct uec_mii_info *mii_info); 123 static int genmii_read_status (struct uec_mii_info *mii_info); 124 u16 uec_phy_read(struct uec_mii_info *mii_info, u16 regnum); 125 void uec_phy_write(struct uec_mii_info *mii_info, u16 regnum, u16 val); 126 127 /* Write value to the PHY for this device to the register at regnum, */ 128 /* waiting until the write is done before it returns. All PHY */ 129 /* configuration has to be done through the TSEC1 MIIM regs */ 130 void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) 131 { 132 uec_private_t *ugeth = (uec_private_t *) dev->priv; 133 uec_mii_t *ug_regs; 134 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 135 u32 tmp_reg; 136 137 138 #if defined(CONFIG_BITBANGMII) 139 u32 i = 0; 140 141 for (i = 0; i < ARRAY_SIZE(bitbang_phy_port); i++) { 142 if (strncmp(dev->name, bitbang_phy_port[i], 143 sizeof(dev->name)) == 0) { 144 (void)bb_miiphy_write(NULL, mii_id, regnum, value); 145 return; 146 } 147 } 148 #endif /* CONFIG_BITBANGMII */ 149 150 ug_regs = ugeth->uec_mii_regs; 151 152 /* Stop the MII management read cycle */ 153 out_be32 (&ug_regs->miimcom, 0); 154 /* Setting up the MII Mangement Address Register */ 155 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 156 out_be32 (&ug_regs->miimadd, tmp_reg); 157 158 /* Setting up the MII Mangement Control Register with the value */ 159 out_be32 (&ug_regs->miimcon, (u32) value); 160 sync(); 161 162 /* Wait till MII management write is complete */ 163 while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY); 164 } 165 166 /* Reads from register regnum in the PHY for device dev, */ 167 /* returning the value. Clears miimcom first. All PHY */ 168 /* configuration has to be done through the TSEC1 MIIM regs */ 169 int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum) 170 { 171 uec_private_t *ugeth = (uec_private_t *) dev->priv; 172 uec_mii_t *ug_regs; 173 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 174 u32 tmp_reg; 175 u16 value; 176 177 178 #if defined(CONFIG_BITBANGMII) 179 u32 i = 0; 180 181 for (i = 0; i < ARRAY_SIZE(bitbang_phy_port); i++) { 182 if (strncmp(dev->name, bitbang_phy_port[i], 183 sizeof(dev->name)) == 0) { 184 (void)bb_miiphy_read(NULL, mii_id, regnum, &value); 185 return (value); 186 } 187 } 188 #endif /* CONFIG_BITBANGMII */ 189 190 ug_regs = ugeth->uec_mii_regs; 191 192 /* Setting up the MII Mangement Address Register */ 193 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 194 out_be32 (&ug_regs->miimadd, tmp_reg); 195 196 /* clear MII management command cycle */ 197 out_be32 (&ug_regs->miimcom, 0); 198 sync(); 199 200 /* Perform an MII management read cycle */ 201 out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE); 202 203 /* Wait till MII management write is complete */ 204 while ((in_be32 (&ug_regs->miimind)) & 205 (MIIMIND_NOT_VALID | MIIMIND_BUSY)); 206 207 /* Read MII management status */ 208 value = (u16) in_be32 (&ug_regs->miimstat); 209 if (value == 0xffff) 210 ugphy_vdbg 211 ("read wrong value : mii_id %d,mii_reg %d, base %08x", 212 mii_id, mii_reg, (u32) & (ug_regs->miimcfg)); 213 214 return (value); 215 } 216 217 void mii_clear_phy_interrupt (struct uec_mii_info *mii_info) 218 { 219 if (mii_info->phyinfo->ack_interrupt) 220 mii_info->phyinfo->ack_interrupt (mii_info); 221 } 222 223 void mii_configure_phy_interrupt (struct uec_mii_info *mii_info, 224 u32 interrupts) 225 { 226 mii_info->interrupts = interrupts; 227 if (mii_info->phyinfo->config_intr) 228 mii_info->phyinfo->config_intr (mii_info); 229 } 230 231 /* Writes MII_ADVERTISE with the appropriate values, after 232 * sanitizing advertise to make sure only supported features 233 * are advertised 234 */ 235 static void config_genmii_advert (struct uec_mii_info *mii_info) 236 { 237 u32 advertise; 238 u16 adv; 239 240 /* Only allow advertising what this PHY supports */ 241 mii_info->advertising &= mii_info->phyinfo->features; 242 advertise = mii_info->advertising; 243 244 /* Setup standard advertisement */ 245 adv = uec_phy_read(mii_info, MII_ADVERTISE); 246 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 247 if (advertise & ADVERTISED_10baseT_Half) 248 adv |= ADVERTISE_10HALF; 249 if (advertise & ADVERTISED_10baseT_Full) 250 adv |= ADVERTISE_10FULL; 251 if (advertise & ADVERTISED_100baseT_Half) 252 adv |= ADVERTISE_100HALF; 253 if (advertise & ADVERTISED_100baseT_Full) 254 adv |= ADVERTISE_100FULL; 255 uec_phy_write(mii_info, MII_ADVERTISE, adv); 256 } 257 258 static void genmii_setup_forced (struct uec_mii_info *mii_info) 259 { 260 u16 ctrl; 261 u32 features = mii_info->phyinfo->features; 262 263 ctrl = uec_phy_read(mii_info, MII_BMCR); 264 265 ctrl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | 266 BMCR_SPEED1000 | BMCR_ANENABLE); 267 ctrl |= BMCR_RESET; 268 269 switch (mii_info->speed) { 270 case SPEED_1000: 271 if (features & (SUPPORTED_1000baseT_Half 272 | SUPPORTED_1000baseT_Full)) { 273 ctrl |= BMCR_SPEED1000; 274 break; 275 } 276 mii_info->speed = SPEED_100; 277 case SPEED_100: 278 if (features & (SUPPORTED_100baseT_Half 279 | SUPPORTED_100baseT_Full)) { 280 ctrl |= BMCR_SPEED100; 281 break; 282 } 283 mii_info->speed = SPEED_10; 284 case SPEED_10: 285 if (features & (SUPPORTED_10baseT_Half 286 | SUPPORTED_10baseT_Full)) 287 break; 288 default: /* Unsupported speed! */ 289 ugphy_err ("%s: Bad speed!", mii_info->dev->name); 290 break; 291 } 292 293 uec_phy_write(mii_info, MII_BMCR, ctrl); 294 } 295 296 /* Enable and Restart Autonegotiation */ 297 static void genmii_restart_aneg (struct uec_mii_info *mii_info) 298 { 299 u16 ctl; 300 301 ctl = uec_phy_read(mii_info, MII_BMCR); 302 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 303 uec_phy_write(mii_info, MII_BMCR, ctl); 304 } 305 306 static int gbit_config_aneg (struct uec_mii_info *mii_info) 307 { 308 u16 adv; 309 u32 advertise; 310 311 if (mii_info->autoneg) { 312 /* Configure the ADVERTISE register */ 313 config_genmii_advert (mii_info); 314 advertise = mii_info->advertising; 315 316 adv = uec_phy_read(mii_info, MII_CTRL1000); 317 adv &= ~(ADVERTISE_1000FULL | 318 ADVERTISE_1000HALF); 319 if (advertise & SUPPORTED_1000baseT_Half) 320 adv |= ADVERTISE_1000HALF; 321 if (advertise & SUPPORTED_1000baseT_Full) 322 adv |= ADVERTISE_1000FULL; 323 uec_phy_write(mii_info, MII_CTRL1000, adv); 324 325 /* Start/Restart aneg */ 326 genmii_restart_aneg (mii_info); 327 } else 328 genmii_setup_forced (mii_info); 329 330 return 0; 331 } 332 333 static int marvell_config_aneg (struct uec_mii_info *mii_info) 334 { 335 /* The Marvell PHY has an errata which requires 336 * that certain registers get written in order 337 * to restart autonegotiation */ 338 uec_phy_write(mii_info, MII_BMCR, BMCR_RESET); 339 340 uec_phy_write(mii_info, 0x1d, 0x1f); 341 uec_phy_write(mii_info, 0x1e, 0x200c); 342 uec_phy_write(mii_info, 0x1d, 0x5); 343 uec_phy_write(mii_info, 0x1e, 0); 344 uec_phy_write(mii_info, 0x1e, 0x100); 345 346 gbit_config_aneg (mii_info); 347 348 return 0; 349 } 350 351 static int genmii_config_aneg (struct uec_mii_info *mii_info) 352 { 353 if (mii_info->autoneg) { 354 /* Speed up the common case, if link is already up, speed and 355 duplex match, skip auto neg as it already matches */ 356 if (!genmii_read_status(mii_info) && mii_info->link) 357 if (mii_info->duplex == DUPLEX_FULL && 358 mii_info->speed == SPEED_100) 359 if (mii_info->advertising & 360 ADVERTISED_100baseT_Full) 361 return 0; 362 363 config_genmii_advert (mii_info); 364 genmii_restart_aneg (mii_info); 365 } else 366 genmii_setup_forced (mii_info); 367 368 return 0; 369 } 370 371 static int genmii_update_link (struct uec_mii_info *mii_info) 372 { 373 u16 status; 374 375 /* Status is read once to clear old link state */ 376 uec_phy_read(mii_info, MII_BMSR); 377 378 /* 379 * Wait if the link is up, and autonegotiation is in progress 380 * (ie - we're capable and it's not done) 381 */ 382 status = uec_phy_read(mii_info, MII_BMSR); 383 if ((status & BMSR_LSTATUS) && (status & BMSR_ANEGCAPABLE) 384 && !(status & BMSR_ANEGCOMPLETE)) { 385 int i = 0; 386 387 while (!(status & BMSR_ANEGCOMPLETE)) { 388 /* 389 * Timeout reached ? 390 */ 391 if (i > UGETH_AN_TIMEOUT) { 392 mii_info->link = 0; 393 return 0; 394 } 395 396 i++; 397 udelay(1000); /* 1 ms */ 398 status = uec_phy_read(mii_info, MII_BMSR); 399 } 400 mii_info->link = 1; 401 } else { 402 if (status & BMSR_LSTATUS) 403 mii_info->link = 1; 404 else 405 mii_info->link = 0; 406 } 407 408 return 0; 409 } 410 411 static int genmii_read_status (struct uec_mii_info *mii_info) 412 { 413 u16 status; 414 int err; 415 416 /* Update the link, but return if there 417 * was an error */ 418 err = genmii_update_link (mii_info); 419 if (err) 420 return err; 421 422 if (mii_info->autoneg) { 423 status = uec_phy_read(mii_info, MII_STAT1000); 424 425 if (status & (LPA_1000FULL | LPA_1000HALF)) { 426 mii_info->speed = SPEED_1000; 427 if (status & LPA_1000FULL) 428 mii_info->duplex = DUPLEX_FULL; 429 else 430 mii_info->duplex = DUPLEX_HALF; 431 } else { 432 status = uec_phy_read(mii_info, MII_LPA); 433 434 if (status & (LPA_10FULL | LPA_100FULL)) 435 mii_info->duplex = DUPLEX_FULL; 436 else 437 mii_info->duplex = DUPLEX_HALF; 438 if (status & (LPA_100FULL | LPA_100HALF)) 439 mii_info->speed = SPEED_100; 440 else 441 mii_info->speed = SPEED_10; 442 } 443 mii_info->pause = 0; 444 } 445 /* On non-aneg, we assume what we put in BMCR is the speed, 446 * though magic-aneg shouldn't prevent this case from occurring 447 */ 448 449 return 0; 450 } 451 452 static int bcm_init(struct uec_mii_info *mii_info) 453 { 454 struct eth_device *edev = mii_info->dev; 455 uec_private_t *uec = edev->priv; 456 457 gbit_config_aneg(mii_info); 458 459 if ((uec->uec_info->enet_interface_type == RGMII_RXID) && 460 (uec->uec_info->speed == 1000)) { 461 u16 val; 462 int cnt = 50; 463 464 /* Wait for aneg to complete. */ 465 do 466 val = uec_phy_read(mii_info, MII_BMSR); 467 while (--cnt && !(val & BMSR_ANEGCOMPLETE)); 468 469 /* Set RDX clk delay. */ 470 uec_phy_write(mii_info, 0x18, 0x7 | (7 << 12)); 471 472 val = uec_phy_read(mii_info, 0x18); 473 /* Set RDX-RXC skew. */ 474 val |= (1 << 8); 475 val |= (7 | (7 << 12)); 476 /* Write bits 14:0. */ 477 val |= (1 << 15); 478 uec_phy_write(mii_info, 0x18, val); 479 } 480 481 return 0; 482 } 483 484 static int uec_marvell_init(struct uec_mii_info *mii_info) 485 { 486 struct eth_device *edev = mii_info->dev; 487 uec_private_t *uec = edev->priv; 488 enum fsl_phy_enet_if iface = uec->uec_info->enet_interface_type; 489 int speed = uec->uec_info->speed; 490 491 if ((speed == 1000) && 492 (iface == RGMII_ID || 493 iface == RGMII_RXID || 494 iface == RGMII_TXID)) { 495 int temp; 496 497 temp = uec_phy_read(mii_info, MII_M1111_PHY_EXT_CR); 498 if (iface == RGMII_ID) { 499 temp |= MII_M1111_RX_DELAY | MII_M1111_TX_DELAY; 500 } else if (iface == RGMII_RXID) { 501 temp &= ~MII_M1111_TX_DELAY; 502 temp |= MII_M1111_RX_DELAY; 503 } else if (iface == RGMII_TXID) { 504 temp &= ~MII_M1111_RX_DELAY; 505 temp |= MII_M1111_TX_DELAY; 506 } 507 uec_phy_write(mii_info, MII_M1111_PHY_EXT_CR, temp); 508 509 temp = uec_phy_read(mii_info, MII_M1111_PHY_EXT_SR); 510 temp &= ~MII_M1111_HWCFG_MODE_MASK; 511 temp |= MII_M1111_HWCFG_MODE_RGMII; 512 uec_phy_write(mii_info, MII_M1111_PHY_EXT_SR, temp); 513 514 uec_phy_write(mii_info, MII_BMCR, BMCR_RESET); 515 } 516 517 return 0; 518 } 519 520 static int marvell_read_status (struct uec_mii_info *mii_info) 521 { 522 u16 status; 523 int err; 524 525 /* Update the link, but return if there 526 * was an error */ 527 err = genmii_update_link (mii_info); 528 if (err) 529 return err; 530 531 /* If the link is up, read the speed and duplex */ 532 /* If we aren't autonegotiating, assume speeds 533 * are as set */ 534 if (mii_info->autoneg && mii_info->link) { 535 int speed; 536 537 status = uec_phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS); 538 539 /* Get the duplexity */ 540 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) 541 mii_info->duplex = DUPLEX_FULL; 542 else 543 mii_info->duplex = DUPLEX_HALF; 544 545 /* Get the speed */ 546 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; 547 switch (speed) { 548 case MII_M1011_PHY_SPEC_STATUS_1000: 549 mii_info->speed = SPEED_1000; 550 break; 551 case MII_M1011_PHY_SPEC_STATUS_100: 552 mii_info->speed = SPEED_100; 553 break; 554 default: 555 mii_info->speed = SPEED_10; 556 break; 557 } 558 mii_info->pause = 0; 559 } 560 561 return 0; 562 } 563 564 static int marvell_ack_interrupt (struct uec_mii_info *mii_info) 565 { 566 /* Clear the interrupts by reading the reg */ 567 uec_phy_read(mii_info, MII_M1011_IEVENT); 568 569 return 0; 570 } 571 572 static int marvell_config_intr (struct uec_mii_info *mii_info) 573 { 574 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 575 uec_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 576 else 577 uec_phy_write(mii_info, MII_M1011_IMASK, 578 MII_M1011_IMASK_CLEAR); 579 580 return 0; 581 } 582 583 static int dm9161_init (struct uec_mii_info *mii_info) 584 { 585 /* Reset the PHY */ 586 uec_phy_write(mii_info, MII_BMCR, uec_phy_read(mii_info, MII_BMCR) | 587 BMCR_RESET); 588 /* PHY and MAC connect */ 589 uec_phy_write(mii_info, MII_BMCR, uec_phy_read(mii_info, MII_BMCR) & 590 ~BMCR_ISOLATE); 591 592 uec_phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); 593 594 config_genmii_advert (mii_info); 595 /* Start/restart aneg */ 596 genmii_config_aneg (mii_info); 597 598 return 0; 599 } 600 601 static int dm9161_config_aneg (struct uec_mii_info *mii_info) 602 { 603 return 0; 604 } 605 606 static int dm9161_read_status (struct uec_mii_info *mii_info) 607 { 608 u16 status; 609 int err; 610 611 /* Update the link, but return if there was an error */ 612 err = genmii_update_link (mii_info); 613 if (err) 614 return err; 615 /* If the link is up, read the speed and duplex 616 If we aren't autonegotiating assume speeds are as set */ 617 if (mii_info->autoneg && mii_info->link) { 618 status = uec_phy_read(mii_info, MII_DM9161_SCSR); 619 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) 620 mii_info->speed = SPEED_100; 621 else 622 mii_info->speed = SPEED_10; 623 624 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) 625 mii_info->duplex = DUPLEX_FULL; 626 else 627 mii_info->duplex = DUPLEX_HALF; 628 } 629 630 return 0; 631 } 632 633 static int dm9161_ack_interrupt (struct uec_mii_info *mii_info) 634 { 635 /* Clear the interrupt by reading the reg */ 636 uec_phy_read(mii_info, MII_DM9161_INTR); 637 638 return 0; 639 } 640 641 static int dm9161_config_intr (struct uec_mii_info *mii_info) 642 { 643 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 644 uec_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); 645 else 646 uec_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); 647 648 return 0; 649 } 650 651 static void dm9161_close (struct uec_mii_info *mii_info) 652 { 653 } 654 655 static int fixed_phy_aneg (struct uec_mii_info *mii_info) 656 { 657 mii_info->autoneg = 0; /* Turn off auto negotiation for fixed phy */ 658 return 0; 659 } 660 661 static int fixed_phy_read_status (struct uec_mii_info *mii_info) 662 { 663 int i = 0; 664 665 for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) { 666 if (strncmp(mii_info->dev->name, fixed_phy_port[i].name, 667 strlen(mii_info->dev->name)) == 0) { 668 mii_info->speed = fixed_phy_port[i].speed; 669 mii_info->duplex = fixed_phy_port[i].duplex; 670 mii_info->link = 1; /* Link is always UP */ 671 mii_info->pause = 0; 672 break; 673 } 674 } 675 return 0; 676 } 677 678 static int smsc_config_aneg (struct uec_mii_info *mii_info) 679 { 680 return 0; 681 } 682 683 static int smsc_read_status (struct uec_mii_info *mii_info) 684 { 685 u16 status; 686 int err; 687 688 /* Update the link, but return if there 689 * was an error */ 690 err = genmii_update_link (mii_info); 691 if (err) 692 return err; 693 694 /* If the link is up, read the speed and duplex */ 695 /* If we aren't autonegotiating, assume speeds 696 * are as set */ 697 if (mii_info->autoneg && mii_info->link) { 698 int val; 699 700 status = uec_phy_read(mii_info, 0x1f); 701 val = (status & 0x1c) >> 2; 702 703 switch (val) { 704 case 1: 705 mii_info->duplex = DUPLEX_HALF; 706 mii_info->speed = SPEED_10; 707 break; 708 case 5: 709 mii_info->duplex = DUPLEX_FULL; 710 mii_info->speed = SPEED_10; 711 break; 712 case 2: 713 mii_info->duplex = DUPLEX_HALF; 714 mii_info->speed = SPEED_100; 715 break; 716 case 6: 717 mii_info->duplex = DUPLEX_FULL; 718 mii_info->speed = SPEED_100; 719 break; 720 } 721 mii_info->pause = 0; 722 } 723 724 return 0; 725 } 726 727 static struct phy_info phy_info_dm9161 = { 728 .phy_id = 0x0181b880, 729 .phy_id_mask = 0x0ffffff0, 730 .name = "Davicom DM9161E", 731 .init = dm9161_init, 732 .config_aneg = dm9161_config_aneg, 733 .read_status = dm9161_read_status, 734 .close = dm9161_close, 735 }; 736 737 static struct phy_info phy_info_dm9161a = { 738 .phy_id = 0x0181b8a0, 739 .phy_id_mask = 0x0ffffff0, 740 .name = "Davicom DM9161A", 741 .features = MII_BASIC_FEATURES, 742 .init = dm9161_init, 743 .config_aneg = dm9161_config_aneg, 744 .read_status = dm9161_read_status, 745 .ack_interrupt = dm9161_ack_interrupt, 746 .config_intr = dm9161_config_intr, 747 .close = dm9161_close, 748 }; 749 750 static struct phy_info phy_info_marvell = { 751 .phy_id = 0x01410c00, 752 .phy_id_mask = 0xffffff00, 753 .name = "Marvell 88E11x1", 754 .features = MII_GBIT_FEATURES, 755 .init = &uec_marvell_init, 756 .config_aneg = &marvell_config_aneg, 757 .read_status = &marvell_read_status, 758 .ack_interrupt = &marvell_ack_interrupt, 759 .config_intr = &marvell_config_intr, 760 }; 761 762 static struct phy_info phy_info_bcm5481 = { 763 .phy_id = 0x0143bca0, 764 .phy_id_mask = 0xffffff0, 765 .name = "Broadcom 5481", 766 .features = MII_GBIT_FEATURES, 767 .read_status = genmii_read_status, 768 .init = bcm_init, 769 }; 770 771 static struct phy_info phy_info_fixedphy = { 772 .phy_id = CONFIG_FIXED_PHY, 773 .phy_id_mask = CONFIG_FIXED_PHY, 774 .name = "Fixed PHY", 775 .config_aneg = fixed_phy_aneg, 776 .read_status = fixed_phy_read_status, 777 }; 778 779 static struct phy_info phy_info_smsclan8700 = { 780 .phy_id = 0x0007c0c0, 781 .phy_id_mask = 0xfffffff0, 782 .name = "SMSC LAN8700", 783 .features = MII_BASIC_FEATURES, 784 .config_aneg = smsc_config_aneg, 785 .read_status = smsc_read_status, 786 }; 787 788 static struct phy_info phy_info_genmii = { 789 .phy_id = 0x00000000, 790 .phy_id_mask = 0x00000000, 791 .name = "Generic MII", 792 .features = MII_BASIC_FEATURES, 793 .config_aneg = genmii_config_aneg, 794 .read_status = genmii_read_status, 795 }; 796 797 static struct phy_info *phy_info[] = { 798 &phy_info_dm9161, 799 &phy_info_dm9161a, 800 &phy_info_marvell, 801 &phy_info_bcm5481, 802 &phy_info_smsclan8700, 803 &phy_info_fixedphy, 804 &phy_info_genmii, 805 NULL 806 }; 807 808 u16 uec_phy_read(struct uec_mii_info *mii_info, u16 regnum) 809 { 810 return mii_info->mdio_read (mii_info->dev, mii_info->mii_id, regnum); 811 } 812 813 void uec_phy_write(struct uec_mii_info *mii_info, u16 regnum, u16 val) 814 { 815 mii_info->mdio_write (mii_info->dev, mii_info->mii_id, regnum, val); 816 } 817 818 /* Use the PHY ID registers to determine what type of PHY is attached 819 * to device dev. return a struct phy_info structure describing that PHY 820 */ 821 struct phy_info *uec_get_phy_info (struct uec_mii_info *mii_info) 822 { 823 u16 phy_reg; 824 u32 phy_ID; 825 int i; 826 struct phy_info *theInfo = NULL; 827 828 /* Grab the bits from PHYIR1, and put them in the upper half */ 829 phy_reg = uec_phy_read(mii_info, MII_PHYSID1); 830 phy_ID = (phy_reg & 0xffff) << 16; 831 832 /* Grab the bits from PHYIR2, and put them in the lower half */ 833 phy_reg = uec_phy_read(mii_info, MII_PHYSID2); 834 phy_ID |= (phy_reg & 0xffff); 835 836 /* loop through all the known PHY types, and find one that */ 837 /* matches the ID we read from the PHY. */ 838 for (i = 0; phy_info[i]; i++) 839 if (phy_info[i]->phy_id == 840 (phy_ID & phy_info[i]->phy_id_mask)) { 841 theInfo = phy_info[i]; 842 break; 843 } 844 845 /* This shouldn't happen, as we have generic PHY support */ 846 if (theInfo == NULL) { 847 ugphy_info ("UEC: PHY id %x is not supported!", phy_ID); 848 return NULL; 849 } else { 850 ugphy_info ("UEC: PHY is %s (%x)", theInfo->name, phy_ID); 851 } 852 853 return theInfo; 854 } 855 856 void marvell_phy_interface_mode (struct eth_device *dev, 857 enum fsl_phy_enet_if type, 858 int speed 859 ) 860 { 861 uec_private_t *uec = (uec_private_t *) dev->priv; 862 struct uec_mii_info *mii_info; 863 u16 status; 864 865 if (!uec->mii_info) { 866 printf ("%s: the PHY not initialized\n", __FUNCTION__); 867 return; 868 } 869 mii_info = uec->mii_info; 870 871 if (type == RGMII) { 872 if (speed == 100) { 873 uec_phy_write(mii_info, 0x00, 0x9140); 874 uec_phy_write(mii_info, 0x1d, 0x001f); 875 uec_phy_write(mii_info, 0x1e, 0x200c); 876 uec_phy_write(mii_info, 0x1d, 0x0005); 877 uec_phy_write(mii_info, 0x1e, 0x0000); 878 uec_phy_write(mii_info, 0x1e, 0x0100); 879 uec_phy_write(mii_info, 0x09, 0x0e00); 880 uec_phy_write(mii_info, 0x04, 0x01e1); 881 uec_phy_write(mii_info, 0x00, 0x9140); 882 uec_phy_write(mii_info, 0x00, 0x1000); 883 udelay (100000); 884 uec_phy_write(mii_info, 0x00, 0x2900); 885 uec_phy_write(mii_info, 0x14, 0x0cd2); 886 uec_phy_write(mii_info, 0x00, 0xa100); 887 uec_phy_write(mii_info, 0x09, 0x0000); 888 uec_phy_write(mii_info, 0x1b, 0x800b); 889 uec_phy_write(mii_info, 0x04, 0x05e1); 890 uec_phy_write(mii_info, 0x00, 0xa100); 891 uec_phy_write(mii_info, 0x00, 0x2100); 892 udelay (1000000); 893 } else if (speed == 10) { 894 uec_phy_write(mii_info, 0x14, 0x8e40); 895 uec_phy_write(mii_info, 0x1b, 0x800b); 896 uec_phy_write(mii_info, 0x14, 0x0c82); 897 uec_phy_write(mii_info, 0x00, 0x8100); 898 udelay (1000000); 899 } 900 } 901 902 /* handle 88e1111 rev.B2 erratum 5.6 */ 903 if (mii_info->autoneg) { 904 status = uec_phy_read(mii_info, MII_BMCR); 905 uec_phy_write(mii_info, MII_BMCR, status | BMCR_ANENABLE); 906 } 907 /* now the B2 will correctly report autoneg completion status */ 908 } 909 910 void change_phy_interface_mode (struct eth_device *dev, 911 enum fsl_phy_enet_if type, int speed) 912 { 913 #ifdef CONFIG_PHY_MODE_NEED_CHANGE 914 marvell_phy_interface_mode (dev, type, speed); 915 #endif 916 } 917