Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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