1 /* 2 * Copyright (C) 2005 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 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("FSL UEC0",SPEED_100,DUPLEX_FULL) \ 75 * CONFIG_SYS_FIXED_PHY_PORT("FSL 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 static void config_genmii_advert (struct uec_mii_info *mii_info); 97 static void genmii_setup_forced (struct uec_mii_info *mii_info); 98 static void genmii_restart_aneg (struct uec_mii_info *mii_info); 99 static int gbit_config_aneg (struct uec_mii_info *mii_info); 100 static int genmii_config_aneg (struct uec_mii_info *mii_info); 101 static int genmii_update_link (struct uec_mii_info *mii_info); 102 static int genmii_read_status (struct uec_mii_info *mii_info); 103 u16 phy_read (struct uec_mii_info *mii_info, u16 regnum); 104 void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val); 105 106 /* Write value to the PHY for this device to the register at regnum, */ 107 /* waiting until the write is done before it returns. All PHY */ 108 /* configuration has to be done through the TSEC1 MIIM regs */ 109 void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) 110 { 111 uec_private_t *ugeth = (uec_private_t *) dev->priv; 112 uec_mii_t *ug_regs; 113 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 114 u32 tmp_reg; 115 116 ug_regs = ugeth->uec_mii_regs; 117 118 /* Stop the MII management read cycle */ 119 out_be32 (&ug_regs->miimcom, 0); 120 /* Setting up the MII Mangement Address Register */ 121 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 122 out_be32 (&ug_regs->miimadd, tmp_reg); 123 124 /* Setting up the MII Mangement Control Register with the value */ 125 out_be32 (&ug_regs->miimcon, (u32) value); 126 sync(); 127 128 /* Wait till MII management write is complete */ 129 while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY); 130 } 131 132 /* Reads from register regnum in the PHY for device dev, */ 133 /* returning the value. Clears miimcom first. All PHY */ 134 /* configuration has to be done through the TSEC1 MIIM regs */ 135 int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum) 136 { 137 uec_private_t *ugeth = (uec_private_t *) dev->priv; 138 uec_mii_t *ug_regs; 139 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 140 u32 tmp_reg; 141 u16 value; 142 143 ug_regs = ugeth->uec_mii_regs; 144 145 /* Setting up the MII Mangement Address Register */ 146 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 147 out_be32 (&ug_regs->miimadd, tmp_reg); 148 149 /* clear MII management command cycle */ 150 out_be32 (&ug_regs->miimcom, 0); 151 sync(); 152 153 /* Perform an MII management read cycle */ 154 out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE); 155 156 /* Wait till MII management write is complete */ 157 while ((in_be32 (&ug_regs->miimind)) & 158 (MIIMIND_NOT_VALID | MIIMIND_BUSY)); 159 160 /* Read MII management status */ 161 value = (u16) in_be32 (&ug_regs->miimstat); 162 if (value == 0xffff) 163 ugphy_vdbg 164 ("read wrong value : mii_id %d,mii_reg %d, base %08x", 165 mii_id, mii_reg, (u32) & (ug_regs->miimcfg)); 166 167 return (value); 168 } 169 170 void mii_clear_phy_interrupt (struct uec_mii_info *mii_info) 171 { 172 if (mii_info->phyinfo->ack_interrupt) 173 mii_info->phyinfo->ack_interrupt (mii_info); 174 } 175 176 void mii_configure_phy_interrupt (struct uec_mii_info *mii_info, 177 u32 interrupts) 178 { 179 mii_info->interrupts = interrupts; 180 if (mii_info->phyinfo->config_intr) 181 mii_info->phyinfo->config_intr (mii_info); 182 } 183 184 /* Writes MII_ADVERTISE with the appropriate values, after 185 * sanitizing advertise to make sure only supported features 186 * are advertised 187 */ 188 static void config_genmii_advert (struct uec_mii_info *mii_info) 189 { 190 u32 advertise; 191 u16 adv; 192 193 /* Only allow advertising what this PHY supports */ 194 mii_info->advertising &= mii_info->phyinfo->features; 195 advertise = mii_info->advertising; 196 197 /* Setup standard advertisement */ 198 adv = phy_read (mii_info, PHY_ANAR); 199 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 200 if (advertise & ADVERTISED_10baseT_Half) 201 adv |= ADVERTISE_10HALF; 202 if (advertise & ADVERTISED_10baseT_Full) 203 adv |= ADVERTISE_10FULL; 204 if (advertise & ADVERTISED_100baseT_Half) 205 adv |= ADVERTISE_100HALF; 206 if (advertise & ADVERTISED_100baseT_Full) 207 adv |= ADVERTISE_100FULL; 208 phy_write (mii_info, PHY_ANAR, adv); 209 } 210 211 static void genmii_setup_forced (struct uec_mii_info *mii_info) 212 { 213 u16 ctrl; 214 u32 features = mii_info->phyinfo->features; 215 216 ctrl = phy_read (mii_info, PHY_BMCR); 217 218 ctrl &= ~(PHY_BMCR_DPLX | PHY_BMCR_100_MBPS | 219 PHY_BMCR_1000_MBPS | PHY_BMCR_AUTON); 220 ctrl |= PHY_BMCR_RESET; 221 222 switch (mii_info->speed) { 223 case SPEED_1000: 224 if (features & (SUPPORTED_1000baseT_Half 225 | SUPPORTED_1000baseT_Full)) { 226 ctrl |= PHY_BMCR_1000_MBPS; 227 break; 228 } 229 mii_info->speed = SPEED_100; 230 case SPEED_100: 231 if (features & (SUPPORTED_100baseT_Half 232 | SUPPORTED_100baseT_Full)) { 233 ctrl |= PHY_BMCR_100_MBPS; 234 break; 235 } 236 mii_info->speed = SPEED_10; 237 case SPEED_10: 238 if (features & (SUPPORTED_10baseT_Half 239 | SUPPORTED_10baseT_Full)) 240 break; 241 default: /* Unsupported speed! */ 242 ugphy_err ("%s: Bad speed!", mii_info->dev->name); 243 break; 244 } 245 246 phy_write (mii_info, PHY_BMCR, ctrl); 247 } 248 249 /* Enable and Restart Autonegotiation */ 250 static void genmii_restart_aneg (struct uec_mii_info *mii_info) 251 { 252 u16 ctl; 253 254 ctl = phy_read (mii_info, PHY_BMCR); 255 ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); 256 phy_write (mii_info, PHY_BMCR, ctl); 257 } 258 259 static int gbit_config_aneg (struct uec_mii_info *mii_info) 260 { 261 u16 adv; 262 u32 advertise; 263 264 if (mii_info->autoneg) { 265 /* Configure the ADVERTISE register */ 266 config_genmii_advert (mii_info); 267 advertise = mii_info->advertising; 268 269 adv = phy_read (mii_info, MII_1000BASETCONTROL); 270 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | 271 MII_1000BASETCONTROL_HALFDUPLEXCAP); 272 if (advertise & SUPPORTED_1000baseT_Half) 273 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 274 if (advertise & SUPPORTED_1000baseT_Full) 275 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 276 phy_write (mii_info, MII_1000BASETCONTROL, adv); 277 278 /* Start/Restart aneg */ 279 genmii_restart_aneg (mii_info); 280 } else 281 genmii_setup_forced (mii_info); 282 283 return 0; 284 } 285 286 static int marvell_config_aneg (struct uec_mii_info *mii_info) 287 { 288 /* The Marvell PHY has an errata which requires 289 * that certain registers get written in order 290 * to restart autonegotiation */ 291 phy_write (mii_info, PHY_BMCR, PHY_BMCR_RESET); 292 293 phy_write (mii_info, 0x1d, 0x1f); 294 phy_write (mii_info, 0x1e, 0x200c); 295 phy_write (mii_info, 0x1d, 0x5); 296 phy_write (mii_info, 0x1e, 0); 297 phy_write (mii_info, 0x1e, 0x100); 298 299 gbit_config_aneg (mii_info); 300 301 return 0; 302 } 303 304 static int genmii_config_aneg (struct uec_mii_info *mii_info) 305 { 306 if (mii_info->autoneg) { 307 config_genmii_advert (mii_info); 308 genmii_restart_aneg (mii_info); 309 } else 310 genmii_setup_forced (mii_info); 311 312 return 0; 313 } 314 315 static int genmii_update_link (struct uec_mii_info *mii_info) 316 { 317 u16 status; 318 319 /* Status is read once to clear old link state */ 320 phy_read (mii_info, PHY_BMSR); 321 322 /* 323 * Wait if the link is up, and autonegotiation is in progress 324 * (ie - we're capable and it's not done) 325 */ 326 status = phy_read(mii_info, PHY_BMSR); 327 if ((status & PHY_BMSR_LS) && (status & PHY_BMSR_AUTN_ABLE) 328 && !(status & PHY_BMSR_AUTN_COMP)) { 329 int i = 0; 330 331 while (!(status & PHY_BMSR_AUTN_COMP)) { 332 /* 333 * Timeout reached ? 334 */ 335 if (i > UGETH_AN_TIMEOUT) { 336 mii_info->link = 0; 337 return 0; 338 } 339 340 i++; 341 udelay(1000); /* 1 ms */ 342 status = phy_read(mii_info, PHY_BMSR); 343 } 344 mii_info->link = 1; 345 udelay(500000); /* another 500 ms (results in faster booting) */ 346 } else { 347 if (status & PHY_BMSR_LS) 348 mii_info->link = 1; 349 else 350 mii_info->link = 0; 351 } 352 353 return 0; 354 } 355 356 static int genmii_read_status (struct uec_mii_info *mii_info) 357 { 358 u16 status; 359 int err; 360 361 /* Update the link, but return if there 362 * was an error */ 363 err = genmii_update_link (mii_info); 364 if (err) 365 return err; 366 367 if (mii_info->autoneg) { 368 status = phy_read(mii_info, MII_1000BASETSTATUS); 369 370 if (status & (LPA_1000FULL | LPA_1000HALF)) { 371 mii_info->speed = SPEED_1000; 372 if (status & LPA_1000FULL) 373 mii_info->duplex = DUPLEX_FULL; 374 else 375 mii_info->duplex = DUPLEX_HALF; 376 } else { 377 status = phy_read(mii_info, PHY_ANLPAR); 378 379 if (status & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) 380 mii_info->duplex = DUPLEX_FULL; 381 else 382 mii_info->duplex = DUPLEX_HALF; 383 if (status & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) 384 mii_info->speed = SPEED_100; 385 else 386 mii_info->speed = SPEED_10; 387 } 388 mii_info->pause = 0; 389 } 390 /* On non-aneg, we assume what we put in BMCR is the speed, 391 * though magic-aneg shouldn't prevent this case from occurring 392 */ 393 394 return 0; 395 } 396 397 static int bcm_init(struct uec_mii_info *mii_info) 398 { 399 struct eth_device *edev = mii_info->dev; 400 uec_private_t *uec = edev->priv; 401 402 gbit_config_aneg(mii_info); 403 404 if (uec->uec_info->enet_interface == ENET_1000_RGMII_RXID) { 405 u16 val; 406 int cnt = 50; 407 408 /* Wait for aneg to complete. */ 409 do 410 val = phy_read(mii_info, PHY_BMSR); 411 while (--cnt && !(val & PHY_BMSR_AUTN_COMP)); 412 413 /* Set RDX clk delay. */ 414 phy_write(mii_info, 0x18, 0x7 | (7 << 12)); 415 416 val = phy_read(mii_info, 0x18); 417 /* Set RDX-RXC skew. */ 418 val |= (1 << 8); 419 val |= (7 | (7 << 12)); 420 /* Write bits 14:0. */ 421 val |= (1 << 15); 422 phy_write(mii_info, 0x18, val); 423 } 424 425 return 0; 426 } 427 428 static int marvell_init(struct uec_mii_info *mii_info) 429 { 430 struct eth_device *edev = mii_info->dev; 431 uec_private_t *uec = edev->priv; 432 enum enet_interface iface = uec->uec_info->enet_interface; 433 434 if (iface == ENET_1000_RGMII_ID || 435 iface == ENET_1000_RGMII_RXID || 436 iface == ENET_1000_RGMII_TXID) { 437 int temp; 438 439 temp = phy_read(mii_info, MII_M1111_PHY_EXT_CR); 440 if (iface == ENET_1000_RGMII_ID) { 441 temp |= MII_M1111_RX_DELAY | MII_M1111_TX_DELAY; 442 } else if (iface == ENET_1000_RGMII_RXID) { 443 temp &= ~MII_M1111_TX_DELAY; 444 temp |= MII_M1111_RX_DELAY; 445 } else if (iface == ENET_1000_RGMII_TXID) { 446 temp &= ~MII_M1111_RX_DELAY; 447 temp |= MII_M1111_TX_DELAY; 448 } 449 phy_write(mii_info, MII_M1111_PHY_EXT_CR, temp); 450 451 temp = phy_read(mii_info, MII_M1111_PHY_EXT_SR); 452 temp &= ~MII_M1111_HWCFG_MODE_MASK; 453 temp |= MII_M1111_HWCFG_MODE_RGMII; 454 phy_write(mii_info, MII_M1111_PHY_EXT_SR, temp); 455 456 phy_write(mii_info, PHY_BMCR, PHY_BMCR_RESET); 457 } 458 459 return 0; 460 } 461 462 static int marvell_read_status (struct uec_mii_info *mii_info) 463 { 464 u16 status; 465 int err; 466 467 /* Update the link, but return if there 468 * was an error */ 469 err = genmii_update_link (mii_info); 470 if (err) 471 return err; 472 473 /* If the link is up, read the speed and duplex */ 474 /* If we aren't autonegotiating, assume speeds 475 * are as set */ 476 if (mii_info->autoneg && mii_info->link) { 477 int speed; 478 479 status = phy_read (mii_info, MII_M1011_PHY_SPEC_STATUS); 480 481 /* Get the duplexity */ 482 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) 483 mii_info->duplex = DUPLEX_FULL; 484 else 485 mii_info->duplex = DUPLEX_HALF; 486 487 /* Get the speed */ 488 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; 489 switch (speed) { 490 case MII_M1011_PHY_SPEC_STATUS_1000: 491 mii_info->speed = SPEED_1000; 492 break; 493 case MII_M1011_PHY_SPEC_STATUS_100: 494 mii_info->speed = SPEED_100; 495 break; 496 default: 497 mii_info->speed = SPEED_10; 498 break; 499 } 500 mii_info->pause = 0; 501 } 502 503 return 0; 504 } 505 506 static int marvell_ack_interrupt (struct uec_mii_info *mii_info) 507 { 508 /* Clear the interrupts by reading the reg */ 509 phy_read (mii_info, MII_M1011_IEVENT); 510 511 return 0; 512 } 513 514 static int marvell_config_intr (struct uec_mii_info *mii_info) 515 { 516 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 517 phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 518 else 519 phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 520 521 return 0; 522 } 523 524 static int dm9161_init (struct uec_mii_info *mii_info) 525 { 526 /* Reset the PHY */ 527 phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) | 528 PHY_BMCR_RESET); 529 /* PHY and MAC connect */ 530 phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) & 531 ~PHY_BMCR_ISO); 532 533 phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); 534 535 config_genmii_advert (mii_info); 536 /* Start/restart aneg */ 537 genmii_config_aneg (mii_info); 538 539 return 0; 540 } 541 542 static int dm9161_config_aneg (struct uec_mii_info *mii_info) 543 { 544 return 0; 545 } 546 547 static int dm9161_read_status (struct uec_mii_info *mii_info) 548 { 549 u16 status; 550 int err; 551 552 /* Update the link, but return if there was an error */ 553 err = genmii_update_link (mii_info); 554 if (err) 555 return err; 556 /* If the link is up, read the speed and duplex 557 If we aren't autonegotiating assume speeds are as set */ 558 if (mii_info->autoneg && mii_info->link) { 559 status = phy_read (mii_info, MII_DM9161_SCSR); 560 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) 561 mii_info->speed = SPEED_100; 562 else 563 mii_info->speed = SPEED_10; 564 565 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) 566 mii_info->duplex = DUPLEX_FULL; 567 else 568 mii_info->duplex = DUPLEX_HALF; 569 } 570 571 return 0; 572 } 573 574 static int dm9161_ack_interrupt (struct uec_mii_info *mii_info) 575 { 576 /* Clear the interrupt by reading the reg */ 577 phy_read (mii_info, MII_DM9161_INTR); 578 579 return 0; 580 } 581 582 static int dm9161_config_intr (struct uec_mii_info *mii_info) 583 { 584 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 585 phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); 586 else 587 phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); 588 589 return 0; 590 } 591 592 static void dm9161_close (struct uec_mii_info *mii_info) 593 { 594 } 595 596 static int fixed_phy_aneg (struct uec_mii_info *mii_info) 597 { 598 mii_info->autoneg = 0; /* Turn off auto negotiation for fixed phy */ 599 return 0; 600 } 601 602 static int fixed_phy_read_status (struct uec_mii_info *mii_info) 603 { 604 int i = 0; 605 606 for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) { 607 if (strncmp(mii_info->dev->name, fixed_phy_port[i].name, 608 strlen(mii_info->dev->name)) == 0) { 609 mii_info->speed = fixed_phy_port[i].speed; 610 mii_info->duplex = fixed_phy_port[i].duplex; 611 mii_info->link = 1; /* Link is always UP */ 612 mii_info->pause = 0; 613 break; 614 } 615 } 616 return 0; 617 } 618 619 static int smsc_config_aneg (struct uec_mii_info *mii_info) 620 { 621 return 0; 622 } 623 624 static int smsc_read_status (struct uec_mii_info *mii_info) 625 { 626 u16 status; 627 int err; 628 629 /* Update the link, but return if there 630 * was an error */ 631 err = genmii_update_link (mii_info); 632 if (err) 633 return err; 634 635 /* If the link is up, read the speed and duplex */ 636 /* If we aren't autonegotiating, assume speeds 637 * are as set */ 638 if (mii_info->autoneg && mii_info->link) { 639 int val; 640 641 status = phy_read (mii_info, 0x1f); 642 val = (status & 0x1c) >> 2; 643 644 switch (val) { 645 case 1: 646 mii_info->duplex = DUPLEX_HALF; 647 mii_info->speed = SPEED_10; 648 break; 649 case 5: 650 mii_info->duplex = DUPLEX_FULL; 651 mii_info->speed = SPEED_10; 652 break; 653 case 2: 654 mii_info->duplex = DUPLEX_HALF; 655 mii_info->speed = SPEED_100; 656 break; 657 case 6: 658 mii_info->duplex = DUPLEX_FULL; 659 mii_info->speed = SPEED_100; 660 break; 661 } 662 mii_info->pause = 0; 663 } 664 665 return 0; 666 } 667 668 static struct phy_info phy_info_dm9161 = { 669 .phy_id = 0x0181b880, 670 .phy_id_mask = 0x0ffffff0, 671 .name = "Davicom DM9161E", 672 .init = dm9161_init, 673 .config_aneg = dm9161_config_aneg, 674 .read_status = dm9161_read_status, 675 .close = dm9161_close, 676 }; 677 678 static struct phy_info phy_info_dm9161a = { 679 .phy_id = 0x0181b8a0, 680 .phy_id_mask = 0x0ffffff0, 681 .name = "Davicom DM9161A", 682 .features = MII_BASIC_FEATURES, 683 .init = dm9161_init, 684 .config_aneg = dm9161_config_aneg, 685 .read_status = dm9161_read_status, 686 .ack_interrupt = dm9161_ack_interrupt, 687 .config_intr = dm9161_config_intr, 688 .close = dm9161_close, 689 }; 690 691 static struct phy_info phy_info_marvell = { 692 .phy_id = 0x01410c00, 693 .phy_id_mask = 0xffffff00, 694 .name = "Marvell 88E11x1", 695 .features = MII_GBIT_FEATURES, 696 .init = &marvell_init, 697 .config_aneg = &marvell_config_aneg, 698 .read_status = &marvell_read_status, 699 .ack_interrupt = &marvell_ack_interrupt, 700 .config_intr = &marvell_config_intr, 701 }; 702 703 static struct phy_info phy_info_bcm5481 = { 704 .phy_id = 0x0143bca0, 705 .phy_id_mask = 0xffffff0, 706 .name = "Broadcom 5481", 707 .features = MII_GBIT_FEATURES, 708 .read_status = genmii_read_status, 709 .init = bcm_init, 710 }; 711 712 static struct phy_info phy_info_fixedphy = { 713 .phy_id = CONFIG_FIXED_PHY, 714 .phy_id_mask = CONFIG_FIXED_PHY, 715 .name = "Fixed PHY", 716 .config_aneg = fixed_phy_aneg, 717 .read_status = fixed_phy_read_status, 718 }; 719 720 static struct phy_info phy_info_smsclan8700 = { 721 .phy_id = 0x0007c0c0, 722 .phy_id_mask = 0xfffffff0, 723 .name = "SMSC LAN8700", 724 .features = MII_BASIC_FEATURES, 725 .config_aneg = smsc_config_aneg, 726 .read_status = smsc_read_status, 727 }; 728 729 static struct phy_info phy_info_genmii = { 730 .phy_id = 0x00000000, 731 .phy_id_mask = 0x00000000, 732 .name = "Generic MII", 733 .features = MII_BASIC_FEATURES, 734 .config_aneg = genmii_config_aneg, 735 .read_status = genmii_read_status, 736 }; 737 738 static struct phy_info *phy_info[] = { 739 &phy_info_dm9161, 740 &phy_info_dm9161a, 741 &phy_info_marvell, 742 &phy_info_bcm5481, 743 &phy_info_smsclan8700, 744 &phy_info_fixedphy, 745 &phy_info_genmii, 746 NULL 747 }; 748 749 u16 phy_read (struct uec_mii_info *mii_info, u16 regnum) 750 { 751 return mii_info->mdio_read (mii_info->dev, mii_info->mii_id, regnum); 752 } 753 754 void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val) 755 { 756 mii_info->mdio_write (mii_info->dev, mii_info->mii_id, regnum, val); 757 } 758 759 /* Use the PHY ID registers to determine what type of PHY is attached 760 * to device dev. return a struct phy_info structure describing that PHY 761 */ 762 struct phy_info *uec_get_phy_info (struct uec_mii_info *mii_info) 763 { 764 u16 phy_reg; 765 u32 phy_ID; 766 int i; 767 struct phy_info *theInfo = NULL; 768 769 /* Grab the bits from PHYIR1, and put them in the upper half */ 770 phy_reg = phy_read (mii_info, PHY_PHYIDR1); 771 phy_ID = (phy_reg & 0xffff) << 16; 772 773 /* Grab the bits from PHYIR2, and put them in the lower half */ 774 phy_reg = phy_read (mii_info, PHY_PHYIDR2); 775 phy_ID |= (phy_reg & 0xffff); 776 777 /* loop through all the known PHY types, and find one that */ 778 /* matches the ID we read from the PHY. */ 779 for (i = 0; phy_info[i]; i++) 780 if (phy_info[i]->phy_id == 781 (phy_ID & phy_info[i]->phy_id_mask)) { 782 theInfo = phy_info[i]; 783 break; 784 } 785 786 /* This shouldn't happen, as we have generic PHY support */ 787 if (theInfo == NULL) { 788 ugphy_info ("UEC: PHY id %x is not supported!", phy_ID); 789 return NULL; 790 } else { 791 ugphy_info ("UEC: PHY is %s (%x)", theInfo->name, phy_ID); 792 } 793 794 return theInfo; 795 } 796 797 void marvell_phy_interface_mode (struct eth_device *dev, 798 enet_interface_e mode) 799 { 800 uec_private_t *uec = (uec_private_t *) dev->priv; 801 struct uec_mii_info *mii_info; 802 u16 status; 803 804 if (!uec->mii_info) { 805 printf ("%s: the PHY not initialized\n", __FUNCTION__); 806 return; 807 } 808 mii_info = uec->mii_info; 809 810 if (mode == ENET_100_RGMII) { 811 phy_write (mii_info, 0x00, 0x9140); 812 phy_write (mii_info, 0x1d, 0x001f); 813 phy_write (mii_info, 0x1e, 0x200c); 814 phy_write (mii_info, 0x1d, 0x0005); 815 phy_write (mii_info, 0x1e, 0x0000); 816 phy_write (mii_info, 0x1e, 0x0100); 817 phy_write (mii_info, 0x09, 0x0e00); 818 phy_write (mii_info, 0x04, 0x01e1); 819 phy_write (mii_info, 0x00, 0x9140); 820 phy_write (mii_info, 0x00, 0x1000); 821 udelay (100000); 822 phy_write (mii_info, 0x00, 0x2900); 823 phy_write (mii_info, 0x14, 0x0cd2); 824 phy_write (mii_info, 0x00, 0xa100); 825 phy_write (mii_info, 0x09, 0x0000); 826 phy_write (mii_info, 0x1b, 0x800b); 827 phy_write (mii_info, 0x04, 0x05e1); 828 phy_write (mii_info, 0x00, 0xa100); 829 phy_write (mii_info, 0x00, 0x2100); 830 udelay (1000000); 831 } else if (mode == ENET_10_RGMII) { 832 phy_write (mii_info, 0x14, 0x8e40); 833 phy_write (mii_info, 0x1b, 0x800b); 834 phy_write (mii_info, 0x14, 0x0c82); 835 phy_write (mii_info, 0x00, 0x8100); 836 udelay (1000000); 837 } 838 839 /* handle 88e1111 rev.B2 erratum 5.6 */ 840 if (mii_info->autoneg) { 841 status = phy_read (mii_info, PHY_BMCR); 842 phy_write (mii_info, PHY_BMCR, status | PHY_BMCR_AUTON); 843 } 844 /* now the B2 will correctly report autoneg completion status */ 845 } 846 847 void change_phy_interface_mode (struct eth_device *dev, enet_interface_e mode) 848 { 849 #ifdef CONFIG_PHY_MODE_NEED_CHANGE 850 marvell_phy_interface_mode (dev, mode); 851 #endif 852 } 853