1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * drivers/net/phy/marvell.c 4 * 5 * Driver for Marvell PHYs 6 * 7 * Author: Andy Fleming 8 * 9 * Copyright (c) 2004 Freescale Semiconductor, Inc. 10 * 11 * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de> 12 */ 13 #include <linux/kernel.h> 14 #include <linux/string.h> 15 #include <linux/ctype.h> 16 #include <linux/errno.h> 17 #include <linux/unistd.h> 18 #include <linux/hwmon.h> 19 #include <linux/interrupt.h> 20 #include <linux/init.h> 21 #include <linux/delay.h> 22 #include <linux/netdevice.h> 23 #include <linux/etherdevice.h> 24 #include <linux/skbuff.h> 25 #include <linux/spinlock.h> 26 #include <linux/mm.h> 27 #include <linux/module.h> 28 #include <linux/mii.h> 29 #include <linux/ethtool.h> 30 #include <linux/ethtool_netlink.h> 31 #include <linux/phy.h> 32 #include <linux/marvell_phy.h> 33 #include <linux/bitfield.h> 34 #include <linux/of.h> 35 36 #include <linux/io.h> 37 #include <asm/irq.h> 38 #include <linux/uaccess.h> 39 40 #define MII_MARVELL_PHY_PAGE 22 41 #define MII_MARVELL_COPPER_PAGE 0x00 42 #define MII_MARVELL_FIBER_PAGE 0x01 43 #define MII_MARVELL_MSCR_PAGE 0x02 44 #define MII_MARVELL_LED_PAGE 0x03 45 #define MII_MARVELL_MISC_TEST_PAGE 0x06 46 #define MII_MARVELL_VCT7_PAGE 0x07 47 #define MII_MARVELL_WOL_PAGE 0x11 48 49 #define MII_M1011_IEVENT 0x13 50 #define MII_M1011_IEVENT_CLEAR 0x0000 51 52 #define MII_M1011_IMASK 0x12 53 #define MII_M1011_IMASK_INIT 0x6400 54 #define MII_M1011_IMASK_CLEAR 0x0000 55 56 #define MII_M1011_PHY_SCR 0x10 57 #define MII_M1011_PHY_SCR_DOWNSHIFT_EN BIT(11) 58 #define MII_M1011_PHY_SCR_DOWNSHIFT_MASK GENMASK(14, 12) 59 #define MII_M1011_PHY_SCR_DOWNSHIFT_MAX 8 60 #define MII_M1011_PHY_SCR_MDI (0x0 << 5) 61 #define MII_M1011_PHY_SCR_MDI_X (0x1 << 5) 62 #define MII_M1011_PHY_SCR_AUTO_CROSS (0x3 << 5) 63 64 #define MII_M1011_PHY_SSR 0x11 65 #define MII_M1011_PHY_SSR_DOWNSHIFT BIT(5) 66 67 #define MII_M1111_PHY_LED_CONTROL 0x18 68 #define MII_M1111_PHY_LED_DIRECT 0x4100 69 #define MII_M1111_PHY_LED_COMBINE 0x411c 70 #define MII_M1111_PHY_EXT_CR 0x14 71 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK GENMASK(11, 9) 72 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX 8 73 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN BIT(8) 74 #define MII_M1111_RGMII_RX_DELAY BIT(7) 75 #define MII_M1111_RGMII_TX_DELAY BIT(1) 76 #define MII_M1111_PHY_EXT_SR 0x1b 77 78 #define MII_M1111_HWCFG_MODE_MASK 0xf 79 #define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 80 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 81 #define MII_M1111_HWCFG_MODE_RTBI 0x7 82 #define MII_M1111_HWCFG_MODE_COPPER_RTBI 0x9 83 #define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb 84 #define MII_M1111_HWCFG_FIBER_COPPER_RES BIT(13) 85 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO BIT(15) 86 87 #define MII_88E1121_PHY_MSCR_REG 21 88 #define MII_88E1121_PHY_MSCR_RX_DELAY BIT(5) 89 #define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4) 90 #define MII_88E1121_PHY_MSCR_DELAY_MASK (BIT(5) | BIT(4)) 91 92 #define MII_88E1121_MISC_TEST 0x1a 93 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK 0x1f00 94 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT 8 95 #define MII_88E1510_MISC_TEST_TEMP_IRQ_EN BIT(7) 96 #define MII_88E1510_MISC_TEST_TEMP_IRQ BIT(6) 97 #define MII_88E1121_MISC_TEST_TEMP_SENSOR_EN BIT(5) 98 #define MII_88E1121_MISC_TEST_TEMP_MASK 0x1f 99 100 #define MII_88E1510_TEMP_SENSOR 0x1b 101 #define MII_88E1510_TEMP_SENSOR_MASK 0xff 102 103 #define MII_88E1540_COPPER_CTRL3 0x1a 104 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK GENMASK(11, 10) 105 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS 0 106 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS 1 107 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS 2 108 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS 3 109 #define MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN BIT(9) 110 111 #define MII_88E6390_MISC_TEST 0x1b 112 #define MII_88E6390_MISC_TEST_SAMPLE_1S 0 113 #define MII_88E6390_MISC_TEST_SAMPLE_10MS BIT(14) 114 #define MII_88E6390_MISC_TEST_SAMPLE_DISABLE BIT(15) 115 #define MII_88E6390_MISC_TEST_SAMPLE_ENABLE 0 116 #define MII_88E6390_MISC_TEST_SAMPLE_MASK (0x3 << 14) 117 118 #define MII_88E6390_TEMP_SENSOR 0x1c 119 #define MII_88E6390_TEMP_SENSOR_MASK 0xff 120 #define MII_88E6390_TEMP_SENSOR_SAMPLES 10 121 122 #define MII_88E1318S_PHY_MSCR1_REG 16 123 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6) 124 125 /* Copper Specific Interrupt Enable Register */ 126 #define MII_88E1318S_PHY_CSIER 0x12 127 /* WOL Event Interrupt Enable */ 128 #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) 129 130 /* LED Timer Control Register */ 131 #define MII_88E1318S_PHY_LED_TCR 0x12 132 #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) 133 #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) 134 #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) 135 136 /* Magic Packet MAC address registers */ 137 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 138 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1 0x18 139 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0 0x19 140 141 #define MII_88E1318S_PHY_WOL_CTRL 0x10 142 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS BIT(12) 143 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14) 144 145 #define MII_PHY_LED_CTRL 16 146 #define MII_88E1121_PHY_LED_DEF 0x0030 147 #define MII_88E1510_PHY_LED_DEF 0x1177 148 #define MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE 0x1040 149 150 #define MII_M1011_PHY_STATUS 0x11 151 #define MII_M1011_PHY_STATUS_1000 0x8000 152 #define MII_M1011_PHY_STATUS_100 0x4000 153 #define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 154 #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 155 #define MII_M1011_PHY_STATUS_RESOLVED 0x0800 156 #define MII_M1011_PHY_STATUS_LINK 0x0400 157 158 #define MII_88E3016_PHY_SPEC_CTRL 0x10 159 #define MII_88E3016_DISABLE_SCRAMBLER 0x0200 160 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030 161 162 #define MII_88E1510_GEN_CTRL_REG_1 0x14 163 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7 164 #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1 /* SGMII to copper */ 165 #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */ 166 167 #define MII_VCT7_PAIR_0_DISTANCE 0x10 168 #define MII_VCT7_PAIR_1_DISTANCE 0x11 169 #define MII_VCT7_PAIR_2_DISTANCE 0x12 170 #define MII_VCT7_PAIR_3_DISTANCE 0x13 171 172 #define MII_VCT7_RESULTS 0x14 173 #define MII_VCT7_RESULTS_PAIR3_MASK 0xf000 174 #define MII_VCT7_RESULTS_PAIR2_MASK 0x0f00 175 #define MII_VCT7_RESULTS_PAIR1_MASK 0x00f0 176 #define MII_VCT7_RESULTS_PAIR0_MASK 0x000f 177 #define MII_VCT7_RESULTS_PAIR3_SHIFT 12 178 #define MII_VCT7_RESULTS_PAIR2_SHIFT 8 179 #define MII_VCT7_RESULTS_PAIR1_SHIFT 4 180 #define MII_VCT7_RESULTS_PAIR0_SHIFT 0 181 #define MII_VCT7_RESULTS_INVALID 0 182 #define MII_VCT7_RESULTS_OK 1 183 #define MII_VCT7_RESULTS_OPEN 2 184 #define MII_VCT7_RESULTS_SAME_SHORT 3 185 #define MII_VCT7_RESULTS_CROSS_SHORT 4 186 #define MII_VCT7_RESULTS_BUSY 9 187 188 #define MII_VCT7_CTRL 0x15 189 #define MII_VCT7_CTRL_RUN_NOW BIT(15) 190 #define MII_VCT7_CTRL_RUN_ANEG BIT(14) 191 #define MII_VCT7_CTRL_DISABLE_CROSS BIT(13) 192 #define MII_VCT7_CTRL_RUN_AFTER_BREAK_LINK BIT(12) 193 #define MII_VCT7_CTRL_IN_PROGRESS BIT(11) 194 #define MII_VCT7_CTRL_METERS BIT(10) 195 #define MII_VCT7_CTRL_CENTIMETERS 0 196 197 #define LPA_PAUSE_FIBER 0x180 198 #define LPA_PAUSE_ASYM_FIBER 0x100 199 200 #define NB_FIBER_STATS 1 201 202 MODULE_DESCRIPTION("Marvell PHY driver"); 203 MODULE_AUTHOR("Andy Fleming"); 204 MODULE_LICENSE("GPL"); 205 206 struct marvell_hw_stat { 207 const char *string; 208 u8 page; 209 u8 reg; 210 u8 bits; 211 }; 212 213 static struct marvell_hw_stat marvell_hw_stats[] = { 214 { "phy_receive_errors_copper", 0, 21, 16}, 215 { "phy_idle_errors", 0, 10, 8 }, 216 { "phy_receive_errors_fiber", 1, 21, 16}, 217 }; 218 219 struct marvell_priv { 220 u64 stats[ARRAY_SIZE(marvell_hw_stats)]; 221 char *hwmon_name; 222 struct device *hwmon_dev; 223 }; 224 225 static int marvell_read_page(struct phy_device *phydev) 226 { 227 return __phy_read(phydev, MII_MARVELL_PHY_PAGE); 228 } 229 230 static int marvell_write_page(struct phy_device *phydev, int page) 231 { 232 return __phy_write(phydev, MII_MARVELL_PHY_PAGE, page); 233 } 234 235 static int marvell_set_page(struct phy_device *phydev, int page) 236 { 237 return phy_write(phydev, MII_MARVELL_PHY_PAGE, page); 238 } 239 240 static int marvell_ack_interrupt(struct phy_device *phydev) 241 { 242 int err; 243 244 /* Clear the interrupts by reading the reg */ 245 err = phy_read(phydev, MII_M1011_IEVENT); 246 247 if (err < 0) 248 return err; 249 250 return 0; 251 } 252 253 static int marvell_config_intr(struct phy_device *phydev) 254 { 255 int err; 256 257 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 258 err = phy_write(phydev, MII_M1011_IMASK, 259 MII_M1011_IMASK_INIT); 260 else 261 err = phy_write(phydev, MII_M1011_IMASK, 262 MII_M1011_IMASK_CLEAR); 263 264 return err; 265 } 266 267 static int marvell_set_polarity(struct phy_device *phydev, int polarity) 268 { 269 int reg; 270 int err; 271 int val; 272 273 /* get the current settings */ 274 reg = phy_read(phydev, MII_M1011_PHY_SCR); 275 if (reg < 0) 276 return reg; 277 278 val = reg; 279 val &= ~MII_M1011_PHY_SCR_AUTO_CROSS; 280 switch (polarity) { 281 case ETH_TP_MDI: 282 val |= MII_M1011_PHY_SCR_MDI; 283 break; 284 case ETH_TP_MDI_X: 285 val |= MII_M1011_PHY_SCR_MDI_X; 286 break; 287 case ETH_TP_MDI_AUTO: 288 case ETH_TP_MDI_INVALID: 289 default: 290 val |= MII_M1011_PHY_SCR_AUTO_CROSS; 291 break; 292 } 293 294 if (val != reg) { 295 /* Set the new polarity value in the register */ 296 err = phy_write(phydev, MII_M1011_PHY_SCR, val); 297 if (err) 298 return err; 299 } 300 301 return val != reg; 302 } 303 304 static int marvell_config_aneg(struct phy_device *phydev) 305 { 306 int changed = 0; 307 int err; 308 309 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 310 if (err < 0) 311 return err; 312 313 changed = err; 314 315 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, 316 MII_M1111_PHY_LED_DIRECT); 317 if (err < 0) 318 return err; 319 320 err = genphy_config_aneg(phydev); 321 if (err < 0) 322 return err; 323 324 if (phydev->autoneg != AUTONEG_ENABLE || changed) { 325 /* A write to speed/duplex bits (that is performed by 326 * genphy_config_aneg() call above) must be followed by 327 * a software reset. Otherwise, the write has no effect. 328 */ 329 err = genphy_soft_reset(phydev); 330 if (err < 0) 331 return err; 332 } 333 334 return 0; 335 } 336 337 static int m88e1101_config_aneg(struct phy_device *phydev) 338 { 339 int err; 340 341 /* This Marvell PHY has an errata which requires 342 * that certain registers get written in order 343 * to restart autonegotiation 344 */ 345 err = genphy_soft_reset(phydev); 346 if (err < 0) 347 return err; 348 349 err = phy_write(phydev, 0x1d, 0x1f); 350 if (err < 0) 351 return err; 352 353 err = phy_write(phydev, 0x1e, 0x200c); 354 if (err < 0) 355 return err; 356 357 err = phy_write(phydev, 0x1d, 0x5); 358 if (err < 0) 359 return err; 360 361 err = phy_write(phydev, 0x1e, 0); 362 if (err < 0) 363 return err; 364 365 err = phy_write(phydev, 0x1e, 0x100); 366 if (err < 0) 367 return err; 368 369 return marvell_config_aneg(phydev); 370 } 371 372 #ifdef CONFIG_OF_MDIO 373 /* Set and/or override some configuration registers based on the 374 * marvell,reg-init property stored in the of_node for the phydev. 375 * 376 * marvell,reg-init = <reg-page reg mask value>,...; 377 * 378 * There may be one or more sets of <reg-page reg mask value>: 379 * 380 * reg-page: which register bank to use. 381 * reg: the register. 382 * mask: if non-zero, ANDed with existing register value. 383 * value: ORed with the masked value and written to the regiser. 384 * 385 */ 386 static int marvell_of_reg_init(struct phy_device *phydev) 387 { 388 const __be32 *paddr; 389 int len, i, saved_page, current_page, ret = 0; 390 391 if (!phydev->mdio.dev.of_node) 392 return 0; 393 394 paddr = of_get_property(phydev->mdio.dev.of_node, 395 "marvell,reg-init", &len); 396 if (!paddr || len < (4 * sizeof(*paddr))) 397 return 0; 398 399 saved_page = phy_save_page(phydev); 400 if (saved_page < 0) 401 goto err; 402 current_page = saved_page; 403 404 len /= sizeof(*paddr); 405 for (i = 0; i < len - 3; i += 4) { 406 u16 page = be32_to_cpup(paddr + i); 407 u16 reg = be32_to_cpup(paddr + i + 1); 408 u16 mask = be32_to_cpup(paddr + i + 2); 409 u16 val_bits = be32_to_cpup(paddr + i + 3); 410 int val; 411 412 if (page != current_page) { 413 current_page = page; 414 ret = marvell_write_page(phydev, page); 415 if (ret < 0) 416 goto err; 417 } 418 419 val = 0; 420 if (mask) { 421 val = __phy_read(phydev, reg); 422 if (val < 0) { 423 ret = val; 424 goto err; 425 } 426 val &= mask; 427 } 428 val |= val_bits; 429 430 ret = __phy_write(phydev, reg, val); 431 if (ret < 0) 432 goto err; 433 } 434 err: 435 return phy_restore_page(phydev, saved_page, ret); 436 } 437 #else 438 static int marvell_of_reg_init(struct phy_device *phydev) 439 { 440 return 0; 441 } 442 #endif /* CONFIG_OF_MDIO */ 443 444 static int m88e1121_config_aneg_rgmii_delays(struct phy_device *phydev) 445 { 446 int mscr; 447 448 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 449 mscr = MII_88E1121_PHY_MSCR_RX_DELAY | 450 MII_88E1121_PHY_MSCR_TX_DELAY; 451 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 452 mscr = MII_88E1121_PHY_MSCR_RX_DELAY; 453 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 454 mscr = MII_88E1121_PHY_MSCR_TX_DELAY; 455 else 456 mscr = 0; 457 458 return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE, 459 MII_88E1121_PHY_MSCR_REG, 460 MII_88E1121_PHY_MSCR_DELAY_MASK, mscr); 461 } 462 463 static int m88e1121_config_aneg(struct phy_device *phydev) 464 { 465 int changed = 0; 466 int err = 0; 467 468 if (phy_interface_is_rgmii(phydev)) { 469 err = m88e1121_config_aneg_rgmii_delays(phydev); 470 if (err < 0) 471 return err; 472 } 473 474 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 475 if (err < 0) 476 return err; 477 478 changed = err; 479 480 err = genphy_config_aneg(phydev); 481 if (err < 0) 482 return err; 483 484 if (phydev->autoneg != AUTONEG_ENABLE || changed) { 485 /* A software reset is used to ensure a "commit" of the 486 * changes is done. 487 */ 488 err = genphy_soft_reset(phydev); 489 if (err < 0) 490 return err; 491 } 492 493 return 0; 494 } 495 496 static int m88e1318_config_aneg(struct phy_device *phydev) 497 { 498 int err; 499 500 err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE, 501 MII_88E1318S_PHY_MSCR1_REG, 502 0, MII_88E1318S_PHY_MSCR1_PAD_ODD); 503 if (err < 0) 504 return err; 505 506 return m88e1121_config_aneg(phydev); 507 } 508 509 /** 510 * linkmode_adv_to_fiber_adv_t 511 * @advertise: the linkmode advertisement settings 512 * 513 * A small helper function that translates linkmode advertisement 514 * settings to phy autonegotiation advertisements for the MII_ADV 515 * register for fiber link. 516 */ 517 static inline u32 linkmode_adv_to_fiber_adv_t(unsigned long *advertise) 518 { 519 u32 result = 0; 520 521 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertise)) 522 result |= ADVERTISE_1000XHALF; 523 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertise)) 524 result |= ADVERTISE_1000XFULL; 525 526 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertise) && 527 linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise)) 528 result |= ADVERTISE_1000XPSE_ASYM; 529 else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise)) 530 result |= ADVERTISE_1000XPAUSE; 531 532 return result; 533 } 534 535 /** 536 * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR 537 * @phydev: target phy_device struct 538 * 539 * Description: If auto-negotiation is enabled, we configure the 540 * advertising, and then restart auto-negotiation. If it is not 541 * enabled, then we write the BMCR. Adapted for fiber link in 542 * some Marvell's devices. 543 */ 544 static int marvell_config_aneg_fiber(struct phy_device *phydev) 545 { 546 int changed = 0; 547 int err; 548 u16 adv; 549 550 if (phydev->autoneg != AUTONEG_ENABLE) 551 return genphy_setup_forced(phydev); 552 553 /* Only allow advertising what this PHY supports */ 554 linkmode_and(phydev->advertising, phydev->advertising, 555 phydev->supported); 556 557 adv = linkmode_adv_to_fiber_adv_t(phydev->advertising); 558 559 /* Setup fiber advertisement */ 560 err = phy_modify_changed(phydev, MII_ADVERTISE, 561 ADVERTISE_1000XHALF | ADVERTISE_1000XFULL | 562 ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM, 563 adv); 564 if (err < 0) 565 return err; 566 if (err > 0) 567 changed = 1; 568 569 return genphy_check_and_restart_aneg(phydev, changed); 570 } 571 572 static int m88e1510_config_aneg(struct phy_device *phydev) 573 { 574 int err; 575 576 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 577 if (err < 0) 578 goto error; 579 580 /* Configure the copper link first */ 581 err = m88e1318_config_aneg(phydev); 582 if (err < 0) 583 goto error; 584 585 /* Do not touch the fiber page if we're in copper->sgmii mode */ 586 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) 587 return 0; 588 589 /* Then the fiber link */ 590 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 591 if (err < 0) 592 goto error; 593 594 err = marvell_config_aneg_fiber(phydev); 595 if (err < 0) 596 goto error; 597 598 return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 599 600 error: 601 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 602 return err; 603 } 604 605 static void marvell_config_led(struct phy_device *phydev) 606 { 607 u16 def_config; 608 int err; 609 610 switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) { 611 /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */ 612 case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R): 613 case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S): 614 def_config = MII_88E1121_PHY_LED_DEF; 615 break; 616 /* Default PHY LED config: 617 * LED[0] .. 1000Mbps Link 618 * LED[1] .. 100Mbps Link 619 * LED[2] .. Blink, Activity 620 */ 621 case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510): 622 if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE) 623 def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE; 624 else 625 def_config = MII_88E1510_PHY_LED_DEF; 626 break; 627 default: 628 return; 629 } 630 631 err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, MII_PHY_LED_CTRL, 632 def_config); 633 if (err < 0) 634 phydev_warn(phydev, "Fail to config marvell phy LED.\n"); 635 } 636 637 static int marvell_config_init(struct phy_device *phydev) 638 { 639 /* Set defalut LED */ 640 marvell_config_led(phydev); 641 642 /* Set registers from marvell,reg-init DT property */ 643 return marvell_of_reg_init(phydev); 644 } 645 646 static int m88e3016_config_init(struct phy_device *phydev) 647 { 648 int ret; 649 650 /* Enable Scrambler and Auto-Crossover */ 651 ret = phy_modify(phydev, MII_88E3016_PHY_SPEC_CTRL, 652 MII_88E3016_DISABLE_SCRAMBLER, 653 MII_88E3016_AUTO_MDIX_CROSSOVER); 654 if (ret < 0) 655 return ret; 656 657 return marvell_config_init(phydev); 658 } 659 660 static int m88e1111_config_init_hwcfg_mode(struct phy_device *phydev, 661 u16 mode, 662 int fibre_copper_auto) 663 { 664 if (fibre_copper_auto) 665 mode |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; 666 667 return phy_modify(phydev, MII_M1111_PHY_EXT_SR, 668 MII_M1111_HWCFG_MODE_MASK | 669 MII_M1111_HWCFG_FIBER_COPPER_AUTO | 670 MII_M1111_HWCFG_FIBER_COPPER_RES, 671 mode); 672 } 673 674 static int m88e1111_config_init_rgmii_delays(struct phy_device *phydev) 675 { 676 int delay; 677 678 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 679 delay = MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY; 680 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 681 delay = MII_M1111_RGMII_RX_DELAY; 682 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 683 delay = MII_M1111_RGMII_TX_DELAY; 684 } else { 685 delay = 0; 686 } 687 688 return phy_modify(phydev, MII_M1111_PHY_EXT_CR, 689 MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY, 690 delay); 691 } 692 693 static int m88e1111_config_init_rgmii(struct phy_device *phydev) 694 { 695 int temp; 696 int err; 697 698 err = m88e1111_config_init_rgmii_delays(phydev); 699 if (err < 0) 700 return err; 701 702 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 703 if (temp < 0) 704 return temp; 705 706 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 707 708 if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES) 709 temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; 710 else 711 temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; 712 713 return phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 714 } 715 716 static int m88e1111_config_init_sgmii(struct phy_device *phydev) 717 { 718 int err; 719 720 err = m88e1111_config_init_hwcfg_mode( 721 phydev, 722 MII_M1111_HWCFG_MODE_SGMII_NO_CLK, 723 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 724 if (err < 0) 725 return err; 726 727 /* make sure copper is selected */ 728 return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 729 } 730 731 static int m88e1111_config_init_rtbi(struct phy_device *phydev) 732 { 733 int err; 734 735 err = m88e1111_config_init_rgmii_delays(phydev); 736 if (err < 0) 737 return err; 738 739 err = m88e1111_config_init_hwcfg_mode( 740 phydev, 741 MII_M1111_HWCFG_MODE_RTBI, 742 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 743 if (err < 0) 744 return err; 745 746 /* soft reset */ 747 err = genphy_soft_reset(phydev); 748 if (err < 0) 749 return err; 750 751 return m88e1111_config_init_hwcfg_mode( 752 phydev, 753 MII_M1111_HWCFG_MODE_RTBI, 754 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 755 } 756 757 static int m88e1111_config_init(struct phy_device *phydev) 758 { 759 int err; 760 761 if (phy_interface_is_rgmii(phydev)) { 762 err = m88e1111_config_init_rgmii(phydev); 763 if (err < 0) 764 return err; 765 } 766 767 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 768 err = m88e1111_config_init_sgmii(phydev); 769 if (err < 0) 770 return err; 771 } 772 773 if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { 774 err = m88e1111_config_init_rtbi(phydev); 775 if (err < 0) 776 return err; 777 } 778 779 err = marvell_of_reg_init(phydev); 780 if (err < 0) 781 return err; 782 783 return genphy_soft_reset(phydev); 784 } 785 786 static int m88e1111_get_downshift(struct phy_device *phydev, u8 *data) 787 { 788 int val, cnt, enable; 789 790 val = phy_read(phydev, MII_M1111_PHY_EXT_CR); 791 if (val < 0) 792 return val; 793 794 enable = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN, val); 795 cnt = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, val) + 1; 796 797 *data = enable ? cnt : DOWNSHIFT_DEV_DISABLE; 798 799 return 0; 800 } 801 802 static int m88e1111_set_downshift(struct phy_device *phydev, u8 cnt) 803 { 804 int val; 805 806 if (cnt > MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX) 807 return -E2BIG; 808 809 if (!cnt) 810 return phy_clear_bits(phydev, MII_M1111_PHY_EXT_CR, 811 MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN); 812 813 val = MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN; 814 val |= FIELD_PREP(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, cnt - 1); 815 816 return phy_modify(phydev, MII_M1111_PHY_EXT_CR, 817 MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN | 818 MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, 819 val); 820 } 821 822 static int m88e1111_get_tunable(struct phy_device *phydev, 823 struct ethtool_tunable *tuna, void *data) 824 { 825 switch (tuna->id) { 826 case ETHTOOL_PHY_DOWNSHIFT: 827 return m88e1111_get_downshift(phydev, data); 828 default: 829 return -EOPNOTSUPP; 830 } 831 } 832 833 static int m88e1111_set_tunable(struct phy_device *phydev, 834 struct ethtool_tunable *tuna, const void *data) 835 { 836 switch (tuna->id) { 837 case ETHTOOL_PHY_DOWNSHIFT: 838 return m88e1111_set_downshift(phydev, *(const u8 *)data); 839 default: 840 return -EOPNOTSUPP; 841 } 842 } 843 844 static int m88e1011_get_downshift(struct phy_device *phydev, u8 *data) 845 { 846 int val, cnt, enable; 847 848 val = phy_read(phydev, MII_M1011_PHY_SCR); 849 if (val < 0) 850 return val; 851 852 enable = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_EN, val); 853 cnt = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, val) + 1; 854 855 *data = enable ? cnt : DOWNSHIFT_DEV_DISABLE; 856 857 return 0; 858 } 859 860 static int m88e1011_set_downshift(struct phy_device *phydev, u8 cnt) 861 { 862 int val; 863 864 if (cnt > MII_M1011_PHY_SCR_DOWNSHIFT_MAX) 865 return -E2BIG; 866 867 if (!cnt) 868 return phy_clear_bits(phydev, MII_M1011_PHY_SCR, 869 MII_M1011_PHY_SCR_DOWNSHIFT_EN); 870 871 val = MII_M1011_PHY_SCR_DOWNSHIFT_EN; 872 val |= FIELD_PREP(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, cnt - 1); 873 874 return phy_modify(phydev, MII_M1011_PHY_SCR, 875 MII_M1011_PHY_SCR_DOWNSHIFT_EN | 876 MII_M1011_PHY_SCR_DOWNSHIFT_MASK, 877 val); 878 } 879 880 static int m88e1011_get_tunable(struct phy_device *phydev, 881 struct ethtool_tunable *tuna, void *data) 882 { 883 switch (tuna->id) { 884 case ETHTOOL_PHY_DOWNSHIFT: 885 return m88e1011_get_downshift(phydev, data); 886 default: 887 return -EOPNOTSUPP; 888 } 889 } 890 891 static int m88e1011_set_tunable(struct phy_device *phydev, 892 struct ethtool_tunable *tuna, const void *data) 893 { 894 switch (tuna->id) { 895 case ETHTOOL_PHY_DOWNSHIFT: 896 return m88e1011_set_downshift(phydev, *(const u8 *)data); 897 default: 898 return -EOPNOTSUPP; 899 } 900 } 901 902 static int m88e1116r_config_init(struct phy_device *phydev) 903 { 904 int err; 905 906 err = genphy_soft_reset(phydev); 907 if (err < 0) 908 return err; 909 910 msleep(500); 911 912 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 913 if (err < 0) 914 return err; 915 916 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 917 if (err < 0) 918 return err; 919 920 err = m88e1011_set_downshift(phydev, 8); 921 if (err < 0) 922 return err; 923 924 if (phy_interface_is_rgmii(phydev)) { 925 err = m88e1121_config_aneg_rgmii_delays(phydev); 926 if (err < 0) 927 return err; 928 } 929 930 err = genphy_soft_reset(phydev); 931 if (err < 0) 932 return err; 933 934 return marvell_config_init(phydev); 935 } 936 937 static int m88e1318_config_init(struct phy_device *phydev) 938 { 939 if (phy_interrupt_is_valid(phydev)) { 940 int err = phy_modify_paged( 941 phydev, MII_MARVELL_LED_PAGE, 942 MII_88E1318S_PHY_LED_TCR, 943 MII_88E1318S_PHY_LED_TCR_FORCE_INT, 944 MII_88E1318S_PHY_LED_TCR_INTn_ENABLE | 945 MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW); 946 if (err < 0) 947 return err; 948 } 949 950 return marvell_config_init(phydev); 951 } 952 953 static int m88e1510_config_init(struct phy_device *phydev) 954 { 955 int err; 956 957 /* SGMII-to-Copper mode initialization */ 958 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 959 /* Select page 18 */ 960 err = marvell_set_page(phydev, 18); 961 if (err < 0) 962 return err; 963 964 /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ 965 err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1, 966 MII_88E1510_GEN_CTRL_REG_1_MODE_MASK, 967 MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII); 968 if (err < 0) 969 return err; 970 971 /* PHY reset is necessary after changing MODE[2:0] */ 972 err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1, 0, 973 MII_88E1510_GEN_CTRL_REG_1_RESET); 974 if (err < 0) 975 return err; 976 977 /* Reset page selection */ 978 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 979 if (err < 0) 980 return err; 981 } 982 983 return m88e1318_config_init(phydev); 984 } 985 986 static int m88e1118_config_aneg(struct phy_device *phydev) 987 { 988 int err; 989 990 err = genphy_soft_reset(phydev); 991 if (err < 0) 992 return err; 993 994 err = marvell_set_polarity(phydev, phydev->mdix_ctrl); 995 if (err < 0) 996 return err; 997 998 err = genphy_config_aneg(phydev); 999 return 0; 1000 } 1001 1002 static int m88e1118_config_init(struct phy_device *phydev) 1003 { 1004 int err; 1005 1006 /* Change address */ 1007 err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE); 1008 if (err < 0) 1009 return err; 1010 1011 /* Enable 1000 Mbit */ 1012 err = phy_write(phydev, 0x15, 0x1070); 1013 if (err < 0) 1014 return err; 1015 1016 /* Change address */ 1017 err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE); 1018 if (err < 0) 1019 return err; 1020 1021 /* Adjust LED Control */ 1022 if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS) 1023 err = phy_write(phydev, 0x10, 0x1100); 1024 else 1025 err = phy_write(phydev, 0x10, 0x021e); 1026 if (err < 0) 1027 return err; 1028 1029 err = marvell_of_reg_init(phydev); 1030 if (err < 0) 1031 return err; 1032 1033 /* Reset address */ 1034 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1035 if (err < 0) 1036 return err; 1037 1038 return genphy_soft_reset(phydev); 1039 } 1040 1041 static int m88e1149_config_init(struct phy_device *phydev) 1042 { 1043 int err; 1044 1045 /* Change address */ 1046 err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE); 1047 if (err < 0) 1048 return err; 1049 1050 /* Enable 1000 Mbit */ 1051 err = phy_write(phydev, 0x15, 0x1048); 1052 if (err < 0) 1053 return err; 1054 1055 err = marvell_of_reg_init(phydev); 1056 if (err < 0) 1057 return err; 1058 1059 /* Reset address */ 1060 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1061 if (err < 0) 1062 return err; 1063 1064 return genphy_soft_reset(phydev); 1065 } 1066 1067 static int m88e1145_config_init_rgmii(struct phy_device *phydev) 1068 { 1069 int err; 1070 1071 err = m88e1111_config_init_rgmii_delays(phydev); 1072 if (err < 0) 1073 return err; 1074 1075 if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) { 1076 err = phy_write(phydev, 0x1d, 0x0012); 1077 if (err < 0) 1078 return err; 1079 1080 err = phy_modify(phydev, 0x1e, 0x0fc0, 1081 2 << 9 | /* 36 ohm */ 1082 2 << 6); /* 39 ohm */ 1083 if (err < 0) 1084 return err; 1085 1086 err = phy_write(phydev, 0x1d, 0x3); 1087 if (err < 0) 1088 return err; 1089 1090 err = phy_write(phydev, 0x1e, 0x8000); 1091 } 1092 return err; 1093 } 1094 1095 static int m88e1145_config_init_sgmii(struct phy_device *phydev) 1096 { 1097 return m88e1111_config_init_hwcfg_mode( 1098 phydev, MII_M1111_HWCFG_MODE_SGMII_NO_CLK, 1099 MII_M1111_HWCFG_FIBER_COPPER_AUTO); 1100 } 1101 1102 static int m88e1145_config_init(struct phy_device *phydev) 1103 { 1104 int err; 1105 1106 /* Take care of errata E0 & E1 */ 1107 err = phy_write(phydev, 0x1d, 0x001b); 1108 if (err < 0) 1109 return err; 1110 1111 err = phy_write(phydev, 0x1e, 0x418f); 1112 if (err < 0) 1113 return err; 1114 1115 err = phy_write(phydev, 0x1d, 0x0016); 1116 if (err < 0) 1117 return err; 1118 1119 err = phy_write(phydev, 0x1e, 0xa2da); 1120 if (err < 0) 1121 return err; 1122 1123 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 1124 err = m88e1145_config_init_rgmii(phydev); 1125 if (err < 0) 1126 return err; 1127 } 1128 1129 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 1130 err = m88e1145_config_init_sgmii(phydev); 1131 if (err < 0) 1132 return err; 1133 } 1134 1135 err = marvell_of_reg_init(phydev); 1136 if (err < 0) 1137 return err; 1138 1139 return 0; 1140 } 1141 1142 static int m88e1540_get_fld(struct phy_device *phydev, u8 *msecs) 1143 { 1144 int val; 1145 1146 val = phy_read(phydev, MII_88E1540_COPPER_CTRL3); 1147 if (val < 0) 1148 return val; 1149 1150 if (!(val & MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN)) { 1151 *msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF; 1152 return 0; 1153 } 1154 1155 val = FIELD_GET(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val); 1156 1157 switch (val) { 1158 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS: 1159 *msecs = 0; 1160 break; 1161 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS: 1162 *msecs = 10; 1163 break; 1164 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS: 1165 *msecs = 20; 1166 break; 1167 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS: 1168 *msecs = 40; 1169 break; 1170 default: 1171 return -EINVAL; 1172 } 1173 1174 return 0; 1175 } 1176 1177 static int m88e1540_set_fld(struct phy_device *phydev, const u8 *msecs) 1178 { 1179 struct ethtool_eee eee; 1180 int val, ret; 1181 1182 if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF) 1183 return phy_clear_bits(phydev, MII_88E1540_COPPER_CTRL3, 1184 MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN); 1185 1186 /* According to the Marvell data sheet EEE must be disabled for 1187 * Fast Link Down detection to work properly 1188 */ 1189 ret = phy_ethtool_get_eee(phydev, &eee); 1190 if (!ret && eee.eee_enabled) { 1191 phydev_warn(phydev, "Fast Link Down detection requires EEE to be disabled!\n"); 1192 return -EBUSY; 1193 } 1194 1195 if (*msecs <= 5) 1196 val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS; 1197 else if (*msecs <= 15) 1198 val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS; 1199 else if (*msecs <= 30) 1200 val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS; 1201 else 1202 val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS; 1203 1204 val = FIELD_PREP(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val); 1205 1206 ret = phy_modify(phydev, MII_88E1540_COPPER_CTRL3, 1207 MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val); 1208 if (ret) 1209 return ret; 1210 1211 return phy_set_bits(phydev, MII_88E1540_COPPER_CTRL3, 1212 MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN); 1213 } 1214 1215 static int m88e1540_get_tunable(struct phy_device *phydev, 1216 struct ethtool_tunable *tuna, void *data) 1217 { 1218 switch (tuna->id) { 1219 case ETHTOOL_PHY_FAST_LINK_DOWN: 1220 return m88e1540_get_fld(phydev, data); 1221 case ETHTOOL_PHY_DOWNSHIFT: 1222 return m88e1011_get_downshift(phydev, data); 1223 default: 1224 return -EOPNOTSUPP; 1225 } 1226 } 1227 1228 static int m88e1540_set_tunable(struct phy_device *phydev, 1229 struct ethtool_tunable *tuna, const void *data) 1230 { 1231 switch (tuna->id) { 1232 case ETHTOOL_PHY_FAST_LINK_DOWN: 1233 return m88e1540_set_fld(phydev, data); 1234 case ETHTOOL_PHY_DOWNSHIFT: 1235 return m88e1011_set_downshift(phydev, *(const u8 *)data); 1236 default: 1237 return -EOPNOTSUPP; 1238 } 1239 } 1240 1241 /* The VOD can be out of specification on link up. Poke an 1242 * undocumented register, in an undocumented page, with a magic value 1243 * to fix this. 1244 */ 1245 static int m88e6390_errata(struct phy_device *phydev) 1246 { 1247 int err; 1248 1249 err = phy_write(phydev, MII_BMCR, 1250 BMCR_ANENABLE | BMCR_SPEED1000 | BMCR_FULLDPLX); 1251 if (err) 1252 return err; 1253 1254 usleep_range(300, 400); 1255 1256 err = phy_write_paged(phydev, 0xf8, 0x08, 0x36); 1257 if (err) 1258 return err; 1259 1260 return genphy_soft_reset(phydev); 1261 } 1262 1263 static int m88e6390_config_aneg(struct phy_device *phydev) 1264 { 1265 int err; 1266 1267 err = m88e6390_errata(phydev); 1268 if (err) 1269 return err; 1270 1271 return m88e1510_config_aneg(phydev); 1272 } 1273 1274 /** 1275 * fiber_lpa_mod_linkmode_lpa_t 1276 * @advertising: the linkmode advertisement settings 1277 * @lpa: value of the MII_LPA register for fiber link 1278 * 1279 * A small helper function that translates MII_LPA bits to linkmode LP 1280 * advertisement settings. Other bits in advertising are left 1281 * unchanged. 1282 */ 1283 static void fiber_lpa_mod_linkmode_lpa_t(unsigned long *advertising, u32 lpa) 1284 { 1285 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, 1286 advertising, lpa & LPA_1000XHALF); 1287 1288 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 1289 advertising, lpa & LPA_1000XFULL); 1290 } 1291 1292 static int marvell_read_status_page_an(struct phy_device *phydev, 1293 int fiber, int status) 1294 { 1295 int lpa; 1296 int err; 1297 1298 if (!(status & MII_M1011_PHY_STATUS_RESOLVED)) { 1299 phydev->link = 0; 1300 return 0; 1301 } 1302 1303 if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) 1304 phydev->duplex = DUPLEX_FULL; 1305 else 1306 phydev->duplex = DUPLEX_HALF; 1307 1308 switch (status & MII_M1011_PHY_STATUS_SPD_MASK) { 1309 case MII_M1011_PHY_STATUS_1000: 1310 phydev->speed = SPEED_1000; 1311 break; 1312 1313 case MII_M1011_PHY_STATUS_100: 1314 phydev->speed = SPEED_100; 1315 break; 1316 1317 default: 1318 phydev->speed = SPEED_10; 1319 break; 1320 } 1321 1322 if (!fiber) { 1323 err = genphy_read_lpa(phydev); 1324 if (err < 0) 1325 return err; 1326 1327 phy_resolve_aneg_pause(phydev); 1328 } else { 1329 lpa = phy_read(phydev, MII_LPA); 1330 if (lpa < 0) 1331 return lpa; 1332 1333 /* The fiber link is only 1000M capable */ 1334 fiber_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); 1335 1336 if (phydev->duplex == DUPLEX_FULL) { 1337 if (!(lpa & LPA_PAUSE_FIBER)) { 1338 phydev->pause = 0; 1339 phydev->asym_pause = 0; 1340 } else if ((lpa & LPA_PAUSE_ASYM_FIBER)) { 1341 phydev->pause = 1; 1342 phydev->asym_pause = 1; 1343 } else { 1344 phydev->pause = 1; 1345 phydev->asym_pause = 0; 1346 } 1347 } 1348 } 1349 1350 return 0; 1351 } 1352 1353 /* marvell_read_status_page 1354 * 1355 * Description: 1356 * Check the link, then figure out the current state 1357 * by comparing what we advertise with what the link partner 1358 * advertises. Start by checking the gigabit possibilities, 1359 * then move on to 10/100. 1360 */ 1361 static int marvell_read_status_page(struct phy_device *phydev, int page) 1362 { 1363 int status; 1364 int fiber; 1365 int err; 1366 1367 status = phy_read(phydev, MII_M1011_PHY_STATUS); 1368 if (status < 0) 1369 return status; 1370 1371 /* Use the generic register for copper link status, 1372 * and the PHY status register for fiber link status. 1373 */ 1374 if (page == MII_MARVELL_FIBER_PAGE) { 1375 phydev->link = !!(status & MII_M1011_PHY_STATUS_LINK); 1376 } else { 1377 err = genphy_update_link(phydev); 1378 if (err) 1379 return err; 1380 } 1381 1382 if (page == MII_MARVELL_FIBER_PAGE) 1383 fiber = 1; 1384 else 1385 fiber = 0; 1386 1387 linkmode_zero(phydev->lp_advertising); 1388 phydev->pause = 0; 1389 phydev->asym_pause = 0; 1390 phydev->speed = SPEED_UNKNOWN; 1391 phydev->duplex = DUPLEX_UNKNOWN; 1392 1393 if (phydev->autoneg == AUTONEG_ENABLE) 1394 err = marvell_read_status_page_an(phydev, fiber, status); 1395 else 1396 err = genphy_read_status_fixed(phydev); 1397 1398 return err; 1399 } 1400 1401 /* marvell_read_status 1402 * 1403 * Some Marvell's phys have two modes: fiber and copper. 1404 * Both need status checked. 1405 * Description: 1406 * First, check the fiber link and status. 1407 * If the fiber link is down, check the copper link and status which 1408 * will be the default value if both link are down. 1409 */ 1410 static int marvell_read_status(struct phy_device *phydev) 1411 { 1412 int err; 1413 1414 /* Check the fiber mode first */ 1415 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 1416 phydev->supported) && 1417 phydev->interface != PHY_INTERFACE_MODE_SGMII) { 1418 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 1419 if (err < 0) 1420 goto error; 1421 1422 err = marvell_read_status_page(phydev, MII_MARVELL_FIBER_PAGE); 1423 if (err < 0) 1424 goto error; 1425 1426 /* If the fiber link is up, it is the selected and 1427 * used link. In this case, we need to stay in the 1428 * fiber page. Please to be careful about that, avoid 1429 * to restore Copper page in other functions which 1430 * could break the behaviour for some fiber phy like 1431 * 88E1512. 1432 */ 1433 if (phydev->link) 1434 return 0; 1435 1436 /* If fiber link is down, check and save copper mode state */ 1437 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1438 if (err < 0) 1439 goto error; 1440 } 1441 1442 return marvell_read_status_page(phydev, MII_MARVELL_COPPER_PAGE); 1443 1444 error: 1445 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1446 return err; 1447 } 1448 1449 /* marvell_suspend 1450 * 1451 * Some Marvell's phys have two modes: fiber and copper. 1452 * Both need to be suspended 1453 */ 1454 static int marvell_suspend(struct phy_device *phydev) 1455 { 1456 int err; 1457 1458 /* Suspend the fiber mode first */ 1459 if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 1460 phydev->supported)) { 1461 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 1462 if (err < 0) 1463 goto error; 1464 1465 /* With the page set, use the generic suspend */ 1466 err = genphy_suspend(phydev); 1467 if (err < 0) 1468 goto error; 1469 1470 /* Then, the copper link */ 1471 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1472 if (err < 0) 1473 goto error; 1474 } 1475 1476 /* With the page set, use the generic suspend */ 1477 return genphy_suspend(phydev); 1478 1479 error: 1480 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1481 return err; 1482 } 1483 1484 /* marvell_resume 1485 * 1486 * Some Marvell's phys have two modes: fiber and copper. 1487 * Both need to be resumed 1488 */ 1489 static int marvell_resume(struct phy_device *phydev) 1490 { 1491 int err; 1492 1493 /* Resume the fiber mode first */ 1494 if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 1495 phydev->supported)) { 1496 err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); 1497 if (err < 0) 1498 goto error; 1499 1500 /* With the page set, use the generic resume */ 1501 err = genphy_resume(phydev); 1502 if (err < 0) 1503 goto error; 1504 1505 /* Then, the copper link */ 1506 err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1507 if (err < 0) 1508 goto error; 1509 } 1510 1511 /* With the page set, use the generic resume */ 1512 return genphy_resume(phydev); 1513 1514 error: 1515 marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); 1516 return err; 1517 } 1518 1519 static int marvell_aneg_done(struct phy_device *phydev) 1520 { 1521 int retval = phy_read(phydev, MII_M1011_PHY_STATUS); 1522 1523 return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED); 1524 } 1525 1526 static int m88e1121_did_interrupt(struct phy_device *phydev) 1527 { 1528 int imask; 1529 1530 imask = phy_read(phydev, MII_M1011_IEVENT); 1531 1532 if (imask & MII_M1011_IMASK_INIT) 1533 return 1; 1534 1535 return 0; 1536 } 1537 1538 static void m88e1318_get_wol(struct phy_device *phydev, 1539 struct ethtool_wolinfo *wol) 1540 { 1541 int oldpage, ret = 0; 1542 1543 wol->supported = WAKE_MAGIC; 1544 wol->wolopts = 0; 1545 1546 oldpage = phy_select_page(phydev, MII_MARVELL_WOL_PAGE); 1547 if (oldpage < 0) 1548 goto error; 1549 1550 ret = __phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); 1551 if (ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE) 1552 wol->wolopts |= WAKE_MAGIC; 1553 1554 error: 1555 phy_restore_page(phydev, oldpage, ret); 1556 } 1557 1558 static int m88e1318_set_wol(struct phy_device *phydev, 1559 struct ethtool_wolinfo *wol) 1560 { 1561 int err = 0, oldpage; 1562 1563 oldpage = phy_save_page(phydev); 1564 if (oldpage < 0) 1565 goto error; 1566 1567 if (wol->wolopts & WAKE_MAGIC) { 1568 /* Explicitly switch to page 0x00, just to be sure */ 1569 err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE); 1570 if (err < 0) 1571 goto error; 1572 1573 /* If WOL event happened once, the LED[2] interrupt pin 1574 * will not be cleared unless we reading the interrupt status 1575 * register. If interrupts are in use, the normal interrupt 1576 * handling will clear the WOL event. Clear the WOL event 1577 * before enabling it if !phy_interrupt_is_valid() 1578 */ 1579 if (!phy_interrupt_is_valid(phydev)) 1580 __phy_read(phydev, MII_M1011_IEVENT); 1581 1582 /* Enable the WOL interrupt */ 1583 err = __phy_modify(phydev, MII_88E1318S_PHY_CSIER, 0, 1584 MII_88E1318S_PHY_CSIER_WOL_EIE); 1585 if (err < 0) 1586 goto error; 1587 1588 err = marvell_write_page(phydev, MII_MARVELL_LED_PAGE); 1589 if (err < 0) 1590 goto error; 1591 1592 /* Setup LED[2] as interrupt pin (active low) */ 1593 err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR, 1594 MII_88E1318S_PHY_LED_TCR_FORCE_INT, 1595 MII_88E1318S_PHY_LED_TCR_INTn_ENABLE | 1596 MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW); 1597 if (err < 0) 1598 goto error; 1599 1600 err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE); 1601 if (err < 0) 1602 goto error; 1603 1604 /* Store the device address for the magic packet */ 1605 err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2, 1606 ((phydev->attached_dev->dev_addr[5] << 8) | 1607 phydev->attached_dev->dev_addr[4])); 1608 if (err < 0) 1609 goto error; 1610 err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1, 1611 ((phydev->attached_dev->dev_addr[3] << 8) | 1612 phydev->attached_dev->dev_addr[2])); 1613 if (err < 0) 1614 goto error; 1615 err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0, 1616 ((phydev->attached_dev->dev_addr[1] << 8) | 1617 phydev->attached_dev->dev_addr[0])); 1618 if (err < 0) 1619 goto error; 1620 1621 /* Clear WOL status and enable magic packet matching */ 1622 err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0, 1623 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS | 1624 MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE); 1625 if (err < 0) 1626 goto error; 1627 } else { 1628 err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE); 1629 if (err < 0) 1630 goto error; 1631 1632 /* Clear WOL status and disable magic packet matching */ 1633 err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 1634 MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE, 1635 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS); 1636 if (err < 0) 1637 goto error; 1638 } 1639 1640 error: 1641 return phy_restore_page(phydev, oldpage, err); 1642 } 1643 1644 static int marvell_get_sset_count(struct phy_device *phydev) 1645 { 1646 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 1647 phydev->supported)) 1648 return ARRAY_SIZE(marvell_hw_stats); 1649 else 1650 return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS; 1651 } 1652 1653 static void marvell_get_strings(struct phy_device *phydev, u8 *data) 1654 { 1655 int count = marvell_get_sset_count(phydev); 1656 int i; 1657 1658 for (i = 0; i < count; i++) { 1659 strlcpy(data + i * ETH_GSTRING_LEN, 1660 marvell_hw_stats[i].string, ETH_GSTRING_LEN); 1661 } 1662 } 1663 1664 static u64 marvell_get_stat(struct phy_device *phydev, int i) 1665 { 1666 struct marvell_hw_stat stat = marvell_hw_stats[i]; 1667 struct marvell_priv *priv = phydev->priv; 1668 int val; 1669 u64 ret; 1670 1671 val = phy_read_paged(phydev, stat.page, stat.reg); 1672 if (val < 0) { 1673 ret = U64_MAX; 1674 } else { 1675 val = val & ((1 << stat.bits) - 1); 1676 priv->stats[i] += val; 1677 ret = priv->stats[i]; 1678 } 1679 1680 return ret; 1681 } 1682 1683 static void marvell_get_stats(struct phy_device *phydev, 1684 struct ethtool_stats *stats, u64 *data) 1685 { 1686 int count = marvell_get_sset_count(phydev); 1687 int i; 1688 1689 for (i = 0; i < count; i++) 1690 data[i] = marvell_get_stat(phydev, i); 1691 } 1692 1693 static int marvell_vct7_cable_test_start(struct phy_device *phydev) 1694 { 1695 int bmcr, bmsr, ret; 1696 1697 /* If auto-negotiation is enabled, but not complete, the cable 1698 * test never completes. So disable auto-neg. 1699 */ 1700 bmcr = phy_read(phydev, MII_BMCR); 1701 if (bmcr < 0) 1702 return bmcr; 1703 1704 bmsr = phy_read(phydev, MII_BMSR); 1705 1706 if (bmsr < 0) 1707 return bmsr; 1708 1709 if (bmcr & BMCR_ANENABLE) { 1710 ret = phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0); 1711 if (ret < 0) 1712 return ret; 1713 ret = genphy_soft_reset(phydev); 1714 if (ret < 0) 1715 return ret; 1716 } 1717 1718 /* If the link is up, allow it some time to go down */ 1719 if (bmsr & BMSR_LSTATUS) 1720 msleep(1500); 1721 1722 return phy_write_paged(phydev, MII_MARVELL_VCT7_PAGE, 1723 MII_VCT7_CTRL, 1724 MII_VCT7_CTRL_RUN_NOW | 1725 MII_VCT7_CTRL_CENTIMETERS); 1726 } 1727 1728 static int marvell_vct7_distance_to_length(int distance, bool meter) 1729 { 1730 if (meter) 1731 distance *= 100; 1732 1733 return distance; 1734 } 1735 1736 static bool marvell_vct7_distance_valid(int result) 1737 { 1738 switch (result) { 1739 case MII_VCT7_RESULTS_OPEN: 1740 case MII_VCT7_RESULTS_SAME_SHORT: 1741 case MII_VCT7_RESULTS_CROSS_SHORT: 1742 return true; 1743 } 1744 return false; 1745 } 1746 1747 static int marvell_vct7_report_length(struct phy_device *phydev, 1748 int pair, bool meter) 1749 { 1750 int length; 1751 int ret; 1752 1753 ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE, 1754 MII_VCT7_PAIR_0_DISTANCE + pair); 1755 if (ret < 0) 1756 return ret; 1757 1758 length = marvell_vct7_distance_to_length(ret, meter); 1759 1760 ethnl_cable_test_fault_length(phydev, pair, length); 1761 1762 return 0; 1763 } 1764 1765 static int marvell_vct7_cable_test_report_trans(int result) 1766 { 1767 switch (result) { 1768 case MII_VCT7_RESULTS_OK: 1769 return ETHTOOL_A_CABLE_RESULT_CODE_OK; 1770 case MII_VCT7_RESULTS_OPEN: 1771 return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; 1772 case MII_VCT7_RESULTS_SAME_SHORT: 1773 return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; 1774 case MII_VCT7_RESULTS_CROSS_SHORT: 1775 return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; 1776 default: 1777 return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; 1778 } 1779 } 1780 1781 static int marvell_vct7_cable_test_report(struct phy_device *phydev) 1782 { 1783 int pair0, pair1, pair2, pair3; 1784 bool meter; 1785 int ret; 1786 1787 ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE, 1788 MII_VCT7_RESULTS); 1789 if (ret < 0) 1790 return ret; 1791 1792 pair3 = (ret & MII_VCT7_RESULTS_PAIR3_MASK) >> 1793 MII_VCT7_RESULTS_PAIR3_SHIFT; 1794 pair2 = (ret & MII_VCT7_RESULTS_PAIR2_MASK) >> 1795 MII_VCT7_RESULTS_PAIR2_SHIFT; 1796 pair1 = (ret & MII_VCT7_RESULTS_PAIR1_MASK) >> 1797 MII_VCT7_RESULTS_PAIR1_SHIFT; 1798 pair0 = (ret & MII_VCT7_RESULTS_PAIR0_MASK) >> 1799 MII_VCT7_RESULTS_PAIR0_SHIFT; 1800 1801 ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, 1802 marvell_vct7_cable_test_report_trans(pair0)); 1803 ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B, 1804 marvell_vct7_cable_test_report_trans(pair1)); 1805 ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C, 1806 marvell_vct7_cable_test_report_trans(pair2)); 1807 ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D, 1808 marvell_vct7_cable_test_report_trans(pair3)); 1809 1810 ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE, MII_VCT7_CTRL); 1811 if (ret < 0) 1812 return ret; 1813 1814 meter = ret & MII_VCT7_CTRL_METERS; 1815 1816 if (marvell_vct7_distance_valid(pair0)) 1817 marvell_vct7_report_length(phydev, 0, meter); 1818 if (marvell_vct7_distance_valid(pair1)) 1819 marvell_vct7_report_length(phydev, 1, meter); 1820 if (marvell_vct7_distance_valid(pair2)) 1821 marvell_vct7_report_length(phydev, 2, meter); 1822 if (marvell_vct7_distance_valid(pair3)) 1823 marvell_vct7_report_length(phydev, 3, meter); 1824 1825 return 0; 1826 } 1827 1828 static int marvell_vct7_cable_test_get_status(struct phy_device *phydev, 1829 bool *finished) 1830 { 1831 int ret; 1832 1833 *finished = false; 1834 1835 ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE, 1836 MII_VCT7_CTRL); 1837 1838 if (ret < 0) 1839 return ret; 1840 1841 if (!(ret & MII_VCT7_CTRL_IN_PROGRESS)) { 1842 *finished = true; 1843 1844 return marvell_vct7_cable_test_report(phydev); 1845 } 1846 1847 return 0; 1848 } 1849 1850 #ifdef CONFIG_HWMON 1851 static int m88e1121_get_temp(struct phy_device *phydev, long *temp) 1852 { 1853 int oldpage; 1854 int ret = 0; 1855 int val; 1856 1857 *temp = 0; 1858 1859 oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE); 1860 if (oldpage < 0) 1861 goto error; 1862 1863 /* Enable temperature sensor */ 1864 ret = __phy_read(phydev, MII_88E1121_MISC_TEST); 1865 if (ret < 0) 1866 goto error; 1867 1868 ret = __phy_write(phydev, MII_88E1121_MISC_TEST, 1869 ret | MII_88E1121_MISC_TEST_TEMP_SENSOR_EN); 1870 if (ret < 0) 1871 goto error; 1872 1873 /* Wait for temperature to stabilize */ 1874 usleep_range(10000, 12000); 1875 1876 val = __phy_read(phydev, MII_88E1121_MISC_TEST); 1877 if (val < 0) { 1878 ret = val; 1879 goto error; 1880 } 1881 1882 /* Disable temperature sensor */ 1883 ret = __phy_write(phydev, MII_88E1121_MISC_TEST, 1884 ret & ~MII_88E1121_MISC_TEST_TEMP_SENSOR_EN); 1885 if (ret < 0) 1886 goto error; 1887 1888 *temp = ((val & MII_88E1121_MISC_TEST_TEMP_MASK) - 5) * 5000; 1889 1890 error: 1891 return phy_restore_page(phydev, oldpage, ret); 1892 } 1893 1894 static int m88e1121_hwmon_read(struct device *dev, 1895 enum hwmon_sensor_types type, 1896 u32 attr, int channel, long *temp) 1897 { 1898 struct phy_device *phydev = dev_get_drvdata(dev); 1899 int err; 1900 1901 switch (attr) { 1902 case hwmon_temp_input: 1903 err = m88e1121_get_temp(phydev, temp); 1904 break; 1905 default: 1906 return -EOPNOTSUPP; 1907 } 1908 1909 return err; 1910 } 1911 1912 static umode_t m88e1121_hwmon_is_visible(const void *data, 1913 enum hwmon_sensor_types type, 1914 u32 attr, int channel) 1915 { 1916 if (type != hwmon_temp) 1917 return 0; 1918 1919 switch (attr) { 1920 case hwmon_temp_input: 1921 return 0444; 1922 default: 1923 return 0; 1924 } 1925 } 1926 1927 static u32 m88e1121_hwmon_chip_config[] = { 1928 HWMON_C_REGISTER_TZ, 1929 0 1930 }; 1931 1932 static const struct hwmon_channel_info m88e1121_hwmon_chip = { 1933 .type = hwmon_chip, 1934 .config = m88e1121_hwmon_chip_config, 1935 }; 1936 1937 static u32 m88e1121_hwmon_temp_config[] = { 1938 HWMON_T_INPUT, 1939 0 1940 }; 1941 1942 static const struct hwmon_channel_info m88e1121_hwmon_temp = { 1943 .type = hwmon_temp, 1944 .config = m88e1121_hwmon_temp_config, 1945 }; 1946 1947 static const struct hwmon_channel_info *m88e1121_hwmon_info[] = { 1948 &m88e1121_hwmon_chip, 1949 &m88e1121_hwmon_temp, 1950 NULL 1951 }; 1952 1953 static const struct hwmon_ops m88e1121_hwmon_hwmon_ops = { 1954 .is_visible = m88e1121_hwmon_is_visible, 1955 .read = m88e1121_hwmon_read, 1956 }; 1957 1958 static const struct hwmon_chip_info m88e1121_hwmon_chip_info = { 1959 .ops = &m88e1121_hwmon_hwmon_ops, 1960 .info = m88e1121_hwmon_info, 1961 }; 1962 1963 static int m88e1510_get_temp(struct phy_device *phydev, long *temp) 1964 { 1965 int ret; 1966 1967 *temp = 0; 1968 1969 ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 1970 MII_88E1510_TEMP_SENSOR); 1971 if (ret < 0) 1972 return ret; 1973 1974 *temp = ((ret & MII_88E1510_TEMP_SENSOR_MASK) - 25) * 1000; 1975 1976 return 0; 1977 } 1978 1979 static int m88e1510_get_temp_critical(struct phy_device *phydev, long *temp) 1980 { 1981 int ret; 1982 1983 *temp = 0; 1984 1985 ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 1986 MII_88E1121_MISC_TEST); 1987 if (ret < 0) 1988 return ret; 1989 1990 *temp = (((ret & MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK) >> 1991 MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT) * 5) - 25; 1992 /* convert to mC */ 1993 *temp *= 1000; 1994 1995 return 0; 1996 } 1997 1998 static int m88e1510_set_temp_critical(struct phy_device *phydev, long temp) 1999 { 2000 temp = temp / 1000; 2001 temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f); 2002 2003 return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 2004 MII_88E1121_MISC_TEST, 2005 MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK, 2006 temp << MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT); 2007 } 2008 2009 static int m88e1510_get_temp_alarm(struct phy_device *phydev, long *alarm) 2010 { 2011 int ret; 2012 2013 *alarm = false; 2014 2015 ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE, 2016 MII_88E1121_MISC_TEST); 2017 if (ret < 0) 2018 return ret; 2019 2020 *alarm = !!(ret & MII_88E1510_MISC_TEST_TEMP_IRQ); 2021 2022 return 0; 2023 } 2024 2025 static int m88e1510_hwmon_read(struct device *dev, 2026 enum hwmon_sensor_types type, 2027 u32 attr, int channel, long *temp) 2028 { 2029 struct phy_device *phydev = dev_get_drvdata(dev); 2030 int err; 2031 2032 switch (attr) { 2033 case hwmon_temp_input: 2034 err = m88e1510_get_temp(phydev, temp); 2035 break; 2036 case hwmon_temp_crit: 2037 err = m88e1510_get_temp_critical(phydev, temp); 2038 break; 2039 case hwmon_temp_max_alarm: 2040 err = m88e1510_get_temp_alarm(phydev, temp); 2041 break; 2042 default: 2043 return -EOPNOTSUPP; 2044 } 2045 2046 return err; 2047 } 2048 2049 static int m88e1510_hwmon_write(struct device *dev, 2050 enum hwmon_sensor_types type, 2051 u32 attr, int channel, long temp) 2052 { 2053 struct phy_device *phydev = dev_get_drvdata(dev); 2054 int err; 2055 2056 switch (attr) { 2057 case hwmon_temp_crit: 2058 err = m88e1510_set_temp_critical(phydev, temp); 2059 break; 2060 default: 2061 return -EOPNOTSUPP; 2062 } 2063 return err; 2064 } 2065 2066 static umode_t m88e1510_hwmon_is_visible(const void *data, 2067 enum hwmon_sensor_types type, 2068 u32 attr, int channel) 2069 { 2070 if (type != hwmon_temp) 2071 return 0; 2072 2073 switch (attr) { 2074 case hwmon_temp_input: 2075 case hwmon_temp_max_alarm: 2076 return 0444; 2077 case hwmon_temp_crit: 2078 return 0644; 2079 default: 2080 return 0; 2081 } 2082 } 2083 2084 static u32 m88e1510_hwmon_temp_config[] = { 2085 HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM, 2086 0 2087 }; 2088 2089 static const struct hwmon_channel_info m88e1510_hwmon_temp = { 2090 .type = hwmon_temp, 2091 .config = m88e1510_hwmon_temp_config, 2092 }; 2093 2094 static const struct hwmon_channel_info *m88e1510_hwmon_info[] = { 2095 &m88e1121_hwmon_chip, 2096 &m88e1510_hwmon_temp, 2097 NULL 2098 }; 2099 2100 static const struct hwmon_ops m88e1510_hwmon_hwmon_ops = { 2101 .is_visible = m88e1510_hwmon_is_visible, 2102 .read = m88e1510_hwmon_read, 2103 .write = m88e1510_hwmon_write, 2104 }; 2105 2106 static const struct hwmon_chip_info m88e1510_hwmon_chip_info = { 2107 .ops = &m88e1510_hwmon_hwmon_ops, 2108 .info = m88e1510_hwmon_info, 2109 }; 2110 2111 static int m88e6390_get_temp(struct phy_device *phydev, long *temp) 2112 { 2113 int sum = 0; 2114 int oldpage; 2115 int ret = 0; 2116 int i; 2117 2118 *temp = 0; 2119 2120 oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE); 2121 if (oldpage < 0) 2122 goto error; 2123 2124 /* Enable temperature sensor */ 2125 ret = __phy_read(phydev, MII_88E6390_MISC_TEST); 2126 if (ret < 0) 2127 goto error; 2128 2129 ret = ret & ~MII_88E6390_MISC_TEST_SAMPLE_MASK; 2130 ret |= MII_88E6390_MISC_TEST_SAMPLE_ENABLE | 2131 MII_88E6390_MISC_TEST_SAMPLE_1S; 2132 2133 ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret); 2134 if (ret < 0) 2135 goto error; 2136 2137 /* Wait for temperature to stabilize */ 2138 usleep_range(10000, 12000); 2139 2140 /* Reading the temperature sense has an errata. You need to read 2141 * a number of times and take an average. 2142 */ 2143 for (i = 0; i < MII_88E6390_TEMP_SENSOR_SAMPLES; i++) { 2144 ret = __phy_read(phydev, MII_88E6390_TEMP_SENSOR); 2145 if (ret < 0) 2146 goto error; 2147 sum += ret & MII_88E6390_TEMP_SENSOR_MASK; 2148 } 2149 2150 sum /= MII_88E6390_TEMP_SENSOR_SAMPLES; 2151 *temp = (sum - 75) * 1000; 2152 2153 /* Disable temperature sensor */ 2154 ret = __phy_read(phydev, MII_88E6390_MISC_TEST); 2155 if (ret < 0) 2156 goto error; 2157 2158 ret = ret & ~MII_88E6390_MISC_TEST_SAMPLE_MASK; 2159 ret |= MII_88E6390_MISC_TEST_SAMPLE_DISABLE; 2160 2161 ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret); 2162 2163 error: 2164 phy_restore_page(phydev, oldpage, ret); 2165 2166 return ret; 2167 } 2168 2169 static int m88e6390_hwmon_read(struct device *dev, 2170 enum hwmon_sensor_types type, 2171 u32 attr, int channel, long *temp) 2172 { 2173 struct phy_device *phydev = dev_get_drvdata(dev); 2174 int err; 2175 2176 switch (attr) { 2177 case hwmon_temp_input: 2178 err = m88e6390_get_temp(phydev, temp); 2179 break; 2180 default: 2181 return -EOPNOTSUPP; 2182 } 2183 2184 return err; 2185 } 2186 2187 static umode_t m88e6390_hwmon_is_visible(const void *data, 2188 enum hwmon_sensor_types type, 2189 u32 attr, int channel) 2190 { 2191 if (type != hwmon_temp) 2192 return 0; 2193 2194 switch (attr) { 2195 case hwmon_temp_input: 2196 return 0444; 2197 default: 2198 return 0; 2199 } 2200 } 2201 2202 static u32 m88e6390_hwmon_temp_config[] = { 2203 HWMON_T_INPUT, 2204 0 2205 }; 2206 2207 static const struct hwmon_channel_info m88e6390_hwmon_temp = { 2208 .type = hwmon_temp, 2209 .config = m88e6390_hwmon_temp_config, 2210 }; 2211 2212 static const struct hwmon_channel_info *m88e6390_hwmon_info[] = { 2213 &m88e1121_hwmon_chip, 2214 &m88e6390_hwmon_temp, 2215 NULL 2216 }; 2217 2218 static const struct hwmon_ops m88e6390_hwmon_hwmon_ops = { 2219 .is_visible = m88e6390_hwmon_is_visible, 2220 .read = m88e6390_hwmon_read, 2221 }; 2222 2223 static const struct hwmon_chip_info m88e6390_hwmon_chip_info = { 2224 .ops = &m88e6390_hwmon_hwmon_ops, 2225 .info = m88e6390_hwmon_info, 2226 }; 2227 2228 static int marvell_hwmon_name(struct phy_device *phydev) 2229 { 2230 struct marvell_priv *priv = phydev->priv; 2231 struct device *dev = &phydev->mdio.dev; 2232 const char *devname = dev_name(dev); 2233 size_t len = strlen(devname); 2234 int i, j; 2235 2236 priv->hwmon_name = devm_kzalloc(dev, len, GFP_KERNEL); 2237 if (!priv->hwmon_name) 2238 return -ENOMEM; 2239 2240 for (i = j = 0; i < len && devname[i]; i++) { 2241 if (isalnum(devname[i])) 2242 priv->hwmon_name[j++] = devname[i]; 2243 } 2244 2245 return 0; 2246 } 2247 2248 static int marvell_hwmon_probe(struct phy_device *phydev, 2249 const struct hwmon_chip_info *chip) 2250 { 2251 struct marvell_priv *priv = phydev->priv; 2252 struct device *dev = &phydev->mdio.dev; 2253 int err; 2254 2255 err = marvell_hwmon_name(phydev); 2256 if (err) 2257 return err; 2258 2259 priv->hwmon_dev = devm_hwmon_device_register_with_info( 2260 dev, priv->hwmon_name, phydev, chip, NULL); 2261 2262 return PTR_ERR_OR_ZERO(priv->hwmon_dev); 2263 } 2264 2265 static int m88e1121_hwmon_probe(struct phy_device *phydev) 2266 { 2267 return marvell_hwmon_probe(phydev, &m88e1121_hwmon_chip_info); 2268 } 2269 2270 static int m88e1510_hwmon_probe(struct phy_device *phydev) 2271 { 2272 return marvell_hwmon_probe(phydev, &m88e1510_hwmon_chip_info); 2273 } 2274 2275 static int m88e6390_hwmon_probe(struct phy_device *phydev) 2276 { 2277 return marvell_hwmon_probe(phydev, &m88e6390_hwmon_chip_info); 2278 } 2279 #else 2280 static int m88e1121_hwmon_probe(struct phy_device *phydev) 2281 { 2282 return 0; 2283 } 2284 2285 static int m88e1510_hwmon_probe(struct phy_device *phydev) 2286 { 2287 return 0; 2288 } 2289 2290 static int m88e6390_hwmon_probe(struct phy_device *phydev) 2291 { 2292 return 0; 2293 } 2294 #endif 2295 2296 static int marvell_probe(struct phy_device *phydev) 2297 { 2298 struct marvell_priv *priv; 2299 2300 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 2301 if (!priv) 2302 return -ENOMEM; 2303 2304 phydev->priv = priv; 2305 2306 return 0; 2307 } 2308 2309 static int m88e1121_probe(struct phy_device *phydev) 2310 { 2311 int err; 2312 2313 err = marvell_probe(phydev); 2314 if (err) 2315 return err; 2316 2317 return m88e1121_hwmon_probe(phydev); 2318 } 2319 2320 static int m88e1510_probe(struct phy_device *phydev) 2321 { 2322 int err; 2323 2324 err = marvell_probe(phydev); 2325 if (err) 2326 return err; 2327 2328 return m88e1510_hwmon_probe(phydev); 2329 } 2330 2331 static int m88e6390_probe(struct phy_device *phydev) 2332 { 2333 int err; 2334 2335 err = marvell_probe(phydev); 2336 if (err) 2337 return err; 2338 2339 return m88e6390_hwmon_probe(phydev); 2340 } 2341 2342 static struct phy_driver marvell_drivers[] = { 2343 { 2344 .phy_id = MARVELL_PHY_ID_88E1101, 2345 .phy_id_mask = MARVELL_PHY_ID_MASK, 2346 .name = "Marvell 88E1101", 2347 /* PHY_GBIT_FEATURES */ 2348 .probe = marvell_probe, 2349 .config_init = &marvell_config_init, 2350 .config_aneg = &m88e1101_config_aneg, 2351 .ack_interrupt = &marvell_ack_interrupt, 2352 .config_intr = &marvell_config_intr, 2353 .resume = &genphy_resume, 2354 .suspend = &genphy_suspend, 2355 .read_page = marvell_read_page, 2356 .write_page = marvell_write_page, 2357 .get_sset_count = marvell_get_sset_count, 2358 .get_strings = marvell_get_strings, 2359 .get_stats = marvell_get_stats, 2360 }, 2361 { 2362 .phy_id = MARVELL_PHY_ID_88E1112, 2363 .phy_id_mask = MARVELL_PHY_ID_MASK, 2364 .name = "Marvell 88E1112", 2365 /* PHY_GBIT_FEATURES */ 2366 .probe = marvell_probe, 2367 .config_init = &m88e1111_config_init, 2368 .config_aneg = &marvell_config_aneg, 2369 .ack_interrupt = &marvell_ack_interrupt, 2370 .config_intr = &marvell_config_intr, 2371 .resume = &genphy_resume, 2372 .suspend = &genphy_suspend, 2373 .read_page = marvell_read_page, 2374 .write_page = marvell_write_page, 2375 .get_sset_count = marvell_get_sset_count, 2376 .get_strings = marvell_get_strings, 2377 .get_stats = marvell_get_stats, 2378 .get_tunable = m88e1011_get_tunable, 2379 .set_tunable = m88e1011_set_tunable, 2380 }, 2381 { 2382 .phy_id = MARVELL_PHY_ID_88E1111, 2383 .phy_id_mask = MARVELL_PHY_ID_MASK, 2384 .name = "Marvell 88E1111", 2385 /* PHY_GBIT_FEATURES */ 2386 .probe = marvell_probe, 2387 .config_init = &m88e1111_config_init, 2388 .config_aneg = &marvell_config_aneg, 2389 .read_status = &marvell_read_status, 2390 .ack_interrupt = &marvell_ack_interrupt, 2391 .config_intr = &marvell_config_intr, 2392 .resume = &genphy_resume, 2393 .suspend = &genphy_suspend, 2394 .read_page = marvell_read_page, 2395 .write_page = marvell_write_page, 2396 .get_sset_count = marvell_get_sset_count, 2397 .get_strings = marvell_get_strings, 2398 .get_stats = marvell_get_stats, 2399 .get_tunable = m88e1111_get_tunable, 2400 .set_tunable = m88e1111_set_tunable, 2401 }, 2402 { 2403 .phy_id = MARVELL_PHY_ID_88E1118, 2404 .phy_id_mask = MARVELL_PHY_ID_MASK, 2405 .name = "Marvell 88E1118", 2406 /* PHY_GBIT_FEATURES */ 2407 .probe = marvell_probe, 2408 .config_init = &m88e1118_config_init, 2409 .config_aneg = &m88e1118_config_aneg, 2410 .ack_interrupt = &marvell_ack_interrupt, 2411 .config_intr = &marvell_config_intr, 2412 .resume = &genphy_resume, 2413 .suspend = &genphy_suspend, 2414 .read_page = marvell_read_page, 2415 .write_page = marvell_write_page, 2416 .get_sset_count = marvell_get_sset_count, 2417 .get_strings = marvell_get_strings, 2418 .get_stats = marvell_get_stats, 2419 }, 2420 { 2421 .phy_id = MARVELL_PHY_ID_88E1121R, 2422 .phy_id_mask = MARVELL_PHY_ID_MASK, 2423 .name = "Marvell 88E1121R", 2424 /* PHY_GBIT_FEATURES */ 2425 .probe = &m88e1121_probe, 2426 .config_init = &marvell_config_init, 2427 .config_aneg = &m88e1121_config_aneg, 2428 .read_status = &marvell_read_status, 2429 .ack_interrupt = &marvell_ack_interrupt, 2430 .config_intr = &marvell_config_intr, 2431 .did_interrupt = &m88e1121_did_interrupt, 2432 .resume = &genphy_resume, 2433 .suspend = &genphy_suspend, 2434 .read_page = marvell_read_page, 2435 .write_page = marvell_write_page, 2436 .get_sset_count = marvell_get_sset_count, 2437 .get_strings = marvell_get_strings, 2438 .get_stats = marvell_get_stats, 2439 .get_tunable = m88e1011_get_tunable, 2440 .set_tunable = m88e1011_set_tunable, 2441 }, 2442 { 2443 .phy_id = MARVELL_PHY_ID_88E1318S, 2444 .phy_id_mask = MARVELL_PHY_ID_MASK, 2445 .name = "Marvell 88E1318S", 2446 /* PHY_GBIT_FEATURES */ 2447 .probe = marvell_probe, 2448 .config_init = &m88e1318_config_init, 2449 .config_aneg = &m88e1318_config_aneg, 2450 .read_status = &marvell_read_status, 2451 .ack_interrupt = &marvell_ack_interrupt, 2452 .config_intr = &marvell_config_intr, 2453 .did_interrupt = &m88e1121_did_interrupt, 2454 .get_wol = &m88e1318_get_wol, 2455 .set_wol = &m88e1318_set_wol, 2456 .resume = &genphy_resume, 2457 .suspend = &genphy_suspend, 2458 .read_page = marvell_read_page, 2459 .write_page = marvell_write_page, 2460 .get_sset_count = marvell_get_sset_count, 2461 .get_strings = marvell_get_strings, 2462 .get_stats = marvell_get_stats, 2463 }, 2464 { 2465 .phy_id = MARVELL_PHY_ID_88E1145, 2466 .phy_id_mask = MARVELL_PHY_ID_MASK, 2467 .name = "Marvell 88E1145", 2468 /* PHY_GBIT_FEATURES */ 2469 .probe = marvell_probe, 2470 .config_init = &m88e1145_config_init, 2471 .config_aneg = &m88e1101_config_aneg, 2472 .read_status = &genphy_read_status, 2473 .ack_interrupt = &marvell_ack_interrupt, 2474 .config_intr = &marvell_config_intr, 2475 .resume = &genphy_resume, 2476 .suspend = &genphy_suspend, 2477 .read_page = marvell_read_page, 2478 .write_page = marvell_write_page, 2479 .get_sset_count = marvell_get_sset_count, 2480 .get_strings = marvell_get_strings, 2481 .get_stats = marvell_get_stats, 2482 .get_tunable = m88e1111_get_tunable, 2483 .set_tunable = m88e1111_set_tunable, 2484 }, 2485 { 2486 .phy_id = MARVELL_PHY_ID_88E1149R, 2487 .phy_id_mask = MARVELL_PHY_ID_MASK, 2488 .name = "Marvell 88E1149R", 2489 /* PHY_GBIT_FEATURES */ 2490 .probe = marvell_probe, 2491 .config_init = &m88e1149_config_init, 2492 .config_aneg = &m88e1118_config_aneg, 2493 .ack_interrupt = &marvell_ack_interrupt, 2494 .config_intr = &marvell_config_intr, 2495 .resume = &genphy_resume, 2496 .suspend = &genphy_suspend, 2497 .read_page = marvell_read_page, 2498 .write_page = marvell_write_page, 2499 .get_sset_count = marvell_get_sset_count, 2500 .get_strings = marvell_get_strings, 2501 .get_stats = marvell_get_stats, 2502 }, 2503 { 2504 .phy_id = MARVELL_PHY_ID_88E1240, 2505 .phy_id_mask = MARVELL_PHY_ID_MASK, 2506 .name = "Marvell 88E1240", 2507 /* PHY_GBIT_FEATURES */ 2508 .probe = marvell_probe, 2509 .config_init = &m88e1111_config_init, 2510 .config_aneg = &marvell_config_aneg, 2511 .ack_interrupt = &marvell_ack_interrupt, 2512 .config_intr = &marvell_config_intr, 2513 .resume = &genphy_resume, 2514 .suspend = &genphy_suspend, 2515 .read_page = marvell_read_page, 2516 .write_page = marvell_write_page, 2517 .get_sset_count = marvell_get_sset_count, 2518 .get_strings = marvell_get_strings, 2519 .get_stats = marvell_get_stats, 2520 }, 2521 { 2522 .phy_id = MARVELL_PHY_ID_88E1116R, 2523 .phy_id_mask = MARVELL_PHY_ID_MASK, 2524 .name = "Marvell 88E1116R", 2525 /* PHY_GBIT_FEATURES */ 2526 .probe = marvell_probe, 2527 .config_init = &m88e1116r_config_init, 2528 .ack_interrupt = &marvell_ack_interrupt, 2529 .config_intr = &marvell_config_intr, 2530 .resume = &genphy_resume, 2531 .suspend = &genphy_suspend, 2532 .read_page = marvell_read_page, 2533 .write_page = marvell_write_page, 2534 .get_sset_count = marvell_get_sset_count, 2535 .get_strings = marvell_get_strings, 2536 .get_stats = marvell_get_stats, 2537 .get_tunable = m88e1011_get_tunable, 2538 .set_tunable = m88e1011_set_tunable, 2539 }, 2540 { 2541 .phy_id = MARVELL_PHY_ID_88E1510, 2542 .phy_id_mask = MARVELL_PHY_ID_MASK, 2543 .name = "Marvell 88E1510", 2544 .features = PHY_GBIT_FIBRE_FEATURES, 2545 .flags = PHY_POLL_CABLE_TEST, 2546 .probe = &m88e1510_probe, 2547 .config_init = &m88e1510_config_init, 2548 .config_aneg = &m88e1510_config_aneg, 2549 .read_status = &marvell_read_status, 2550 .ack_interrupt = &marvell_ack_interrupt, 2551 .config_intr = &marvell_config_intr, 2552 .did_interrupt = &m88e1121_did_interrupt, 2553 .get_wol = &m88e1318_get_wol, 2554 .set_wol = &m88e1318_set_wol, 2555 .resume = &marvell_resume, 2556 .suspend = &marvell_suspend, 2557 .read_page = marvell_read_page, 2558 .write_page = marvell_write_page, 2559 .get_sset_count = marvell_get_sset_count, 2560 .get_strings = marvell_get_strings, 2561 .get_stats = marvell_get_stats, 2562 .set_loopback = genphy_loopback, 2563 .get_tunable = m88e1011_get_tunable, 2564 .set_tunable = m88e1011_set_tunable, 2565 .cable_test_start = marvell_vct7_cable_test_start, 2566 .cable_test_get_status = marvell_vct7_cable_test_get_status, 2567 }, 2568 { 2569 .phy_id = MARVELL_PHY_ID_88E1540, 2570 .phy_id_mask = MARVELL_PHY_ID_MASK, 2571 .name = "Marvell 88E1540", 2572 /* PHY_GBIT_FEATURES */ 2573 .flags = PHY_POLL_CABLE_TEST, 2574 .probe = m88e1510_probe, 2575 .config_init = &marvell_config_init, 2576 .config_aneg = &m88e1510_config_aneg, 2577 .read_status = &marvell_read_status, 2578 .ack_interrupt = &marvell_ack_interrupt, 2579 .config_intr = &marvell_config_intr, 2580 .did_interrupt = &m88e1121_did_interrupt, 2581 .resume = &genphy_resume, 2582 .suspend = &genphy_suspend, 2583 .read_page = marvell_read_page, 2584 .write_page = marvell_write_page, 2585 .get_sset_count = marvell_get_sset_count, 2586 .get_strings = marvell_get_strings, 2587 .get_stats = marvell_get_stats, 2588 .get_tunable = m88e1540_get_tunable, 2589 .set_tunable = m88e1540_set_tunable, 2590 .cable_test_start = marvell_vct7_cable_test_start, 2591 .cable_test_get_status = marvell_vct7_cable_test_get_status, 2592 }, 2593 { 2594 .phy_id = MARVELL_PHY_ID_88E1545, 2595 .phy_id_mask = MARVELL_PHY_ID_MASK, 2596 .name = "Marvell 88E1545", 2597 .probe = m88e1510_probe, 2598 /* PHY_GBIT_FEATURES */ 2599 .flags = PHY_POLL_CABLE_TEST, 2600 .config_init = &marvell_config_init, 2601 .config_aneg = &m88e1510_config_aneg, 2602 .read_status = &marvell_read_status, 2603 .ack_interrupt = &marvell_ack_interrupt, 2604 .config_intr = &marvell_config_intr, 2605 .did_interrupt = &m88e1121_did_interrupt, 2606 .resume = &genphy_resume, 2607 .suspend = &genphy_suspend, 2608 .read_page = marvell_read_page, 2609 .write_page = marvell_write_page, 2610 .get_sset_count = marvell_get_sset_count, 2611 .get_strings = marvell_get_strings, 2612 .get_stats = marvell_get_stats, 2613 .get_tunable = m88e1540_get_tunable, 2614 .set_tunable = m88e1540_set_tunable, 2615 .cable_test_start = marvell_vct7_cable_test_start, 2616 .cable_test_get_status = marvell_vct7_cable_test_get_status, 2617 }, 2618 { 2619 .phy_id = MARVELL_PHY_ID_88E3016, 2620 .phy_id_mask = MARVELL_PHY_ID_MASK, 2621 .name = "Marvell 88E3016", 2622 /* PHY_BASIC_FEATURES */ 2623 .probe = marvell_probe, 2624 .config_init = &m88e3016_config_init, 2625 .aneg_done = &marvell_aneg_done, 2626 .read_status = &marvell_read_status, 2627 .ack_interrupt = &marvell_ack_interrupt, 2628 .config_intr = &marvell_config_intr, 2629 .did_interrupt = &m88e1121_did_interrupt, 2630 .resume = &genphy_resume, 2631 .suspend = &genphy_suspend, 2632 .read_page = marvell_read_page, 2633 .write_page = marvell_write_page, 2634 .get_sset_count = marvell_get_sset_count, 2635 .get_strings = marvell_get_strings, 2636 .get_stats = marvell_get_stats, 2637 }, 2638 { 2639 .phy_id = MARVELL_PHY_ID_88E6390, 2640 .phy_id_mask = MARVELL_PHY_ID_MASK, 2641 .name = "Marvell 88E6390", 2642 /* PHY_GBIT_FEATURES */ 2643 .flags = PHY_POLL_CABLE_TEST, 2644 .probe = m88e6390_probe, 2645 .config_init = &marvell_config_init, 2646 .config_aneg = &m88e6390_config_aneg, 2647 .read_status = &marvell_read_status, 2648 .ack_interrupt = &marvell_ack_interrupt, 2649 .config_intr = &marvell_config_intr, 2650 .did_interrupt = &m88e1121_did_interrupt, 2651 .resume = &genphy_resume, 2652 .suspend = &genphy_suspend, 2653 .read_page = marvell_read_page, 2654 .write_page = marvell_write_page, 2655 .get_sset_count = marvell_get_sset_count, 2656 .get_strings = marvell_get_strings, 2657 .get_stats = marvell_get_stats, 2658 .get_tunable = m88e1540_get_tunable, 2659 .set_tunable = m88e1540_set_tunable, 2660 .cable_test_start = marvell_vct7_cable_test_start, 2661 .cable_test_get_status = marvell_vct7_cable_test_get_status, 2662 }, 2663 }; 2664 2665 module_phy_driver(marvell_drivers); 2666 2667 static struct mdio_device_id __maybe_unused marvell_tbl[] = { 2668 { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK }, 2669 { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK }, 2670 { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK }, 2671 { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK }, 2672 { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK }, 2673 { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, 2674 { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, 2675 { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, 2676 { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, 2677 { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, 2678 { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, 2679 { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK }, 2680 { MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK }, 2681 { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK }, 2682 { MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK }, 2683 { } 2684 }; 2685 2686 MODULE_DEVICE_TABLE(mdio, marvell_tbl); 2687