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/ctype.h> 21 #include <linux/errno.h> 22 #include <linux/unistd.h> 23 #include <linux/hwmon.h> 24 #include <linux/interrupt.h> 25 #include <linux/init.h> 26 #include <linux/delay.h> 27 #include <linux/netdevice.h> 28 #include <linux/etherdevice.h> 29 #include <linux/skbuff.h> 30 #include <linux/spinlock.h> 31 #include <linux/mm.h> 32 #include <linux/module.h> 33 #include <linux/mii.h> 34 #include <linux/ethtool.h> 35 #include <linux/phy.h> 36 #include <linux/marvell_phy.h> 37 #include <linux/of.h> 38 39 #include <linux/io.h> 40 #include <asm/irq.h> 41 #include <linux/uaccess.h> 42 43 #define MII_MARVELL_PHY_PAGE 22 44 #define MII_MARVELL_COPPER_PAGE 0x00 45 #define MII_MARVELL_FIBER_PAGE 0x01 46 #define MII_MARVELL_MSCR_PAGE 0x02 47 #define MII_MARVELL_LED_PAGE 0x03 48 #define MII_MARVELL_MISC_TEST_PAGE 0x06 49 #define MII_MARVELL_WOL_PAGE 0x11 50 51 #define MII_M1011_IEVENT 0x13 52 #define MII_M1011_IEVENT_CLEAR 0x0000 53 54 #define MII_M1011_IMASK 0x12 55 #define MII_M1011_IMASK_INIT 0x6400 56 #define MII_M1011_IMASK_CLEAR 0x0000 57 58 #define MII_M1011_PHY_SCR 0x10 59 #define MII_M1011_PHY_SCR_DOWNSHIFT_EN BIT(11) 60 #define MII_M1011_PHY_SCR_DOWNSHIFT_SHIFT 12 61 #define MII_M1011_PHY_SRC_DOWNSHIFT_MASK 0x7800 62 #define MII_M1011_PHY_SCR_MDI (0x0 << 5) 63 #define MII_M1011_PHY_SCR_MDI_X (0x1 << 5) 64 #define MII_M1011_PHY_SCR_AUTO_CROSS (0x3 << 5) 65 66 #define MII_M1111_PHY_LED_CONTROL 0x18 67 #define MII_M1111_PHY_LED_DIRECT 0x4100 68 #define MII_M1111_PHY_LED_COMBINE 0x411c 69 #define MII_M1111_PHY_EXT_CR 0x14 70 #define MII_M1111_RGMII_RX_DELAY BIT(7) 71 #define MII_M1111_RGMII_TX_DELAY BIT(1) 72 #define MII_M1111_PHY_EXT_SR 0x1b 73 74 #define MII_M1111_HWCFG_MODE_MASK 0xf 75 #define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 76 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 77 #define MII_M1111_HWCFG_MODE_RTBI 0x7 78 #define MII_M1111_HWCFG_MODE_COPPER_RTBI 0x9 79 #define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb 80 #define MII_M1111_HWCFG_FIBER_COPPER_RES BIT(13) 81 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO BIT(15) 82 83 #define MII_88E1121_PHY_MSCR_REG 21 84 #define MII_88E1121_PHY_MSCR_RX_DELAY BIT(5) 85 #define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4) 86 #define MII_88E1121_PHY_MSCR_DELAY_MASK (BIT(5) | BIT(4)) 87 88 #define MII_88E1121_MISC_TEST 0x1a 89 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK 0x1f00 90 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT 8 91 #define MII_88E1510_MISC_TEST_TEMP_IRQ_EN BIT(7) 92 #define MII_88E1510_MISC_TEST_TEMP_IRQ BIT(6) 93 #define MII_88E1121_MISC_TEST_TEMP_SENSOR_EN BIT(5) 94 #define MII_88E1121_MISC_TEST_TEMP_MASK 0x1f 95 96 #define MII_88E1510_TEMP_SENSOR 0x1b 97 #define MII_88E1510_TEMP_SENSOR_MASK 0xff 98 99 #define MII_88E1318S_PHY_MSCR1_REG 16 100 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6) 101 102 /* Copper Specific Interrupt Enable Register */ 103 #define MII_88E1318S_PHY_CSIER 0x12 104 /* WOL Event Interrupt Enable */ 105 #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) 106 107 /* LED Timer Control Register */ 108 #define MII_88E1318S_PHY_LED_TCR 0x12 109 #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) 110 #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) 111 #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) 112 113 /* Magic Packet MAC address registers */ 114 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 115 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1 0x18 116 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0 0x19 117 118 #define MII_88E1318S_PHY_WOL_CTRL 0x10 119 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS BIT(12) 120 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14) 121 122 #define MII_88E1121_PHY_LED_CTRL 16 123 #define MII_88E1121_PHY_LED_DEF 0x0030 124 125 #define MII_M1011_PHY_STATUS 0x11 126 #define MII_M1011_PHY_STATUS_1000 0x8000 127 #define MII_M1011_PHY_STATUS_100 0x4000 128 #define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 129 #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 130 #define MII_M1011_PHY_STATUS_RESOLVED 0x0800 131 #define MII_M1011_PHY_STATUS_LINK 0x0400 132 133 #define MII_88E3016_PHY_SPEC_CTRL 0x10 134 #define MII_88E3016_DISABLE_SCRAMBLER 0x0200 135 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030 136 137 #define MII_88E1510_GEN_CTRL_REG_1 0x14 138 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7 139 #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1 /* SGMII to copper */ 140 #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */ 141 142 #define LPA_FIBER_1000HALF 0x40 143 #define LPA_FIBER_1000FULL 0x20 144 145 #define LPA_PAUSE_FIBER 0x180 146 #define LPA_PAUSE_ASYM_FIBER 0x100 147 148 #define ADVERTISE_FIBER_1000HALF 0x40 149 #define ADVERTISE_FIBER_1000FULL 0x20 150 151 #define ADVERTISE_PAUSE_FIBER 0x180 152 #define ADVERTISE_PAUSE_ASYM_FIBER 0x100 153 154 #define REGISTER_LINK_STATUS 0x400 155 #define NB_FIBER_STATS 1 156 157 MODULE_DESCRIPTION("Marvell PHY driver"); 158 MODULE_AUTHOR("Andy Fleming"); 159 MODULE_LICENSE("GPL"); 160 161 struct marvell_hw_stat { 162 const char *string; 163 u8 page; 164 u8 reg; 165 u8 bits; 166 }; 167 168 static struct marvell_hw_stat marvell_hw_stats[] = { 169 { "phy_receive_errors_copper", 0, 21, 16}, 170 { "phy_idle_errors", 0, 10, 8 }, 171 { "phy_receive_errors_fiber", 1, 21, 16}, 172 }; 173 174 struct marvell_priv { 175 u64 stats[ARRAY_SIZE(marvell_hw_stats)]; 176 char *hwmon_name; 177 struct device *hwmon_dev; 178 }; 179 180 static int marvell_read_page(struct phy_device *phydev) 181 { 182 return __phy_read(phydev, MII_MARVELL_PHY_PAGE); 183 } 184 185 static int marvell_write_page(struct phy_device *phydev, int page) 186 { 187 return __phy_write(phydev, MII_MARVELL_PHY_PAGE, page); 188 } 189 190 static int marvell_set_page(struct phy_device *phydev, int page) 191 { 192 return phy_write(phydev, MII_MARVELL_PHY_PAGE, page); 193 } 194 195 static int marvell_ack_interrupt(struct phy_device *phydev) 196 { 197 int err; 198 199 /* Clear the interrupts by reading the reg */ 200 err = phy_read(phydev, MII_M1011_IEVENT); 201 202 if (err < 0) 203 return err; 204 205 return 0; 206 } 207 208 static int marvell_config_intr(struct phy_device *phydev) 209 { 210 int err; 211 212 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 213 err = phy_write(phydev, MII_M1011_IMASK, 214 MII_M1011_IMASK_INIT); 215 else 216 err = phy_write(phydev, MII_M1011_IMASK, 217 MII_M1011_IMASK_CLEAR); 218 219 return err; 220 } 221 222 static int marvell_set_polarity(struct phy_device *phydev, int polarity) 223 { 224 int reg; 225 int err; 226 int val; 227 228 /* get the current settings */ 229 reg = phy_read(phydev, MII_M1011_PHY_SCR); 230 if (reg < 0) 231 return reg; 232 233 val = reg; 234 val &= ~MII_M1011_PHY_SCR_AUTO_CROSS; 235 switch (polarity) { 236 case ETH_TP_MDI: 237 val |= MII_M1011_PHY_SCR_MDI; 238 break; 239 case ETH_TP_MDI_X: 240 val |= MII_M1011_PHY_SCR_MDI_X; 241 break; 242 case ETH_TP_MDI_AUTO: 243 case ETH_TP_MDI_INVALID: 244 default: 245 val |= MII_M1011_PHY_SCR_AUTO_CROSS; 246 break; 247 } 248 249 if (val != reg) { 250 /* Set the new polarity value in the register */ 251 err = phy_write(phydev, MII_M1011_PHY_SCR, val); 252 if (err) 253 return err; 254 } 255 256 return 0; 257 } 258 259 static int marvell_set_downshift(struct phy_device *phydev, bool enable, 260 u8 retries) 261 { 262 int reg; 263 264 reg = phy_read(phydev, MII_M1011_PHY_SCR); 265 if (reg < 0) 266 return reg; 267 268 reg &= MII_M1011_PHY_SRC_DOWNSHIFT_MASK; 269 reg |= ((retries - 1) << MII_M1011_PHY_SCR_DOWNSHIFT_SHIFT); 270 if (enable) 271 reg |= MII_M1011_PHY_SCR_DOWNSHIFT_EN; 272 273 return phy_write(phydev, MII_M1011_PHY_SCR, reg); 274 } 275 276 static int marvell_config_aneg(struct phy_device *phydev) 277 { 278 int err; 279 280 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 281 if (err < 0) 282 return err; 283 284 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, 285 MII_M1111_PHY_LED_DIRECT); 286 if (err < 0) 287 return err; 288 289 err = genphy_config_aneg(phydev); 290 if (err < 0) 291 return err; 292 293 if (phydev->autoneg != AUTONEG_ENABLE) { 294 /* A write to speed/duplex bits (that is performed by 295 * genphy_config_aneg() call above) must be followed by 296 * a software reset. Otherwise, the write has no effect. 297 */ 298 err = genphy_soft_reset(phydev); 299 if (err < 0) 300 return err; 301 } 302 303 return 0; 304 } 305 306 static int m88e1101_config_aneg(struct phy_device *phydev) 307 { 308 int err; 309 310 /* This Marvell PHY has an errata which requires 311 * that certain registers get written in order 312 * to restart autonegotiation 313 */ 314 err = genphy_soft_reset(phydev); 315 if (err < 0) 316 return err; 317 318 err = phy_write(phydev, 0x1d, 0x1f); 319 if (err < 0) 320 return err; 321 322 err = phy_write(phydev, 0x1e, 0x200c); 323 if (err < 0) 324 return err; 325 326 err = phy_write(phydev, 0x1d, 0x5); 327 if (err < 0) 328 return err; 329 330 err = phy_write(phydev, 0x1e, 0); 331 if (err < 0) 332 return err; 333 334 err = phy_write(phydev, 0x1e, 0x100); 335 if (err < 0) 336 return err; 337 338 return marvell_config_aneg(phydev); 339 } 340 341 static int m88e1111_config_aneg(struct phy_device *phydev) 342 { 343 int err; 344 345 /* The Marvell PHY has an errata which requires 346 * that certain registers get written in order 347 * to restart autonegotiation 348 */ 349 err = genphy_soft_reset(phydev); 350 351 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 352 if (err < 0) 353 return err; 354 355 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, 356 MII_M1111_PHY_LED_DIRECT); 357 if (err < 0) 358 return err; 359 360 err = genphy_config_aneg(phydev); 361 if (err < 0) 362 return err; 363 364 if (phydev->autoneg != AUTONEG_ENABLE) { 365 /* A write to speed/duplex bits (that is performed by 366 * genphy_config_aneg() call above) must be followed by 367 * a software reset. Otherwise, the write has no effect. 368 */ 369 err = genphy_soft_reset(phydev); 370 if (err < 0) 371 return err; 372 } 373 374 return 0; 375 } 376 377 #ifdef CONFIG_OF_MDIO 378 /* Set and/or override some configuration registers based on the 379 * marvell,reg-init property stored in the of_node for the phydev. 380 * 381 * marvell,reg-init = <reg-page reg mask value>,...; 382 * 383 * There may be one or more sets of <reg-page reg mask value>: 384 * 385 * reg-page: which register bank to use. 386 * reg: the register. 387 * mask: if non-zero, ANDed with existing register value. 388 * value: ORed with the masked value and written to the regiser. 389 * 390 */ 391 static int marvell_of_reg_init(struct phy_device *phydev) 392 { 393 const __be32 *paddr; 394 int len, i, saved_page, current_page, ret = 0; 395 396 if (!phydev->mdio.dev.of_node) 397 return 0; 398 399 paddr = of_get_property(phydev->mdio.dev.of_node, 400 "marvell,reg-init", &len); 401 if (!paddr || len < (4 * sizeof(*paddr))) 402 return 0; 403 404 saved_page = phy_save_page(phydev); 405 if (saved_page < 0) 406 goto err; 407 current_page = saved_page; 408 409 len /= sizeof(*paddr); 410 for (i = 0; i < len - 3; i += 4) { 411 u16 page = be32_to_cpup(paddr + i); 412 u16 reg = be32_to_cpup(paddr + i + 1); 413 u16 mask = be32_to_cpup(paddr + i + 2); 414 u16 val_bits = be32_to_cpup(paddr + i + 3); 415 int val; 416 417 if (page != current_page) { 418 current_page = page; 419 ret = marvell_write_page(phydev, page); 420 if (ret < 0) 421 goto err; 422 } 423 424 val = 0; 425 if (mask) { 426 val = __phy_read(phydev, reg); 427 if (val < 0) { 428 ret = val; 429 goto err; 430 } 431 val &= mask; 432 } 433 val |= val_bits; 434 435 ret = __phy_write(phydev, reg, val); 436 if (ret < 0) 437 goto err; 438 } 439 err: 440 return phy_restore_page(phydev, saved_page, ret); 441 } 442 #else 443 static int marvell_of_reg_init(struct phy_device *phydev) 444 { 445 return 0; 446 } 447 #endif /* CONFIG_OF_MDIO */ 448 449 static int m88e1121_config_aneg_rgmii_delays(struct phy_device *phydev) 450 { 451 int mscr; 452 453 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 454 mscr = MII_88E1121_PHY_MSCR_RX_DELAY | 455 MII_88E1121_PHY_MSCR_TX_DELAY; 456 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 457 mscr = MII_88E1121_PHY_MSCR_RX_DELAY; 458 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 459 mscr = MII_88E1121_PHY_MSCR_TX_DELAY; 460 else 461 mscr = 0; 462 463 return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE, 464 MII_88E1121_PHY_MSCR_REG, 465 MII_88E1121_PHY_MSCR_DELAY_MASK, mscr); 466 } 467 468 static int m88e1121_config_aneg(struct phy_device *phydev) 469 { 470 int err = 0; 471 472 if (phy_interface_is_rgmii(phydev)) { 473 err = m88e1121_config_aneg_rgmii_delays(phydev); 474 if (err < 0) 475 return err; 476 } 477 478 err = genphy_soft_reset(phydev); 479 if (err < 0) 480 return err; 481 482 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 483 if (err < 0) 484 return err; 485 486 return genphy_config_aneg(phydev); 487 } 488 489 static int m88e1318_config_aneg(struct phy_device *phydev) 490 { 491 int err; 492 493 err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE, 494 MII_88E1318S_PHY_MSCR1_REG, 495 0, MII_88E1318S_PHY_MSCR1_PAD_ODD); 496 if (err < 0) 497 return err; 498 499 return m88e1121_config_aneg(phydev); 500 } 501 502 /** 503 * ethtool_adv_to_fiber_adv_t 504 * @ethadv: the ethtool advertisement settings 505 * 506 * A small helper function that translates ethtool advertisement 507 * settings to phy autonegotiation advertisements for the 508 * MII_ADV register for fiber link. 509 */ 510 static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv) 511 { 512 u32 result = 0; 513 514 if (ethadv & ADVERTISED_1000baseT_Half) 515 result |= ADVERTISE_FIBER_1000HALF; 516 if (ethadv & ADVERTISED_1000baseT_Full) 517 result |= ADVERTISE_FIBER_1000FULL; 518 519 if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP)) 520 result |= LPA_PAUSE_ASYM_FIBER; 521 else if (ethadv & ADVERTISE_PAUSE_CAP) 522 result |= (ADVERTISE_PAUSE_FIBER 523 & (~ADVERTISE_PAUSE_ASYM_FIBER)); 524 525 return result; 526 } 527 528 /** 529 * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR 530 * @phydev: target phy_device struct 531 * 532 * Description: If auto-negotiation is enabled, we configure the 533 * advertising, and then restart auto-negotiation. If it is not 534 * enabled, then we write the BMCR. Adapted for fiber link in 535 * some Marvell's devices. 536 */ 537 static int marvell_config_aneg_fiber(struct phy_device *phydev) 538 { 539 int changed = 0; 540 int err; 541 int adv, oldadv; 542 u32 advertise; 543 544 if (phydev->autoneg != AUTONEG_ENABLE) 545 return genphy_setup_forced(phydev); 546 547 /* Only allow advertising what this PHY supports */ 548 phydev->advertising &= phydev->supported; 549 advertise = phydev->advertising; 550 551 /* Setup fiber advertisement */ 552 adv = phy_read(phydev, MII_ADVERTISE); 553 if (adv < 0) 554 return adv; 555 556 oldadv = adv; 557 adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL 558 | LPA_PAUSE_FIBER); 559 adv |= ethtool_adv_to_fiber_adv_t(advertise); 560 561 if (adv != oldadv) { 562 err = phy_write(phydev, MII_ADVERTISE, adv); 563 if (err < 0) 564 return err; 565 566 changed = 1; 567 } 568 569 if (changed == 0) { 570 /* Advertisement hasn't changed, but maybe aneg was never on to 571 * begin with? Or maybe phy was isolated? 572 */ 573 int ctl = phy_read(phydev, MII_BMCR); 574 575 if (ctl < 0) 576 return ctl; 577 578 if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) 579 changed = 1; /* do restart aneg */ 580 } 581 582 /* Only restart aneg if we are advertising something different 583 * than we were before. 584 */ 585 if (changed > 0) 586 changed = genphy_restart_aneg(phydev); 587 588 return changed; 589 } 590 591 static int m88e1510_config_aneg(struct phy_device *phydev) 592 { 593 int err; 594 595 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 596 if (err < 0) 597 goto error; 598 599 /* Configure the copper link first */ 600 err = m88e1318_config_aneg(phydev); 601 if (err < 0) 602 goto error; 603 604 /* Do not touch the fiber page if we're in copper->sgmii mode */ 605 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) 606 return 0; 607 608 /* Then the fiber link */ 609 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 610 if (err < 0) 611 goto error; 612 613 err = marvell_config_aneg_fiber(phydev); 614 if (err < 0) 615 goto error; 616 617 return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 618 619 error: 620 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 621 return err; 622 } 623 624 static int marvell_config_init(struct phy_device *phydev) 625 { 626 /* Set registers from marvell,reg-init DT property */ 627 return marvell_of_reg_init(phydev); 628 } 629 630 static int m88e1116r_config_init(struct phy_device *phydev) 631 { 632 int err; 633 634 err = genphy_soft_reset(phydev); 635 if (err < 0) 636 return err; 637 638 mdelay(500); 639 640 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 641 if (err < 0) 642 return err; 643 644 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 645 if (err < 0) 646 return err; 647 648 err = marvell_set_downshift(phydev, true, 8); 649 if (err < 0) 650 return err; 651 652 if (phy_interface_is_rgmii(phydev)) { 653 err = m88e1121_config_aneg_rgmii_delays(phydev); 654 if (err < 0) 655 return err; 656 } 657 658 err = genphy_soft_reset(phydev); 659 if (err < 0) 660 return err; 661 662 return marvell_config_init(phydev); 663 } 664 665 static int m88e3016_config_init(struct phy_device *phydev) 666 { 667 int ret; 668 669 /* Enable Scrambler and Auto-Crossover */ 670 ret = phy_modify(phydev, MII_88E3016_PHY_SPEC_CTRL, 671 ~MII_88E3016_DISABLE_SCRAMBLER, 672 MII_88E3016_AUTO_MDIX_CROSSOVER); 673 if (ret < 0) 674 return ret; 675 676 return marvell_config_init(phydev); 677 } 678 679 static int m88e1111_config_init_hwcfg_mode(struct phy_device *phydev, 680 u16 mode, 681 int fibre_copper_auto) 682 { 683 if (fibre_copper_auto) 684 mode |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; 685 686 return phy_modify(phydev, MII_M1111_PHY_EXT_SR, 687 (u16)~(MII_M1111_HWCFG_MODE_MASK | 688 MII_M1111_HWCFG_FIBER_COPPER_AUTO | 689 MII_M1111_HWCFG_FIBER_COPPER_RES), 690 mode); 691 } 692 693 static int m88e1111_config_init_rgmii_delays(struct phy_device *phydev) 694 { 695 int delay; 696 697 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 698 delay = MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY; 699 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 700 delay = MII_M1111_RGMII_RX_DELAY; 701 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 702 delay = MII_M1111_RGMII_TX_DELAY; 703 } else { 704 delay = 0; 705 } 706 707 return phy_modify(phydev, MII_M1111_PHY_EXT_CR, 708 (u16)~(MII_M1111_RGMII_RX_DELAY | 709 MII_M1111_RGMII_TX_DELAY), 710 delay); 711 } 712 713 static int m88e1111_config_init_rgmii(struct phy_device *phydev) 714 { 715 int temp; 716 int err; 717 718 err = m88e1111_config_init_rgmii_delays(phydev); 719 if (err < 0) 720 return err; 721 722 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 723 if (temp < 0) 724 return temp; 725 726 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 727 728 if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES) 729 temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; 730 else 731 temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; 732 733 return phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 734 } 735 736 static int m88e1111_config_init_sgmii(struct phy_device *phydev) 737 { 738 int err; 739 740 err = m88e1111_config_init_hwcfg_mode( 741 phydev, 742 MII_M1111_HWCFG_MODE_SGMII_NO_CLK, 743 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 744 if (err < 0) 745 return err; 746 747 /* make sure copper is selected */ 748 return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 749 } 750 751 static int m88e1111_config_init_rtbi(struct phy_device *phydev) 752 { 753 int err; 754 755 err = m88e1111_config_init_rgmii_delays(phydev); 756 if (err < 0) 757 return err; 758 759 err = m88e1111_config_init_hwcfg_mode( 760 phydev, 761 MII_M1111_HWCFG_MODE_RTBI, 762 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 763 if (err < 0) 764 return err; 765 766 /* soft reset */ 767 err = genphy_soft_reset(phydev); 768 if (err < 0) 769 return err; 770 771 return m88e1111_config_init_hwcfg_mode( 772 phydev, 773 MII_M1111_HWCFG_MODE_RTBI, 774 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 775 } 776 777 static int m88e1111_config_init(struct phy_device *phydev) 778 { 779 int err; 780 781 if (phy_interface_is_rgmii(phydev)) { 782 err = m88e1111_config_init_rgmii(phydev); 783 if (err < 0) 784 return err; 785 } 786 787 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 788 err = m88e1111_config_init_sgmii(phydev); 789 if (err < 0) 790 return err; 791 } 792 793 if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { 794 err = m88e1111_config_init_rtbi(phydev); 795 if (err < 0) 796 return err; 797 } 798 799 err = marvell_of_reg_init(phydev); 800 if (err < 0) 801 return err; 802 803 return genphy_soft_reset(phydev); 804 } 805 806 static int m88e1121_config_init(struct phy_device *phydev) 807 { 808 int err; 809 810 /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */ 811 err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, 812 MII_88E1121_PHY_LED_CTRL, 813 MII_88E1121_PHY_LED_DEF); 814 if (err < 0) 815 return err; 816 817 /* Set marvell,reg-init configuration from device tree */ 818 return marvell_config_init(phydev); 819 } 820 821 static int m88e1510_config_init(struct phy_device *phydev) 822 { 823 int err; 824 825 /* SGMII-to-Copper mode initialization */ 826 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 827 u32 pause; 828 829 /* Select page 18 */ 830 err = marvell_set_page(phydev, 18); 831 if (err < 0) 832 return err; 833 834 /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ 835 err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1, 836 ~MII_88E1510_GEN_CTRL_REG_1_MODE_MASK, 837 MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII); 838 if (err < 0) 839 return err; 840 841 /* PHY reset is necessary after changing MODE[2:0] */ 842 err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1, 0, 843 MII_88E1510_GEN_CTRL_REG_1_RESET); 844 if (err < 0) 845 return err; 846 847 /* Reset page selection */ 848 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 849 if (err < 0) 850 return err; 851 852 /* There appears to be a bug in the 88e1512 when used in 853 * SGMII to copper mode, where the AN advertisment register 854 * clears the pause bits each time a negotiation occurs. 855 * This means we can never be truely sure what was advertised, 856 * so disable Pause support. 857 */ 858 pause = SUPPORTED_Pause | SUPPORTED_Asym_Pause; 859 phydev->supported &= ~pause; 860 phydev->advertising &= ~pause; 861 } 862 863 return m88e1121_config_init(phydev); 864 } 865 866 static int m88e1118_config_aneg(struct phy_device *phydev) 867 { 868 int err; 869 870 err = genphy_soft_reset(phydev); 871 if (err < 0) 872 return err; 873 874 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 875 if (err < 0) 876 return err; 877 878 err = genphy_config_aneg(phydev); 879 return 0; 880 } 881 882 static int m88e1118_config_init(struct phy_device *phydev) 883 { 884 int err; 885 886 /* Change address */ 887 err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE); 888 if (err < 0) 889 return err; 890 891 /* Enable 1000 Mbit */ 892 err = phy_write(phydev, 0x15, 0x1070); 893 if (err < 0) 894 return err; 895 896 /* Change address */ 897 err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE); 898 if (err < 0) 899 return err; 900 901 /* Adjust LED Control */ 902 if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS) 903 err = phy_write(phydev, 0x10, 0x1100); 904 else 905 err = phy_write(phydev, 0x10, 0x021e); 906 if (err < 0) 907 return err; 908 909 err = marvell_of_reg_init(phydev); 910 if (err < 0) 911 return err; 912 913 /* Reset address */ 914 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 915 if (err < 0) 916 return err; 917 918 return genphy_soft_reset(phydev); 919 } 920 921 static int m88e1149_config_init(struct phy_device *phydev) 922 { 923 int err; 924 925 /* Change address */ 926 err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE); 927 if (err < 0) 928 return err; 929 930 /* Enable 1000 Mbit */ 931 err = phy_write(phydev, 0x15, 0x1048); 932 if (err < 0) 933 return err; 934 935 err = marvell_of_reg_init(phydev); 936 if (err < 0) 937 return err; 938 939 /* Reset address */ 940 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 941 if (err < 0) 942 return err; 943 944 return genphy_soft_reset(phydev); 945 } 946 947 static int m88e1145_config_init_rgmii(struct phy_device *phydev) 948 { 949 int err; 950 951 err = m88e1111_config_init_rgmii_delays(phydev); 952 if (err < 0) 953 return err; 954 955 if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) { 956 err = phy_write(phydev, 0x1d, 0x0012); 957 if (err < 0) 958 return err; 959 960 err = phy_modify(phydev, 0x1e, 0xf03f, 961 2 << 9 | /* 36 ohm */ 962 2 << 6); /* 39 ohm */ 963 if (err < 0) 964 return err; 965 966 err = phy_write(phydev, 0x1d, 0x3); 967 if (err < 0) 968 return err; 969 970 err = phy_write(phydev, 0x1e, 0x8000); 971 } 972 return err; 973 } 974 975 static int m88e1145_config_init_sgmii(struct phy_device *phydev) 976 { 977 return m88e1111_config_init_hwcfg_mode( 978 phydev, MII_M1111_HWCFG_MODE_SGMII_NO_CLK, 979 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 980 } 981 982 static int m88e1145_config_init(struct phy_device *phydev) 983 { 984 int err; 985 986 /* Take care of errata E0 & E1 */ 987 err = phy_write(phydev, 0x1d, 0x001b); 988 if (err < 0) 989 return err; 990 991 err = phy_write(phydev, 0x1e, 0x418f); 992 if (err < 0) 993 return err; 994 995 err = phy_write(phydev, 0x1d, 0x0016); 996 if (err < 0) 997 return err; 998 999 err = phy_write(phydev, 0x1e, 0xa2da); 1000 if (err < 0) 1001 return err; 1002 1003 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 1004 err = m88e1145_config_init_rgmii(phydev); 1005 if (err < 0) 1006 return err; 1007 } 1008 1009 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 1010 err = m88e1145_config_init_sgmii(phydev); 1011 if (err < 0) 1012 return err; 1013 } 1014 1015 err = marvell_of_reg_init(phydev); 1016 if (err < 0) 1017 return err; 1018 1019 return 0; 1020 } 1021 1022 /** 1023 * fiber_lpa_to_ethtool_lpa_t 1024 * @lpa: value of the MII_LPA register for fiber link 1025 * 1026 * A small helper function that translates MII_LPA 1027 * bits to ethtool LP advertisement settings. 1028 */ 1029 static u32 fiber_lpa_to_ethtool_lpa_t(u32 lpa) 1030 { 1031 u32 result = 0; 1032 1033 if (lpa & LPA_FIBER_1000HALF) 1034 result |= ADVERTISED_1000baseT_Half; 1035 if (lpa & LPA_FIBER_1000FULL) 1036 result |= ADVERTISED_1000baseT_Full; 1037 1038 return result; 1039 } 1040 1041 /** 1042 * marvell_update_link - update link status in real time in @phydev 1043 * @phydev: target phy_device struct 1044 * 1045 * Description: Update the value in phydev->link to reflect the 1046 * current link value. 1047 */ 1048 static int marvell_update_link(struct phy_device *phydev, int fiber) 1049 { 1050 int status; 1051 1052 /* Use the generic register for copper link, or specific 1053 * register for fiber case 1054 */ 1055 if (fiber) { 1056 status = phy_read(phydev, MII_M1011_PHY_STATUS); 1057 if (status < 0) 1058 return status; 1059 1060 if ((status & REGISTER_LINK_STATUS) == 0) 1061 phydev->link = 0; 1062 else 1063 phydev->link = 1; 1064 } else { 1065 return genphy_update_link(phydev); 1066 } 1067 1068 return 0; 1069 } 1070 1071 static int marvell_read_status_page_an(struct phy_device *phydev, 1072 int fiber) 1073 { 1074 int status; 1075 int lpa; 1076 int lpagb; 1077 1078 status = phy_read(phydev, MII_M1011_PHY_STATUS); 1079 if (status < 0) 1080 return status; 1081 1082 lpa = phy_read(phydev, MII_LPA); 1083 if (lpa < 0) 1084 return lpa; 1085 1086 lpagb = phy_read(phydev, MII_STAT1000); 1087 if (lpagb < 0) 1088 return lpagb; 1089 1090 if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) 1091 phydev->duplex = DUPLEX_FULL; 1092 else 1093 phydev->duplex = DUPLEX_HALF; 1094 1095 status = status & MII_M1011_PHY_STATUS_SPD_MASK; 1096 phydev->pause = 0; 1097 phydev->asym_pause = 0; 1098 1099 switch (status) { 1100 case MII_M1011_PHY_STATUS_1000: 1101 phydev->speed = SPEED_1000; 1102 break; 1103 1104 case MII_M1011_PHY_STATUS_100: 1105 phydev->speed = SPEED_100; 1106 break; 1107 1108 default: 1109 phydev->speed = SPEED_10; 1110 break; 1111 } 1112 1113 if (!fiber) { 1114 phydev->lp_advertising = 1115 mii_stat1000_to_ethtool_lpa_t(lpagb) | 1116 mii_lpa_to_ethtool_lpa_t(lpa); 1117 1118 if (phydev->duplex == DUPLEX_FULL) { 1119 phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; 1120 phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; 1121 } 1122 } else { 1123 /* The fiber link is only 1000M capable */ 1124 phydev->lp_advertising = fiber_lpa_to_ethtool_lpa_t(lpa); 1125 1126 if (phydev->duplex == DUPLEX_FULL) { 1127 if (!(lpa & LPA_PAUSE_FIBER)) { 1128 phydev->pause = 0; 1129 phydev->asym_pause = 0; 1130 } else if ((lpa & LPA_PAUSE_ASYM_FIBER)) { 1131 phydev->pause = 1; 1132 phydev->asym_pause = 1; 1133 } else { 1134 phydev->pause = 1; 1135 phydev->asym_pause = 0; 1136 } 1137 } 1138 } 1139 return 0; 1140 } 1141 1142 static int marvell_read_status_page_fixed(struct phy_device *phydev) 1143 { 1144 int bmcr = phy_read(phydev, MII_BMCR); 1145 1146 if (bmcr < 0) 1147 return bmcr; 1148 1149 if (bmcr & BMCR_FULLDPLX) 1150 phydev->duplex = DUPLEX_FULL; 1151 else 1152 phydev->duplex = DUPLEX_HALF; 1153 1154 if (bmcr & BMCR_SPEED1000) 1155 phydev->speed = SPEED_1000; 1156 else if (bmcr & BMCR_SPEED100) 1157 phydev->speed = SPEED_100; 1158 else 1159 phydev->speed = SPEED_10; 1160 1161 phydev->pause = 0; 1162 phydev->asym_pause = 0; 1163 phydev->lp_advertising = 0; 1164 1165 return 0; 1166 } 1167 1168 /* marvell_read_status_page 1169 * 1170 * Description: 1171 * Check the link, then figure out the current state 1172 * by comparing what we advertise with what the link partner 1173 * advertises. Start by checking the gigabit possibilities, 1174 * then move on to 10/100. 1175 */ 1176 static int marvell_read_status_page(struct phy_device *phydev, int page) 1177 { 1178 int fiber; 1179 int err; 1180 1181 /* Detect and update the link, but return if there 1182 * was an error 1183 */ 1184 if (page == MII_MARVELL_FIBER_PAGE) 1185 fiber = 1; 1186 else 1187 fiber = 0; 1188 1189 err = marvell_update_link(phydev, fiber); 1190 if (err) 1191 return err; 1192 1193 if (phydev->autoneg == AUTONEG_ENABLE) 1194 err = marvell_read_status_page_an(phydev, fiber); 1195 else 1196 err = marvell_read_status_page_fixed(phydev); 1197 1198 return err; 1199 } 1200 1201 /* marvell_read_status 1202 * 1203 * Some Marvell's phys have two modes: fiber and copper. 1204 * Both need status checked. 1205 * Description: 1206 * First, check the fiber link and status. 1207 * If the fiber link is down, check the copper link and status which 1208 * will be the default value if both link are down. 1209 */ 1210 static int marvell_read_status(struct phy_device *phydev) 1211 { 1212 int err; 1213 1214 /* Check the fiber mode first */ 1215 if (phydev->supported & SUPPORTED_FIBRE && 1216 phydev->interface != PHY_INTERFACE_MODE_SGMII) { 1217 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 1218 if (err < 0) 1219 goto error; 1220 1221 err = marvell_read_status_page(phydev, MII_MARVELL_FIBER_PAGE); 1222 if (err < 0) 1223 goto error; 1224 1225 /* If the fiber link is up, it is the selected and 1226 * used link. In this case, we need to stay in the 1227 * fiber page. Please to be careful about that, avoid 1228 * to restore Copper page in other functions which 1229 * could break the behaviour for some fiber phy like 1230 * 88E1512. 1231 */ 1232 if (phydev->link) 1233 return 0; 1234 1235 /* If fiber link is down, check and save copper mode state */ 1236 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1237 if (err < 0) 1238 goto error; 1239 } 1240 1241 return marvell_read_status_page(phydev, MII_MARVELL_COPPER_PAGE); 1242 1243 error: 1244 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1245 return err; 1246 } 1247 1248 /* marvell_suspend 1249 * 1250 * Some Marvell's phys have two modes: fiber and copper. 1251 * Both need to be suspended 1252 */ 1253 static int marvell_suspend(struct phy_device *phydev) 1254 { 1255 int err; 1256 1257 /* Suspend the fiber mode first */ 1258 if (!(phydev->supported & SUPPORTED_FIBRE)) { 1259 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 1260 if (err < 0) 1261 goto error; 1262 1263 /* With the page set, use the generic suspend */ 1264 err = genphy_suspend(phydev); 1265 if (err < 0) 1266 goto error; 1267 1268 /* Then, the copper link */ 1269 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1270 if (err < 0) 1271 goto error; 1272 } 1273 1274 /* With the page set, use the generic suspend */ 1275 return genphy_suspend(phydev); 1276 1277 error: 1278 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1279 return err; 1280 } 1281 1282 /* marvell_resume 1283 * 1284 * Some Marvell's phys have two modes: fiber and copper. 1285 * Both need to be resumed 1286 */ 1287 static int marvell_resume(struct phy_device *phydev) 1288 { 1289 int err; 1290 1291 /* Resume the fiber mode first */ 1292 if (!(phydev->supported & SUPPORTED_FIBRE)) { 1293 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 1294 if (err < 0) 1295 goto error; 1296 1297 /* With the page set, use the generic resume */ 1298 err = genphy_resume(phydev); 1299 if (err < 0) 1300 goto error; 1301 1302 /* Then, the copper link */ 1303 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1304 if (err < 0) 1305 goto error; 1306 } 1307 1308 /* With the page set, use the generic resume */ 1309 return genphy_resume(phydev); 1310 1311 error: 1312 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1313 return err; 1314 } 1315 1316 static int marvell_aneg_done(struct phy_device *phydev) 1317 { 1318 int retval = phy_read(phydev, MII_M1011_PHY_STATUS); 1319 1320 return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED); 1321 } 1322 1323 static int m88e1121_did_interrupt(struct phy_device *phydev) 1324 { 1325 int imask; 1326 1327 imask = phy_read(phydev, MII_M1011_IEVENT); 1328 1329 if (imask & MII_M1011_IMASK_INIT) 1330 return 1; 1331 1332 return 0; 1333 } 1334 1335 static void m88e1318_get_wol(struct phy_device *phydev, 1336 struct ethtool_wolinfo *wol) 1337 { 1338 int oldpage, ret = 0; 1339 1340 wol->supported = WAKE_MAGIC; 1341 wol->wolopts = 0; 1342 1343 oldpage = phy_select_page(phydev, MII_MARVELL_WOL_PAGE); 1344 if (oldpage < 0) 1345 goto error; 1346 1347 ret = __phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); 1348 if (ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE) 1349 wol->wolopts |= WAKE_MAGIC; 1350 1351 error: 1352 phy_restore_page(phydev, oldpage, ret); 1353 } 1354 1355 static int m88e1318_set_wol(struct phy_device *phydev, 1356 struct ethtool_wolinfo *wol) 1357 { 1358 int err = 0, oldpage; 1359 1360 oldpage = phy_save_page(phydev); 1361 if (oldpage < 0) 1362 goto error; 1363 1364 if (wol->wolopts & WAKE_MAGIC) { 1365 /* Explicitly switch to page 0x00, just to be sure */ 1366 err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE); 1367 if (err < 0) 1368 goto error; 1369 1370 /* Enable the WOL interrupt */ 1371 err = __phy_modify(phydev, MII_88E1318S_PHY_CSIER, 0, 1372 MII_88E1318S_PHY_CSIER_WOL_EIE); 1373 if (err < 0) 1374 goto error; 1375 1376 err = marvell_write_page(phydev, MII_MARVELL_LED_PAGE); 1377 if (err < 0) 1378 goto error; 1379 1380 /* Setup LED[2] as interrupt pin (active low) */ 1381 err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR, 1382 (u16)~MII_88E1318S_PHY_LED_TCR_FORCE_INT, 1383 MII_88E1318S_PHY_LED_TCR_INTn_ENABLE | 1384 MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW); 1385 if (err < 0) 1386 goto error; 1387 1388 err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE); 1389 if (err < 0) 1390 goto error; 1391 1392 /* Store the device address for the magic packet */ 1393 err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2, 1394 ((phydev->attached_dev->dev_addr[5] << 8) | 1395 phydev->attached_dev->dev_addr[4])); 1396 if (err < 0) 1397 goto error; 1398 err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1, 1399 ((phydev->attached_dev->dev_addr[3] << 8) | 1400 phydev->attached_dev->dev_addr[2])); 1401 if (err < 0) 1402 goto error; 1403 err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0, 1404 ((phydev->attached_dev->dev_addr[1] << 8) | 1405 phydev->attached_dev->dev_addr[0])); 1406 if (err < 0) 1407 goto error; 1408 1409 /* Clear WOL status and enable magic packet matching */ 1410 err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0, 1411 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS | 1412 MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE); 1413 if (err < 0) 1414 goto error; 1415 } else { 1416 err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE); 1417 if (err < 0) 1418 goto error; 1419 1420 /* Clear WOL status and disable magic packet matching */ 1421 err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 1422 (u16)~MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE, 1423 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS); 1424 if (err < 0) 1425 goto error; 1426 } 1427 1428 error: 1429 return phy_restore_page(phydev, oldpage, err); 1430 } 1431 1432 static int marvell_get_sset_count(struct phy_device *phydev) 1433 { 1434 if (phydev->supported & SUPPORTED_FIBRE) 1435 return ARRAY_SIZE(marvell_hw_stats); 1436 else 1437 return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS; 1438 } 1439 1440 static void marvell_get_strings(struct phy_device *phydev, u8 *data) 1441 { 1442 int i; 1443 1444 for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { 1445 memcpy(data + i * ETH_GSTRING_LEN, 1446 marvell_hw_stats[i].string, ETH_GSTRING_LEN); 1447 } 1448 } 1449 1450 #ifndef UINT64_MAX 1451 #define UINT64_MAX (u64)(~((u64)0)) 1452 #endif 1453 static u64 marvell_get_stat(struct phy_device *phydev, int i) 1454 { 1455 struct marvell_hw_stat stat = marvell_hw_stats[i]; 1456 struct marvell_priv *priv = phydev->priv; 1457 int val; 1458 u64 ret; 1459 1460 val = phy_read_paged(phydev, stat.page, stat.reg); 1461 if (val < 0) { 1462 ret = UINT64_MAX; 1463 } else { 1464 val = val & ((1 << stat.bits) - 1); 1465 priv->stats[i] += val; 1466 ret = priv->stats[i]; 1467 } 1468 1469 return ret; 1470 } 1471 1472 static void marvell_get_stats(struct phy_device *phydev, 1473 struct ethtool_stats *stats, u64 *data) 1474 { 1475 int i; 1476 1477 for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) 1478 data[i] = marvell_get_stat(phydev, i); 1479 } 1480 1481 #ifdef CONFIG_HWMON 1482 static int m88e1121_get_temp(struct phy_device *phydev, long *temp) 1483 { 1484 int oldpage; 1485 int ret = 0; 1486 int val; 1487 1488 *temp = 0; 1489 1490 oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE); 1491 if (oldpage < 0) 1492 goto error; 1493 1494 /* Enable temperature sensor */ 1495 ret = __phy_read(phydev, MII_88E1121_MISC_TEST); 1496 if (ret < 0) 1497 goto error; 1498 1499 ret = __phy_write(phydev, MII_88E1121_MISC_TEST, 1500 ret | MII_88E1121_MISC_TEST_TEMP_SENSOR_EN); 1501 if (ret < 0) 1502 goto error; 1503 1504 /* Wait for temperature to stabilize */ 1505 usleep_range(10000, 12000); 1506 1507 val = __phy_read(phydev, MII_88E1121_MISC_TEST); 1508 if (val < 0) { 1509 ret = val; 1510 goto error; 1511 } 1512 1513 /* Disable temperature sensor */ 1514 ret = __phy_write(phydev, MII_88E1121_MISC_TEST, 1515 ret & ~MII_88E1121_MISC_TEST_TEMP_SENSOR_EN); 1516 if (ret < 0) 1517 goto error; 1518 1519 *temp = ((val & MII_88E1121_MISC_TEST_TEMP_MASK) - 5) * 5000; 1520 1521 error: 1522 return phy_restore_page(phydev, oldpage, ret); 1523 } 1524 1525 static int m88e1121_hwmon_read(struct device *dev, 1526 enum hwmon_sensor_types type, 1527 u32 attr, int channel, long *temp) 1528 { 1529 struct phy_device *phydev = dev_get_drvdata(dev); 1530 int err; 1531 1532 switch (attr) { 1533 case hwmon_temp_input: 1534 err = m88e1121_get_temp(phydev, temp); 1535 break; 1536 default: 1537 return -EOPNOTSUPP; 1538 } 1539 1540 return err; 1541 } 1542 1543 static umode_t m88e1121_hwmon_is_visible(const void *data, 1544 enum hwmon_sensor_types type, 1545 u32 attr, int channel) 1546 { 1547 if (type != hwmon_temp) 1548 return 0; 1549 1550 switch (attr) { 1551 case hwmon_temp_input: 1552 return 0444; 1553 default: 1554 return 0; 1555 } 1556 } 1557 1558 static u32 m88e1121_hwmon_chip_config[] = { 1559 HWMON_C_REGISTER_TZ, 1560 0 1561 }; 1562 1563 static const struct hwmon_channel_info m88e1121_hwmon_chip = { 1564 .type = hwmon_chip, 1565 .config = m88e1121_hwmon_chip_config, 1566 }; 1567 1568 static u32 m88e1121_hwmon_temp_config[] = { 1569 HWMON_T_INPUT, 1570 0 1571 }; 1572 1573 static const struct hwmon_channel_info m88e1121_hwmon_temp = { 1574 .type = hwmon_temp, 1575 .config = m88e1121_hwmon_temp_config, 1576 }; 1577 1578 static const struct hwmon_channel_info *m88e1121_hwmon_info[] = { 1579 &m88e1121_hwmon_chip, 1580 &m88e1121_hwmon_temp, 1581 NULL 1582 }; 1583 1584 static const struct hwmon_ops m88e1121_hwmon_hwmon_ops = { 1585 .is_visible = m88e1121_hwmon_is_visible, 1586 .read = m88e1121_hwmon_read, 1587 }; 1588 1589 static const struct hwmon_chip_info m88e1121_hwmon_chip_info = { 1590 .ops = &m88e1121_hwmon_hwmon_ops, 1591 .info = m88e1121_hwmon_info, 1592 }; 1593 1594 static int m88e1510_get_temp(struct phy_device *phydev, long *temp) 1595 { 1596 int ret; 1597 1598 *temp = 0; 1599 1600 ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 1601 MII_88E1510_TEMP_SENSOR); 1602 if (ret < 0) 1603 return ret; 1604 1605 *temp = ((ret & MII_88E1510_TEMP_SENSOR_MASK) - 25) * 1000; 1606 1607 return 0; 1608 } 1609 1610 static int m88e1510_get_temp_critical(struct phy_device *phydev, long *temp) 1611 { 1612 int ret; 1613 1614 *temp = 0; 1615 1616 ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 1617 MII_88E1121_MISC_TEST); 1618 if (ret < 0) 1619 return ret; 1620 1621 *temp = (((ret & MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK) >> 1622 MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT) * 5) - 25; 1623 /* convert to mC */ 1624 *temp *= 1000; 1625 1626 return 0; 1627 } 1628 1629 static int m88e1510_set_temp_critical(struct phy_device *phydev, long temp) 1630 { 1631 temp = temp / 1000; 1632 temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f); 1633 1634 return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 1635 MII_88E1121_MISC_TEST, 1636 MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK, 1637 temp << MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT); 1638 } 1639 1640 static int m88e1510_get_temp_alarm(struct phy_device *phydev, long *alarm) 1641 { 1642 int ret; 1643 1644 *alarm = false; 1645 1646 ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 1647 MII_88E1121_MISC_TEST); 1648 if (ret < 0) 1649 return ret; 1650 1651 *alarm = !!(ret & MII_88E1510_MISC_TEST_TEMP_IRQ); 1652 1653 return 0; 1654 } 1655 1656 static int m88e1510_hwmon_read(struct device *dev, 1657 enum hwmon_sensor_types type, 1658 u32 attr, int channel, long *temp) 1659 { 1660 struct phy_device *phydev = dev_get_drvdata(dev); 1661 int err; 1662 1663 switch (attr) { 1664 case hwmon_temp_input: 1665 err = m88e1510_get_temp(phydev, temp); 1666 break; 1667 case hwmon_temp_crit: 1668 err = m88e1510_get_temp_critical(phydev, temp); 1669 break; 1670 case hwmon_temp_max_alarm: 1671 err = m88e1510_get_temp_alarm(phydev, temp); 1672 break; 1673 default: 1674 return -EOPNOTSUPP; 1675 } 1676 1677 return err; 1678 } 1679 1680 static int m88e1510_hwmon_write(struct device *dev, 1681 enum hwmon_sensor_types type, 1682 u32 attr, int channel, long temp) 1683 { 1684 struct phy_device *phydev = dev_get_drvdata(dev); 1685 int err; 1686 1687 switch (attr) { 1688 case hwmon_temp_crit: 1689 err = m88e1510_set_temp_critical(phydev, temp); 1690 break; 1691 default: 1692 return -EOPNOTSUPP; 1693 } 1694 return err; 1695 } 1696 1697 static umode_t m88e1510_hwmon_is_visible(const void *data, 1698 enum hwmon_sensor_types type, 1699 u32 attr, int channel) 1700 { 1701 if (type != hwmon_temp) 1702 return 0; 1703 1704 switch (attr) { 1705 case hwmon_temp_input: 1706 case hwmon_temp_max_alarm: 1707 return 0444; 1708 case hwmon_temp_crit: 1709 return 0644; 1710 default: 1711 return 0; 1712 } 1713 } 1714 1715 static u32 m88e1510_hwmon_temp_config[] = { 1716 HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM, 1717 0 1718 }; 1719 1720 static const struct hwmon_channel_info m88e1510_hwmon_temp = { 1721 .type = hwmon_temp, 1722 .config = m88e1510_hwmon_temp_config, 1723 }; 1724 1725 static const struct hwmon_channel_info *m88e1510_hwmon_info[] = { 1726 &m88e1121_hwmon_chip, 1727 &m88e1510_hwmon_temp, 1728 NULL 1729 }; 1730 1731 static const struct hwmon_ops m88e1510_hwmon_hwmon_ops = { 1732 .is_visible = m88e1510_hwmon_is_visible, 1733 .read = m88e1510_hwmon_read, 1734 .write = m88e1510_hwmon_write, 1735 }; 1736 1737 static const struct hwmon_chip_info m88e1510_hwmon_chip_info = { 1738 .ops = &m88e1510_hwmon_hwmon_ops, 1739 .info = m88e1510_hwmon_info, 1740 }; 1741 1742 static int marvell_hwmon_name(struct phy_device *phydev) 1743 { 1744 struct marvell_priv *priv = phydev->priv; 1745 struct device *dev = &phydev->mdio.dev; 1746 const char *devname = dev_name(dev); 1747 size_t len = strlen(devname); 1748 int i, j; 1749 1750 priv->hwmon_name = devm_kzalloc(dev, len, GFP_KERNEL); 1751 if (!priv->hwmon_name) 1752 return -ENOMEM; 1753 1754 for (i = j = 0; i < len && devname[i]; i++) { 1755 if (isalnum(devname[i])) 1756 priv->hwmon_name[j++] = devname[i]; 1757 } 1758 1759 return 0; 1760 } 1761 1762 static int marvell_hwmon_probe(struct phy_device *phydev, 1763 const struct hwmon_chip_info *chip) 1764 { 1765 struct marvell_priv *priv = phydev->priv; 1766 struct device *dev = &phydev->mdio.dev; 1767 int err; 1768 1769 err = marvell_hwmon_name(phydev); 1770 if (err) 1771 return err; 1772 1773 priv->hwmon_dev = devm_hwmon_device_register_with_info( 1774 dev, priv->hwmon_name, phydev, chip, NULL); 1775 1776 return PTR_ERR_OR_ZERO(priv->hwmon_dev); 1777 } 1778 1779 static int m88e1121_hwmon_probe(struct phy_device *phydev) 1780 { 1781 return marvell_hwmon_probe(phydev, &m88e1121_hwmon_chip_info); 1782 } 1783 1784 static int m88e1510_hwmon_probe(struct phy_device *phydev) 1785 { 1786 return marvell_hwmon_probe(phydev, &m88e1510_hwmon_chip_info); 1787 } 1788 #else 1789 static int m88e1121_hwmon_probe(struct phy_device *phydev) 1790 { 1791 return 0; 1792 } 1793 1794 static int m88e1510_hwmon_probe(struct phy_device *phydev) 1795 { 1796 return 0; 1797 } 1798 #endif 1799 1800 static int marvell_probe(struct phy_device *phydev) 1801 { 1802 struct marvell_priv *priv; 1803 1804 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 1805 if (!priv) 1806 return -ENOMEM; 1807 1808 phydev->priv = priv; 1809 1810 return 0; 1811 } 1812 1813 static int m88e1121_probe(struct phy_device *phydev) 1814 { 1815 int err; 1816 1817 err = marvell_probe(phydev); 1818 if (err) 1819 return err; 1820 1821 return m88e1121_hwmon_probe(phydev); 1822 } 1823 1824 static int m88e1510_probe(struct phy_device *phydev) 1825 { 1826 int err; 1827 1828 err = marvell_probe(phydev); 1829 if (err) 1830 return err; 1831 1832 return m88e1510_hwmon_probe(phydev); 1833 } 1834 1835 static struct phy_driver marvell_drivers[] = { 1836 { 1837 .phy_id = MARVELL_PHY_ID_88E1101, 1838 .phy_id_mask = MARVELL_PHY_ID_MASK, 1839 .name = "Marvell 88E1101", 1840 .features = PHY_GBIT_FEATURES, 1841 .flags = PHY_HAS_INTERRUPT, 1842 .probe = marvell_probe, 1843 .config_init = &marvell_config_init, 1844 .config_aneg = &m88e1101_config_aneg, 1845 .ack_interrupt = &marvell_ack_interrupt, 1846 .config_intr = &marvell_config_intr, 1847 .resume = &genphy_resume, 1848 .suspend = &genphy_suspend, 1849 .read_page = marvell_read_page, 1850 .write_page = marvell_write_page, 1851 .get_sset_count = marvell_get_sset_count, 1852 .get_strings = marvell_get_strings, 1853 .get_stats = marvell_get_stats, 1854 }, 1855 { 1856 .phy_id = MARVELL_PHY_ID_88E1112, 1857 .phy_id_mask = MARVELL_PHY_ID_MASK, 1858 .name = "Marvell 88E1112", 1859 .features = PHY_GBIT_FEATURES, 1860 .flags = PHY_HAS_INTERRUPT, 1861 .probe = marvell_probe, 1862 .config_init = &m88e1111_config_init, 1863 .config_aneg = &marvell_config_aneg, 1864 .ack_interrupt = &marvell_ack_interrupt, 1865 .config_intr = &marvell_config_intr, 1866 .resume = &genphy_resume, 1867 .suspend = &genphy_suspend, 1868 .read_page = marvell_read_page, 1869 .write_page = marvell_write_page, 1870 .get_sset_count = marvell_get_sset_count, 1871 .get_strings = marvell_get_strings, 1872 .get_stats = marvell_get_stats, 1873 }, 1874 { 1875 .phy_id = MARVELL_PHY_ID_88E1111, 1876 .phy_id_mask = MARVELL_PHY_ID_MASK, 1877 .name = "Marvell 88E1111", 1878 .features = PHY_GBIT_FEATURES, 1879 .flags = PHY_HAS_INTERRUPT, 1880 .probe = marvell_probe, 1881 .config_init = &m88e1111_config_init, 1882 .config_aneg = &m88e1111_config_aneg, 1883 .read_status = &marvell_read_status, 1884 .ack_interrupt = &marvell_ack_interrupt, 1885 .config_intr = &marvell_config_intr, 1886 .resume = &genphy_resume, 1887 .suspend = &genphy_suspend, 1888 .read_page = marvell_read_page, 1889 .write_page = marvell_write_page, 1890 .get_sset_count = marvell_get_sset_count, 1891 .get_strings = marvell_get_strings, 1892 .get_stats = marvell_get_stats, 1893 }, 1894 { 1895 .phy_id = MARVELL_PHY_ID_88E1118, 1896 .phy_id_mask = MARVELL_PHY_ID_MASK, 1897 .name = "Marvell 88E1118", 1898 .features = PHY_GBIT_FEATURES, 1899 .flags = PHY_HAS_INTERRUPT, 1900 .probe = marvell_probe, 1901 .config_init = &m88e1118_config_init, 1902 .config_aneg = &m88e1118_config_aneg, 1903 .ack_interrupt = &marvell_ack_interrupt, 1904 .config_intr = &marvell_config_intr, 1905 .resume = &genphy_resume, 1906 .suspend = &genphy_suspend, 1907 .read_page = marvell_read_page, 1908 .write_page = marvell_write_page, 1909 .get_sset_count = marvell_get_sset_count, 1910 .get_strings = marvell_get_strings, 1911 .get_stats = marvell_get_stats, 1912 }, 1913 { 1914 .phy_id = MARVELL_PHY_ID_88E1121R, 1915 .phy_id_mask = MARVELL_PHY_ID_MASK, 1916 .name = "Marvell 88E1121R", 1917 .features = PHY_GBIT_FEATURES, 1918 .flags = PHY_HAS_INTERRUPT, 1919 .probe = &m88e1121_probe, 1920 .config_init = &m88e1121_config_init, 1921 .config_aneg = &m88e1121_config_aneg, 1922 .read_status = &marvell_read_status, 1923 .ack_interrupt = &marvell_ack_interrupt, 1924 .config_intr = &marvell_config_intr, 1925 .did_interrupt = &m88e1121_did_interrupt, 1926 .resume = &genphy_resume, 1927 .suspend = &genphy_suspend, 1928 .read_page = marvell_read_page, 1929 .write_page = marvell_write_page, 1930 .get_sset_count = marvell_get_sset_count, 1931 .get_strings = marvell_get_strings, 1932 .get_stats = marvell_get_stats, 1933 }, 1934 { 1935 .phy_id = MARVELL_PHY_ID_88E1318S, 1936 .phy_id_mask = MARVELL_PHY_ID_MASK, 1937 .name = "Marvell 88E1318S", 1938 .features = PHY_GBIT_FEATURES, 1939 .flags = PHY_HAS_INTERRUPT, 1940 .probe = marvell_probe, 1941 .config_init = &m88e1121_config_init, 1942 .config_aneg = &m88e1318_config_aneg, 1943 .read_status = &marvell_read_status, 1944 .ack_interrupt = &marvell_ack_interrupt, 1945 .config_intr = &marvell_config_intr, 1946 .did_interrupt = &m88e1121_did_interrupt, 1947 .get_wol = &m88e1318_get_wol, 1948 .set_wol = &m88e1318_set_wol, 1949 .resume = &genphy_resume, 1950 .suspend = &genphy_suspend, 1951 .read_page = marvell_read_page, 1952 .write_page = marvell_write_page, 1953 .get_sset_count = marvell_get_sset_count, 1954 .get_strings = marvell_get_strings, 1955 .get_stats = marvell_get_stats, 1956 }, 1957 { 1958 .phy_id = MARVELL_PHY_ID_88E1145, 1959 .phy_id_mask = MARVELL_PHY_ID_MASK, 1960 .name = "Marvell 88E1145", 1961 .features = PHY_GBIT_FEATURES, 1962 .flags = PHY_HAS_INTERRUPT, 1963 .probe = marvell_probe, 1964 .config_init = &m88e1145_config_init, 1965 .config_aneg = &m88e1101_config_aneg, 1966 .read_status = &genphy_read_status, 1967 .ack_interrupt = &marvell_ack_interrupt, 1968 .config_intr = &marvell_config_intr, 1969 .resume = &genphy_resume, 1970 .suspend = &genphy_suspend, 1971 .read_page = marvell_read_page, 1972 .write_page = marvell_write_page, 1973 .get_sset_count = marvell_get_sset_count, 1974 .get_strings = marvell_get_strings, 1975 .get_stats = marvell_get_stats, 1976 }, 1977 { 1978 .phy_id = MARVELL_PHY_ID_88E1149R, 1979 .phy_id_mask = MARVELL_PHY_ID_MASK, 1980 .name = "Marvell 88E1149R", 1981 .features = PHY_GBIT_FEATURES, 1982 .flags = PHY_HAS_INTERRUPT, 1983 .probe = marvell_probe, 1984 .config_init = &m88e1149_config_init, 1985 .config_aneg = &m88e1118_config_aneg, 1986 .ack_interrupt = &marvell_ack_interrupt, 1987 .config_intr = &marvell_config_intr, 1988 .resume = &genphy_resume, 1989 .suspend = &genphy_suspend, 1990 .read_page = marvell_read_page, 1991 .write_page = marvell_write_page, 1992 .get_sset_count = marvell_get_sset_count, 1993 .get_strings = marvell_get_strings, 1994 .get_stats = marvell_get_stats, 1995 }, 1996 { 1997 .phy_id = MARVELL_PHY_ID_88E1240, 1998 .phy_id_mask = MARVELL_PHY_ID_MASK, 1999 .name = "Marvell 88E1240", 2000 .features = PHY_GBIT_FEATURES, 2001 .flags = PHY_HAS_INTERRUPT, 2002 .probe = marvell_probe, 2003 .config_init = &m88e1111_config_init, 2004 .config_aneg = &marvell_config_aneg, 2005 .ack_interrupt = &marvell_ack_interrupt, 2006 .config_intr = &marvell_config_intr, 2007 .resume = &genphy_resume, 2008 .suspend = &genphy_suspend, 2009 .read_page = marvell_read_page, 2010 .write_page = marvell_write_page, 2011 .get_sset_count = marvell_get_sset_count, 2012 .get_strings = marvell_get_strings, 2013 .get_stats = marvell_get_stats, 2014 }, 2015 { 2016 .phy_id = MARVELL_PHY_ID_88E1116R, 2017 .phy_id_mask = MARVELL_PHY_ID_MASK, 2018 .name = "Marvell 88E1116R", 2019 .features = PHY_GBIT_FEATURES, 2020 .flags = PHY_HAS_INTERRUPT, 2021 .probe = marvell_probe, 2022 .config_init = &m88e1116r_config_init, 2023 .ack_interrupt = &marvell_ack_interrupt, 2024 .config_intr = &marvell_config_intr, 2025 .resume = &genphy_resume, 2026 .suspend = &genphy_suspend, 2027 .read_page = marvell_read_page, 2028 .write_page = marvell_write_page, 2029 .get_sset_count = marvell_get_sset_count, 2030 .get_strings = marvell_get_strings, 2031 .get_stats = marvell_get_stats, 2032 }, 2033 { 2034 .phy_id = MARVELL_PHY_ID_88E1510, 2035 .phy_id_mask = MARVELL_PHY_ID_MASK, 2036 .name = "Marvell 88E1510", 2037 .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE, 2038 .flags = PHY_HAS_INTERRUPT, 2039 .probe = &m88e1510_probe, 2040 .config_init = &m88e1510_config_init, 2041 .config_aneg = &m88e1510_config_aneg, 2042 .read_status = &marvell_read_status, 2043 .ack_interrupt = &marvell_ack_interrupt, 2044 .config_intr = &marvell_config_intr, 2045 .did_interrupt = &m88e1121_did_interrupt, 2046 .get_wol = &m88e1318_get_wol, 2047 .set_wol = &m88e1318_set_wol, 2048 .resume = &marvell_resume, 2049 .suspend = &marvell_suspend, 2050 .read_page = marvell_read_page, 2051 .write_page = marvell_write_page, 2052 .get_sset_count = marvell_get_sset_count, 2053 .get_strings = marvell_get_strings, 2054 .get_stats = marvell_get_stats, 2055 .set_loopback = genphy_loopback, 2056 }, 2057 { 2058 .phy_id = MARVELL_PHY_ID_88E1540, 2059 .phy_id_mask = MARVELL_PHY_ID_MASK, 2060 .name = "Marvell 88E1540", 2061 .features = PHY_GBIT_FEATURES, 2062 .flags = PHY_HAS_INTERRUPT, 2063 .probe = m88e1510_probe, 2064 .config_init = &marvell_config_init, 2065 .config_aneg = &m88e1510_config_aneg, 2066 .read_status = &marvell_read_status, 2067 .ack_interrupt = &marvell_ack_interrupt, 2068 .config_intr = &marvell_config_intr, 2069 .did_interrupt = &m88e1121_did_interrupt, 2070 .resume = &genphy_resume, 2071 .suspend = &genphy_suspend, 2072 .read_page = marvell_read_page, 2073 .write_page = marvell_write_page, 2074 .get_sset_count = marvell_get_sset_count, 2075 .get_strings = marvell_get_strings, 2076 .get_stats = marvell_get_stats, 2077 }, 2078 { 2079 .phy_id = MARVELL_PHY_ID_88E1545, 2080 .phy_id_mask = MARVELL_PHY_ID_MASK, 2081 .name = "Marvell 88E1545", 2082 .probe = m88e1510_probe, 2083 .features = PHY_GBIT_FEATURES, 2084 .flags = PHY_HAS_INTERRUPT, 2085 .config_init = &marvell_config_init, 2086 .config_aneg = &m88e1510_config_aneg, 2087 .read_status = &marvell_read_status, 2088 .ack_interrupt = &marvell_ack_interrupt, 2089 .config_intr = &marvell_config_intr, 2090 .did_interrupt = &m88e1121_did_interrupt, 2091 .resume = &genphy_resume, 2092 .suspend = &genphy_suspend, 2093 .read_page = marvell_read_page, 2094 .write_page = marvell_write_page, 2095 .get_sset_count = marvell_get_sset_count, 2096 .get_strings = marvell_get_strings, 2097 .get_stats = marvell_get_stats, 2098 }, 2099 { 2100 .phy_id = MARVELL_PHY_ID_88E3016, 2101 .phy_id_mask = MARVELL_PHY_ID_MASK, 2102 .name = "Marvell 88E3016", 2103 .features = PHY_BASIC_FEATURES, 2104 .flags = PHY_HAS_INTERRUPT, 2105 .probe = marvell_probe, 2106 .config_init = &m88e3016_config_init, 2107 .aneg_done = &marvell_aneg_done, 2108 .read_status = &marvell_read_status, 2109 .ack_interrupt = &marvell_ack_interrupt, 2110 .config_intr = &marvell_config_intr, 2111 .did_interrupt = &m88e1121_did_interrupt, 2112 .resume = &genphy_resume, 2113 .suspend = &genphy_suspend, 2114 .read_page = marvell_read_page, 2115 .write_page = marvell_write_page, 2116 .get_sset_count = marvell_get_sset_count, 2117 .get_strings = marvell_get_strings, 2118 .get_stats = marvell_get_stats, 2119 }, 2120 { 2121 .phy_id = MARVELL_PHY_ID_88E6390, 2122 .phy_id_mask = MARVELL_PHY_ID_MASK, 2123 .name = "Marvell 88E6390", 2124 .features = PHY_GBIT_FEATURES, 2125 .flags = PHY_HAS_INTERRUPT, 2126 .probe = m88e1510_probe, 2127 .config_init = &marvell_config_init, 2128 .config_aneg = &m88e1510_config_aneg, 2129 .read_status = &marvell_read_status, 2130 .ack_interrupt = &marvell_ack_interrupt, 2131 .config_intr = &marvell_config_intr, 2132 .did_interrupt = &m88e1121_did_interrupt, 2133 .resume = &genphy_resume, 2134 .suspend = &genphy_suspend, 2135 .read_page = marvell_read_page, 2136 .write_page = marvell_write_page, 2137 .get_sset_count = marvell_get_sset_count, 2138 .get_strings = marvell_get_strings, 2139 .get_stats = marvell_get_stats, 2140 }, 2141 }; 2142 2143 module_phy_driver(marvell_drivers); 2144 2145 static struct mdio_device_id __maybe_unused marvell_tbl[] = { 2146 { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK }, 2147 { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK }, 2148 { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK }, 2149 { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK }, 2150 { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK }, 2151 { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, 2152 { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, 2153 { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, 2154 { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, 2155 { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, 2156 { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, 2157 { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK }, 2158 { MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK }, 2159 { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK }, 2160 { MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK }, 2161 { } 2162 }; 2163 2164 MODULE_DEVICE_TABLE(mdio, marvell_tbl); 2165