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