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