1 /* 2 * drivers/net/phy/marvell.c 3 * 4 * Driver for Marvell PHYs 5 * 6 * Author: Andy Fleming 7 * 8 * Copyright (c) 2004 Freescale Semiconductor, Inc. 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the 12 * Free Software Foundation; either version 2 of the License, or (at your 13 * option) any later version. 14 * 15 */ 16 #include <linux/kernel.h> 17 #include <linux/string.h> 18 #include <linux/errno.h> 19 #include <linux/unistd.h> 20 #include <linux/slab.h> 21 #include <linux/interrupt.h> 22 #include <linux/init.h> 23 #include <linux/delay.h> 24 #include <linux/netdevice.h> 25 #include <linux/etherdevice.h> 26 #include <linux/skbuff.h> 27 #include <linux/spinlock.h> 28 #include <linux/mm.h> 29 #include <linux/module.h> 30 #include <linux/mii.h> 31 #include <linux/ethtool.h> 32 #include <linux/phy.h> 33 34 #include <asm/io.h> 35 #include <asm/irq.h> 36 #include <asm/uaccess.h> 37 38 #define MII_M1011_IEVENT 0x13 39 #define MII_M1011_IEVENT_CLEAR 0x0000 40 41 #define MII_M1011_IMASK 0x12 42 #define MII_M1011_IMASK_INIT 0x6400 43 #define MII_M1011_IMASK_CLEAR 0x0000 44 45 #define MII_M1011_PHY_SCR 0x10 46 #define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 47 48 #define MII_M1145_PHY_EXT_CR 0x14 49 #define MII_M1145_RGMII_RX_DELAY 0x0080 50 #define MII_M1145_RGMII_TX_DELAY 0x0002 51 52 #define M1145_DEV_FLAGS_RESISTANCE 0x00000001 53 54 #define MII_M1111_PHY_LED_CONTROL 0x18 55 #define MII_M1111_PHY_LED_DIRECT 0x4100 56 #define MII_M1111_PHY_LED_COMBINE 0x411c 57 #define MII_M1111_PHY_EXT_CR 0x14 58 #define MII_M1111_RX_DELAY 0x80 59 #define MII_M1111_TX_DELAY 0x2 60 #define MII_M1111_PHY_EXT_SR 0x1b 61 62 #define MII_M1111_HWCFG_MODE_MASK 0xf 63 #define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb 64 #define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 65 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 66 #define MII_M1111_HWCFG_MODE_COPPER_RTBI 0x9 67 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO 0x8000 68 #define MII_M1111_HWCFG_FIBER_COPPER_RES 0x2000 69 70 #define MII_M1111_COPPER 0 71 #define MII_M1111_FIBER 1 72 73 #define MII_88E1121_PHY_LED_CTRL 16 74 #define MII_88E1121_PHY_LED_PAGE 3 75 #define MII_88E1121_PHY_LED_DEF 0x0030 76 #define MII_88E1121_PHY_PAGE 22 77 78 #define MII_M1011_PHY_STATUS 0x11 79 #define MII_M1011_PHY_STATUS_1000 0x8000 80 #define MII_M1011_PHY_STATUS_100 0x4000 81 #define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 82 #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 83 #define MII_M1011_PHY_STATUS_RESOLVED 0x0800 84 #define MII_M1011_PHY_STATUS_LINK 0x0400 85 86 87 MODULE_DESCRIPTION("Marvell PHY driver"); 88 MODULE_AUTHOR("Andy Fleming"); 89 MODULE_LICENSE("GPL"); 90 91 static int marvell_ack_interrupt(struct phy_device *phydev) 92 { 93 int err; 94 95 /* Clear the interrupts by reading the reg */ 96 err = phy_read(phydev, MII_M1011_IEVENT); 97 98 if (err < 0) 99 return err; 100 101 return 0; 102 } 103 104 static int marvell_config_intr(struct phy_device *phydev) 105 { 106 int err; 107 108 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 109 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 110 else 111 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 112 113 return err; 114 } 115 116 static int marvell_config_aneg(struct phy_device *phydev) 117 { 118 int err; 119 120 /* The Marvell PHY has an errata which requires 121 * that certain registers get written in order 122 * to restart autonegotiation */ 123 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 124 125 if (err < 0) 126 return err; 127 128 err = phy_write(phydev, 0x1d, 0x1f); 129 if (err < 0) 130 return err; 131 132 err = phy_write(phydev, 0x1e, 0x200c); 133 if (err < 0) 134 return err; 135 136 err = phy_write(phydev, 0x1d, 0x5); 137 if (err < 0) 138 return err; 139 140 err = phy_write(phydev, 0x1e, 0); 141 if (err < 0) 142 return err; 143 144 err = phy_write(phydev, 0x1e, 0x100); 145 if (err < 0) 146 return err; 147 148 err = phy_write(phydev, MII_M1011_PHY_SCR, 149 MII_M1011_PHY_SCR_AUTO_CROSS); 150 if (err < 0) 151 return err; 152 153 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, 154 MII_M1111_PHY_LED_DIRECT); 155 if (err < 0) 156 return err; 157 158 err = genphy_config_aneg(phydev); 159 if (err < 0) 160 return err; 161 162 if (phydev->autoneg != AUTONEG_ENABLE) { 163 int bmcr; 164 165 /* 166 * A write to speed/duplex bits (that is performed by 167 * genphy_config_aneg() call above) must be followed by 168 * a software reset. Otherwise, the write has no effect. 169 */ 170 bmcr = phy_read(phydev, MII_BMCR); 171 if (bmcr < 0) 172 return bmcr; 173 174 err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET); 175 if (err < 0) 176 return err; 177 } 178 179 return 0; 180 } 181 182 static int m88e1121_config_aneg(struct phy_device *phydev) 183 { 184 int err, temp; 185 186 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 187 if (err < 0) 188 return err; 189 190 err = phy_write(phydev, MII_M1011_PHY_SCR, 191 MII_M1011_PHY_SCR_AUTO_CROSS); 192 if (err < 0) 193 return err; 194 195 temp = phy_read(phydev, MII_88E1121_PHY_PAGE); 196 197 phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); 198 phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); 199 phy_write(phydev, MII_88E1121_PHY_PAGE, temp); 200 201 err = genphy_config_aneg(phydev); 202 203 return err; 204 } 205 206 static int m88e1111_config_init(struct phy_device *phydev) 207 { 208 int err; 209 int temp; 210 211 /* Enable Fiber/Copper auto selection */ 212 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 213 temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO; 214 phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 215 216 temp = phy_read(phydev, MII_BMCR); 217 temp |= BMCR_RESET; 218 phy_write(phydev, MII_BMCR, temp); 219 220 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || 221 (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || 222 (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || 223 (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { 224 225 temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); 226 if (temp < 0) 227 return temp; 228 229 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 230 temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); 231 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 232 temp &= ~MII_M1111_TX_DELAY; 233 temp |= MII_M1111_RX_DELAY; 234 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 235 temp &= ~MII_M1111_RX_DELAY; 236 temp |= MII_M1111_TX_DELAY; 237 } 238 239 err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); 240 if (err < 0) 241 return err; 242 243 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 244 if (temp < 0) 245 return temp; 246 247 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 248 249 if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES) 250 temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; 251 else 252 temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; 253 254 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 255 if (err < 0) 256 return err; 257 } 258 259 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 260 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 261 if (temp < 0) 262 return temp; 263 264 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 265 temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK; 266 temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; 267 268 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 269 if (err < 0) 270 return err; 271 } 272 273 if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { 274 temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); 275 if (temp < 0) 276 return temp; 277 temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); 278 err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); 279 if (err < 0) 280 return err; 281 282 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 283 if (temp < 0) 284 return temp; 285 temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); 286 temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO; 287 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 288 if (err < 0) 289 return err; 290 291 /* soft reset */ 292 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 293 if (err < 0) 294 return err; 295 do 296 temp = phy_read(phydev, MII_BMCR); 297 while (temp & BMCR_RESET); 298 299 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 300 if (temp < 0) 301 return temp; 302 temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); 303 temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO; 304 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 305 if (err < 0) 306 return err; 307 } 308 309 310 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 311 if (err < 0) 312 return err; 313 314 return 0; 315 } 316 317 static int m88e1118_config_aneg(struct phy_device *phydev) 318 { 319 int err; 320 321 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 322 if (err < 0) 323 return err; 324 325 err = phy_write(phydev, MII_M1011_PHY_SCR, 326 MII_M1011_PHY_SCR_AUTO_CROSS); 327 if (err < 0) 328 return err; 329 330 err = genphy_config_aneg(phydev); 331 return 0; 332 } 333 334 static int m88e1118_config_init(struct phy_device *phydev) 335 { 336 int err; 337 338 /* Change address */ 339 err = phy_write(phydev, 0x16, 0x0002); 340 if (err < 0) 341 return err; 342 343 /* Enable 1000 Mbit */ 344 err = phy_write(phydev, 0x15, 0x1070); 345 if (err < 0) 346 return err; 347 348 /* Change address */ 349 err = phy_write(phydev, 0x16, 0x0003); 350 if (err < 0) 351 return err; 352 353 /* Adjust LED Control */ 354 err = phy_write(phydev, 0x10, 0x021e); 355 if (err < 0) 356 return err; 357 358 /* Reset address */ 359 err = phy_write(phydev, 0x16, 0x0); 360 if (err < 0) 361 return err; 362 363 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 364 if (err < 0) 365 return err; 366 367 return 0; 368 } 369 370 static int m88e1145_config_init(struct phy_device *phydev) 371 { 372 int err; 373 374 /* Take care of errata E0 & E1 */ 375 err = phy_write(phydev, 0x1d, 0x001b); 376 if (err < 0) 377 return err; 378 379 err = phy_write(phydev, 0x1e, 0x418f); 380 if (err < 0) 381 return err; 382 383 err = phy_write(phydev, 0x1d, 0x0016); 384 if (err < 0) 385 return err; 386 387 err = phy_write(phydev, 0x1e, 0xa2da); 388 if (err < 0) 389 return err; 390 391 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 392 int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR); 393 if (temp < 0) 394 return temp; 395 396 temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY); 397 398 err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp); 399 if (err < 0) 400 return err; 401 402 if (phydev->dev_flags & M1145_DEV_FLAGS_RESISTANCE) { 403 err = phy_write(phydev, 0x1d, 0x0012); 404 if (err < 0) 405 return err; 406 407 temp = phy_read(phydev, 0x1e); 408 if (temp < 0) 409 return temp; 410 411 temp &= 0xf03f; 412 temp |= 2 << 9; /* 36 ohm */ 413 temp |= 2 << 6; /* 39 ohm */ 414 415 err = phy_write(phydev, 0x1e, temp); 416 if (err < 0) 417 return err; 418 419 err = phy_write(phydev, 0x1d, 0x3); 420 if (err < 0) 421 return err; 422 423 err = phy_write(phydev, 0x1e, 0x8000); 424 if (err < 0) 425 return err; 426 } 427 } 428 429 return 0; 430 } 431 432 /* marvell_read_status 433 * 434 * Generic status code does not detect Fiber correctly! 435 * Description: 436 * Check the link, then figure out the current state 437 * by comparing what we advertise with what the link partner 438 * advertises. Start by checking the gigabit possibilities, 439 * then move on to 10/100. 440 */ 441 static int marvell_read_status(struct phy_device *phydev) 442 { 443 int adv; 444 int err; 445 int lpa; 446 int status = 0; 447 448 /* Update the link, but return if there 449 * was an error */ 450 err = genphy_update_link(phydev); 451 if (err) 452 return err; 453 454 if (AUTONEG_ENABLE == phydev->autoneg) { 455 status = phy_read(phydev, MII_M1011_PHY_STATUS); 456 if (status < 0) 457 return status; 458 459 lpa = phy_read(phydev, MII_LPA); 460 if (lpa < 0) 461 return lpa; 462 463 adv = phy_read(phydev, MII_ADVERTISE); 464 if (adv < 0) 465 return adv; 466 467 lpa &= adv; 468 469 if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) 470 phydev->duplex = DUPLEX_FULL; 471 else 472 phydev->duplex = DUPLEX_HALF; 473 474 status = status & MII_M1011_PHY_STATUS_SPD_MASK; 475 phydev->pause = phydev->asym_pause = 0; 476 477 switch (status) { 478 case MII_M1011_PHY_STATUS_1000: 479 phydev->speed = SPEED_1000; 480 break; 481 482 case MII_M1011_PHY_STATUS_100: 483 phydev->speed = SPEED_100; 484 break; 485 486 default: 487 phydev->speed = SPEED_10; 488 break; 489 } 490 491 if (phydev->duplex == DUPLEX_FULL) { 492 phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; 493 phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; 494 } 495 } else { 496 int bmcr = phy_read(phydev, MII_BMCR); 497 498 if (bmcr < 0) 499 return bmcr; 500 501 if (bmcr & BMCR_FULLDPLX) 502 phydev->duplex = DUPLEX_FULL; 503 else 504 phydev->duplex = DUPLEX_HALF; 505 506 if (bmcr & BMCR_SPEED1000) 507 phydev->speed = SPEED_1000; 508 else if (bmcr & BMCR_SPEED100) 509 phydev->speed = SPEED_100; 510 else 511 phydev->speed = SPEED_10; 512 513 phydev->pause = phydev->asym_pause = 0; 514 } 515 516 return 0; 517 } 518 519 static int m88e1121_did_interrupt(struct phy_device *phydev) 520 { 521 int imask; 522 523 imask = phy_read(phydev, MII_M1011_IEVENT); 524 525 if (imask & MII_M1011_IMASK_INIT) 526 return 1; 527 528 return 0; 529 } 530 531 static struct phy_driver marvell_drivers[] = { 532 { 533 .phy_id = 0x01410c60, 534 .phy_id_mask = 0xfffffff0, 535 .name = "Marvell 88E1101", 536 .features = PHY_GBIT_FEATURES, 537 .flags = PHY_HAS_INTERRUPT, 538 .config_aneg = &marvell_config_aneg, 539 .read_status = &genphy_read_status, 540 .ack_interrupt = &marvell_ack_interrupt, 541 .config_intr = &marvell_config_intr, 542 .driver = { .owner = THIS_MODULE }, 543 }, 544 { 545 .phy_id = 0x01410c90, 546 .phy_id_mask = 0xfffffff0, 547 .name = "Marvell 88E1112", 548 .features = PHY_GBIT_FEATURES, 549 .flags = PHY_HAS_INTERRUPT, 550 .config_init = &m88e1111_config_init, 551 .config_aneg = &marvell_config_aneg, 552 .read_status = &genphy_read_status, 553 .ack_interrupt = &marvell_ack_interrupt, 554 .config_intr = &marvell_config_intr, 555 .driver = { .owner = THIS_MODULE }, 556 }, 557 { 558 .phy_id = 0x01410cc0, 559 .phy_id_mask = 0xfffffff0, 560 .name = "Marvell 88E1111", 561 .features = PHY_GBIT_FEATURES, 562 .flags = PHY_HAS_INTERRUPT, 563 .config_init = &m88e1111_config_init, 564 .config_aneg = &marvell_config_aneg, 565 .read_status = &marvell_read_status, 566 .ack_interrupt = &marvell_ack_interrupt, 567 .config_intr = &marvell_config_intr, 568 .driver = { .owner = THIS_MODULE }, 569 }, 570 { 571 .phy_id = 0x01410e10, 572 .phy_id_mask = 0xfffffff0, 573 .name = "Marvell 88E1118", 574 .features = PHY_GBIT_FEATURES, 575 .flags = PHY_HAS_INTERRUPT, 576 .config_init = &m88e1118_config_init, 577 .config_aneg = &m88e1118_config_aneg, 578 .read_status = &genphy_read_status, 579 .ack_interrupt = &marvell_ack_interrupt, 580 .config_intr = &marvell_config_intr, 581 .driver = {.owner = THIS_MODULE,}, 582 }, 583 { 584 .phy_id = 0x01410cb0, 585 .phy_id_mask = 0xfffffff0, 586 .name = "Marvell 88E1121R", 587 .features = PHY_GBIT_FEATURES, 588 .flags = PHY_HAS_INTERRUPT, 589 .config_aneg = &m88e1121_config_aneg, 590 .read_status = &marvell_read_status, 591 .ack_interrupt = &marvell_ack_interrupt, 592 .config_intr = &marvell_config_intr, 593 .did_interrupt = &m88e1121_did_interrupt, 594 .driver = { .owner = THIS_MODULE }, 595 }, 596 { 597 .phy_id = 0x01410cd0, 598 .phy_id_mask = 0xfffffff0, 599 .name = "Marvell 88E1145", 600 .features = PHY_GBIT_FEATURES, 601 .flags = PHY_HAS_INTERRUPT, 602 .config_init = &m88e1145_config_init, 603 .config_aneg = &marvell_config_aneg, 604 .read_status = &genphy_read_status, 605 .ack_interrupt = &marvell_ack_interrupt, 606 .config_intr = &marvell_config_intr, 607 .driver = { .owner = THIS_MODULE }, 608 }, 609 { 610 .phy_id = 0x01410e30, 611 .phy_id_mask = 0xfffffff0, 612 .name = "Marvell 88E1240", 613 .features = PHY_GBIT_FEATURES, 614 .flags = PHY_HAS_INTERRUPT, 615 .config_init = &m88e1111_config_init, 616 .config_aneg = &marvell_config_aneg, 617 .read_status = &genphy_read_status, 618 .ack_interrupt = &marvell_ack_interrupt, 619 .config_intr = &marvell_config_intr, 620 .driver = { .owner = THIS_MODULE }, 621 }, 622 }; 623 624 static int __init marvell_init(void) 625 { 626 int ret; 627 int i; 628 629 for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) { 630 ret = phy_driver_register(&marvell_drivers[i]); 631 632 if (ret) { 633 while (i-- > 0) 634 phy_driver_unregister(&marvell_drivers[i]); 635 return ret; 636 } 637 } 638 639 return 0; 640 } 641 642 static void __exit marvell_exit(void) 643 { 644 int i; 645 646 for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) 647 phy_driver_unregister(&marvell_drivers[i]); 648 } 649 650 module_init(marvell_init); 651 module_exit(marvell_exit); 652