1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Marvell 10G 88x3310 PHY driver 4 * 5 * Based upon the ID registers, this PHY appears to be a mixture of IPs 6 * from two different companies. 7 * 8 * There appears to be several different data paths through the PHY which 9 * are automatically managed by the PHY. The following has been determined 10 * via observation and experimentation for a setup using single-lane Serdes: 11 * 12 * SGMII PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for <= 1G) 13 * 10GBASE-KR PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for 10G) 14 * 10GBASE-KR PHYXS -- BASE-R PCS -- Fiber 15 * 16 * With XAUI, observation shows: 17 * 18 * XAUI PHYXS -- <appropriate PCS as above> 19 * 20 * and no switching of the host interface mode occurs. 21 * 22 * If both the fiber and copper ports are connected, the first to gain 23 * link takes priority and the other port is completely locked out. 24 */ 25 #include <linux/ctype.h> 26 #include <linux/delay.h> 27 #include <linux/hwmon.h> 28 #include <linux/marvell_phy.h> 29 #include <linux/phy.h> 30 #include <linux/sfp.h> 31 32 #define MV_PHY_ALASKA_NBT_QUIRK_MASK 0xfffffffe 33 #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa) 34 35 enum { 36 MV_PMA_BOOT = 0xc050, 37 MV_PMA_BOOT_FATAL = BIT(0), 38 39 MV_PCS_BASE_T = 0x0000, 40 MV_PCS_BASE_R = 0x1000, 41 MV_PCS_1000BASEX = 0x2000, 42 43 MV_PCS_CSCR1 = 0x8000, 44 MV_PCS_CSCR1_ED_MASK = 0x0300, 45 MV_PCS_CSCR1_ED_OFF = 0x0000, 46 MV_PCS_CSCR1_ED_RX = 0x0200, 47 MV_PCS_CSCR1_ED_NLP = 0x0300, 48 MV_PCS_CSCR1_MDIX_MASK = 0x0060, 49 MV_PCS_CSCR1_MDIX_MDI = 0x0000, 50 MV_PCS_CSCR1_MDIX_MDIX = 0x0020, 51 MV_PCS_CSCR1_MDIX_AUTO = 0x0060, 52 53 MV_PCS_CSSR1 = 0x8008, 54 MV_PCS_CSSR1_SPD1_MASK = 0xc000, 55 MV_PCS_CSSR1_SPD1_SPD2 = 0xc000, 56 MV_PCS_CSSR1_SPD1_1000 = 0x8000, 57 MV_PCS_CSSR1_SPD1_100 = 0x4000, 58 MV_PCS_CSSR1_SPD1_10 = 0x0000, 59 MV_PCS_CSSR1_DUPLEX_FULL= BIT(13), 60 MV_PCS_CSSR1_RESOLVED = BIT(11), 61 MV_PCS_CSSR1_MDIX = BIT(6), 62 MV_PCS_CSSR1_SPD2_MASK = 0x000c, 63 MV_PCS_CSSR1_SPD2_5000 = 0x0008, 64 MV_PCS_CSSR1_SPD2_2500 = 0x0004, 65 MV_PCS_CSSR1_SPD2_10000 = 0x0000, 66 67 /* These registers appear at 0x800X and 0xa00X - the 0xa00X control 68 * registers appear to set themselves to the 0x800X when AN is 69 * restarted, but status registers appear readable from either. 70 */ 71 MV_AN_CTRL1000 = 0x8000, /* 1000base-T control register */ 72 MV_AN_STAT1000 = 0x8001, /* 1000base-T status register */ 73 74 /* Vendor2 MMD registers */ 75 MV_V2_PORT_CTRL = 0xf001, 76 MV_V2_PORT_CTRL_PWRDOWN = 0x0800, 77 MV_V2_TEMP_CTRL = 0xf08a, 78 MV_V2_TEMP_CTRL_MASK = 0xc000, 79 MV_V2_TEMP_CTRL_SAMPLE = 0x0000, 80 MV_V2_TEMP_CTRL_DISABLE = 0xc000, 81 MV_V2_TEMP = 0xf08c, 82 MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */ 83 }; 84 85 struct mv3310_priv { 86 struct device *hwmon_dev; 87 char *hwmon_name; 88 }; 89 90 #ifdef CONFIG_HWMON 91 static umode_t mv3310_hwmon_is_visible(const void *data, 92 enum hwmon_sensor_types type, 93 u32 attr, int channel) 94 { 95 if (type == hwmon_chip && attr == hwmon_chip_update_interval) 96 return 0444; 97 if (type == hwmon_temp && attr == hwmon_temp_input) 98 return 0444; 99 return 0; 100 } 101 102 static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 103 u32 attr, int channel, long *value) 104 { 105 struct phy_device *phydev = dev_get_drvdata(dev); 106 int temp; 107 108 if (type == hwmon_chip && attr == hwmon_chip_update_interval) { 109 *value = MSEC_PER_SEC; 110 return 0; 111 } 112 113 if (type == hwmon_temp && attr == hwmon_temp_input) { 114 temp = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP); 115 if (temp < 0) 116 return temp; 117 118 *value = ((temp & 0xff) - 75) * 1000; 119 120 return 0; 121 } 122 123 return -EOPNOTSUPP; 124 } 125 126 static const struct hwmon_ops mv3310_hwmon_ops = { 127 .is_visible = mv3310_hwmon_is_visible, 128 .read = mv3310_hwmon_read, 129 }; 130 131 static u32 mv3310_hwmon_chip_config[] = { 132 HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL, 133 0, 134 }; 135 136 static const struct hwmon_channel_info mv3310_hwmon_chip = { 137 .type = hwmon_chip, 138 .config = mv3310_hwmon_chip_config, 139 }; 140 141 static u32 mv3310_hwmon_temp_config[] = { 142 HWMON_T_INPUT, 143 0, 144 }; 145 146 static const struct hwmon_channel_info mv3310_hwmon_temp = { 147 .type = hwmon_temp, 148 .config = mv3310_hwmon_temp_config, 149 }; 150 151 static const struct hwmon_channel_info *mv3310_hwmon_info[] = { 152 &mv3310_hwmon_chip, 153 &mv3310_hwmon_temp, 154 NULL, 155 }; 156 157 static const struct hwmon_chip_info mv3310_hwmon_chip_info = { 158 .ops = &mv3310_hwmon_ops, 159 .info = mv3310_hwmon_info, 160 }; 161 162 static int mv3310_hwmon_config(struct phy_device *phydev, bool enable) 163 { 164 u16 val; 165 int ret; 166 167 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP, 168 MV_V2_TEMP_UNKNOWN); 169 if (ret < 0) 170 return ret; 171 172 val = enable ? MV_V2_TEMP_CTRL_SAMPLE : MV_V2_TEMP_CTRL_DISABLE; 173 174 return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL, 175 MV_V2_TEMP_CTRL_MASK, val); 176 } 177 178 static void mv3310_hwmon_disable(void *data) 179 { 180 struct phy_device *phydev = data; 181 182 mv3310_hwmon_config(phydev, false); 183 } 184 185 static int mv3310_hwmon_probe(struct phy_device *phydev) 186 { 187 struct device *dev = &phydev->mdio.dev; 188 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 189 int i, j, ret; 190 191 priv->hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); 192 if (!priv->hwmon_name) 193 return -ENODEV; 194 195 for (i = j = 0; priv->hwmon_name[i]; i++) { 196 if (isalnum(priv->hwmon_name[i])) { 197 if (i != j) 198 priv->hwmon_name[j] = priv->hwmon_name[i]; 199 j++; 200 } 201 } 202 priv->hwmon_name[j] = '\0'; 203 204 ret = mv3310_hwmon_config(phydev, true); 205 if (ret) 206 return ret; 207 208 ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev); 209 if (ret) 210 return ret; 211 212 priv->hwmon_dev = devm_hwmon_device_register_with_info(dev, 213 priv->hwmon_name, phydev, 214 &mv3310_hwmon_chip_info, NULL); 215 216 return PTR_ERR_OR_ZERO(priv->hwmon_dev); 217 } 218 #else 219 static inline int mv3310_hwmon_config(struct phy_device *phydev, bool enable) 220 { 221 return 0; 222 } 223 224 static int mv3310_hwmon_probe(struct phy_device *phydev) 225 { 226 return 0; 227 } 228 #endif 229 230 static int mv3310_power_down(struct phy_device *phydev) 231 { 232 return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, 233 MV_V2_PORT_CTRL_PWRDOWN); 234 } 235 236 static int mv3310_power_up(struct phy_device *phydev) 237 { 238 return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, 239 MV_V2_PORT_CTRL_PWRDOWN); 240 } 241 242 static int mv3310_reset(struct phy_device *phydev, u32 unit) 243 { 244 int retries, val, err; 245 246 err = phy_modify_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1, 247 MDIO_CTRL1_RESET, MDIO_CTRL1_RESET); 248 if (err < 0) 249 return err; 250 251 retries = 20; 252 do { 253 msleep(5); 254 val = phy_read_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1); 255 if (val < 0) 256 return val; 257 } while (val & MDIO_CTRL1_RESET && --retries); 258 259 return val & MDIO_CTRL1_RESET ? -ETIMEDOUT : 0; 260 } 261 262 static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd) 263 { 264 int val; 265 266 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1); 267 if (val < 0) 268 return val; 269 270 switch (val & MV_PCS_CSCR1_ED_MASK) { 271 case MV_PCS_CSCR1_ED_NLP: 272 *edpd = 1000; 273 break; 274 case MV_PCS_CSCR1_ED_RX: 275 *edpd = ETHTOOL_PHY_EDPD_NO_TX; 276 break; 277 default: 278 *edpd = ETHTOOL_PHY_EDPD_DISABLE; 279 break; 280 } 281 return 0; 282 } 283 284 static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd) 285 { 286 u16 val; 287 int err; 288 289 switch (edpd) { 290 case 1000: 291 case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS: 292 val = MV_PCS_CSCR1_ED_NLP; 293 break; 294 295 case ETHTOOL_PHY_EDPD_NO_TX: 296 val = MV_PCS_CSCR1_ED_RX; 297 break; 298 299 case ETHTOOL_PHY_EDPD_DISABLE: 300 val = MV_PCS_CSCR1_ED_OFF; 301 break; 302 303 default: 304 return -EINVAL; 305 } 306 307 err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1, 308 MV_PCS_CSCR1_ED_MASK, val); 309 if (err > 0) 310 err = mv3310_reset(phydev, MV_PCS_BASE_T); 311 312 return err; 313 } 314 315 static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) 316 { 317 struct phy_device *phydev = upstream; 318 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; 319 phy_interface_t iface; 320 321 sfp_parse_support(phydev->sfp_bus, id, support); 322 iface = sfp_select_interface(phydev->sfp_bus, support); 323 324 if (iface != PHY_INTERFACE_MODE_10GBASER) { 325 dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); 326 return -EINVAL; 327 } 328 return 0; 329 } 330 331 static const struct sfp_upstream_ops mv3310_sfp_ops = { 332 .attach = phy_sfp_attach, 333 .detach = phy_sfp_detach, 334 .module_insert = mv3310_sfp_insert, 335 }; 336 337 static int mv3310_probe(struct phy_device *phydev) 338 { 339 struct mv3310_priv *priv; 340 u32 mmd_mask = MDIO_DEVS_PMAPMD | MDIO_DEVS_AN; 341 int ret; 342 343 if (!phydev->is_c45 || 344 (phydev->c45_ids.devices_in_package & mmd_mask) != mmd_mask) 345 return -ENODEV; 346 347 ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT); 348 if (ret < 0) 349 return ret; 350 351 if (ret & MV_PMA_BOOT_FATAL) { 352 dev_warn(&phydev->mdio.dev, 353 "PHY failed to boot firmware, status=%04x\n", ret); 354 return -ENODEV; 355 } 356 357 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 358 if (!priv) 359 return -ENOMEM; 360 361 dev_set_drvdata(&phydev->mdio.dev, priv); 362 363 /* Powering down the port when not in use saves about 600mW */ 364 ret = mv3310_power_down(phydev); 365 if (ret) 366 return ret; 367 368 ret = mv3310_hwmon_probe(phydev); 369 if (ret) 370 return ret; 371 372 return phy_sfp_probe(phydev, &mv3310_sfp_ops); 373 } 374 375 static int mv3310_suspend(struct phy_device *phydev) 376 { 377 return mv3310_power_down(phydev); 378 } 379 380 static int mv3310_resume(struct phy_device *phydev) 381 { 382 int ret; 383 384 ret = mv3310_power_up(phydev); 385 if (ret) 386 return ret; 387 388 return mv3310_hwmon_config(phydev, true); 389 } 390 391 /* Some PHYs in the Alaska family such as the 88X3310 and the 88E2010 392 * don't set bit 14 in PMA Extended Abilities (1.11), although they do 393 * support 2.5GBASET and 5GBASET. For these models, we can still read their 394 * 2.5G/5G extended abilities register (1.21). We detect these models based on 395 * the PMA device identifier, with a mask matching models known to have this 396 * issue 397 */ 398 static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev) 399 { 400 if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_PMAPMD)) 401 return false; 402 403 /* Only some revisions of the 88X3310 family PMA seem to be impacted */ 404 return (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 405 MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV; 406 } 407 408 static int mv3310_config_init(struct phy_device *phydev) 409 { 410 int err; 411 412 /* Check that the PHY interface type is compatible */ 413 if (phydev->interface != PHY_INTERFACE_MODE_SGMII && 414 phydev->interface != PHY_INTERFACE_MODE_2500BASEX && 415 phydev->interface != PHY_INTERFACE_MODE_XAUI && 416 phydev->interface != PHY_INTERFACE_MODE_RXAUI && 417 phydev->interface != PHY_INTERFACE_MODE_10GBASER) 418 return -ENODEV; 419 420 phydev->mdix_ctrl = ETH_TP_MDI_AUTO; 421 422 /* Power up so reset works */ 423 err = mv3310_power_up(phydev); 424 if (err) 425 return err; 426 427 /* Enable EDPD mode - saving 600mW */ 428 return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS); 429 } 430 431 static int mv3310_get_features(struct phy_device *phydev) 432 { 433 int ret, val; 434 435 ret = genphy_c45_pma_read_abilities(phydev); 436 if (ret) 437 return ret; 438 439 if (mv3310_has_pma_ngbaset_quirk(phydev)) { 440 val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, 441 MDIO_PMA_NG_EXTABLE); 442 if (val < 0) 443 return val; 444 445 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, 446 phydev->supported, 447 val & MDIO_PMA_NG_EXTABLE_2_5GBT); 448 449 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, 450 phydev->supported, 451 val & MDIO_PMA_NG_EXTABLE_5GBT); 452 } 453 454 return 0; 455 } 456 457 static int mv3310_config_mdix(struct phy_device *phydev) 458 { 459 u16 val; 460 int err; 461 462 switch (phydev->mdix_ctrl) { 463 case ETH_TP_MDI_AUTO: 464 val = MV_PCS_CSCR1_MDIX_AUTO; 465 break; 466 case ETH_TP_MDI_X: 467 val = MV_PCS_CSCR1_MDIX_MDIX; 468 break; 469 case ETH_TP_MDI: 470 val = MV_PCS_CSCR1_MDIX_MDI; 471 break; 472 default: 473 return -EINVAL; 474 } 475 476 err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1, 477 MV_PCS_CSCR1_MDIX_MASK, val); 478 if (err > 0) 479 err = mv3310_reset(phydev, MV_PCS_BASE_T); 480 481 return err; 482 } 483 484 static int mv3310_config_aneg(struct phy_device *phydev) 485 { 486 bool changed = false; 487 u16 reg; 488 int ret; 489 490 ret = mv3310_config_mdix(phydev); 491 if (ret < 0) 492 return ret; 493 494 if (phydev->autoneg == AUTONEG_DISABLE) 495 return genphy_c45_pma_setup_forced(phydev); 496 497 ret = genphy_c45_an_config_aneg(phydev); 498 if (ret < 0) 499 return ret; 500 if (ret > 0) 501 changed = true; 502 503 /* Clause 45 has no standardized support for 1000BaseT, therefore 504 * use vendor registers for this mode. 505 */ 506 reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); 507 ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MV_AN_CTRL1000, 508 ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg); 509 if (ret < 0) 510 return ret; 511 if (ret > 0) 512 changed = true; 513 514 return genphy_c45_check_and_restart_aneg(phydev, changed); 515 } 516 517 static int mv3310_aneg_done(struct phy_device *phydev) 518 { 519 int val; 520 521 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1); 522 if (val < 0) 523 return val; 524 525 if (val & MDIO_STAT1_LSTATUS) 526 return 1; 527 528 return genphy_c45_aneg_done(phydev); 529 } 530 531 static void mv3310_update_interface(struct phy_device *phydev) 532 { 533 if ((phydev->interface == PHY_INTERFACE_MODE_SGMII || 534 phydev->interface == PHY_INTERFACE_MODE_2500BASEX || 535 phydev->interface == PHY_INTERFACE_MODE_10GBASER) && 536 phydev->link) { 537 /* The PHY automatically switches its serdes interface (and 538 * active PHYXS instance) between Cisco SGMII, 10GBase-R and 539 * 2500BaseX modes according to the speed. Florian suggests 540 * setting phydev->interface to communicate this to the MAC. 541 * Only do this if we are already in one of the above modes. 542 */ 543 switch (phydev->speed) { 544 case SPEED_10000: 545 phydev->interface = PHY_INTERFACE_MODE_10GBASER; 546 break; 547 case SPEED_2500: 548 phydev->interface = PHY_INTERFACE_MODE_2500BASEX; 549 break; 550 case SPEED_1000: 551 case SPEED_100: 552 case SPEED_10: 553 phydev->interface = PHY_INTERFACE_MODE_SGMII; 554 break; 555 default: 556 break; 557 } 558 } 559 } 560 561 /* 10GBASE-ER,LR,LRM,SR do not support autonegotiation. */ 562 static int mv3310_read_status_10gbaser(struct phy_device *phydev) 563 { 564 phydev->link = 1; 565 phydev->speed = SPEED_10000; 566 phydev->duplex = DUPLEX_FULL; 567 568 return 0; 569 } 570 571 static int mv3310_read_status_copper(struct phy_device *phydev) 572 { 573 int cssr1, speed, val; 574 575 val = genphy_c45_read_link(phydev); 576 if (val < 0) 577 return val; 578 579 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); 580 if (val < 0) 581 return val; 582 583 cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1); 584 if (cssr1 < 0) 585 return val; 586 587 /* If the link settings are not resolved, mark the link down */ 588 if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) { 589 phydev->link = 0; 590 return 0; 591 } 592 593 /* Read the copper link settings */ 594 speed = cssr1 & MV_PCS_CSSR1_SPD1_MASK; 595 if (speed == MV_PCS_CSSR1_SPD1_SPD2) 596 speed |= cssr1 & MV_PCS_CSSR1_SPD2_MASK; 597 598 switch (speed) { 599 case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_10000: 600 phydev->speed = SPEED_10000; 601 break; 602 603 case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_5000: 604 phydev->speed = SPEED_5000; 605 break; 606 607 case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_2500: 608 phydev->speed = SPEED_2500; 609 break; 610 611 case MV_PCS_CSSR1_SPD1_1000: 612 phydev->speed = SPEED_1000; 613 break; 614 615 case MV_PCS_CSSR1_SPD1_100: 616 phydev->speed = SPEED_100; 617 break; 618 619 case MV_PCS_CSSR1_SPD1_10: 620 phydev->speed = SPEED_10; 621 break; 622 } 623 624 phydev->duplex = cssr1 & MV_PCS_CSSR1_DUPLEX_FULL ? 625 DUPLEX_FULL : DUPLEX_HALF; 626 phydev->mdix = cssr1 & MV_PCS_CSSR1_MDIX ? 627 ETH_TP_MDI_X : ETH_TP_MDI; 628 629 if (val & MDIO_AN_STAT1_COMPLETE) { 630 val = genphy_c45_read_lpa(phydev); 631 if (val < 0) 632 return val; 633 634 /* Read the link partner's 1G advertisement */ 635 val = phy_read_mmd(phydev, MDIO_MMD_AN, MV_AN_STAT1000); 636 if (val < 0) 637 return val; 638 639 mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val); 640 641 /* Update the pause status */ 642 phy_resolve_aneg_pause(phydev); 643 } 644 645 return 0; 646 } 647 648 static int mv3310_read_status(struct phy_device *phydev) 649 { 650 int err, val; 651 652 phydev->speed = SPEED_UNKNOWN; 653 phydev->duplex = DUPLEX_UNKNOWN; 654 linkmode_zero(phydev->lp_advertising); 655 phydev->link = 0; 656 phydev->pause = 0; 657 phydev->asym_pause = 0; 658 phydev->mdix = ETH_TP_MDI_INVALID; 659 660 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1); 661 if (val < 0) 662 return val; 663 664 if (val & MDIO_STAT1_LSTATUS) 665 err = mv3310_read_status_10gbaser(phydev); 666 else 667 err = mv3310_read_status_copper(phydev); 668 if (err < 0) 669 return err; 670 671 if (phydev->link) 672 mv3310_update_interface(phydev); 673 674 return 0; 675 } 676 677 static int mv3310_get_tunable(struct phy_device *phydev, 678 struct ethtool_tunable *tuna, void *data) 679 { 680 switch (tuna->id) { 681 case ETHTOOL_PHY_EDPD: 682 return mv3310_get_edpd(phydev, data); 683 default: 684 return -EOPNOTSUPP; 685 } 686 } 687 688 static int mv3310_set_tunable(struct phy_device *phydev, 689 struct ethtool_tunable *tuna, const void *data) 690 { 691 switch (tuna->id) { 692 case ETHTOOL_PHY_EDPD: 693 return mv3310_set_edpd(phydev, *(u16 *)data); 694 default: 695 return -EOPNOTSUPP; 696 } 697 } 698 699 static struct phy_driver mv3310_drivers[] = { 700 { 701 .phy_id = MARVELL_PHY_ID_88X3310, 702 .phy_id_mask = MARVELL_PHY_ID_MASK, 703 .name = "mv88x3310", 704 .get_features = mv3310_get_features, 705 .soft_reset = genphy_no_soft_reset, 706 .config_init = mv3310_config_init, 707 .probe = mv3310_probe, 708 .suspend = mv3310_suspend, 709 .resume = mv3310_resume, 710 .config_aneg = mv3310_config_aneg, 711 .aneg_done = mv3310_aneg_done, 712 .read_status = mv3310_read_status, 713 .get_tunable = mv3310_get_tunable, 714 .set_tunable = mv3310_set_tunable, 715 }, 716 { 717 .phy_id = MARVELL_PHY_ID_88E2110, 718 .phy_id_mask = MARVELL_PHY_ID_MASK, 719 .name = "mv88x2110", 720 .probe = mv3310_probe, 721 .suspend = mv3310_suspend, 722 .resume = mv3310_resume, 723 .soft_reset = genphy_no_soft_reset, 724 .config_init = mv3310_config_init, 725 .config_aneg = mv3310_config_aneg, 726 .aneg_done = mv3310_aneg_done, 727 .read_status = mv3310_read_status, 728 .get_tunable = mv3310_get_tunable, 729 .set_tunable = mv3310_set_tunable, 730 }, 731 }; 732 733 module_phy_driver(mv3310_drivers); 734 735 static struct mdio_device_id __maybe_unused mv3310_tbl[] = { 736 { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK }, 737 { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK }, 738 { }, 739 }; 740 MODULE_DEVICE_TABLE(mdio, mv3310_tbl); 741 MODULE_DESCRIPTION("Marvell Alaska X 10Gigabit Ethernet PHY driver (MV88X3310)"); 742 MODULE_LICENSE("GPL"); 743