1 /* 2 * drivers/net/ethernet/ibm/emac/phy.c 3 * 4 * Driver for PowerPC 4xx on-chip ethernet controller, PHY support. 5 * Borrowed from sungem_phy.c, though I only kept the generic MII 6 * driver for now. 7 * 8 * This file should be shared with other drivers or eventually 9 * merged as the "low level" part of miilib 10 * 11 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp. 12 * <benh@kernel.crashing.org> 13 * 14 * Based on the arch/ppc version of the driver: 15 * 16 * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org) 17 * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net> 18 * 19 */ 20 #include <linux/module.h> 21 #include <linux/kernel.h> 22 #include <linux/types.h> 23 #include <linux/netdevice.h> 24 #include <linux/mii.h> 25 #include <linux/ethtool.h> 26 #include <linux/delay.h> 27 28 #include "emac.h" 29 #include "phy.h" 30 31 #define phy_read _phy_read 32 #define phy_write _phy_write 33 34 static inline int _phy_read(struct mii_phy *phy, int reg) 35 { 36 return phy->mdio_read(phy->dev, phy->address, reg); 37 } 38 39 static inline void _phy_write(struct mii_phy *phy, int reg, int val) 40 { 41 phy->mdio_write(phy->dev, phy->address, reg, val); 42 } 43 44 static inline int gpcs_phy_read(struct mii_phy *phy, int reg) 45 { 46 return phy->mdio_read(phy->dev, phy->gpcs_address, reg); 47 } 48 49 static inline void gpcs_phy_write(struct mii_phy *phy, int reg, int val) 50 { 51 phy->mdio_write(phy->dev, phy->gpcs_address, reg, val); 52 } 53 54 int emac_mii_reset_phy(struct mii_phy *phy) 55 { 56 int val; 57 int limit = 10000; 58 59 val = phy_read(phy, MII_BMCR); 60 val &= ~(BMCR_ISOLATE | BMCR_ANENABLE); 61 val |= BMCR_RESET; 62 phy_write(phy, MII_BMCR, val); 63 64 udelay(300); 65 66 while (--limit) { 67 val = phy_read(phy, MII_BMCR); 68 if (val >= 0 && (val & BMCR_RESET) == 0) 69 break; 70 udelay(10); 71 } 72 if ((val & BMCR_ISOLATE) && limit > 0) 73 phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE); 74 75 return limit <= 0; 76 } 77 78 int emac_mii_reset_gpcs(struct mii_phy *phy) 79 { 80 int val; 81 int limit = 10000; 82 83 val = gpcs_phy_read(phy, MII_BMCR); 84 val &= ~(BMCR_ISOLATE | BMCR_ANENABLE); 85 val |= BMCR_RESET; 86 gpcs_phy_write(phy, MII_BMCR, val); 87 88 udelay(300); 89 90 while (--limit) { 91 val = gpcs_phy_read(phy, MII_BMCR); 92 if (val >= 0 && (val & BMCR_RESET) == 0) 93 break; 94 udelay(10); 95 } 96 if ((val & BMCR_ISOLATE) && limit > 0) 97 gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE); 98 99 if (limit > 0 && phy->mode == PHY_INTERFACE_MODE_SGMII) { 100 /* Configure GPCS interface to recommended setting for SGMII */ 101 gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */ 102 gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */ 103 gpcs_phy_write(phy, 0x00, 0x0140); /* 1Gbps, FDX */ 104 } 105 106 return limit <= 0; 107 } 108 109 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) 110 { 111 int ctl, adv; 112 113 phy->autoneg = AUTONEG_ENABLE; 114 phy->speed = SPEED_10; 115 phy->duplex = DUPLEX_HALF; 116 phy->pause = phy->asym_pause = 0; 117 phy->advertising = advertise; 118 119 ctl = phy_read(phy, MII_BMCR); 120 if (ctl < 0) 121 return ctl; 122 ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE); 123 124 /* First clear the PHY */ 125 phy_write(phy, MII_BMCR, ctl); 126 127 /* Setup standard advertise */ 128 adv = phy_read(phy, MII_ADVERTISE); 129 if (adv < 0) 130 return adv; 131 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | 132 ADVERTISE_PAUSE_ASYM); 133 if (advertise & ADVERTISED_10baseT_Half) 134 adv |= ADVERTISE_10HALF; 135 if (advertise & ADVERTISED_10baseT_Full) 136 adv |= ADVERTISE_10FULL; 137 if (advertise & ADVERTISED_100baseT_Half) 138 adv |= ADVERTISE_100HALF; 139 if (advertise & ADVERTISED_100baseT_Full) 140 adv |= ADVERTISE_100FULL; 141 if (advertise & ADVERTISED_Pause) 142 adv |= ADVERTISE_PAUSE_CAP; 143 if (advertise & ADVERTISED_Asym_Pause) 144 adv |= ADVERTISE_PAUSE_ASYM; 145 phy_write(phy, MII_ADVERTISE, adv); 146 147 if (phy->features & 148 (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) { 149 adv = phy_read(phy, MII_CTRL1000); 150 if (adv < 0) 151 return adv; 152 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); 153 if (advertise & ADVERTISED_1000baseT_Full) 154 adv |= ADVERTISE_1000FULL; 155 if (advertise & ADVERTISED_1000baseT_Half) 156 adv |= ADVERTISE_1000HALF; 157 phy_write(phy, MII_CTRL1000, adv); 158 } 159 160 /* Start/Restart aneg */ 161 ctl = phy_read(phy, MII_BMCR); 162 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 163 phy_write(phy, MII_BMCR, ctl); 164 165 return 0; 166 } 167 168 static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd) 169 { 170 int ctl; 171 172 phy->autoneg = AUTONEG_DISABLE; 173 phy->speed = speed; 174 phy->duplex = fd; 175 phy->pause = phy->asym_pause = 0; 176 177 ctl = phy_read(phy, MII_BMCR); 178 if (ctl < 0) 179 return ctl; 180 ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE); 181 182 /* First clear the PHY */ 183 phy_write(phy, MII_BMCR, ctl | BMCR_RESET); 184 185 /* Select speed & duplex */ 186 switch (speed) { 187 case SPEED_10: 188 break; 189 case SPEED_100: 190 ctl |= BMCR_SPEED100; 191 break; 192 case SPEED_1000: 193 ctl |= BMCR_SPEED1000; 194 break; 195 default: 196 return -EINVAL; 197 } 198 if (fd == DUPLEX_FULL) 199 ctl |= BMCR_FULLDPLX; 200 phy_write(phy, MII_BMCR, ctl); 201 202 return 0; 203 } 204 205 static int genmii_poll_link(struct mii_phy *phy) 206 { 207 int status; 208 209 /* Clear latched value with dummy read */ 210 phy_read(phy, MII_BMSR); 211 status = phy_read(phy, MII_BMSR); 212 if (status < 0 || (status & BMSR_LSTATUS) == 0) 213 return 0; 214 if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE)) 215 return 0; 216 return 1; 217 } 218 219 static int genmii_read_link(struct mii_phy *phy) 220 { 221 if (phy->autoneg == AUTONEG_ENABLE) { 222 int glpa = 0; 223 int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE); 224 if (lpa < 0) 225 return lpa; 226 227 if (phy->features & 228 (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) { 229 int adv = phy_read(phy, MII_CTRL1000); 230 glpa = phy_read(phy, MII_STAT1000); 231 232 if (glpa < 0 || adv < 0) 233 return adv; 234 235 glpa &= adv << 2; 236 } 237 238 phy->speed = SPEED_10; 239 phy->duplex = DUPLEX_HALF; 240 phy->pause = phy->asym_pause = 0; 241 242 if (glpa & (LPA_1000FULL | LPA_1000HALF)) { 243 phy->speed = SPEED_1000; 244 if (glpa & LPA_1000FULL) 245 phy->duplex = DUPLEX_FULL; 246 } else if (lpa & (LPA_100FULL | LPA_100HALF)) { 247 phy->speed = SPEED_100; 248 if (lpa & LPA_100FULL) 249 phy->duplex = DUPLEX_FULL; 250 } else if (lpa & LPA_10FULL) 251 phy->duplex = DUPLEX_FULL; 252 253 if (phy->duplex == DUPLEX_FULL) { 254 phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; 255 phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; 256 } 257 } else { 258 int bmcr = phy_read(phy, MII_BMCR); 259 if (bmcr < 0) 260 return bmcr; 261 262 if (bmcr & BMCR_FULLDPLX) 263 phy->duplex = DUPLEX_FULL; 264 else 265 phy->duplex = DUPLEX_HALF; 266 if (bmcr & BMCR_SPEED1000) 267 phy->speed = SPEED_1000; 268 else if (bmcr & BMCR_SPEED100) 269 phy->speed = SPEED_100; 270 else 271 phy->speed = SPEED_10; 272 273 phy->pause = phy->asym_pause = 0; 274 } 275 return 0; 276 } 277 278 /* Generic implementation for most 10/100/1000 PHYs */ 279 static const struct mii_phy_ops generic_phy_ops = { 280 .setup_aneg = genmii_setup_aneg, 281 .setup_forced = genmii_setup_forced, 282 .poll_link = genmii_poll_link, 283 .read_link = genmii_read_link 284 }; 285 286 static struct mii_phy_def genmii_phy_def = { 287 .phy_id = 0x00000000, 288 .phy_id_mask = 0x00000000, 289 .name = "Generic MII", 290 .ops = &generic_phy_ops 291 }; 292 293 /* CIS8201 */ 294 #define MII_CIS8201_10BTCSR 0x16 295 #define TENBTCSR_ECHO_DISABLE 0x2000 296 #define MII_CIS8201_EPCR 0x17 297 #define EPCR_MODE_MASK 0x3000 298 #define EPCR_GMII_MODE 0x0000 299 #define EPCR_RGMII_MODE 0x1000 300 #define EPCR_TBI_MODE 0x2000 301 #define EPCR_RTBI_MODE 0x3000 302 #define MII_CIS8201_ACSR 0x1c 303 #define ACSR_PIN_PRIO_SELECT 0x0004 304 305 static int cis8201_init(struct mii_phy *phy) 306 { 307 int epcr; 308 309 epcr = phy_read(phy, MII_CIS8201_EPCR); 310 if (epcr < 0) 311 return epcr; 312 313 epcr &= ~EPCR_MODE_MASK; 314 315 switch (phy->mode) { 316 case PHY_INTERFACE_MODE_TBI: 317 epcr |= EPCR_TBI_MODE; 318 break; 319 case PHY_INTERFACE_MODE_RTBI: 320 epcr |= EPCR_RTBI_MODE; 321 break; 322 case PHY_INTERFACE_MODE_GMII: 323 epcr |= EPCR_GMII_MODE; 324 break; 325 case PHY_INTERFACE_MODE_RGMII: 326 default: 327 epcr |= EPCR_RGMII_MODE; 328 } 329 330 phy_write(phy, MII_CIS8201_EPCR, epcr); 331 332 /* MII regs override strap pins */ 333 phy_write(phy, MII_CIS8201_ACSR, 334 phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT); 335 336 /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */ 337 phy_write(phy, MII_CIS8201_10BTCSR, 338 phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE); 339 340 return 0; 341 } 342 343 static const struct mii_phy_ops cis8201_phy_ops = { 344 .init = cis8201_init, 345 .setup_aneg = genmii_setup_aneg, 346 .setup_forced = genmii_setup_forced, 347 .poll_link = genmii_poll_link, 348 .read_link = genmii_read_link 349 }; 350 351 static struct mii_phy_def cis8201_phy_def = { 352 .phy_id = 0x000fc410, 353 .phy_id_mask = 0x000ffff0, 354 .name = "CIS8201 Gigabit Ethernet", 355 .ops = &cis8201_phy_ops 356 }; 357 358 static struct mii_phy_def bcm5248_phy_def = { 359 360 .phy_id = 0x0143bc00, 361 .phy_id_mask = 0x0ffffff0, 362 .name = "BCM5248 10/100 SMII Ethernet", 363 .ops = &generic_phy_ops 364 }; 365 366 static int m88e1111_init(struct mii_phy *phy) 367 { 368 pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__); 369 phy_write(phy, 0x14, 0x0ce3); 370 phy_write(phy, 0x18, 0x4101); 371 phy_write(phy, 0x09, 0x0e00); 372 phy_write(phy, 0x04, 0x01e1); 373 phy_write(phy, 0x00, 0x9140); 374 phy_write(phy, 0x00, 0x1140); 375 376 return 0; 377 } 378 379 static int m88e1112_init(struct mii_phy *phy) 380 { 381 /* 382 * Marvell 88E1112 PHY needs to have the SGMII MAC 383 * interace (page 2) properly configured to 384 * communicate with the 460EX/GT GPCS interface. 385 */ 386 387 u16 reg_short; 388 389 pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__); 390 391 /* Set access to Page 2 */ 392 phy_write(phy, 0x16, 0x0002); 393 394 phy_write(phy, 0x00, 0x0040); /* 1Gbps */ 395 reg_short = (u16)(phy_read(phy, 0x1a)); 396 reg_short |= 0x8000; /* bypass Auto-Negotiation */ 397 phy_write(phy, 0x1a, reg_short); 398 emac_mii_reset_phy(phy); /* reset MAC interface */ 399 400 /* Reset access to Page 0 */ 401 phy_write(phy, 0x16, 0x0000); 402 403 return 0; 404 } 405 406 static int et1011c_init(struct mii_phy *phy) 407 { 408 u16 reg_short; 409 410 reg_short = (u16)(phy_read(phy, 0x16)); 411 reg_short &= ~(0x7); 412 reg_short |= 0x6; /* RGMII Trace Delay*/ 413 phy_write(phy, 0x16, reg_short); 414 415 reg_short = (u16)(phy_read(phy, 0x17)); 416 reg_short &= ~(0x40); 417 phy_write(phy, 0x17, reg_short); 418 419 phy_write(phy, 0x1c, 0x74f0); 420 return 0; 421 } 422 423 static const struct mii_phy_ops et1011c_phy_ops = { 424 .init = et1011c_init, 425 .setup_aneg = genmii_setup_aneg, 426 .setup_forced = genmii_setup_forced, 427 .poll_link = genmii_poll_link, 428 .read_link = genmii_read_link 429 }; 430 431 static struct mii_phy_def et1011c_phy_def = { 432 .phy_id = 0x0282f000, 433 .phy_id_mask = 0x0fffff00, 434 .name = "ET1011C Gigabit Ethernet", 435 .ops = &et1011c_phy_ops 436 }; 437 438 439 440 441 442 static const struct mii_phy_ops m88e1111_phy_ops = { 443 .init = m88e1111_init, 444 .setup_aneg = genmii_setup_aneg, 445 .setup_forced = genmii_setup_forced, 446 .poll_link = genmii_poll_link, 447 .read_link = genmii_read_link 448 }; 449 450 static struct mii_phy_def m88e1111_phy_def = { 451 452 .phy_id = 0x01410CC0, 453 .phy_id_mask = 0x0ffffff0, 454 .name = "Marvell 88E1111 Ethernet", 455 .ops = &m88e1111_phy_ops, 456 }; 457 458 static const struct mii_phy_ops m88e1112_phy_ops = { 459 .init = m88e1112_init, 460 .setup_aneg = genmii_setup_aneg, 461 .setup_forced = genmii_setup_forced, 462 .poll_link = genmii_poll_link, 463 .read_link = genmii_read_link 464 }; 465 466 static struct mii_phy_def m88e1112_phy_def = { 467 .phy_id = 0x01410C90, 468 .phy_id_mask = 0x0ffffff0, 469 .name = "Marvell 88E1112 Ethernet", 470 .ops = &m88e1112_phy_ops, 471 }; 472 473 static int ar8035_init(struct mii_phy *phy) 474 { 475 phy_write(phy, 0x1d, 0x5); /* Address debug register 5 */ 476 phy_write(phy, 0x1e, 0x2d47); /* Value copied from u-boot */ 477 phy_write(phy, 0x1d, 0xb); /* Address hib ctrl */ 478 phy_write(phy, 0x1e, 0xbc20); /* Value copied from u-boot */ 479 480 return 0; 481 } 482 483 static const struct mii_phy_ops ar8035_phy_ops = { 484 .init = ar8035_init, 485 .setup_aneg = genmii_setup_aneg, 486 .setup_forced = genmii_setup_forced, 487 .poll_link = genmii_poll_link, 488 .read_link = genmii_read_link, 489 }; 490 491 static struct mii_phy_def ar8035_phy_def = { 492 .phy_id = 0x004dd070, 493 .phy_id_mask = 0xfffffff0, 494 .name = "Atheros 8035 Gigabit Ethernet", 495 .ops = &ar8035_phy_ops, 496 }; 497 498 static struct mii_phy_def *mii_phy_table[] = { 499 &et1011c_phy_def, 500 &cis8201_phy_def, 501 &bcm5248_phy_def, 502 &m88e1111_phy_def, 503 &m88e1112_phy_def, 504 &ar8035_phy_def, 505 &genmii_phy_def, 506 NULL 507 }; 508 509 int emac_mii_phy_probe(struct mii_phy *phy, int address) 510 { 511 struct mii_phy_def *def; 512 int i; 513 u32 id; 514 515 phy->autoneg = AUTONEG_DISABLE; 516 phy->advertising = 0; 517 phy->address = address; 518 phy->speed = SPEED_10; 519 phy->duplex = DUPLEX_HALF; 520 phy->pause = phy->asym_pause = 0; 521 522 /* Take PHY out of isolate mode and reset it. */ 523 if (emac_mii_reset_phy(phy)) 524 return -ENODEV; 525 526 /* Read ID and find matching entry */ 527 id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2); 528 for (i = 0; (def = mii_phy_table[i]) != NULL; i++) 529 if ((id & def->phy_id_mask) == def->phy_id) 530 break; 531 /* Should never be NULL (we have a generic entry), but... */ 532 if (!def) 533 return -ENODEV; 534 535 phy->def = def; 536 537 /* Determine PHY features if needed */ 538 phy->features = def->features; 539 if (!phy->features) { 540 u16 bmsr = phy_read(phy, MII_BMSR); 541 if (bmsr & BMSR_ANEGCAPABLE) 542 phy->features |= SUPPORTED_Autoneg; 543 if (bmsr & BMSR_10HALF) 544 phy->features |= SUPPORTED_10baseT_Half; 545 if (bmsr & BMSR_10FULL) 546 phy->features |= SUPPORTED_10baseT_Full; 547 if (bmsr & BMSR_100HALF) 548 phy->features |= SUPPORTED_100baseT_Half; 549 if (bmsr & BMSR_100FULL) 550 phy->features |= SUPPORTED_100baseT_Full; 551 if (bmsr & BMSR_ESTATEN) { 552 u16 esr = phy_read(phy, MII_ESTATUS); 553 if (esr & ESTATUS_1000_TFULL) 554 phy->features |= SUPPORTED_1000baseT_Full; 555 if (esr & ESTATUS_1000_THALF) 556 phy->features |= SUPPORTED_1000baseT_Half; 557 } 558 phy->features |= SUPPORTED_MII; 559 } 560 561 /* Setup default advertising */ 562 phy->advertising = phy->features; 563 564 return 0; 565 } 566 567 MODULE_LICENSE("GPL"); 568