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