1 /* 2 * PHY drivers for the sungem ethernet driver. 3 * 4 * This file could be shared with other drivers. 5 * 6 * (c) 2002-2007, Benjamin Herrenscmidt (benh@kernel.crashing.org) 7 * 8 * TODO: 9 * - Add support for PHYs that provide an IRQ line 10 * - Eventually moved the entire polling state machine in 11 * there (out of the eth driver), so that it can easily be 12 * skipped on PHYs that implement it in hardware. 13 * - On LXT971 & BCM5201, Apple uses some chip specific regs 14 * to read the link status. Figure out why and if it makes 15 * sense to do the same (magic aneg ?) 16 * - Apple has some additional power management code for some 17 * Broadcom PHYs that they "hide" from the OpenSource version 18 * of darwin, still need to reverse engineer that 19 */ 20 21 22 #include <linux/module.h> 23 24 #include <linux/kernel.h> 25 #include <linux/types.h> 26 #include <linux/netdevice.h> 27 #include <linux/etherdevice.h> 28 #include <linux/mii.h> 29 #include <linux/ethtool.h> 30 #include <linux/delay.h> 31 32 #ifdef CONFIG_PPC_PMAC 33 #include <asm/prom.h> 34 #endif 35 36 #include "sungem_phy.h" 37 38 /* Link modes of the BCM5400 PHY */ 39 static const int phy_BCM5400_link_table[8][3] = { 40 { 0, 0, 0 }, /* No link */ 41 { 0, 0, 0 }, /* 10BT Half Duplex */ 42 { 1, 0, 0 }, /* 10BT Full Duplex */ 43 { 0, 1, 0 }, /* 100BT Half Duplex */ 44 { 0, 1, 0 }, /* 100BT Half Duplex */ 45 { 1, 1, 0 }, /* 100BT Full Duplex*/ 46 { 1, 0, 1 }, /* 1000BT */ 47 { 1, 0, 1 }, /* 1000BT */ 48 }; 49 50 static inline int __phy_read(struct mii_phy* phy, int id, int reg) 51 { 52 return phy->mdio_read(phy->dev, id, reg); 53 } 54 55 static inline void __phy_write(struct mii_phy* phy, int id, int reg, int val) 56 { 57 phy->mdio_write(phy->dev, id, reg, val); 58 } 59 60 static inline int phy_read(struct mii_phy* phy, int reg) 61 { 62 return phy->mdio_read(phy->dev, phy->mii_id, reg); 63 } 64 65 static inline void phy_write(struct mii_phy* phy, int reg, int val) 66 { 67 phy->mdio_write(phy->dev, phy->mii_id, reg, val); 68 } 69 70 static int reset_one_mii_phy(struct mii_phy* phy, int phy_id) 71 { 72 u16 val; 73 int limit = 10000; 74 75 val = __phy_read(phy, phy_id, MII_BMCR); 76 val &= ~(BMCR_ISOLATE | BMCR_PDOWN); 77 val |= BMCR_RESET; 78 __phy_write(phy, phy_id, MII_BMCR, val); 79 80 udelay(100); 81 82 while (limit--) { 83 val = __phy_read(phy, phy_id, MII_BMCR); 84 if ((val & BMCR_RESET) == 0) 85 break; 86 udelay(10); 87 } 88 if ((val & BMCR_ISOLATE) && limit > 0) 89 __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE); 90 91 return (limit <= 0); 92 } 93 94 static int bcm5201_init(struct mii_phy* phy) 95 { 96 u16 data; 97 98 data = phy_read(phy, MII_BCM5201_MULTIPHY); 99 data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE; 100 phy_write(phy, MII_BCM5201_MULTIPHY, data); 101 102 phy_write(phy, MII_BCM5201_INTERRUPT, 0); 103 104 return 0; 105 } 106 107 static int bcm5201_suspend(struct mii_phy* phy) 108 { 109 phy_write(phy, MII_BCM5201_INTERRUPT, 0); 110 phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE); 111 112 return 0; 113 } 114 115 static int bcm5221_init(struct mii_phy* phy) 116 { 117 u16 data; 118 119 data = phy_read(phy, MII_BCM5221_TEST); 120 phy_write(phy, MII_BCM5221_TEST, 121 data | MII_BCM5221_TEST_ENABLE_SHADOWS); 122 123 data = phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2); 124 phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2, 125 data | MII_BCM5221_SHDOW_AUX_STAT2_APD); 126 127 data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 128 phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 129 data | MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR); 130 131 data = phy_read(phy, MII_BCM5221_TEST); 132 phy_write(phy, MII_BCM5221_TEST, 133 data & ~MII_BCM5221_TEST_ENABLE_SHADOWS); 134 135 return 0; 136 } 137 138 static int bcm5221_suspend(struct mii_phy* phy) 139 { 140 u16 data; 141 142 data = phy_read(phy, MII_BCM5221_TEST); 143 phy_write(phy, MII_BCM5221_TEST, 144 data | MII_BCM5221_TEST_ENABLE_SHADOWS); 145 146 data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 147 phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 148 data | MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE); 149 150 return 0; 151 } 152 153 static int bcm5241_init(struct mii_phy* phy) 154 { 155 u16 data; 156 157 data = phy_read(phy, MII_BCM5221_TEST); 158 phy_write(phy, MII_BCM5221_TEST, 159 data | MII_BCM5221_TEST_ENABLE_SHADOWS); 160 161 data = phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2); 162 phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2, 163 data | MII_BCM5221_SHDOW_AUX_STAT2_APD); 164 165 data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 166 phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 167 data & ~MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR); 168 169 data = phy_read(phy, MII_BCM5221_TEST); 170 phy_write(phy, MII_BCM5221_TEST, 171 data & ~MII_BCM5221_TEST_ENABLE_SHADOWS); 172 173 return 0; 174 } 175 176 static int bcm5241_suspend(struct mii_phy* phy) 177 { 178 u16 data; 179 180 data = phy_read(phy, MII_BCM5221_TEST); 181 phy_write(phy, MII_BCM5221_TEST, 182 data | MII_BCM5221_TEST_ENABLE_SHADOWS); 183 184 data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); 185 phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, 186 data | MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR); 187 188 return 0; 189 } 190 191 static int bcm5400_init(struct mii_phy* phy) 192 { 193 u16 data; 194 195 /* Configure for gigabit full duplex */ 196 data = phy_read(phy, MII_BCM5400_AUXCONTROL); 197 data |= MII_BCM5400_AUXCONTROL_PWR10BASET; 198 phy_write(phy, MII_BCM5400_AUXCONTROL, data); 199 200 data = phy_read(phy, MII_BCM5400_GB_CONTROL); 201 data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; 202 phy_write(phy, MII_BCM5400_GB_CONTROL, data); 203 204 udelay(100); 205 206 /* Reset and configure cascaded 10/100 PHY */ 207 (void)reset_one_mii_phy(phy, 0x1f); 208 209 data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY); 210 data |= MII_BCM5201_MULTIPHY_SERIALMODE; 211 __phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data); 212 213 data = phy_read(phy, MII_BCM5400_AUXCONTROL); 214 data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET; 215 phy_write(phy, MII_BCM5400_AUXCONTROL, data); 216 217 return 0; 218 } 219 220 static int bcm5400_suspend(struct mii_phy* phy) 221 { 222 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */ 223 phy_write(phy, MII_BMCR, BMCR_PDOWN); 224 #endif 225 return 0; 226 } 227 228 static int bcm5401_init(struct mii_phy* phy) 229 { 230 u16 data; 231 int rev; 232 233 rev = phy_read(phy, MII_PHYSID2) & 0x000f; 234 if (rev == 0 || rev == 3) { 235 /* Some revisions of 5401 appear to need this 236 * initialisation sequence to disable, according 237 * to OF, "tap power management" 238 * 239 * WARNING ! OF and Darwin don't agree on the 240 * register addresses. OF seem to interpret the 241 * register numbers below as decimal 242 * 243 * Note: This should (and does) match tg3_init_5401phy_dsp 244 * in the tg3.c driver. -DaveM 245 */ 246 phy_write(phy, 0x18, 0x0c20); 247 phy_write(phy, 0x17, 0x0012); 248 phy_write(phy, 0x15, 0x1804); 249 phy_write(phy, 0x17, 0x0013); 250 phy_write(phy, 0x15, 0x1204); 251 phy_write(phy, 0x17, 0x8006); 252 phy_write(phy, 0x15, 0x0132); 253 phy_write(phy, 0x17, 0x8006); 254 phy_write(phy, 0x15, 0x0232); 255 phy_write(phy, 0x17, 0x201f); 256 phy_write(phy, 0x15, 0x0a20); 257 } 258 259 /* Configure for gigabit full duplex */ 260 data = phy_read(phy, MII_BCM5400_GB_CONTROL); 261 data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; 262 phy_write(phy, MII_BCM5400_GB_CONTROL, data); 263 264 udelay(10); 265 266 /* Reset and configure cascaded 10/100 PHY */ 267 (void)reset_one_mii_phy(phy, 0x1f); 268 269 data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY); 270 data |= MII_BCM5201_MULTIPHY_SERIALMODE; 271 __phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data); 272 273 return 0; 274 } 275 276 static int bcm5401_suspend(struct mii_phy* phy) 277 { 278 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */ 279 phy_write(phy, MII_BMCR, BMCR_PDOWN); 280 #endif 281 return 0; 282 } 283 284 static int bcm5411_init(struct mii_phy* phy) 285 { 286 u16 data; 287 288 /* Here's some more Apple black magic to setup 289 * some voltage stuffs. 290 */ 291 phy_write(phy, 0x1c, 0x8c23); 292 phy_write(phy, 0x1c, 0x8ca3); 293 phy_write(phy, 0x1c, 0x8c23); 294 295 /* Here, Apple seems to want to reset it, do 296 * it as well 297 */ 298 phy_write(phy, MII_BMCR, BMCR_RESET); 299 phy_write(phy, MII_BMCR, 0x1340); 300 301 data = phy_read(phy, MII_BCM5400_GB_CONTROL); 302 data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; 303 phy_write(phy, MII_BCM5400_GB_CONTROL, data); 304 305 udelay(10); 306 307 /* Reset and configure cascaded 10/100 PHY */ 308 (void)reset_one_mii_phy(phy, 0x1f); 309 310 return 0; 311 } 312 313 static int generic_suspend(struct mii_phy* phy) 314 { 315 phy_write(phy, MII_BMCR, BMCR_PDOWN); 316 317 return 0; 318 } 319 320 static int bcm5421_init(struct mii_phy* phy) 321 { 322 u16 data; 323 unsigned int id; 324 325 id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2)); 326 327 /* Revision 0 of 5421 needs some fixups */ 328 if (id == 0x002060e0) { 329 /* This is borrowed from MacOS 330 */ 331 phy_write(phy, 0x18, 0x1007); 332 data = phy_read(phy, 0x18); 333 phy_write(phy, 0x18, data | 0x0400); 334 phy_write(phy, 0x18, 0x0007); 335 data = phy_read(phy, 0x18); 336 phy_write(phy, 0x18, data | 0x0800); 337 phy_write(phy, 0x17, 0x000a); 338 data = phy_read(phy, 0x15); 339 phy_write(phy, 0x15, data | 0x0200); 340 } 341 342 /* Pick up some init code from OF for K2 version */ 343 if ((id & 0xfffffff0) == 0x002062e0) { 344 phy_write(phy, 4, 0x01e1); 345 phy_write(phy, 9, 0x0300); 346 } 347 348 /* Check if we can enable automatic low power */ 349 #ifdef CONFIG_PPC_PMAC 350 if (phy->platform_data) { 351 struct device_node *np = of_get_parent(phy->platform_data); 352 int can_low_power = 1; 353 if (np == NULL || get_property(np, "no-autolowpower", NULL)) 354 can_low_power = 0; 355 if (can_low_power) { 356 /* Enable automatic low-power */ 357 phy_write(phy, 0x1c, 0x9002); 358 phy_write(phy, 0x1c, 0xa821); 359 phy_write(phy, 0x1c, 0x941d); 360 } 361 } 362 #endif /* CONFIG_PPC_PMAC */ 363 364 return 0; 365 } 366 367 static int bcm5421_enable_fiber(struct mii_phy* phy) 368 { 369 /* enable fiber mode */ 370 phy_write(phy, MII_NCONFIG, 0x9020); 371 /* LEDs active in both modes, autosense prio = fiber */ 372 phy_write(phy, MII_NCONFIG, 0x945f); 373 374 /* switch off fibre autoneg */ 375 phy_write(phy, MII_NCONFIG, 0xfc01); 376 phy_write(phy, 0x0b, 0x0004); 377 378 return 0; 379 } 380 381 static int bcm5461_enable_fiber(struct mii_phy* phy) 382 { 383 phy_write(phy, MII_NCONFIG, 0xfc0c); 384 phy_write(phy, MII_BMCR, 0x4140); 385 phy_write(phy, MII_NCONFIG, 0xfc0b); 386 phy_write(phy, MII_BMCR, 0x0140); 387 388 return 0; 389 } 390 391 static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise) 392 { 393 u16 ctl, adv; 394 395 phy->autoneg = 1; 396 phy->speed = SPEED_10; 397 phy->duplex = DUPLEX_HALF; 398 phy->pause = 0; 399 phy->advertising = advertise; 400 401 /* Setup standard advertise */ 402 adv = phy_read(phy, MII_ADVERTISE); 403 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 404 if (advertise & ADVERTISED_10baseT_Half) 405 adv |= ADVERTISE_10HALF; 406 if (advertise & ADVERTISED_10baseT_Full) 407 adv |= ADVERTISE_10FULL; 408 if (advertise & ADVERTISED_100baseT_Half) 409 adv |= ADVERTISE_100HALF; 410 if (advertise & ADVERTISED_100baseT_Full) 411 adv |= ADVERTISE_100FULL; 412 if (advertise & ADVERTISED_Pause) 413 adv |= ADVERTISE_PAUSE_CAP; 414 if (advertise & ADVERTISED_Asym_Pause) 415 adv |= ADVERTISE_PAUSE_ASYM; 416 phy_write(phy, MII_ADVERTISE, adv); 417 418 /* Setup 1000BT advertise */ 419 adv = phy_read(phy, MII_1000BASETCONTROL); 420 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP|MII_1000BASETCONTROL_HALFDUPLEXCAP); 421 if (advertise & SUPPORTED_1000baseT_Half) 422 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 423 if (advertise & SUPPORTED_1000baseT_Full) 424 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 425 phy_write(phy, MII_1000BASETCONTROL, adv); 426 427 /* Start/Restart aneg */ 428 ctl = phy_read(phy, MII_BMCR); 429 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 430 phy_write(phy, MII_BMCR, ctl); 431 432 return 0; 433 } 434 435 static int bcm54xx_setup_forced(struct mii_phy *phy, int speed, int fd) 436 { 437 u16 ctl; 438 439 phy->autoneg = 0; 440 phy->speed = speed; 441 phy->duplex = fd; 442 phy->pause = 0; 443 444 ctl = phy_read(phy, MII_BMCR); 445 ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE); 446 447 /* First reset the PHY */ 448 phy_write(phy, MII_BMCR, ctl | BMCR_RESET); 449 450 /* Select speed & duplex */ 451 switch(speed) { 452 case SPEED_10: 453 break; 454 case SPEED_100: 455 ctl |= BMCR_SPEED100; 456 break; 457 case SPEED_1000: 458 ctl |= BMCR_SPD2; 459 } 460 if (fd == DUPLEX_FULL) 461 ctl |= BMCR_FULLDPLX; 462 463 // XXX Should we set the sungem to GII now on 1000BT ? 464 465 phy_write(phy, MII_BMCR, ctl); 466 467 return 0; 468 } 469 470 static int bcm54xx_read_link(struct mii_phy *phy) 471 { 472 int link_mode; 473 u16 val; 474 475 if (phy->autoneg) { 476 val = phy_read(phy, MII_BCM5400_AUXSTATUS); 477 link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >> 478 MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT); 479 phy->duplex = phy_BCM5400_link_table[link_mode][0] ? 480 DUPLEX_FULL : DUPLEX_HALF; 481 phy->speed = phy_BCM5400_link_table[link_mode][2] ? 482 SPEED_1000 : 483 (phy_BCM5400_link_table[link_mode][1] ? 484 SPEED_100 : SPEED_10); 485 val = phy_read(phy, MII_LPA); 486 phy->pause = (phy->duplex == DUPLEX_FULL) && 487 ((val & LPA_PAUSE) != 0); 488 } 489 /* On non-aneg, we assume what we put in BMCR is the speed, 490 * though magic-aneg shouldn't prevent this case from occurring 491 */ 492 493 return 0; 494 } 495 496 static int marvell88e1111_init(struct mii_phy* phy) 497 { 498 u16 rev; 499 500 /* magic init sequence for rev 0 */ 501 rev = phy_read(phy, MII_PHYSID2) & 0x000f; 502 if (rev == 0) { 503 phy_write(phy, 0x1d, 0x000a); 504 phy_write(phy, 0x1e, 0x0821); 505 506 phy_write(phy, 0x1d, 0x0006); 507 phy_write(phy, 0x1e, 0x8600); 508 509 phy_write(phy, 0x1d, 0x000b); 510 phy_write(phy, 0x1e, 0x0100); 511 512 phy_write(phy, 0x1d, 0x0004); 513 phy_write(phy, 0x1e, 0x4850); 514 } 515 return 0; 516 } 517 518 static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise) 519 { 520 u16 ctl, adv; 521 522 phy->autoneg = 1; 523 phy->speed = SPEED_10; 524 phy->duplex = DUPLEX_HALF; 525 phy->pause = 0; 526 phy->advertising = advertise; 527 528 /* Setup standard advertise */ 529 adv = phy_read(phy, MII_ADVERTISE); 530 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 531 if (advertise & ADVERTISED_10baseT_Half) 532 adv |= ADVERTISE_10HALF; 533 if (advertise & ADVERTISED_10baseT_Full) 534 adv |= ADVERTISE_10FULL; 535 if (advertise & ADVERTISED_100baseT_Half) 536 adv |= ADVERTISE_100HALF; 537 if (advertise & ADVERTISED_100baseT_Full) 538 adv |= ADVERTISE_100FULL; 539 if (advertise & ADVERTISED_Pause) 540 adv |= ADVERTISE_PAUSE_CAP; 541 if (advertise & ADVERTISED_Asym_Pause) 542 adv |= ADVERTISE_PAUSE_ASYM; 543 phy_write(phy, MII_ADVERTISE, adv); 544 545 /* Setup 1000BT advertise & enable crossover detect 546 * XXX How do we advertise 1000BT ? Darwin source is 547 * confusing here, they read from specific control and 548 * write to control... Someone has specs for those 549 * beasts ? 550 */ 551 adv = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL); 552 adv |= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX; 553 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | 554 MII_1000BASETCONTROL_HALFDUPLEXCAP); 555 if (advertise & SUPPORTED_1000baseT_Half) 556 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 557 if (advertise & SUPPORTED_1000baseT_Full) 558 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 559 phy_write(phy, MII_1000BASETCONTROL, adv); 560 561 /* Start/Restart aneg */ 562 ctl = phy_read(phy, MII_BMCR); 563 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 564 phy_write(phy, MII_BMCR, ctl); 565 566 return 0; 567 } 568 569 static int marvell_setup_forced(struct mii_phy *phy, int speed, int fd) 570 { 571 u16 ctl, ctl2; 572 573 phy->autoneg = 0; 574 phy->speed = speed; 575 phy->duplex = fd; 576 phy->pause = 0; 577 578 ctl = phy_read(phy, MII_BMCR); 579 ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE); 580 ctl |= BMCR_RESET; 581 582 /* Select speed & duplex */ 583 switch(speed) { 584 case SPEED_10: 585 break; 586 case SPEED_100: 587 ctl |= BMCR_SPEED100; 588 break; 589 /* I'm not sure about the one below, again, Darwin source is 590 * quite confusing and I lack chip specs 591 */ 592 case SPEED_1000: 593 ctl |= BMCR_SPD2; 594 } 595 if (fd == DUPLEX_FULL) 596 ctl |= BMCR_FULLDPLX; 597 598 /* Disable crossover. Again, the way Apple does it is strange, 599 * though I don't assume they are wrong ;) 600 */ 601 ctl2 = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL); 602 ctl2 &= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX | 603 MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX | 604 MII_1000BASETCONTROL_FULLDUPLEXCAP | 605 MII_1000BASETCONTROL_HALFDUPLEXCAP); 606 if (speed == SPEED_1000) 607 ctl2 |= (fd == DUPLEX_FULL) ? 608 MII_1000BASETCONTROL_FULLDUPLEXCAP : 609 MII_1000BASETCONTROL_HALFDUPLEXCAP; 610 phy_write(phy, MII_1000BASETCONTROL, ctl2); 611 612 // XXX Should we set the sungem to GII now on 1000BT ? 613 614 phy_write(phy, MII_BMCR, ctl); 615 616 return 0; 617 } 618 619 static int marvell_read_link(struct mii_phy *phy) 620 { 621 u16 status, pmask; 622 623 if (phy->autoneg) { 624 status = phy_read(phy, MII_M1011_PHY_SPEC_STATUS); 625 if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0) 626 return -EAGAIN; 627 if (status & MII_M1011_PHY_SPEC_STATUS_1000) 628 phy->speed = SPEED_1000; 629 else if (status & MII_M1011_PHY_SPEC_STATUS_100) 630 phy->speed = SPEED_100; 631 else 632 phy->speed = SPEED_10; 633 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) 634 phy->duplex = DUPLEX_FULL; 635 else 636 phy->duplex = DUPLEX_HALF; 637 pmask = MII_M1011_PHY_SPEC_STATUS_TX_PAUSE | 638 MII_M1011_PHY_SPEC_STATUS_RX_PAUSE; 639 phy->pause = (status & pmask) == pmask; 640 } 641 /* On non-aneg, we assume what we put in BMCR is the speed, 642 * though magic-aneg shouldn't prevent this case from occurring 643 */ 644 645 return 0; 646 } 647 648 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) 649 { 650 u16 ctl, adv; 651 652 phy->autoneg = 1; 653 phy->speed = SPEED_10; 654 phy->duplex = DUPLEX_HALF; 655 phy->pause = 0; 656 phy->advertising = advertise; 657 658 /* Setup standard advertise */ 659 adv = phy_read(phy, MII_ADVERTISE); 660 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 661 if (advertise & ADVERTISED_10baseT_Half) 662 adv |= ADVERTISE_10HALF; 663 if (advertise & ADVERTISED_10baseT_Full) 664 adv |= ADVERTISE_10FULL; 665 if (advertise & ADVERTISED_100baseT_Half) 666 adv |= ADVERTISE_100HALF; 667 if (advertise & ADVERTISED_100baseT_Full) 668 adv |= ADVERTISE_100FULL; 669 if (advertise & ADVERTISED_Pause) 670 adv |= ADVERTISE_PAUSE_CAP; 671 if (advertise & ADVERTISED_Asym_Pause) 672 adv |= ADVERTISE_PAUSE_ASYM; 673 phy_write(phy, MII_ADVERTISE, adv); 674 675 /* Start/Restart aneg */ 676 ctl = phy_read(phy, MII_BMCR); 677 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 678 phy_write(phy, MII_BMCR, ctl); 679 680 return 0; 681 } 682 683 static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd) 684 { 685 u16 ctl; 686 687 phy->autoneg = 0; 688 phy->speed = speed; 689 phy->duplex = fd; 690 phy->pause = 0; 691 692 ctl = phy_read(phy, MII_BMCR); 693 ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE); 694 695 /* First reset the PHY */ 696 phy_write(phy, MII_BMCR, ctl | BMCR_RESET); 697 698 /* Select speed & duplex */ 699 switch(speed) { 700 case SPEED_10: 701 break; 702 case SPEED_100: 703 ctl |= BMCR_SPEED100; 704 break; 705 case SPEED_1000: 706 default: 707 return -EINVAL; 708 } 709 if (fd == DUPLEX_FULL) 710 ctl |= BMCR_FULLDPLX; 711 phy_write(phy, MII_BMCR, ctl); 712 713 return 0; 714 } 715 716 static int genmii_poll_link(struct mii_phy *phy) 717 { 718 u16 status; 719 720 (void)phy_read(phy, MII_BMSR); 721 status = phy_read(phy, MII_BMSR); 722 if ((status & BMSR_LSTATUS) == 0) 723 return 0; 724 if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE)) 725 return 0; 726 return 1; 727 } 728 729 static int genmii_read_link(struct mii_phy *phy) 730 { 731 u16 lpa; 732 733 if (phy->autoneg) { 734 lpa = phy_read(phy, MII_LPA); 735 736 if (lpa & (LPA_10FULL | LPA_100FULL)) 737 phy->duplex = DUPLEX_FULL; 738 else 739 phy->duplex = DUPLEX_HALF; 740 if (lpa & (LPA_100FULL | LPA_100HALF)) 741 phy->speed = SPEED_100; 742 else 743 phy->speed = SPEED_10; 744 phy->pause = (phy->duplex == DUPLEX_FULL) && 745 ((lpa & LPA_PAUSE) != 0); 746 } 747 /* On non-aneg, we assume what we put in BMCR is the speed, 748 * though magic-aneg shouldn't prevent this case from occurring 749 */ 750 751 return 0; 752 } 753 754 755 #define MII_BASIC_FEATURES \ 756 (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ 757 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ 758 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | \ 759 SUPPORTED_Pause) 760 761 /* On gigabit capable PHYs, we advertise Pause support but not asym pause 762 * support for now as I'm not sure it's supported and Darwin doesn't do 763 * it neither. --BenH. 764 */ 765 #define MII_GBIT_FEATURES \ 766 (MII_BASIC_FEATURES | \ 767 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full) 768 769 /* Broadcom BCM 5201 */ 770 static struct mii_phy_ops bcm5201_phy_ops = { 771 .init = bcm5201_init, 772 .suspend = bcm5201_suspend, 773 .setup_aneg = genmii_setup_aneg, 774 .setup_forced = genmii_setup_forced, 775 .poll_link = genmii_poll_link, 776 .read_link = genmii_read_link, 777 }; 778 779 static struct mii_phy_def bcm5201_phy_def = { 780 .phy_id = 0x00406210, 781 .phy_id_mask = 0xfffffff0, 782 .name = "BCM5201", 783 .features = MII_BASIC_FEATURES, 784 .magic_aneg = 1, 785 .ops = &bcm5201_phy_ops 786 }; 787 788 /* Broadcom BCM 5221 */ 789 static struct mii_phy_ops bcm5221_phy_ops = { 790 .suspend = bcm5221_suspend, 791 .init = bcm5221_init, 792 .setup_aneg = genmii_setup_aneg, 793 .setup_forced = genmii_setup_forced, 794 .poll_link = genmii_poll_link, 795 .read_link = genmii_read_link, 796 }; 797 798 static struct mii_phy_def bcm5221_phy_def = { 799 .phy_id = 0x004061e0, 800 .phy_id_mask = 0xfffffff0, 801 .name = "BCM5221", 802 .features = MII_BASIC_FEATURES, 803 .magic_aneg = 1, 804 .ops = &bcm5221_phy_ops 805 }; 806 807 /* Broadcom BCM 5241 */ 808 static struct mii_phy_ops bcm5241_phy_ops = { 809 .suspend = bcm5241_suspend, 810 .init = bcm5241_init, 811 .setup_aneg = genmii_setup_aneg, 812 .setup_forced = genmii_setup_forced, 813 .poll_link = genmii_poll_link, 814 .read_link = genmii_read_link, 815 }; 816 static struct mii_phy_def bcm5241_phy_def = { 817 .phy_id = 0x0143bc30, 818 .phy_id_mask = 0xfffffff0, 819 .name = "BCM5241", 820 .features = MII_BASIC_FEATURES, 821 .magic_aneg = 1, 822 .ops = &bcm5241_phy_ops 823 }; 824 825 /* Broadcom BCM 5400 */ 826 static struct mii_phy_ops bcm5400_phy_ops = { 827 .init = bcm5400_init, 828 .suspend = bcm5400_suspend, 829 .setup_aneg = bcm54xx_setup_aneg, 830 .setup_forced = bcm54xx_setup_forced, 831 .poll_link = genmii_poll_link, 832 .read_link = bcm54xx_read_link, 833 }; 834 835 static struct mii_phy_def bcm5400_phy_def = { 836 .phy_id = 0x00206040, 837 .phy_id_mask = 0xfffffff0, 838 .name = "BCM5400", 839 .features = MII_GBIT_FEATURES, 840 .magic_aneg = 1, 841 .ops = &bcm5400_phy_ops 842 }; 843 844 /* Broadcom BCM 5401 */ 845 static struct mii_phy_ops bcm5401_phy_ops = { 846 .init = bcm5401_init, 847 .suspend = bcm5401_suspend, 848 .setup_aneg = bcm54xx_setup_aneg, 849 .setup_forced = bcm54xx_setup_forced, 850 .poll_link = genmii_poll_link, 851 .read_link = bcm54xx_read_link, 852 }; 853 854 static struct mii_phy_def bcm5401_phy_def = { 855 .phy_id = 0x00206050, 856 .phy_id_mask = 0xfffffff0, 857 .name = "BCM5401", 858 .features = MII_GBIT_FEATURES, 859 .magic_aneg = 1, 860 .ops = &bcm5401_phy_ops 861 }; 862 863 /* Broadcom BCM 5411 */ 864 static struct mii_phy_ops bcm5411_phy_ops = { 865 .init = bcm5411_init, 866 .suspend = generic_suspend, 867 .setup_aneg = bcm54xx_setup_aneg, 868 .setup_forced = bcm54xx_setup_forced, 869 .poll_link = genmii_poll_link, 870 .read_link = bcm54xx_read_link, 871 }; 872 873 static struct mii_phy_def bcm5411_phy_def = { 874 .phy_id = 0x00206070, 875 .phy_id_mask = 0xfffffff0, 876 .name = "BCM5411", 877 .features = MII_GBIT_FEATURES, 878 .magic_aneg = 1, 879 .ops = &bcm5411_phy_ops 880 }; 881 882 /* Broadcom BCM 5421 */ 883 static struct mii_phy_ops bcm5421_phy_ops = { 884 .init = bcm5421_init, 885 .suspend = generic_suspend, 886 .setup_aneg = bcm54xx_setup_aneg, 887 .setup_forced = bcm54xx_setup_forced, 888 .poll_link = genmii_poll_link, 889 .read_link = bcm54xx_read_link, 890 .enable_fiber = bcm5421_enable_fiber, 891 }; 892 893 static struct mii_phy_def bcm5421_phy_def = { 894 .phy_id = 0x002060e0, 895 .phy_id_mask = 0xfffffff0, 896 .name = "BCM5421", 897 .features = MII_GBIT_FEATURES, 898 .magic_aneg = 1, 899 .ops = &bcm5421_phy_ops 900 }; 901 902 /* Broadcom BCM 5421 built-in K2 */ 903 static struct mii_phy_ops bcm5421k2_phy_ops = { 904 .init = bcm5421_init, 905 .suspend = generic_suspend, 906 .setup_aneg = bcm54xx_setup_aneg, 907 .setup_forced = bcm54xx_setup_forced, 908 .poll_link = genmii_poll_link, 909 .read_link = bcm54xx_read_link, 910 }; 911 912 static struct mii_phy_def bcm5421k2_phy_def = { 913 .phy_id = 0x002062e0, 914 .phy_id_mask = 0xfffffff0, 915 .name = "BCM5421-K2", 916 .features = MII_GBIT_FEATURES, 917 .magic_aneg = 1, 918 .ops = &bcm5421k2_phy_ops 919 }; 920 921 static struct mii_phy_ops bcm5461_phy_ops = { 922 .init = bcm5421_init, 923 .suspend = generic_suspend, 924 .setup_aneg = bcm54xx_setup_aneg, 925 .setup_forced = bcm54xx_setup_forced, 926 .poll_link = genmii_poll_link, 927 .read_link = bcm54xx_read_link, 928 .enable_fiber = bcm5461_enable_fiber, 929 }; 930 931 static struct mii_phy_def bcm5461_phy_def = { 932 .phy_id = 0x002060c0, 933 .phy_id_mask = 0xfffffff0, 934 .name = "BCM5461", 935 .features = MII_GBIT_FEATURES, 936 .magic_aneg = 1, 937 .ops = &bcm5461_phy_ops 938 }; 939 940 /* Broadcom BCM 5462 built-in Vesta */ 941 static struct mii_phy_ops bcm5462V_phy_ops = { 942 .init = bcm5421_init, 943 .suspend = generic_suspend, 944 .setup_aneg = bcm54xx_setup_aneg, 945 .setup_forced = bcm54xx_setup_forced, 946 .poll_link = genmii_poll_link, 947 .read_link = bcm54xx_read_link, 948 }; 949 950 static struct mii_phy_def bcm5462V_phy_def = { 951 .phy_id = 0x002060d0, 952 .phy_id_mask = 0xfffffff0, 953 .name = "BCM5462-Vesta", 954 .features = MII_GBIT_FEATURES, 955 .magic_aneg = 1, 956 .ops = &bcm5462V_phy_ops 957 }; 958 959 /* Marvell 88E1101 amd 88E1111 */ 960 static struct mii_phy_ops marvell88e1101_phy_ops = { 961 .suspend = generic_suspend, 962 .setup_aneg = marvell_setup_aneg, 963 .setup_forced = marvell_setup_forced, 964 .poll_link = genmii_poll_link, 965 .read_link = marvell_read_link 966 }; 967 968 static struct mii_phy_ops marvell88e1111_phy_ops = { 969 .init = marvell88e1111_init, 970 .suspend = generic_suspend, 971 .setup_aneg = marvell_setup_aneg, 972 .setup_forced = marvell_setup_forced, 973 .poll_link = genmii_poll_link, 974 .read_link = marvell_read_link 975 }; 976 977 /* two revs in darwin for the 88e1101 ... I could use a datasheet 978 * to get the proper names... 979 */ 980 static struct mii_phy_def marvell88e1101v1_phy_def = { 981 .phy_id = 0x01410c20, 982 .phy_id_mask = 0xfffffff0, 983 .name = "Marvell 88E1101v1", 984 .features = MII_GBIT_FEATURES, 985 .magic_aneg = 1, 986 .ops = &marvell88e1101_phy_ops 987 }; 988 static struct mii_phy_def marvell88e1101v2_phy_def = { 989 .phy_id = 0x01410c60, 990 .phy_id_mask = 0xfffffff0, 991 .name = "Marvell 88E1101v2", 992 .features = MII_GBIT_FEATURES, 993 .magic_aneg = 1, 994 .ops = &marvell88e1101_phy_ops 995 }; 996 static struct mii_phy_def marvell88e1111_phy_def = { 997 .phy_id = 0x01410cc0, 998 .phy_id_mask = 0xfffffff0, 999 .name = "Marvell 88E1111", 1000 .features = MII_GBIT_FEATURES, 1001 .magic_aneg = 1, 1002 .ops = &marvell88e1111_phy_ops 1003 }; 1004 1005 /* Generic implementation for most 10/100 PHYs */ 1006 static struct mii_phy_ops generic_phy_ops = { 1007 .setup_aneg = genmii_setup_aneg, 1008 .setup_forced = genmii_setup_forced, 1009 .poll_link = genmii_poll_link, 1010 .read_link = genmii_read_link 1011 }; 1012 1013 static struct mii_phy_def genmii_phy_def = { 1014 .phy_id = 0x00000000, 1015 .phy_id_mask = 0x00000000, 1016 .name = "Generic MII", 1017 .features = MII_BASIC_FEATURES, 1018 .magic_aneg = 0, 1019 .ops = &generic_phy_ops 1020 }; 1021 1022 static struct mii_phy_def* mii_phy_table[] = { 1023 &bcm5201_phy_def, 1024 &bcm5221_phy_def, 1025 &bcm5241_phy_def, 1026 &bcm5400_phy_def, 1027 &bcm5401_phy_def, 1028 &bcm5411_phy_def, 1029 &bcm5421_phy_def, 1030 &bcm5421k2_phy_def, 1031 &bcm5461_phy_def, 1032 &bcm5462V_phy_def, 1033 &marvell88e1101v1_phy_def, 1034 &marvell88e1101v2_phy_def, 1035 &marvell88e1111_phy_def, 1036 &genmii_phy_def, 1037 NULL 1038 }; 1039 1040 int mii_phy_probe(struct mii_phy *phy, int mii_id) 1041 { 1042 int rc; 1043 u32 id; 1044 struct mii_phy_def* def; 1045 int i; 1046 1047 /* We do not reset the mii_phy structure as the driver 1048 * may re-probe the PHY regulary 1049 */ 1050 phy->mii_id = mii_id; 1051 1052 /* Take PHY out of isloate mode and reset it. */ 1053 rc = reset_one_mii_phy(phy, mii_id); 1054 if (rc) 1055 goto fail; 1056 1057 /* Read ID and find matching entry */ 1058 id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2)); 1059 printk(KERN_DEBUG "PHY ID: %x, addr: %x\n", id, mii_id); 1060 for (i=0; (def = mii_phy_table[i]) != NULL; i++) 1061 if ((id & def->phy_id_mask) == def->phy_id) 1062 break; 1063 /* Should never be NULL (we have a generic entry), but... */ 1064 if (def == NULL) 1065 goto fail; 1066 1067 phy->def = def; 1068 1069 return 0; 1070 fail: 1071 phy->speed = 0; 1072 phy->duplex = 0; 1073 phy->pause = 0; 1074 phy->advertising = 0; 1075 return -ENODEV; 1076 } 1077 1078 EXPORT_SYMBOL(mii_phy_probe); 1079 MODULE_LICENSE("GPL"); 1080 1081