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