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 * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de> 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License as published by the 14 * Free Software Foundation; either version 2 of the License, or (at your 15 * option) any later version. 16 * 17 */ 18 #include <linux/kernel.h> 19 #include <linux/string.h> 20 #include <linux/errno.h> 21 #include <linux/unistd.h> 22 #include <linux/interrupt.h> 23 #include <linux/init.h> 24 #include <linux/delay.h> 25 #include <linux/netdevice.h> 26 #include <linux/etherdevice.h> 27 #include <linux/skbuff.h> 28 #include <linux/spinlock.h> 29 #include <linux/mm.h> 30 #include <linux/module.h> 31 #include <linux/mii.h> 32 #include <linux/ethtool.h> 33 #include <linux/phy.h> 34 #include <linux/marvell_phy.h> 35 #include <linux/of.h> 36 37 #include <linux/io.h> 38 #include <asm/irq.h> 39 #include <linux/uaccess.h> 40 41 #define MII_MARVELL_PHY_PAGE 22 42 43 #define MII_M1011_IEVENT 0x13 44 #define MII_M1011_IEVENT_CLEAR 0x0000 45 46 #define MII_M1011_IMASK 0x12 47 #define MII_M1011_IMASK_INIT 0x6400 48 #define MII_M1011_IMASK_CLEAR 0x0000 49 50 #define MII_M1011_PHY_SCR 0x10 51 #define MII_M1011_PHY_SCR_MDI 0x0000 52 #define MII_M1011_PHY_SCR_MDI_X 0x0020 53 #define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 54 55 #define MII_M1145_PHY_EXT_ADDR_PAGE 0x16 56 #define MII_M1145_PHY_EXT_SR 0x1b 57 #define MII_M1145_PHY_EXT_CR 0x14 58 #define MII_M1145_RGMII_RX_DELAY 0x0080 59 #define MII_M1145_RGMII_TX_DELAY 0x0002 60 #define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 61 #define MII_M1145_HWCFG_MODE_MASK 0xf 62 #define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000 63 64 #define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 65 #define MII_M1145_HWCFG_MODE_MASK 0xf 66 #define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000 67 68 #define MII_M1111_PHY_LED_CONTROL 0x18 69 #define MII_M1111_PHY_LED_DIRECT 0x4100 70 #define MII_M1111_PHY_LED_COMBINE 0x411c 71 #define MII_M1111_PHY_EXT_CR 0x14 72 #define MII_M1111_RX_DELAY 0x80 73 #define MII_M1111_TX_DELAY 0x2 74 #define MII_M1111_PHY_EXT_SR 0x1b 75 76 #define MII_M1111_HWCFG_MODE_MASK 0xf 77 #define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb 78 #define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 79 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 80 #define MII_M1111_HWCFG_MODE_COPPER_RTBI 0x9 81 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO 0x8000 82 #define MII_M1111_HWCFG_FIBER_COPPER_RES 0x2000 83 84 #define MII_M1111_COPPER 0 85 #define MII_M1111_FIBER 1 86 87 #define MII_88E1121_PHY_MSCR_PAGE 2 88 #define MII_88E1121_PHY_MSCR_REG 21 89 #define MII_88E1121_PHY_MSCR_RX_DELAY BIT(5) 90 #define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4) 91 #define MII_88E1121_PHY_MSCR_DELAY_MASK (~(0x3 << 4)) 92 93 #define MII_88E1318S_PHY_MSCR1_REG 16 94 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6) 95 96 /* Copper Specific Interrupt Enable Register */ 97 #define MII_88E1318S_PHY_CSIER 0x12 98 /* WOL Event Interrupt Enable */ 99 #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) 100 101 /* LED Timer Control Register */ 102 #define MII_88E1318S_PHY_LED_PAGE 0x03 103 #define MII_88E1318S_PHY_LED_TCR 0x12 104 #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) 105 #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) 106 #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) 107 108 /* Magic Packet MAC address registers */ 109 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 110 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1 0x18 111 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0 0x19 112 113 #define MII_88E1318S_PHY_WOL_PAGE 0x11 114 #define MII_88E1318S_PHY_WOL_CTRL 0x10 115 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS BIT(12) 116 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14) 117 118 #define MII_88E1121_PHY_LED_CTRL 16 119 #define MII_88E1121_PHY_LED_PAGE 3 120 #define MII_88E1121_PHY_LED_DEF 0x0030 121 122 #define MII_M1011_PHY_STATUS 0x11 123 #define MII_M1011_PHY_STATUS_1000 0x8000 124 #define MII_M1011_PHY_STATUS_100 0x4000 125 #define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 126 #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 127 #define MII_M1011_PHY_STATUS_RESOLVED 0x0800 128 #define MII_M1011_PHY_STATUS_LINK 0x0400 129 130 #define MII_M1116R_CONTROL_REG_MAC 21 131 132 #define MII_88E3016_PHY_SPEC_CTRL 0x10 133 #define MII_88E3016_DISABLE_SCRAMBLER 0x0200 134 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030 135 136 #define MII_88E1510_GEN_CTRL_REG_1 0x14 137 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7 138 #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1 /* SGMII to copper */ 139 #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */ 140 141 #define LPA_FIBER_1000HALF 0x40 142 #define LPA_FIBER_1000FULL 0x20 143 144 #define LPA_PAUSE_FIBER 0x180 145 #define LPA_PAUSE_ASYM_FIBER 0x100 146 147 #define ADVERTISE_FIBER_1000HALF 0x40 148 #define ADVERTISE_FIBER_1000FULL 0x20 149 150 #define ADVERTISE_PAUSE_FIBER 0x180 151 #define ADVERTISE_PAUSE_ASYM_FIBER 0x100 152 153 #define REGISTER_LINK_STATUS 0x400 154 #define NB_FIBER_STATS 1 155 156 MODULE_DESCRIPTION("Marvell PHY driver"); 157 MODULE_AUTHOR("Andy Fleming"); 158 MODULE_LICENSE("GPL"); 159 160 struct marvell_hw_stat { 161 const char *string; 162 u8 page; 163 u8 reg; 164 u8 bits; 165 }; 166 167 static struct marvell_hw_stat marvell_hw_stats[] = { 168 { "phy_receive_errors_copper", 0, 21, 16}, 169 { "phy_idle_errors", 0, 10, 8 }, 170 { "phy_receive_errors_fiber", 1, 21, 16}, 171 }; 172 173 struct marvell_priv { 174 u64 stats[ARRAY_SIZE(marvell_hw_stats)]; 175 }; 176 177 static int marvell_ack_interrupt(struct phy_device *phydev) 178 { 179 int err; 180 181 /* Clear the interrupts by reading the reg */ 182 err = phy_read(phydev, MII_M1011_IEVENT); 183 184 if (err < 0) 185 return err; 186 187 return 0; 188 } 189 190 static int marvell_config_intr(struct phy_device *phydev) 191 { 192 int err; 193 194 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 195 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 196 else 197 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 198 199 return err; 200 } 201 202 static int marvell_set_polarity(struct phy_device *phydev, int polarity) 203 { 204 int reg; 205 int err; 206 int val; 207 208 /* get the current settings */ 209 reg = phy_read(phydev, MII_M1011_PHY_SCR); 210 if (reg < 0) 211 return reg; 212 213 val = reg; 214 val &= ~MII_M1011_PHY_SCR_AUTO_CROSS; 215 switch (polarity) { 216 case ETH_TP_MDI: 217 val |= MII_M1011_PHY_SCR_MDI; 218 break; 219 case ETH_TP_MDI_X: 220 val |= MII_M1011_PHY_SCR_MDI_X; 221 break; 222 case ETH_TP_MDI_AUTO: 223 case ETH_TP_MDI_INVALID: 224 default: 225 val |= MII_M1011_PHY_SCR_AUTO_CROSS; 226 break; 227 } 228 229 if (val != reg) { 230 /* Set the new polarity value in the register */ 231 err = phy_write(phydev, MII_M1011_PHY_SCR, val); 232 if (err) 233 return err; 234 } 235 236 return 0; 237 } 238 239 static int marvell_config_aneg(struct phy_device *phydev) 240 { 241 int err; 242 243 /* The Marvell PHY has an errata which requires 244 * that certain registers get written in order 245 * to restart autonegotiation */ 246 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 247 248 if (err < 0) 249 return err; 250 251 err = phy_write(phydev, 0x1d, 0x1f); 252 if (err < 0) 253 return err; 254 255 err = phy_write(phydev, 0x1e, 0x200c); 256 if (err < 0) 257 return err; 258 259 err = phy_write(phydev, 0x1d, 0x5); 260 if (err < 0) 261 return err; 262 263 err = phy_write(phydev, 0x1e, 0); 264 if (err < 0) 265 return err; 266 267 err = phy_write(phydev, 0x1e, 0x100); 268 if (err < 0) 269 return err; 270 271 err = marvell_set_polarity(phydev, phydev->mdix); 272 if (err < 0) 273 return err; 274 275 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, 276 MII_M1111_PHY_LED_DIRECT); 277 if (err < 0) 278 return err; 279 280 err = genphy_config_aneg(phydev); 281 if (err < 0) 282 return err; 283 284 if (phydev->autoneg != AUTONEG_ENABLE) { 285 int bmcr; 286 287 /* 288 * A write to speed/duplex bits (that is performed by 289 * genphy_config_aneg() call above) must be followed by 290 * a software reset. Otherwise, the write has no effect. 291 */ 292 bmcr = phy_read(phydev, MII_BMCR); 293 if (bmcr < 0) 294 return bmcr; 295 296 err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET); 297 if (err < 0) 298 return err; 299 } 300 301 return 0; 302 } 303 304 static int m88e1111_config_aneg(struct phy_device *phydev) 305 { 306 int err; 307 308 /* The Marvell PHY has an errata which requires 309 * that certain registers get written in order 310 * to restart autonegotiation 311 */ 312 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 313 314 err = marvell_set_polarity(phydev, phydev->mdix); 315 if (err < 0) 316 return err; 317 318 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, 319 MII_M1111_PHY_LED_DIRECT); 320 if (err < 0) 321 return err; 322 323 err = genphy_config_aneg(phydev); 324 if (err < 0) 325 return err; 326 327 if (phydev->autoneg != AUTONEG_ENABLE) { 328 int bmcr; 329 330 /* A write to speed/duplex bits (that is performed by 331 * genphy_config_aneg() call above) must be followed by 332 * a software reset. Otherwise, the write has no effect. 333 */ 334 bmcr = phy_read(phydev, MII_BMCR); 335 if (bmcr < 0) 336 return bmcr; 337 338 err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET); 339 if (err < 0) 340 return err; 341 } 342 343 return 0; 344 } 345 346 #ifdef CONFIG_OF_MDIO 347 /* 348 * Set and/or override some configuration registers based on the 349 * marvell,reg-init property stored in the of_node for the phydev. 350 * 351 * marvell,reg-init = <reg-page reg mask value>,...; 352 * 353 * There may be one or more sets of <reg-page reg mask value>: 354 * 355 * reg-page: which register bank to use. 356 * reg: the register. 357 * mask: if non-zero, ANDed with existing register value. 358 * value: ORed with the masked value and written to the regiser. 359 * 360 */ 361 static int marvell_of_reg_init(struct phy_device *phydev) 362 { 363 const __be32 *paddr; 364 int len, i, saved_page, current_page, page_changed, ret; 365 366 if (!phydev->mdio.dev.of_node) 367 return 0; 368 369 paddr = of_get_property(phydev->mdio.dev.of_node, 370 "marvell,reg-init", &len); 371 if (!paddr || len < (4 * sizeof(*paddr))) 372 return 0; 373 374 saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE); 375 if (saved_page < 0) 376 return saved_page; 377 page_changed = 0; 378 current_page = saved_page; 379 380 ret = 0; 381 len /= sizeof(*paddr); 382 for (i = 0; i < len - 3; i += 4) { 383 u16 reg_page = be32_to_cpup(paddr + i); 384 u16 reg = be32_to_cpup(paddr + i + 1); 385 u16 mask = be32_to_cpup(paddr + i + 2); 386 u16 val_bits = be32_to_cpup(paddr + i + 3); 387 int val; 388 389 if (reg_page != current_page) { 390 current_page = reg_page; 391 page_changed = 1; 392 ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page); 393 if (ret < 0) 394 goto err; 395 } 396 397 val = 0; 398 if (mask) { 399 val = phy_read(phydev, reg); 400 if (val < 0) { 401 ret = val; 402 goto err; 403 } 404 val &= mask; 405 } 406 val |= val_bits; 407 408 ret = phy_write(phydev, reg, val); 409 if (ret < 0) 410 goto err; 411 412 } 413 err: 414 if (page_changed) { 415 i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page); 416 if (ret == 0) 417 ret = i; 418 } 419 return ret; 420 } 421 #else 422 static int marvell_of_reg_init(struct phy_device *phydev) 423 { 424 return 0; 425 } 426 #endif /* CONFIG_OF_MDIO */ 427 428 static int m88e1121_config_aneg(struct phy_device *phydev) 429 { 430 int err, oldpage, mscr; 431 432 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 433 434 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 435 MII_88E1121_PHY_MSCR_PAGE); 436 if (err < 0) 437 return err; 438 439 if (phy_interface_is_rgmii(phydev)) { 440 441 mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & 442 MII_88E1121_PHY_MSCR_DELAY_MASK; 443 444 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 445 mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | 446 MII_88E1121_PHY_MSCR_TX_DELAY); 447 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 448 mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; 449 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 450 mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; 451 452 err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); 453 if (err < 0) 454 return err; 455 } 456 457 phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 458 459 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 460 if (err < 0) 461 return err; 462 463 err = phy_write(phydev, MII_M1011_PHY_SCR, 464 MII_M1011_PHY_SCR_AUTO_CROSS); 465 if (err < 0) 466 return err; 467 468 return genphy_config_aneg(phydev); 469 } 470 471 static int m88e1318_config_aneg(struct phy_device *phydev) 472 { 473 int err, oldpage, mscr; 474 475 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 476 477 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 478 MII_88E1121_PHY_MSCR_PAGE); 479 if (err < 0) 480 return err; 481 482 mscr = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG); 483 mscr |= MII_88E1318S_PHY_MSCR1_PAD_ODD; 484 485 err = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, mscr); 486 if (err < 0) 487 return err; 488 489 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 490 if (err < 0) 491 return err; 492 493 return m88e1121_config_aneg(phydev); 494 } 495 496 /** 497 * ethtool_adv_to_fiber_adv_t 498 * @ethadv: the ethtool advertisement settings 499 * 500 * A small helper function that translates ethtool advertisement 501 * settings to phy autonegotiation advertisements for the 502 * MII_ADV register for fiber link. 503 */ 504 static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv) 505 { 506 u32 result = 0; 507 508 if (ethadv & ADVERTISED_1000baseT_Half) 509 result |= ADVERTISE_FIBER_1000HALF; 510 if (ethadv & ADVERTISED_1000baseT_Full) 511 result |= ADVERTISE_FIBER_1000FULL; 512 513 if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP)) 514 result |= LPA_PAUSE_ASYM_FIBER; 515 else if (ethadv & ADVERTISE_PAUSE_CAP) 516 result |= (ADVERTISE_PAUSE_FIBER 517 & (~ADVERTISE_PAUSE_ASYM_FIBER)); 518 519 return result; 520 } 521 522 /** 523 * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR 524 * @phydev: target phy_device struct 525 * 526 * Description: If auto-negotiation is enabled, we configure the 527 * advertising, and then restart auto-negotiation. If it is not 528 * enabled, then we write the BMCR. Adapted for fiber link in 529 * some Marvell's devices. 530 */ 531 static int marvell_config_aneg_fiber(struct phy_device *phydev) 532 { 533 int changed = 0; 534 int err; 535 int adv, oldadv; 536 u32 advertise; 537 538 if (phydev->autoneg != AUTONEG_ENABLE) 539 return genphy_setup_forced(phydev); 540 541 /* Only allow advertising what this PHY supports */ 542 phydev->advertising &= phydev->supported; 543 advertise = phydev->advertising; 544 545 /* Setup fiber advertisement */ 546 adv = phy_read(phydev, MII_ADVERTISE); 547 if (adv < 0) 548 return adv; 549 550 oldadv = adv; 551 adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL 552 | LPA_PAUSE_FIBER); 553 adv |= ethtool_adv_to_fiber_adv_t(advertise); 554 555 if (adv != oldadv) { 556 err = phy_write(phydev, MII_ADVERTISE, adv); 557 if (err < 0) 558 return err; 559 560 changed = 1; 561 } 562 563 if (changed == 0) { 564 /* Advertisement hasn't changed, but maybe aneg was never on to 565 * begin with? Or maybe phy was isolated? 566 */ 567 int ctl = phy_read(phydev, MII_BMCR); 568 569 if (ctl < 0) 570 return ctl; 571 572 if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) 573 changed = 1; /* do restart aneg */ 574 } 575 576 /* Only restart aneg if we are advertising something different 577 * than we were before. 578 */ 579 if (changed > 0) 580 changed = genphy_restart_aneg(phydev); 581 582 return changed; 583 } 584 585 static int m88e1510_config_aneg(struct phy_device *phydev) 586 { 587 int err; 588 589 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 590 if (err < 0) 591 goto error; 592 593 /* Configure the copper link first */ 594 err = m88e1318_config_aneg(phydev); 595 if (err < 0) 596 goto error; 597 598 /* Then the fiber link */ 599 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER); 600 if (err < 0) 601 goto error; 602 603 err = marvell_config_aneg_fiber(phydev); 604 if (err < 0) 605 goto error; 606 607 return phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 608 609 error: 610 phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 611 return err; 612 } 613 614 static int marvell_config_init(struct phy_device *phydev) 615 { 616 /* Set registers from marvell,reg-init DT property */ 617 return marvell_of_reg_init(phydev); 618 } 619 620 static int m88e1116r_config_init(struct phy_device *phydev) 621 { 622 int temp; 623 int err; 624 625 temp = phy_read(phydev, MII_BMCR); 626 temp |= BMCR_RESET; 627 err = phy_write(phydev, MII_BMCR, temp); 628 if (err < 0) 629 return err; 630 631 mdelay(500); 632 633 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0); 634 if (err < 0) 635 return err; 636 637 temp = phy_read(phydev, MII_M1011_PHY_SCR); 638 temp |= (7 << 12); /* max number of gigabit attempts */ 639 temp |= (1 << 11); /* enable downshift */ 640 temp |= MII_M1011_PHY_SCR_AUTO_CROSS; 641 err = phy_write(phydev, MII_M1011_PHY_SCR, temp); 642 if (err < 0) 643 return err; 644 645 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 2); 646 if (err < 0) 647 return err; 648 temp = phy_read(phydev, MII_M1116R_CONTROL_REG_MAC); 649 temp |= (1 << 5); 650 temp |= (1 << 4); 651 err = phy_write(phydev, MII_M1116R_CONTROL_REG_MAC, temp); 652 if (err < 0) 653 return err; 654 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0); 655 if (err < 0) 656 return err; 657 658 temp = phy_read(phydev, MII_BMCR); 659 temp |= BMCR_RESET; 660 err = phy_write(phydev, MII_BMCR, temp); 661 if (err < 0) 662 return err; 663 664 mdelay(500); 665 666 return marvell_config_init(phydev); 667 } 668 669 static int m88e3016_config_init(struct phy_device *phydev) 670 { 671 int reg; 672 673 /* Enable Scrambler and Auto-Crossover */ 674 reg = phy_read(phydev, MII_88E3016_PHY_SPEC_CTRL); 675 if (reg < 0) 676 return reg; 677 678 reg &= ~MII_88E3016_DISABLE_SCRAMBLER; 679 reg |= MII_88E3016_AUTO_MDIX_CROSSOVER; 680 681 reg = phy_write(phydev, MII_88E3016_PHY_SPEC_CTRL, reg); 682 if (reg < 0) 683 return reg; 684 685 return marvell_config_init(phydev); 686 } 687 688 static int m88e1111_config_init(struct phy_device *phydev) 689 { 690 int err; 691 int temp; 692 693 if (phy_interface_is_rgmii(phydev)) { 694 695 temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); 696 if (temp < 0) 697 return temp; 698 699 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 700 temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); 701 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 702 temp &= ~MII_M1111_TX_DELAY; 703 temp |= MII_M1111_RX_DELAY; 704 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 705 temp &= ~MII_M1111_RX_DELAY; 706 temp |= MII_M1111_TX_DELAY; 707 } 708 709 err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); 710 if (err < 0) 711 return err; 712 713 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 714 if (temp < 0) 715 return temp; 716 717 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 718 719 if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES) 720 temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; 721 else 722 temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; 723 724 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 725 if (err < 0) 726 return err; 727 } 728 729 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 730 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 731 if (temp < 0) 732 return temp; 733 734 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 735 temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK; 736 temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; 737 738 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 739 if (err < 0) 740 return err; 741 742 /* make sure copper is selected */ 743 err = phy_read(phydev, MII_M1145_PHY_EXT_ADDR_PAGE); 744 if (err < 0) 745 return err; 746 747 err = phy_write(phydev, MII_M1145_PHY_EXT_ADDR_PAGE, 748 err & (~0xff)); 749 if (err < 0) 750 return err; 751 } 752 753 if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { 754 temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); 755 if (temp < 0) 756 return temp; 757 temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); 758 err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); 759 if (err < 0) 760 return err; 761 762 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 763 if (temp < 0) 764 return temp; 765 temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); 766 temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO; 767 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 768 if (err < 0) 769 return err; 770 771 /* soft reset */ 772 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 773 if (err < 0) 774 return err; 775 do 776 temp = phy_read(phydev, MII_BMCR); 777 while (temp & BMCR_RESET); 778 779 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 780 if (temp < 0) 781 return temp; 782 temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); 783 temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO; 784 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 785 if (err < 0) 786 return err; 787 } 788 789 err = marvell_of_reg_init(phydev); 790 if (err < 0) 791 return err; 792 793 return phy_write(phydev, MII_BMCR, BMCR_RESET); 794 } 795 796 static int m88e1121_config_init(struct phy_device *phydev) 797 { 798 int err, oldpage; 799 800 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 801 802 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); 803 if (err < 0) 804 return err; 805 806 /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */ 807 err = phy_write(phydev, MII_88E1121_PHY_LED_CTRL, 808 MII_88E1121_PHY_LED_DEF); 809 if (err < 0) 810 return err; 811 812 phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 813 814 /* Set marvell,reg-init configuration from device tree */ 815 return marvell_config_init(phydev); 816 } 817 818 static int m88e1510_config_init(struct phy_device *phydev) 819 { 820 int err; 821 int temp; 822 823 /* SGMII-to-Copper mode initialization */ 824 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 825 /* Select page 18 */ 826 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18); 827 if (err < 0) 828 return err; 829 830 /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ 831 temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1); 832 temp &= ~MII_88E1510_GEN_CTRL_REG_1_MODE_MASK; 833 temp |= MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII; 834 err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); 835 if (err < 0) 836 return err; 837 838 /* PHY reset is necessary after changing MODE[2:0] */ 839 temp |= MII_88E1510_GEN_CTRL_REG_1_RESET; 840 err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); 841 if (err < 0) 842 return err; 843 844 /* Reset page selection */ 845 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0); 846 if (err < 0) 847 return err; 848 } 849 850 return m88e1121_config_init(phydev); 851 } 852 853 static int m88e1118_config_aneg(struct phy_device *phydev) 854 { 855 int err; 856 857 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 858 if (err < 0) 859 return err; 860 861 err = phy_write(phydev, MII_M1011_PHY_SCR, 862 MII_M1011_PHY_SCR_AUTO_CROSS); 863 if (err < 0) 864 return err; 865 866 err = genphy_config_aneg(phydev); 867 return 0; 868 } 869 870 static int m88e1118_config_init(struct phy_device *phydev) 871 { 872 int err; 873 874 /* Change address */ 875 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); 876 if (err < 0) 877 return err; 878 879 /* Enable 1000 Mbit */ 880 err = phy_write(phydev, 0x15, 0x1070); 881 if (err < 0) 882 return err; 883 884 /* Change address */ 885 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003); 886 if (err < 0) 887 return err; 888 889 /* Adjust LED Control */ 890 if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS) 891 err = phy_write(phydev, 0x10, 0x1100); 892 else 893 err = phy_write(phydev, 0x10, 0x021e); 894 if (err < 0) 895 return err; 896 897 err = marvell_of_reg_init(phydev); 898 if (err < 0) 899 return err; 900 901 /* Reset address */ 902 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); 903 if (err < 0) 904 return err; 905 906 return phy_write(phydev, MII_BMCR, BMCR_RESET); 907 } 908 909 static int m88e1149_config_init(struct phy_device *phydev) 910 { 911 int err; 912 913 /* Change address */ 914 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); 915 if (err < 0) 916 return err; 917 918 /* Enable 1000 Mbit */ 919 err = phy_write(phydev, 0x15, 0x1048); 920 if (err < 0) 921 return err; 922 923 err = marvell_of_reg_init(phydev); 924 if (err < 0) 925 return err; 926 927 /* Reset address */ 928 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); 929 if (err < 0) 930 return err; 931 932 return phy_write(phydev, MII_BMCR, BMCR_RESET); 933 } 934 935 static int m88e1145_config_init(struct phy_device *phydev) 936 { 937 int err; 938 int temp; 939 940 /* Take care of errata E0 & E1 */ 941 err = phy_write(phydev, 0x1d, 0x001b); 942 if (err < 0) 943 return err; 944 945 err = phy_write(phydev, 0x1e, 0x418f); 946 if (err < 0) 947 return err; 948 949 err = phy_write(phydev, 0x1d, 0x0016); 950 if (err < 0) 951 return err; 952 953 err = phy_write(phydev, 0x1e, 0xa2da); 954 if (err < 0) 955 return err; 956 957 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 958 int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR); 959 if (temp < 0) 960 return temp; 961 962 temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY); 963 964 err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp); 965 if (err < 0) 966 return err; 967 968 if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) { 969 err = phy_write(phydev, 0x1d, 0x0012); 970 if (err < 0) 971 return err; 972 973 temp = phy_read(phydev, 0x1e); 974 if (temp < 0) 975 return temp; 976 977 temp &= 0xf03f; 978 temp |= 2 << 9; /* 36 ohm */ 979 temp |= 2 << 6; /* 39 ohm */ 980 981 err = phy_write(phydev, 0x1e, temp); 982 if (err < 0) 983 return err; 984 985 err = phy_write(phydev, 0x1d, 0x3); 986 if (err < 0) 987 return err; 988 989 err = phy_write(phydev, 0x1e, 0x8000); 990 if (err < 0) 991 return err; 992 } 993 } 994 995 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 996 temp = phy_read(phydev, MII_M1145_PHY_EXT_SR); 997 if (temp < 0) 998 return temp; 999 1000 temp &= ~MII_M1145_HWCFG_MODE_MASK; 1001 temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK; 1002 temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO; 1003 1004 err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp); 1005 if (err < 0) 1006 return err; 1007 } 1008 1009 err = marvell_of_reg_init(phydev); 1010 if (err < 0) 1011 return err; 1012 1013 return 0; 1014 } 1015 1016 /** 1017 * fiber_lpa_to_ethtool_lpa_t 1018 * @lpa: value of the MII_LPA register for fiber link 1019 * 1020 * A small helper function that translates MII_LPA 1021 * bits to ethtool LP advertisement settings. 1022 */ 1023 static u32 fiber_lpa_to_ethtool_lpa_t(u32 lpa) 1024 { 1025 u32 result = 0; 1026 1027 if (lpa & LPA_FIBER_1000HALF) 1028 result |= ADVERTISED_1000baseT_Half; 1029 if (lpa & LPA_FIBER_1000FULL) 1030 result |= ADVERTISED_1000baseT_Full; 1031 1032 return result; 1033 } 1034 1035 /** 1036 * marvell_update_link - update link status in real time in @phydev 1037 * @phydev: target phy_device struct 1038 * 1039 * Description: Update the value in phydev->link to reflect the 1040 * current link value. 1041 */ 1042 static int marvell_update_link(struct phy_device *phydev, int fiber) 1043 { 1044 int status; 1045 1046 /* Use the generic register for copper link, or specific 1047 * register for fiber case */ 1048 if (fiber) { 1049 status = phy_read(phydev, MII_M1011_PHY_STATUS); 1050 if (status < 0) 1051 return status; 1052 1053 if ((status & REGISTER_LINK_STATUS) == 0) 1054 phydev->link = 0; 1055 else 1056 phydev->link = 1; 1057 } else { 1058 return genphy_update_link(phydev); 1059 } 1060 1061 return 0; 1062 } 1063 1064 /* marvell_read_status_page 1065 * 1066 * Description: 1067 * Check the link, then figure out the current state 1068 * by comparing what we advertise with what the link partner 1069 * advertises. Start by checking the gigabit possibilities, 1070 * then move on to 10/100. 1071 */ 1072 static int marvell_read_status_page(struct phy_device *phydev, int page) 1073 { 1074 int adv; 1075 int err; 1076 int lpa; 1077 int lpagb; 1078 int status = 0; 1079 int fiber; 1080 1081 /* Detect and update the link, but return if there 1082 * was an error */ 1083 if (page == MII_M1111_FIBER) 1084 fiber = 1; 1085 else 1086 fiber = 0; 1087 1088 err = marvell_update_link(phydev, fiber); 1089 if (err) 1090 return err; 1091 1092 if (AUTONEG_ENABLE == phydev->autoneg) { 1093 status = phy_read(phydev, MII_M1011_PHY_STATUS); 1094 if (status < 0) 1095 return status; 1096 1097 lpa = phy_read(phydev, MII_LPA); 1098 if (lpa < 0) 1099 return lpa; 1100 1101 lpagb = phy_read(phydev, MII_STAT1000); 1102 if (lpagb < 0) 1103 return lpagb; 1104 1105 adv = phy_read(phydev, MII_ADVERTISE); 1106 if (adv < 0) 1107 return adv; 1108 1109 lpa &= adv; 1110 1111 if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) 1112 phydev->duplex = DUPLEX_FULL; 1113 else 1114 phydev->duplex = DUPLEX_HALF; 1115 1116 status = status & MII_M1011_PHY_STATUS_SPD_MASK; 1117 phydev->pause = phydev->asym_pause = 0; 1118 1119 switch (status) { 1120 case MII_M1011_PHY_STATUS_1000: 1121 phydev->speed = SPEED_1000; 1122 break; 1123 1124 case MII_M1011_PHY_STATUS_100: 1125 phydev->speed = SPEED_100; 1126 break; 1127 1128 default: 1129 phydev->speed = SPEED_10; 1130 break; 1131 } 1132 1133 if (!fiber) { 1134 phydev->lp_advertising = mii_stat1000_to_ethtool_lpa_t(lpagb) | 1135 mii_lpa_to_ethtool_lpa_t(lpa); 1136 1137 if (phydev->duplex == DUPLEX_FULL) { 1138 phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; 1139 phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; 1140 } 1141 } else { 1142 /* The fiber link is only 1000M capable */ 1143 phydev->lp_advertising = fiber_lpa_to_ethtool_lpa_t(lpa); 1144 1145 if (phydev->duplex == DUPLEX_FULL) { 1146 if (!(lpa & LPA_PAUSE_FIBER)) { 1147 phydev->pause = 0; 1148 phydev->asym_pause = 0; 1149 } else if ((lpa & LPA_PAUSE_ASYM_FIBER)) { 1150 phydev->pause = 1; 1151 phydev->asym_pause = 1; 1152 } else { 1153 phydev->pause = 1; 1154 phydev->asym_pause = 0; 1155 } 1156 } 1157 } 1158 } else { 1159 int bmcr = phy_read(phydev, MII_BMCR); 1160 1161 if (bmcr < 0) 1162 return bmcr; 1163 1164 if (bmcr & BMCR_FULLDPLX) 1165 phydev->duplex = DUPLEX_FULL; 1166 else 1167 phydev->duplex = DUPLEX_HALF; 1168 1169 if (bmcr & BMCR_SPEED1000) 1170 phydev->speed = SPEED_1000; 1171 else if (bmcr & BMCR_SPEED100) 1172 phydev->speed = SPEED_100; 1173 else 1174 phydev->speed = SPEED_10; 1175 1176 phydev->pause = phydev->asym_pause = 0; 1177 phydev->lp_advertising = 0; 1178 } 1179 1180 return 0; 1181 } 1182 1183 /* marvell_read_status 1184 * 1185 * Some Marvell's phys have two modes: fiber and copper. 1186 * Both need status checked. 1187 * Description: 1188 * First, check the fiber link and status. 1189 * If the fiber link is down, check the copper link and status which 1190 * will be the default value if both link are down. 1191 */ 1192 static int marvell_read_status(struct phy_device *phydev) 1193 { 1194 int err; 1195 1196 /* Check the fiber mode first */ 1197 if (phydev->supported & SUPPORTED_FIBRE) { 1198 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER); 1199 if (err < 0) 1200 goto error; 1201 1202 err = marvell_read_status_page(phydev, MII_M1111_FIBER); 1203 if (err < 0) 1204 goto error; 1205 1206 /* If the fiber link is up, it is the selected and used link. 1207 * In this case, we need to stay in the fiber page. 1208 * Please to be careful about that, avoid to restore Copper page 1209 * in other functions which could break the behaviour 1210 * for some fiber phy like 88E1512. 1211 * */ 1212 if (phydev->link) 1213 return 0; 1214 1215 /* If fiber link is down, check and save copper mode state */ 1216 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 1217 if (err < 0) 1218 goto error; 1219 } 1220 1221 return marvell_read_status_page(phydev, MII_M1111_COPPER); 1222 1223 error: 1224 phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 1225 return err; 1226 } 1227 1228 /* marvell_suspend 1229 * 1230 * Some Marvell's phys have two modes: fiber and copper. 1231 * Both need to be suspended 1232 */ 1233 static int marvell_suspend(struct phy_device *phydev) 1234 { 1235 int err; 1236 1237 /* Suspend the fiber mode first */ 1238 if (!(phydev->supported & SUPPORTED_FIBRE)) { 1239 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER); 1240 if (err < 0) 1241 goto error; 1242 1243 /* With the page set, use the generic suspend */ 1244 err = genphy_suspend(phydev); 1245 if (err < 0) 1246 goto error; 1247 1248 /* Then, the copper link */ 1249 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 1250 if (err < 0) 1251 goto error; 1252 } 1253 1254 /* With the page set, use the generic suspend */ 1255 return genphy_suspend(phydev); 1256 1257 error: 1258 phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 1259 return err; 1260 } 1261 1262 /* marvell_resume 1263 * 1264 * Some Marvell's phys have two modes: fiber and copper. 1265 * Both need to be resumed 1266 */ 1267 static int marvell_resume(struct phy_device *phydev) 1268 { 1269 int err; 1270 1271 /* Resume the fiber mode first */ 1272 if (!(phydev->supported & SUPPORTED_FIBRE)) { 1273 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER); 1274 if (err < 0) 1275 goto error; 1276 1277 /* With the page set, use the generic resume */ 1278 err = genphy_resume(phydev); 1279 if (err < 0) 1280 goto error; 1281 1282 /* Then, the copper link */ 1283 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 1284 if (err < 0) 1285 goto error; 1286 } 1287 1288 /* With the page set, use the generic resume */ 1289 return genphy_resume(phydev); 1290 1291 error: 1292 phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); 1293 return err; 1294 } 1295 1296 static int marvell_aneg_done(struct phy_device *phydev) 1297 { 1298 int retval = phy_read(phydev, MII_M1011_PHY_STATUS); 1299 return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED); 1300 } 1301 1302 static int m88e1121_did_interrupt(struct phy_device *phydev) 1303 { 1304 int imask; 1305 1306 imask = phy_read(phydev, MII_M1011_IEVENT); 1307 1308 if (imask & MII_M1011_IMASK_INIT) 1309 return 1; 1310 1311 return 0; 1312 } 1313 1314 static void m88e1318_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) 1315 { 1316 wol->supported = WAKE_MAGIC; 1317 wol->wolopts = 0; 1318 1319 if (phy_write(phydev, MII_MARVELL_PHY_PAGE, 1320 MII_88E1318S_PHY_WOL_PAGE) < 0) 1321 return; 1322 1323 if (phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL) & 1324 MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE) 1325 wol->wolopts |= WAKE_MAGIC; 1326 1327 if (phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00) < 0) 1328 return; 1329 } 1330 1331 static int m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) 1332 { 1333 int err, oldpage, temp; 1334 1335 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 1336 1337 if (wol->wolopts & WAKE_MAGIC) { 1338 /* Explicitly switch to page 0x00, just to be sure */ 1339 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00); 1340 if (err < 0) 1341 return err; 1342 1343 /* Enable the WOL interrupt */ 1344 temp = phy_read(phydev, MII_88E1318S_PHY_CSIER); 1345 temp |= MII_88E1318S_PHY_CSIER_WOL_EIE; 1346 err = phy_write(phydev, MII_88E1318S_PHY_CSIER, temp); 1347 if (err < 0) 1348 return err; 1349 1350 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 1351 MII_88E1318S_PHY_LED_PAGE); 1352 if (err < 0) 1353 return err; 1354 1355 /* Setup LED[2] as interrupt pin (active low) */ 1356 temp = phy_read(phydev, MII_88E1318S_PHY_LED_TCR); 1357 temp &= ~MII_88E1318S_PHY_LED_TCR_FORCE_INT; 1358 temp |= MII_88E1318S_PHY_LED_TCR_INTn_ENABLE; 1359 temp |= MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW; 1360 err = phy_write(phydev, MII_88E1318S_PHY_LED_TCR, temp); 1361 if (err < 0) 1362 return err; 1363 1364 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 1365 MII_88E1318S_PHY_WOL_PAGE); 1366 if (err < 0) 1367 return err; 1368 1369 /* Store the device address for the magic packet */ 1370 err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2, 1371 ((phydev->attached_dev->dev_addr[5] << 8) | 1372 phydev->attached_dev->dev_addr[4])); 1373 if (err < 0) 1374 return err; 1375 err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1, 1376 ((phydev->attached_dev->dev_addr[3] << 8) | 1377 phydev->attached_dev->dev_addr[2])); 1378 if (err < 0) 1379 return err; 1380 err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0, 1381 ((phydev->attached_dev->dev_addr[1] << 8) | 1382 phydev->attached_dev->dev_addr[0])); 1383 if (err < 0) 1384 return err; 1385 1386 /* Clear WOL status and enable magic packet matching */ 1387 temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); 1388 temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS; 1389 temp |= MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE; 1390 err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp); 1391 if (err < 0) 1392 return err; 1393 } else { 1394 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 1395 MII_88E1318S_PHY_WOL_PAGE); 1396 if (err < 0) 1397 return err; 1398 1399 /* Clear WOL status and disable magic packet matching */ 1400 temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); 1401 temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS; 1402 temp &= ~MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE; 1403 err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp); 1404 if (err < 0) 1405 return err; 1406 } 1407 1408 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 1409 if (err < 0) 1410 return err; 1411 1412 return 0; 1413 } 1414 1415 static int marvell_get_sset_count(struct phy_device *phydev) 1416 { 1417 if (phydev->supported & SUPPORTED_FIBRE) 1418 return ARRAY_SIZE(marvell_hw_stats); 1419 else 1420 return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS; 1421 } 1422 1423 static void marvell_get_strings(struct phy_device *phydev, u8 *data) 1424 { 1425 int i; 1426 1427 for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { 1428 memcpy(data + i * ETH_GSTRING_LEN, 1429 marvell_hw_stats[i].string, ETH_GSTRING_LEN); 1430 } 1431 } 1432 1433 #ifndef UINT64_MAX 1434 #define UINT64_MAX (u64)(~((u64)0)) 1435 #endif 1436 static u64 marvell_get_stat(struct phy_device *phydev, int i) 1437 { 1438 struct marvell_hw_stat stat = marvell_hw_stats[i]; 1439 struct marvell_priv *priv = phydev->priv; 1440 int err, oldpage, val; 1441 u64 ret; 1442 1443 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 1444 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 1445 stat.page); 1446 if (err < 0) 1447 return UINT64_MAX; 1448 1449 val = phy_read(phydev, stat.reg); 1450 if (val < 0) { 1451 ret = UINT64_MAX; 1452 } else { 1453 val = val & ((1 << stat.bits) - 1); 1454 priv->stats[i] += val; 1455 ret = priv->stats[i]; 1456 } 1457 1458 phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 1459 1460 return ret; 1461 } 1462 1463 static void marvell_get_stats(struct phy_device *phydev, 1464 struct ethtool_stats *stats, u64 *data) 1465 { 1466 int i; 1467 1468 for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) 1469 data[i] = marvell_get_stat(phydev, i); 1470 } 1471 1472 static int marvell_probe(struct phy_device *phydev) 1473 { 1474 struct marvell_priv *priv; 1475 1476 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 1477 if (!priv) 1478 return -ENOMEM; 1479 1480 phydev->priv = priv; 1481 1482 return 0; 1483 } 1484 1485 static struct phy_driver marvell_drivers[] = { 1486 { 1487 .phy_id = MARVELL_PHY_ID_88E1101, 1488 .phy_id_mask = MARVELL_PHY_ID_MASK, 1489 .name = "Marvell 88E1101", 1490 .features = PHY_GBIT_FEATURES, 1491 .probe = marvell_probe, 1492 .flags = PHY_HAS_INTERRUPT, 1493 .config_init = &marvell_config_init, 1494 .config_aneg = &marvell_config_aneg, 1495 .read_status = &genphy_read_status, 1496 .ack_interrupt = &marvell_ack_interrupt, 1497 .config_intr = &marvell_config_intr, 1498 .resume = &genphy_resume, 1499 .suspend = &genphy_suspend, 1500 .get_sset_count = marvell_get_sset_count, 1501 .get_strings = marvell_get_strings, 1502 .get_stats = marvell_get_stats, 1503 }, 1504 { 1505 .phy_id = MARVELL_PHY_ID_88E1112, 1506 .phy_id_mask = MARVELL_PHY_ID_MASK, 1507 .name = "Marvell 88E1112", 1508 .features = PHY_GBIT_FEATURES, 1509 .flags = PHY_HAS_INTERRUPT, 1510 .probe = marvell_probe, 1511 .config_init = &m88e1111_config_init, 1512 .config_aneg = &marvell_config_aneg, 1513 .read_status = &genphy_read_status, 1514 .ack_interrupt = &marvell_ack_interrupt, 1515 .config_intr = &marvell_config_intr, 1516 .resume = &genphy_resume, 1517 .suspend = &genphy_suspend, 1518 .get_sset_count = marvell_get_sset_count, 1519 .get_strings = marvell_get_strings, 1520 .get_stats = marvell_get_stats, 1521 }, 1522 { 1523 .phy_id = MARVELL_PHY_ID_88E1111, 1524 .phy_id_mask = MARVELL_PHY_ID_MASK, 1525 .name = "Marvell 88E1111", 1526 .features = PHY_GBIT_FEATURES, 1527 .flags = PHY_HAS_INTERRUPT, 1528 .probe = marvell_probe, 1529 .config_init = &m88e1111_config_init, 1530 .config_aneg = &m88e1111_config_aneg, 1531 .read_status = &marvell_read_status, 1532 .ack_interrupt = &marvell_ack_interrupt, 1533 .config_intr = &marvell_config_intr, 1534 .resume = &genphy_resume, 1535 .suspend = &genphy_suspend, 1536 .get_sset_count = marvell_get_sset_count, 1537 .get_strings = marvell_get_strings, 1538 .get_stats = marvell_get_stats, 1539 }, 1540 { 1541 .phy_id = MARVELL_PHY_ID_88E1118, 1542 .phy_id_mask = MARVELL_PHY_ID_MASK, 1543 .name = "Marvell 88E1118", 1544 .features = PHY_GBIT_FEATURES, 1545 .flags = PHY_HAS_INTERRUPT, 1546 .probe = marvell_probe, 1547 .config_init = &m88e1118_config_init, 1548 .config_aneg = &m88e1118_config_aneg, 1549 .read_status = &genphy_read_status, 1550 .ack_interrupt = &marvell_ack_interrupt, 1551 .config_intr = &marvell_config_intr, 1552 .resume = &genphy_resume, 1553 .suspend = &genphy_suspend, 1554 .get_sset_count = marvell_get_sset_count, 1555 .get_strings = marvell_get_strings, 1556 .get_stats = marvell_get_stats, 1557 }, 1558 { 1559 .phy_id = MARVELL_PHY_ID_88E1121R, 1560 .phy_id_mask = MARVELL_PHY_ID_MASK, 1561 .name = "Marvell 88E1121R", 1562 .features = PHY_GBIT_FEATURES, 1563 .flags = PHY_HAS_INTERRUPT, 1564 .probe = marvell_probe, 1565 .config_init = &m88e1121_config_init, 1566 .config_aneg = &m88e1121_config_aneg, 1567 .read_status = &marvell_read_status, 1568 .ack_interrupt = &marvell_ack_interrupt, 1569 .config_intr = &marvell_config_intr, 1570 .did_interrupt = &m88e1121_did_interrupt, 1571 .resume = &genphy_resume, 1572 .suspend = &genphy_suspend, 1573 .get_sset_count = marvell_get_sset_count, 1574 .get_strings = marvell_get_strings, 1575 .get_stats = marvell_get_stats, 1576 }, 1577 { 1578 .phy_id = MARVELL_PHY_ID_88E1318S, 1579 .phy_id_mask = MARVELL_PHY_ID_MASK, 1580 .name = "Marvell 88E1318S", 1581 .features = PHY_GBIT_FEATURES, 1582 .flags = PHY_HAS_INTERRUPT, 1583 .probe = marvell_probe, 1584 .config_init = &m88e1121_config_init, 1585 .config_aneg = &m88e1318_config_aneg, 1586 .read_status = &marvell_read_status, 1587 .ack_interrupt = &marvell_ack_interrupt, 1588 .config_intr = &marvell_config_intr, 1589 .did_interrupt = &m88e1121_did_interrupt, 1590 .get_wol = &m88e1318_get_wol, 1591 .set_wol = &m88e1318_set_wol, 1592 .resume = &genphy_resume, 1593 .suspend = &genphy_suspend, 1594 .get_sset_count = marvell_get_sset_count, 1595 .get_strings = marvell_get_strings, 1596 .get_stats = marvell_get_stats, 1597 }, 1598 { 1599 .phy_id = MARVELL_PHY_ID_88E1145, 1600 .phy_id_mask = MARVELL_PHY_ID_MASK, 1601 .name = "Marvell 88E1145", 1602 .features = PHY_GBIT_FEATURES, 1603 .flags = PHY_HAS_INTERRUPT, 1604 .probe = marvell_probe, 1605 .config_init = &m88e1145_config_init, 1606 .config_aneg = &marvell_config_aneg, 1607 .read_status = &genphy_read_status, 1608 .ack_interrupt = &marvell_ack_interrupt, 1609 .config_intr = &marvell_config_intr, 1610 .resume = &genphy_resume, 1611 .suspend = &genphy_suspend, 1612 .get_sset_count = marvell_get_sset_count, 1613 .get_strings = marvell_get_strings, 1614 .get_stats = marvell_get_stats, 1615 }, 1616 { 1617 .phy_id = MARVELL_PHY_ID_88E1149R, 1618 .phy_id_mask = MARVELL_PHY_ID_MASK, 1619 .name = "Marvell 88E1149R", 1620 .features = PHY_GBIT_FEATURES, 1621 .flags = PHY_HAS_INTERRUPT, 1622 .probe = marvell_probe, 1623 .config_init = &m88e1149_config_init, 1624 .config_aneg = &m88e1118_config_aneg, 1625 .read_status = &genphy_read_status, 1626 .ack_interrupt = &marvell_ack_interrupt, 1627 .config_intr = &marvell_config_intr, 1628 .resume = &genphy_resume, 1629 .suspend = &genphy_suspend, 1630 .get_sset_count = marvell_get_sset_count, 1631 .get_strings = marvell_get_strings, 1632 .get_stats = marvell_get_stats, 1633 }, 1634 { 1635 .phy_id = MARVELL_PHY_ID_88E1240, 1636 .phy_id_mask = MARVELL_PHY_ID_MASK, 1637 .name = "Marvell 88E1240", 1638 .features = PHY_GBIT_FEATURES, 1639 .flags = PHY_HAS_INTERRUPT, 1640 .probe = marvell_probe, 1641 .config_init = &m88e1111_config_init, 1642 .config_aneg = &marvell_config_aneg, 1643 .read_status = &genphy_read_status, 1644 .ack_interrupt = &marvell_ack_interrupt, 1645 .config_intr = &marvell_config_intr, 1646 .resume = &genphy_resume, 1647 .suspend = &genphy_suspend, 1648 .get_sset_count = marvell_get_sset_count, 1649 .get_strings = marvell_get_strings, 1650 .get_stats = marvell_get_stats, 1651 }, 1652 { 1653 .phy_id = MARVELL_PHY_ID_88E1116R, 1654 .phy_id_mask = MARVELL_PHY_ID_MASK, 1655 .name = "Marvell 88E1116R", 1656 .features = PHY_GBIT_FEATURES, 1657 .flags = PHY_HAS_INTERRUPT, 1658 .probe = marvell_probe, 1659 .config_init = &m88e1116r_config_init, 1660 .config_aneg = &genphy_config_aneg, 1661 .read_status = &genphy_read_status, 1662 .ack_interrupt = &marvell_ack_interrupt, 1663 .config_intr = &marvell_config_intr, 1664 .resume = &genphy_resume, 1665 .suspend = &genphy_suspend, 1666 .get_sset_count = marvell_get_sset_count, 1667 .get_strings = marvell_get_strings, 1668 .get_stats = marvell_get_stats, 1669 }, 1670 { 1671 .phy_id = MARVELL_PHY_ID_88E1510, 1672 .phy_id_mask = MARVELL_PHY_ID_MASK, 1673 .name = "Marvell 88E1510", 1674 .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE, 1675 .flags = PHY_HAS_INTERRUPT, 1676 .probe = marvell_probe, 1677 .config_init = &m88e1510_config_init, 1678 .config_aneg = &m88e1510_config_aneg, 1679 .read_status = &marvell_read_status, 1680 .ack_interrupt = &marvell_ack_interrupt, 1681 .config_intr = &marvell_config_intr, 1682 .did_interrupt = &m88e1121_did_interrupt, 1683 .resume = &marvell_resume, 1684 .suspend = &marvell_suspend, 1685 .get_sset_count = marvell_get_sset_count, 1686 .get_strings = marvell_get_strings, 1687 .get_stats = marvell_get_stats, 1688 }, 1689 { 1690 .phy_id = MARVELL_PHY_ID_88E1540, 1691 .phy_id_mask = MARVELL_PHY_ID_MASK, 1692 .name = "Marvell 88E1540", 1693 .features = PHY_GBIT_FEATURES, 1694 .flags = PHY_HAS_INTERRUPT, 1695 .probe = marvell_probe, 1696 .config_init = &marvell_config_init, 1697 .config_aneg = &m88e1510_config_aneg, 1698 .read_status = &marvell_read_status, 1699 .ack_interrupt = &marvell_ack_interrupt, 1700 .config_intr = &marvell_config_intr, 1701 .did_interrupt = &m88e1121_did_interrupt, 1702 .resume = &genphy_resume, 1703 .suspend = &genphy_suspend, 1704 .get_sset_count = marvell_get_sset_count, 1705 .get_strings = marvell_get_strings, 1706 .get_stats = marvell_get_stats, 1707 }, 1708 { 1709 .phy_id = MARVELL_PHY_ID_88E3016, 1710 .phy_id_mask = MARVELL_PHY_ID_MASK, 1711 .name = "Marvell 88E3016", 1712 .features = PHY_BASIC_FEATURES, 1713 .flags = PHY_HAS_INTERRUPT, 1714 .probe = marvell_probe, 1715 .config_aneg = &genphy_config_aneg, 1716 .config_init = &m88e3016_config_init, 1717 .aneg_done = &marvell_aneg_done, 1718 .read_status = &marvell_read_status, 1719 .ack_interrupt = &marvell_ack_interrupt, 1720 .config_intr = &marvell_config_intr, 1721 .did_interrupt = &m88e1121_did_interrupt, 1722 .resume = &genphy_resume, 1723 .suspend = &genphy_suspend, 1724 .get_sset_count = marvell_get_sset_count, 1725 .get_strings = marvell_get_strings, 1726 .get_stats = marvell_get_stats, 1727 }, 1728 }; 1729 1730 module_phy_driver(marvell_drivers); 1731 1732 static struct mdio_device_id __maybe_unused marvell_tbl[] = { 1733 { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK }, 1734 { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK }, 1735 { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK }, 1736 { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK }, 1737 { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK }, 1738 { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, 1739 { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, 1740 { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, 1741 { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, 1742 { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, 1743 { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, 1744 { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK }, 1745 { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK }, 1746 { } 1747 }; 1748 1749 MODULE_DEVICE_TABLE(mdio, marvell_tbl); 1750