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