1 /* 2 * drivers/net/phy/marvell.c 3 * 4 * Driver for Marvell PHYs 5 * 6 * Author: Andy Fleming 7 * 8 * Copyright (c) 2004 Freescale Semiconductor, Inc. 9 * 10 * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de> 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License as published by the 14 * Free Software Foundation; either version 2 of the License, or (at your 15 * option) any later version. 16 * 17 */ 18 #include <linux/kernel.h> 19 #include <linux/string.h> 20 #include <linux/errno.h> 21 #include <linux/unistd.h> 22 #include <linux/interrupt.h> 23 #include <linux/init.h> 24 #include <linux/delay.h> 25 #include <linux/netdevice.h> 26 #include <linux/etherdevice.h> 27 #include <linux/skbuff.h> 28 #include <linux/spinlock.h> 29 #include <linux/mm.h> 30 #include <linux/module.h> 31 #include <linux/mii.h> 32 #include <linux/ethtool.h> 33 #include <linux/phy.h> 34 #include <linux/marvell_phy.h> 35 #include <linux/of.h> 36 37 #include <linux/io.h> 38 #include <asm/irq.h> 39 #include <linux/uaccess.h> 40 41 #define MII_MARVELL_PHY_PAGE 22 42 43 #define MII_M1011_IEVENT 0x13 44 #define MII_M1011_IEVENT_CLEAR 0x0000 45 46 #define MII_M1011_IMASK 0x12 47 #define MII_M1011_IMASK_INIT 0x6400 48 #define MII_M1011_IMASK_CLEAR 0x0000 49 50 #define MII_M1011_PHY_SCR 0x10 51 #define MII_M1011_PHY_SCR_MDI 0x0000 52 #define MII_M1011_PHY_SCR_MDI_X 0x0020 53 #define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 54 55 #define MII_M1145_PHY_EXT_ADDR_PAGE 0x16 56 #define MII_M1145_PHY_EXT_SR 0x1b 57 #define MII_M1145_PHY_EXT_CR 0x14 58 #define MII_M1145_RGMII_RX_DELAY 0x0080 59 #define MII_M1145_RGMII_TX_DELAY 0x0002 60 #define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 61 #define MII_M1145_HWCFG_MODE_MASK 0xf 62 #define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000 63 64 #define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 65 #define MII_M1145_HWCFG_MODE_MASK 0xf 66 #define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000 67 68 #define MII_M1111_PHY_LED_CONTROL 0x18 69 #define MII_M1111_PHY_LED_DIRECT 0x4100 70 #define MII_M1111_PHY_LED_COMBINE 0x411c 71 #define MII_M1111_PHY_EXT_CR 0x14 72 #define MII_M1111_RX_DELAY 0x80 73 #define MII_M1111_TX_DELAY 0x2 74 #define MII_M1111_PHY_EXT_SR 0x1b 75 76 #define MII_M1111_HWCFG_MODE_MASK 0xf 77 #define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb 78 #define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 79 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 80 #define MII_M1111_HWCFG_MODE_COPPER_RTBI 0x9 81 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO 0x8000 82 #define MII_M1111_HWCFG_FIBER_COPPER_RES 0x2000 83 84 #define MII_M1111_COPPER 0 85 #define MII_M1111_FIBER 1 86 87 #define MII_88E1121_PHY_MSCR_PAGE 2 88 #define MII_88E1121_PHY_MSCR_REG 21 89 #define MII_88E1121_PHY_MSCR_RX_DELAY BIT(5) 90 #define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4) 91 #define MII_88E1121_PHY_MSCR_DELAY_MASK (~(0x3 << 4)) 92 93 #define MII_88E1318S_PHY_MSCR1_REG 16 94 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6) 95 96 /* Copper Specific Interrupt Enable Register */ 97 #define MII_88E1318S_PHY_CSIER 0x12 98 /* WOL Event Interrupt Enable */ 99 #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) 100 101 /* LED Timer Control Register */ 102 #define MII_88E1318S_PHY_LED_PAGE 0x03 103 #define MII_88E1318S_PHY_LED_TCR 0x12 104 #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) 105 #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) 106 #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) 107 108 /* Magic Packet MAC address registers */ 109 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 110 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1 0x18 111 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0 0x19 112 113 #define MII_88E1318S_PHY_WOL_PAGE 0x11 114 #define MII_88E1318S_PHY_WOL_CTRL 0x10 115 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS BIT(12) 116 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14) 117 118 #define MII_88E1121_PHY_LED_CTRL 16 119 #define MII_88E1121_PHY_LED_PAGE 3 120 #define MII_88E1121_PHY_LED_DEF 0x0030 121 122 #define MII_M1011_PHY_STATUS 0x11 123 #define MII_M1011_PHY_STATUS_1000 0x8000 124 #define MII_M1011_PHY_STATUS_100 0x4000 125 #define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 126 #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 127 #define MII_M1011_PHY_STATUS_RESOLVED 0x0800 128 #define MII_M1011_PHY_STATUS_LINK 0x0400 129 130 #define MII_M1116R_CONTROL_REG_MAC 21 131 132 #define MII_88E3016_PHY_SPEC_CTRL 0x10 133 #define MII_88E3016_DISABLE_SCRAMBLER 0x0200 134 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030 135 136 #define MII_88E1510_GEN_CTRL_REG_1 0x14 137 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7 138 #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1 /* SGMII to copper */ 139 #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */ 140 141 MODULE_DESCRIPTION("Marvell PHY driver"); 142 MODULE_AUTHOR("Andy Fleming"); 143 MODULE_LICENSE("GPL"); 144 145 struct marvell_hw_stat { 146 const char *string; 147 u8 page; 148 u8 reg; 149 u8 bits; 150 }; 151 152 static struct marvell_hw_stat marvell_hw_stats[] = { 153 { "phy_receive_errors", 0, 21, 16}, 154 { "phy_idle_errors", 0, 10, 8 }, 155 }; 156 157 struct marvell_priv { 158 u64 stats[ARRAY_SIZE(marvell_hw_stats)]; 159 }; 160 161 static int marvell_ack_interrupt(struct phy_device *phydev) 162 { 163 int err; 164 165 /* Clear the interrupts by reading the reg */ 166 err = phy_read(phydev, MII_M1011_IEVENT); 167 168 if (err < 0) 169 return err; 170 171 return 0; 172 } 173 174 static int marvell_config_intr(struct phy_device *phydev) 175 { 176 int err; 177 178 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 179 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 180 else 181 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 182 183 return err; 184 } 185 186 static int marvell_set_polarity(struct phy_device *phydev, int polarity) 187 { 188 int reg; 189 int err; 190 int val; 191 192 /* get the current settings */ 193 reg = phy_read(phydev, MII_M1011_PHY_SCR); 194 if (reg < 0) 195 return reg; 196 197 val = reg; 198 val &= ~MII_M1011_PHY_SCR_AUTO_CROSS; 199 switch (polarity) { 200 case ETH_TP_MDI: 201 val |= MII_M1011_PHY_SCR_MDI; 202 break; 203 case ETH_TP_MDI_X: 204 val |= MII_M1011_PHY_SCR_MDI_X; 205 break; 206 case ETH_TP_MDI_AUTO: 207 case ETH_TP_MDI_INVALID: 208 default: 209 val |= MII_M1011_PHY_SCR_AUTO_CROSS; 210 break; 211 } 212 213 if (val != reg) { 214 /* Set the new polarity value in the register */ 215 err = phy_write(phydev, MII_M1011_PHY_SCR, val); 216 if (err) 217 return err; 218 } 219 220 return 0; 221 } 222 223 static int marvell_config_aneg(struct phy_device *phydev) 224 { 225 int err; 226 227 /* The Marvell PHY has an errata which requires 228 * that certain registers get written in order 229 * to restart autonegotiation */ 230 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 231 232 if (err < 0) 233 return err; 234 235 err = phy_write(phydev, 0x1d, 0x1f); 236 if (err < 0) 237 return err; 238 239 err = phy_write(phydev, 0x1e, 0x200c); 240 if (err < 0) 241 return err; 242 243 err = phy_write(phydev, 0x1d, 0x5); 244 if (err < 0) 245 return err; 246 247 err = phy_write(phydev, 0x1e, 0); 248 if (err < 0) 249 return err; 250 251 err = phy_write(phydev, 0x1e, 0x100); 252 if (err < 0) 253 return err; 254 255 err = marvell_set_polarity(phydev, phydev->mdix); 256 if (err < 0) 257 return err; 258 259 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, 260 MII_M1111_PHY_LED_DIRECT); 261 if (err < 0) 262 return err; 263 264 err = genphy_config_aneg(phydev); 265 if (err < 0) 266 return err; 267 268 if (phydev->autoneg != AUTONEG_ENABLE) { 269 int bmcr; 270 271 /* 272 * A write to speed/duplex bits (that is performed by 273 * genphy_config_aneg() call above) must be followed by 274 * a software reset. Otherwise, the write has no effect. 275 */ 276 bmcr = phy_read(phydev, MII_BMCR); 277 if (bmcr < 0) 278 return bmcr; 279 280 err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET); 281 if (err < 0) 282 return err; 283 } 284 285 return 0; 286 } 287 288 #ifdef CONFIG_OF_MDIO 289 /* 290 * Set and/or override some configuration registers based on the 291 * marvell,reg-init property stored in the of_node for the phydev. 292 * 293 * marvell,reg-init = <reg-page reg mask value>,...; 294 * 295 * There may be one or more sets of <reg-page reg mask value>: 296 * 297 * reg-page: which register bank to use. 298 * reg: the register. 299 * mask: if non-zero, ANDed with existing register value. 300 * value: ORed with the masked value and written to the regiser. 301 * 302 */ 303 static int marvell_of_reg_init(struct phy_device *phydev) 304 { 305 const __be32 *paddr; 306 int len, i, saved_page, current_page, page_changed, ret; 307 308 if (!phydev->mdio.dev.of_node) 309 return 0; 310 311 paddr = of_get_property(phydev->mdio.dev.of_node, 312 "marvell,reg-init", &len); 313 if (!paddr || len < (4 * sizeof(*paddr))) 314 return 0; 315 316 saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE); 317 if (saved_page < 0) 318 return saved_page; 319 page_changed = 0; 320 current_page = saved_page; 321 322 ret = 0; 323 len /= sizeof(*paddr); 324 for (i = 0; i < len - 3; i += 4) { 325 u16 reg_page = be32_to_cpup(paddr + i); 326 u16 reg = be32_to_cpup(paddr + i + 1); 327 u16 mask = be32_to_cpup(paddr + i + 2); 328 u16 val_bits = be32_to_cpup(paddr + i + 3); 329 int val; 330 331 if (reg_page != current_page) { 332 current_page = reg_page; 333 page_changed = 1; 334 ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page); 335 if (ret < 0) 336 goto err; 337 } 338 339 val = 0; 340 if (mask) { 341 val = phy_read(phydev, reg); 342 if (val < 0) { 343 ret = val; 344 goto err; 345 } 346 val &= mask; 347 } 348 val |= val_bits; 349 350 ret = phy_write(phydev, reg, val); 351 if (ret < 0) 352 goto err; 353 354 } 355 err: 356 if (page_changed) { 357 i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page); 358 if (ret == 0) 359 ret = i; 360 } 361 return ret; 362 } 363 #else 364 static int marvell_of_reg_init(struct phy_device *phydev) 365 { 366 return 0; 367 } 368 #endif /* CONFIG_OF_MDIO */ 369 370 static int m88e1121_config_aneg(struct phy_device *phydev) 371 { 372 int err, oldpage, mscr; 373 374 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 375 376 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 377 MII_88E1121_PHY_MSCR_PAGE); 378 if (err < 0) 379 return err; 380 381 if (phy_interface_is_rgmii(phydev)) { 382 383 mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & 384 MII_88E1121_PHY_MSCR_DELAY_MASK; 385 386 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 387 mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | 388 MII_88E1121_PHY_MSCR_TX_DELAY); 389 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 390 mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; 391 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 392 mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; 393 394 err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); 395 if (err < 0) 396 return err; 397 } 398 399 phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 400 401 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 402 if (err < 0) 403 return err; 404 405 err = phy_write(phydev, MII_M1011_PHY_SCR, 406 MII_M1011_PHY_SCR_AUTO_CROSS); 407 if (err < 0) 408 return err; 409 410 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 411 412 phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); 413 phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); 414 phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 415 416 err = genphy_config_aneg(phydev); 417 418 return err; 419 } 420 421 static int m88e1318_config_aneg(struct phy_device *phydev) 422 { 423 int err, oldpage, mscr; 424 425 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 426 427 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 428 MII_88E1121_PHY_MSCR_PAGE); 429 if (err < 0) 430 return err; 431 432 mscr = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG); 433 mscr |= MII_88E1318S_PHY_MSCR1_PAD_ODD; 434 435 err = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, mscr); 436 if (err < 0) 437 return err; 438 439 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 440 if (err < 0) 441 return err; 442 443 return m88e1121_config_aneg(phydev); 444 } 445 446 static int m88e1510_config_aneg(struct phy_device *phydev) 447 { 448 int err; 449 450 err = m88e1318_config_aneg(phydev); 451 if (err < 0) 452 return err; 453 454 return 0; 455 } 456 457 static int marvell_config_init(struct phy_device *phydev) 458 { 459 /* Set registers from marvell,reg-init DT property */ 460 return marvell_of_reg_init(phydev); 461 } 462 463 static int m88e1116r_config_init(struct phy_device *phydev) 464 { 465 int temp; 466 int err; 467 468 temp = phy_read(phydev, MII_BMCR); 469 temp |= BMCR_RESET; 470 err = phy_write(phydev, MII_BMCR, temp); 471 if (err < 0) 472 return err; 473 474 mdelay(500); 475 476 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0); 477 if (err < 0) 478 return err; 479 480 temp = phy_read(phydev, MII_M1011_PHY_SCR); 481 temp |= (7 << 12); /* max number of gigabit attempts */ 482 temp |= (1 << 11); /* enable downshift */ 483 temp |= MII_M1011_PHY_SCR_AUTO_CROSS; 484 err = phy_write(phydev, MII_M1011_PHY_SCR, temp); 485 if (err < 0) 486 return err; 487 488 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 2); 489 if (err < 0) 490 return err; 491 temp = phy_read(phydev, MII_M1116R_CONTROL_REG_MAC); 492 temp |= (1 << 5); 493 temp |= (1 << 4); 494 err = phy_write(phydev, MII_M1116R_CONTROL_REG_MAC, temp); 495 if (err < 0) 496 return err; 497 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0); 498 if (err < 0) 499 return err; 500 501 temp = phy_read(phydev, MII_BMCR); 502 temp |= BMCR_RESET; 503 err = phy_write(phydev, MII_BMCR, temp); 504 if (err < 0) 505 return err; 506 507 mdelay(500); 508 509 return marvell_config_init(phydev); 510 } 511 512 static int m88e3016_config_init(struct phy_device *phydev) 513 { 514 int reg; 515 516 /* Enable Scrambler and Auto-Crossover */ 517 reg = phy_read(phydev, MII_88E3016_PHY_SPEC_CTRL); 518 if (reg < 0) 519 return reg; 520 521 reg &= ~MII_88E3016_DISABLE_SCRAMBLER; 522 reg |= MII_88E3016_AUTO_MDIX_CROSSOVER; 523 524 reg = phy_write(phydev, MII_88E3016_PHY_SPEC_CTRL, reg); 525 if (reg < 0) 526 return reg; 527 528 return marvell_config_init(phydev); 529 } 530 531 static int m88e1111_config_init(struct phy_device *phydev) 532 { 533 int err; 534 int temp; 535 536 if (phy_interface_is_rgmii(phydev)) { 537 538 temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); 539 if (temp < 0) 540 return temp; 541 542 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 543 temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); 544 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 545 temp &= ~MII_M1111_TX_DELAY; 546 temp |= MII_M1111_RX_DELAY; 547 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 548 temp &= ~MII_M1111_RX_DELAY; 549 temp |= MII_M1111_TX_DELAY; 550 } 551 552 err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); 553 if (err < 0) 554 return err; 555 556 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 557 if (temp < 0) 558 return temp; 559 560 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 561 562 if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES) 563 temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; 564 else 565 temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; 566 567 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 568 if (err < 0) 569 return err; 570 } 571 572 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 573 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 574 if (temp < 0) 575 return temp; 576 577 temp &= ~(MII_M1111_HWCFG_MODE_MASK); 578 temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK; 579 temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; 580 581 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 582 if (err < 0) 583 return err; 584 585 /* make sure copper is selected */ 586 err = phy_read(phydev, MII_M1145_PHY_EXT_ADDR_PAGE); 587 if (err < 0) 588 return err; 589 590 err = phy_write(phydev, MII_M1145_PHY_EXT_ADDR_PAGE, 591 err & (~0xff)); 592 if (err < 0) 593 return err; 594 } 595 596 if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { 597 temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); 598 if (temp < 0) 599 return temp; 600 temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); 601 err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); 602 if (err < 0) 603 return err; 604 605 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 606 if (temp < 0) 607 return temp; 608 temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); 609 temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO; 610 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 611 if (err < 0) 612 return err; 613 614 /* soft reset */ 615 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 616 if (err < 0) 617 return err; 618 do 619 temp = phy_read(phydev, MII_BMCR); 620 while (temp & BMCR_RESET); 621 622 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); 623 if (temp < 0) 624 return temp; 625 temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); 626 temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO; 627 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); 628 if (err < 0) 629 return err; 630 } 631 632 err = marvell_of_reg_init(phydev); 633 if (err < 0) 634 return err; 635 636 return phy_write(phydev, MII_BMCR, BMCR_RESET); 637 } 638 639 static int m88e1510_config_init(struct phy_device *phydev) 640 { 641 int err; 642 int temp; 643 644 /* SGMII-to-Copper mode initialization */ 645 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 646 /* Select page 18 */ 647 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18); 648 if (err < 0) 649 return err; 650 651 /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ 652 temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1); 653 temp &= ~MII_88E1510_GEN_CTRL_REG_1_MODE_MASK; 654 temp |= MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII; 655 err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); 656 if (err < 0) 657 return err; 658 659 /* PHY reset is necessary after changing MODE[2:0] */ 660 temp |= MII_88E1510_GEN_CTRL_REG_1_RESET; 661 err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); 662 if (err < 0) 663 return err; 664 665 /* Reset page selection */ 666 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0); 667 if (err < 0) 668 return err; 669 } 670 671 return marvell_config_init(phydev); 672 } 673 674 static int m88e1118_config_aneg(struct phy_device *phydev) 675 { 676 int err; 677 678 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 679 if (err < 0) 680 return err; 681 682 err = phy_write(phydev, MII_M1011_PHY_SCR, 683 MII_M1011_PHY_SCR_AUTO_CROSS); 684 if (err < 0) 685 return err; 686 687 err = genphy_config_aneg(phydev); 688 return 0; 689 } 690 691 static int m88e1118_config_init(struct phy_device *phydev) 692 { 693 int err; 694 695 /* Change address */ 696 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); 697 if (err < 0) 698 return err; 699 700 /* Enable 1000 Mbit */ 701 err = phy_write(phydev, 0x15, 0x1070); 702 if (err < 0) 703 return err; 704 705 /* Change address */ 706 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003); 707 if (err < 0) 708 return err; 709 710 /* Adjust LED Control */ 711 if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS) 712 err = phy_write(phydev, 0x10, 0x1100); 713 else 714 err = phy_write(phydev, 0x10, 0x021e); 715 if (err < 0) 716 return err; 717 718 err = marvell_of_reg_init(phydev); 719 if (err < 0) 720 return err; 721 722 /* Reset address */ 723 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); 724 if (err < 0) 725 return err; 726 727 return phy_write(phydev, MII_BMCR, BMCR_RESET); 728 } 729 730 static int m88e1149_config_init(struct phy_device *phydev) 731 { 732 int err; 733 734 /* Change address */ 735 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); 736 if (err < 0) 737 return err; 738 739 /* Enable 1000 Mbit */ 740 err = phy_write(phydev, 0x15, 0x1048); 741 if (err < 0) 742 return err; 743 744 err = marvell_of_reg_init(phydev); 745 if (err < 0) 746 return err; 747 748 /* Reset address */ 749 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); 750 if (err < 0) 751 return err; 752 753 return phy_write(phydev, MII_BMCR, BMCR_RESET); 754 } 755 756 static int m88e1145_config_init(struct phy_device *phydev) 757 { 758 int err; 759 int temp; 760 761 /* Take care of errata E0 & E1 */ 762 err = phy_write(phydev, 0x1d, 0x001b); 763 if (err < 0) 764 return err; 765 766 err = phy_write(phydev, 0x1e, 0x418f); 767 if (err < 0) 768 return err; 769 770 err = phy_write(phydev, 0x1d, 0x0016); 771 if (err < 0) 772 return err; 773 774 err = phy_write(phydev, 0x1e, 0xa2da); 775 if (err < 0) 776 return err; 777 778 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { 779 int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR); 780 if (temp < 0) 781 return temp; 782 783 temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY); 784 785 err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp); 786 if (err < 0) 787 return err; 788 789 if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) { 790 err = phy_write(phydev, 0x1d, 0x0012); 791 if (err < 0) 792 return err; 793 794 temp = phy_read(phydev, 0x1e); 795 if (temp < 0) 796 return temp; 797 798 temp &= 0xf03f; 799 temp |= 2 << 9; /* 36 ohm */ 800 temp |= 2 << 6; /* 39 ohm */ 801 802 err = phy_write(phydev, 0x1e, temp); 803 if (err < 0) 804 return err; 805 806 err = phy_write(phydev, 0x1d, 0x3); 807 if (err < 0) 808 return err; 809 810 err = phy_write(phydev, 0x1e, 0x8000); 811 if (err < 0) 812 return err; 813 } 814 } 815 816 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 817 temp = phy_read(phydev, MII_M1145_PHY_EXT_SR); 818 if (temp < 0) 819 return temp; 820 821 temp &= ~MII_M1145_HWCFG_MODE_MASK; 822 temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK; 823 temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO; 824 825 err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp); 826 if (err < 0) 827 return err; 828 } 829 830 err = marvell_of_reg_init(phydev); 831 if (err < 0) 832 return err; 833 834 return 0; 835 } 836 837 /* marvell_read_status 838 * 839 * Generic status code does not detect Fiber correctly! 840 * Description: 841 * Check the link, then figure out the current state 842 * by comparing what we advertise with what the link partner 843 * advertises. Start by checking the gigabit possibilities, 844 * then move on to 10/100. 845 */ 846 static int marvell_read_status(struct phy_device *phydev) 847 { 848 int adv; 849 int err; 850 int lpa; 851 int lpagb; 852 int status = 0; 853 854 /* Update the link, but return if there 855 * was an error */ 856 err = genphy_update_link(phydev); 857 if (err) 858 return err; 859 860 if (AUTONEG_ENABLE == phydev->autoneg) { 861 status = phy_read(phydev, MII_M1011_PHY_STATUS); 862 if (status < 0) 863 return status; 864 865 lpa = phy_read(phydev, MII_LPA); 866 if (lpa < 0) 867 return lpa; 868 869 lpagb = phy_read(phydev, MII_STAT1000); 870 if (lpagb < 0) 871 return lpagb; 872 873 adv = phy_read(phydev, MII_ADVERTISE); 874 if (adv < 0) 875 return adv; 876 877 phydev->lp_advertising = mii_stat1000_to_ethtool_lpa_t(lpagb) | 878 mii_lpa_to_ethtool_lpa_t(lpa); 879 880 lpa &= adv; 881 882 if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) 883 phydev->duplex = DUPLEX_FULL; 884 else 885 phydev->duplex = DUPLEX_HALF; 886 887 status = status & MII_M1011_PHY_STATUS_SPD_MASK; 888 phydev->pause = phydev->asym_pause = 0; 889 890 switch (status) { 891 case MII_M1011_PHY_STATUS_1000: 892 phydev->speed = SPEED_1000; 893 break; 894 895 case MII_M1011_PHY_STATUS_100: 896 phydev->speed = SPEED_100; 897 break; 898 899 default: 900 phydev->speed = SPEED_10; 901 break; 902 } 903 904 if (phydev->duplex == DUPLEX_FULL) { 905 phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; 906 phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; 907 } 908 } else { 909 int bmcr = phy_read(phydev, MII_BMCR); 910 911 if (bmcr < 0) 912 return bmcr; 913 914 if (bmcr & BMCR_FULLDPLX) 915 phydev->duplex = DUPLEX_FULL; 916 else 917 phydev->duplex = DUPLEX_HALF; 918 919 if (bmcr & BMCR_SPEED1000) 920 phydev->speed = SPEED_1000; 921 else if (bmcr & BMCR_SPEED100) 922 phydev->speed = SPEED_100; 923 else 924 phydev->speed = SPEED_10; 925 926 phydev->pause = phydev->asym_pause = 0; 927 phydev->lp_advertising = 0; 928 } 929 930 return 0; 931 } 932 933 static int marvell_aneg_done(struct phy_device *phydev) 934 { 935 int retval = phy_read(phydev, MII_M1011_PHY_STATUS); 936 return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED); 937 } 938 939 static int m88e1121_did_interrupt(struct phy_device *phydev) 940 { 941 int imask; 942 943 imask = phy_read(phydev, MII_M1011_IEVENT); 944 945 if (imask & MII_M1011_IMASK_INIT) 946 return 1; 947 948 return 0; 949 } 950 951 static void m88e1318_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) 952 { 953 wol->supported = WAKE_MAGIC; 954 wol->wolopts = 0; 955 956 if (phy_write(phydev, MII_MARVELL_PHY_PAGE, 957 MII_88E1318S_PHY_WOL_PAGE) < 0) 958 return; 959 960 if (phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL) & 961 MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE) 962 wol->wolopts |= WAKE_MAGIC; 963 964 if (phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00) < 0) 965 return; 966 } 967 968 static int m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) 969 { 970 int err, oldpage, temp; 971 972 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 973 974 if (wol->wolopts & WAKE_MAGIC) { 975 /* Explicitly switch to page 0x00, just to be sure */ 976 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00); 977 if (err < 0) 978 return err; 979 980 /* Enable the WOL interrupt */ 981 temp = phy_read(phydev, MII_88E1318S_PHY_CSIER); 982 temp |= MII_88E1318S_PHY_CSIER_WOL_EIE; 983 err = phy_write(phydev, MII_88E1318S_PHY_CSIER, temp); 984 if (err < 0) 985 return err; 986 987 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 988 MII_88E1318S_PHY_LED_PAGE); 989 if (err < 0) 990 return err; 991 992 /* Setup LED[2] as interrupt pin (active low) */ 993 temp = phy_read(phydev, MII_88E1318S_PHY_LED_TCR); 994 temp &= ~MII_88E1318S_PHY_LED_TCR_FORCE_INT; 995 temp |= MII_88E1318S_PHY_LED_TCR_INTn_ENABLE; 996 temp |= MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW; 997 err = phy_write(phydev, MII_88E1318S_PHY_LED_TCR, temp); 998 if (err < 0) 999 return err; 1000 1001 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 1002 MII_88E1318S_PHY_WOL_PAGE); 1003 if (err < 0) 1004 return err; 1005 1006 /* Store the device address for the magic packet */ 1007 err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2, 1008 ((phydev->attached_dev->dev_addr[5] << 8) | 1009 phydev->attached_dev->dev_addr[4])); 1010 if (err < 0) 1011 return err; 1012 err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1, 1013 ((phydev->attached_dev->dev_addr[3] << 8) | 1014 phydev->attached_dev->dev_addr[2])); 1015 if (err < 0) 1016 return err; 1017 err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0, 1018 ((phydev->attached_dev->dev_addr[1] << 8) | 1019 phydev->attached_dev->dev_addr[0])); 1020 if (err < 0) 1021 return err; 1022 1023 /* Clear WOL status and enable magic packet matching */ 1024 temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); 1025 temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS; 1026 temp |= MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE; 1027 err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp); 1028 if (err < 0) 1029 return err; 1030 } else { 1031 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 1032 MII_88E1318S_PHY_WOL_PAGE); 1033 if (err < 0) 1034 return err; 1035 1036 /* Clear WOL status and disable magic packet matching */ 1037 temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); 1038 temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS; 1039 temp &= ~MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE; 1040 err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp); 1041 if (err < 0) 1042 return err; 1043 } 1044 1045 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 1046 if (err < 0) 1047 return err; 1048 1049 return 0; 1050 } 1051 1052 static int marvell_get_sset_count(struct phy_device *phydev) 1053 { 1054 return ARRAY_SIZE(marvell_hw_stats); 1055 } 1056 1057 static void marvell_get_strings(struct phy_device *phydev, u8 *data) 1058 { 1059 int i; 1060 1061 for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { 1062 memcpy(data + i * ETH_GSTRING_LEN, 1063 marvell_hw_stats[i].string, ETH_GSTRING_LEN); 1064 } 1065 } 1066 1067 #ifndef UINT64_MAX 1068 #define UINT64_MAX (u64)(~((u64)0)) 1069 #endif 1070 static u64 marvell_get_stat(struct phy_device *phydev, int i) 1071 { 1072 struct marvell_hw_stat stat = marvell_hw_stats[i]; 1073 struct marvell_priv *priv = phydev->priv; 1074 int err, oldpage, val; 1075 u64 ret; 1076 1077 oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); 1078 err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 1079 stat.page); 1080 if (err < 0) 1081 return UINT64_MAX; 1082 1083 val = phy_read(phydev, stat.reg); 1084 if (val < 0) { 1085 ret = UINT64_MAX; 1086 } else { 1087 val = val & ((1 << stat.bits) - 1); 1088 priv->stats[i] += val; 1089 ret = priv->stats[i]; 1090 } 1091 1092 phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); 1093 1094 return ret; 1095 } 1096 1097 static void marvell_get_stats(struct phy_device *phydev, 1098 struct ethtool_stats *stats, u64 *data) 1099 { 1100 int i; 1101 1102 for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) 1103 data[i] = marvell_get_stat(phydev, i); 1104 } 1105 1106 static int marvell_probe(struct phy_device *phydev) 1107 { 1108 struct marvell_priv *priv; 1109 1110 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 1111 if (!priv) 1112 return -ENOMEM; 1113 1114 phydev->priv = priv; 1115 1116 return 0; 1117 } 1118 1119 static struct phy_driver marvell_drivers[] = { 1120 { 1121 .phy_id = MARVELL_PHY_ID_88E1101, 1122 .phy_id_mask = MARVELL_PHY_ID_MASK, 1123 .name = "Marvell 88E1101", 1124 .features = PHY_GBIT_FEATURES, 1125 .probe = marvell_probe, 1126 .flags = PHY_HAS_INTERRUPT, 1127 .config_init = &marvell_config_init, 1128 .config_aneg = &marvell_config_aneg, 1129 .read_status = &genphy_read_status, 1130 .ack_interrupt = &marvell_ack_interrupt, 1131 .config_intr = &marvell_config_intr, 1132 .resume = &genphy_resume, 1133 .suspend = &genphy_suspend, 1134 .get_sset_count = marvell_get_sset_count, 1135 .get_strings = marvell_get_strings, 1136 .get_stats = marvell_get_stats, 1137 }, 1138 { 1139 .phy_id = MARVELL_PHY_ID_88E1112, 1140 .phy_id_mask = MARVELL_PHY_ID_MASK, 1141 .name = "Marvell 88E1112", 1142 .features = PHY_GBIT_FEATURES, 1143 .flags = PHY_HAS_INTERRUPT, 1144 .probe = marvell_probe, 1145 .config_init = &m88e1111_config_init, 1146 .config_aneg = &marvell_config_aneg, 1147 .read_status = &genphy_read_status, 1148 .ack_interrupt = &marvell_ack_interrupt, 1149 .config_intr = &marvell_config_intr, 1150 .resume = &genphy_resume, 1151 .suspend = &genphy_suspend, 1152 .get_sset_count = marvell_get_sset_count, 1153 .get_strings = marvell_get_strings, 1154 .get_stats = marvell_get_stats, 1155 }, 1156 { 1157 .phy_id = MARVELL_PHY_ID_88E1111, 1158 .phy_id_mask = MARVELL_PHY_ID_MASK, 1159 .name = "Marvell 88E1111", 1160 .features = PHY_GBIT_FEATURES, 1161 .flags = PHY_HAS_INTERRUPT, 1162 .probe = marvell_probe, 1163 .config_init = &m88e1111_config_init, 1164 .config_aneg = &marvell_config_aneg, 1165 .read_status = &marvell_read_status, 1166 .ack_interrupt = &marvell_ack_interrupt, 1167 .config_intr = &marvell_config_intr, 1168 .resume = &genphy_resume, 1169 .suspend = &genphy_suspend, 1170 .get_sset_count = marvell_get_sset_count, 1171 .get_strings = marvell_get_strings, 1172 .get_stats = marvell_get_stats, 1173 }, 1174 { 1175 .phy_id = MARVELL_PHY_ID_88E1118, 1176 .phy_id_mask = MARVELL_PHY_ID_MASK, 1177 .name = "Marvell 88E1118", 1178 .features = PHY_GBIT_FEATURES, 1179 .flags = PHY_HAS_INTERRUPT, 1180 .probe = marvell_probe, 1181 .config_init = &m88e1118_config_init, 1182 .config_aneg = &m88e1118_config_aneg, 1183 .read_status = &genphy_read_status, 1184 .ack_interrupt = &marvell_ack_interrupt, 1185 .config_intr = &marvell_config_intr, 1186 .resume = &genphy_resume, 1187 .suspend = &genphy_suspend, 1188 .get_sset_count = marvell_get_sset_count, 1189 .get_strings = marvell_get_strings, 1190 .get_stats = marvell_get_stats, 1191 }, 1192 { 1193 .phy_id = MARVELL_PHY_ID_88E1121R, 1194 .phy_id_mask = MARVELL_PHY_ID_MASK, 1195 .name = "Marvell 88E1121R", 1196 .features = PHY_GBIT_FEATURES, 1197 .flags = PHY_HAS_INTERRUPT, 1198 .probe = marvell_probe, 1199 .config_init = &marvell_config_init, 1200 .config_aneg = &m88e1121_config_aneg, 1201 .read_status = &marvell_read_status, 1202 .ack_interrupt = &marvell_ack_interrupt, 1203 .config_intr = &marvell_config_intr, 1204 .did_interrupt = &m88e1121_did_interrupt, 1205 .resume = &genphy_resume, 1206 .suspend = &genphy_suspend, 1207 .get_sset_count = marvell_get_sset_count, 1208 .get_strings = marvell_get_strings, 1209 .get_stats = marvell_get_stats, 1210 }, 1211 { 1212 .phy_id = MARVELL_PHY_ID_88E1318S, 1213 .phy_id_mask = MARVELL_PHY_ID_MASK, 1214 .name = "Marvell 88E1318S", 1215 .features = PHY_GBIT_FEATURES, 1216 .flags = PHY_HAS_INTERRUPT, 1217 .probe = marvell_probe, 1218 .config_init = &marvell_config_init, 1219 .config_aneg = &m88e1318_config_aneg, 1220 .read_status = &marvell_read_status, 1221 .ack_interrupt = &marvell_ack_interrupt, 1222 .config_intr = &marvell_config_intr, 1223 .did_interrupt = &m88e1121_did_interrupt, 1224 .get_wol = &m88e1318_get_wol, 1225 .set_wol = &m88e1318_set_wol, 1226 .resume = &genphy_resume, 1227 .suspend = &genphy_suspend, 1228 .get_sset_count = marvell_get_sset_count, 1229 .get_strings = marvell_get_strings, 1230 .get_stats = marvell_get_stats, 1231 }, 1232 { 1233 .phy_id = MARVELL_PHY_ID_88E1145, 1234 .phy_id_mask = MARVELL_PHY_ID_MASK, 1235 .name = "Marvell 88E1145", 1236 .features = PHY_GBIT_FEATURES, 1237 .flags = PHY_HAS_INTERRUPT, 1238 .probe = marvell_probe, 1239 .config_init = &m88e1145_config_init, 1240 .config_aneg = &marvell_config_aneg, 1241 .read_status = &genphy_read_status, 1242 .ack_interrupt = &marvell_ack_interrupt, 1243 .config_intr = &marvell_config_intr, 1244 .resume = &genphy_resume, 1245 .suspend = &genphy_suspend, 1246 .get_sset_count = marvell_get_sset_count, 1247 .get_strings = marvell_get_strings, 1248 .get_stats = marvell_get_stats, 1249 }, 1250 { 1251 .phy_id = MARVELL_PHY_ID_88E1149R, 1252 .phy_id_mask = MARVELL_PHY_ID_MASK, 1253 .name = "Marvell 88E1149R", 1254 .features = PHY_GBIT_FEATURES, 1255 .flags = PHY_HAS_INTERRUPT, 1256 .probe = marvell_probe, 1257 .config_init = &m88e1149_config_init, 1258 .config_aneg = &m88e1118_config_aneg, 1259 .read_status = &genphy_read_status, 1260 .ack_interrupt = &marvell_ack_interrupt, 1261 .config_intr = &marvell_config_intr, 1262 .resume = &genphy_resume, 1263 .suspend = &genphy_suspend, 1264 .get_sset_count = marvell_get_sset_count, 1265 .get_strings = marvell_get_strings, 1266 .get_stats = marvell_get_stats, 1267 }, 1268 { 1269 .phy_id = MARVELL_PHY_ID_88E1240, 1270 .phy_id_mask = MARVELL_PHY_ID_MASK, 1271 .name = "Marvell 88E1240", 1272 .features = PHY_GBIT_FEATURES, 1273 .flags = PHY_HAS_INTERRUPT, 1274 .probe = marvell_probe, 1275 .config_init = &m88e1111_config_init, 1276 .config_aneg = &marvell_config_aneg, 1277 .read_status = &genphy_read_status, 1278 .ack_interrupt = &marvell_ack_interrupt, 1279 .config_intr = &marvell_config_intr, 1280 .resume = &genphy_resume, 1281 .suspend = &genphy_suspend, 1282 .get_sset_count = marvell_get_sset_count, 1283 .get_strings = marvell_get_strings, 1284 .get_stats = marvell_get_stats, 1285 }, 1286 { 1287 .phy_id = MARVELL_PHY_ID_88E1116R, 1288 .phy_id_mask = MARVELL_PHY_ID_MASK, 1289 .name = "Marvell 88E1116R", 1290 .features = PHY_GBIT_FEATURES, 1291 .flags = PHY_HAS_INTERRUPT, 1292 .probe = marvell_probe, 1293 .config_init = &m88e1116r_config_init, 1294 .config_aneg = &genphy_config_aneg, 1295 .read_status = &genphy_read_status, 1296 .ack_interrupt = &marvell_ack_interrupt, 1297 .config_intr = &marvell_config_intr, 1298 .resume = &genphy_resume, 1299 .suspend = &genphy_suspend, 1300 .get_sset_count = marvell_get_sset_count, 1301 .get_strings = marvell_get_strings, 1302 .get_stats = marvell_get_stats, 1303 }, 1304 { 1305 .phy_id = MARVELL_PHY_ID_88E1510, 1306 .phy_id_mask = MARVELL_PHY_ID_MASK, 1307 .name = "Marvell 88E1510", 1308 .features = PHY_GBIT_FEATURES, 1309 .flags = PHY_HAS_INTERRUPT, 1310 .probe = marvell_probe, 1311 .config_init = &m88e1510_config_init, 1312 .config_aneg = &m88e1510_config_aneg, 1313 .read_status = &marvell_read_status, 1314 .ack_interrupt = &marvell_ack_interrupt, 1315 .config_intr = &marvell_config_intr, 1316 .did_interrupt = &m88e1121_did_interrupt, 1317 .resume = &genphy_resume, 1318 .suspend = &genphy_suspend, 1319 .get_sset_count = marvell_get_sset_count, 1320 .get_strings = marvell_get_strings, 1321 .get_stats = marvell_get_stats, 1322 }, 1323 { 1324 .phy_id = MARVELL_PHY_ID_88E1540, 1325 .phy_id_mask = MARVELL_PHY_ID_MASK, 1326 .name = "Marvell 88E1540", 1327 .features = PHY_GBIT_FEATURES, 1328 .flags = PHY_HAS_INTERRUPT, 1329 .probe = marvell_probe, 1330 .config_init = &marvell_config_init, 1331 .config_aneg = &m88e1510_config_aneg, 1332 .read_status = &marvell_read_status, 1333 .ack_interrupt = &marvell_ack_interrupt, 1334 .config_intr = &marvell_config_intr, 1335 .did_interrupt = &m88e1121_did_interrupt, 1336 .resume = &genphy_resume, 1337 .suspend = &genphy_suspend, 1338 .get_sset_count = marvell_get_sset_count, 1339 .get_strings = marvell_get_strings, 1340 .get_stats = marvell_get_stats, 1341 }, 1342 { 1343 .phy_id = MARVELL_PHY_ID_88E3016, 1344 .phy_id_mask = MARVELL_PHY_ID_MASK, 1345 .name = "Marvell 88E3016", 1346 .features = PHY_BASIC_FEATURES, 1347 .flags = PHY_HAS_INTERRUPT, 1348 .probe = marvell_probe, 1349 .config_aneg = &genphy_config_aneg, 1350 .config_init = &m88e3016_config_init, 1351 .aneg_done = &marvell_aneg_done, 1352 .read_status = &marvell_read_status, 1353 .ack_interrupt = &marvell_ack_interrupt, 1354 .config_intr = &marvell_config_intr, 1355 .did_interrupt = &m88e1121_did_interrupt, 1356 .resume = &genphy_resume, 1357 .suspend = &genphy_suspend, 1358 .get_sset_count = marvell_get_sset_count, 1359 .get_strings = marvell_get_strings, 1360 .get_stats = marvell_get_stats, 1361 }, 1362 }; 1363 1364 module_phy_driver(marvell_drivers); 1365 1366 static struct mdio_device_id __maybe_unused marvell_tbl[] = { 1367 { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK }, 1368 { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK }, 1369 { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK }, 1370 { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK }, 1371 { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK }, 1372 { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, 1373 { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, 1374 { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, 1375 { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, 1376 { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, 1377 { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, 1378 { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK }, 1379 { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK }, 1380 { } 1381 }; 1382 1383 MODULE_DEVICE_TABLE(mdio, marvell_tbl); 1384