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