Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * drivers/net/phy/marvell.c
0004  *
0005  * Driver for Marvell PHYs
0006  *
0007  * Author: Andy Fleming
0008  *
0009  * Copyright (c) 2004 Freescale Semiconductor, Inc.
0010  *
0011  * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de>
0012  */
0013 #include <linux/kernel.h>
0014 #include <linux/string.h>
0015 #include <linux/ctype.h>
0016 #include <linux/errno.h>
0017 #include <linux/unistd.h>
0018 #include <linux/hwmon.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/init.h>
0021 #include <linux/delay.h>
0022 #include <linux/netdevice.h>
0023 #include <linux/etherdevice.h>
0024 #include <linux/skbuff.h>
0025 #include <linux/spinlock.h>
0026 #include <linux/mm.h>
0027 #include <linux/module.h>
0028 #include <linux/mii.h>
0029 #include <linux/ethtool.h>
0030 #include <linux/ethtool_netlink.h>
0031 #include <linux/phy.h>
0032 #include <linux/marvell_phy.h>
0033 #include <linux/bitfield.h>
0034 #include <linux/of.h>
0035 #include <linux/sfp.h>
0036 
0037 #include <linux/io.h>
0038 #include <asm/irq.h>
0039 #include <linux/uaccess.h>
0040 
0041 #define MII_MARVELL_PHY_PAGE        22
0042 #define MII_MARVELL_COPPER_PAGE     0x00
0043 #define MII_MARVELL_FIBER_PAGE      0x01
0044 #define MII_MARVELL_MSCR_PAGE       0x02
0045 #define MII_MARVELL_LED_PAGE        0x03
0046 #define MII_MARVELL_VCT5_PAGE       0x05
0047 #define MII_MARVELL_MISC_TEST_PAGE  0x06
0048 #define MII_MARVELL_VCT7_PAGE       0x07
0049 #define MII_MARVELL_WOL_PAGE        0x11
0050 #define MII_MARVELL_MODE_PAGE       0x12
0051 
0052 #define MII_M1011_IEVENT        0x13
0053 #define MII_M1011_IEVENT_CLEAR      0x0000
0054 
0055 #define MII_M1011_IMASK         0x12
0056 #define MII_M1011_IMASK_INIT        0x6400
0057 #define MII_M1011_IMASK_CLEAR       0x0000
0058 
0059 #define MII_M1011_PHY_SCR           0x10
0060 #define MII_M1011_PHY_SCR_DOWNSHIFT_EN      BIT(11)
0061 #define MII_M1011_PHY_SCR_DOWNSHIFT_MASK    GENMASK(14, 12)
0062 #define MII_M1011_PHY_SCR_DOWNSHIFT_MAX     8
0063 #define MII_M1011_PHY_SCR_MDI           (0x0 << 5)
0064 #define MII_M1011_PHY_SCR_MDI_X         (0x1 << 5)
0065 #define MII_M1011_PHY_SCR_AUTO_CROSS        (0x3 << 5)
0066 
0067 #define MII_M1011_PHY_SSR           0x11
0068 #define MII_M1011_PHY_SSR_DOWNSHIFT     BIT(5)
0069 
0070 #define MII_M1111_PHY_LED_CONTROL   0x18
0071 #define MII_M1111_PHY_LED_DIRECT    0x4100
0072 #define MII_M1111_PHY_LED_COMBINE   0x411c
0073 #define MII_M1111_PHY_EXT_CR        0x14
0074 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK GENMASK(11, 9)
0075 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX  8
0076 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN   BIT(8)
0077 #define MII_M1111_RGMII_RX_DELAY    BIT(7)
0078 #define MII_M1111_RGMII_TX_DELAY    BIT(1)
0079 #define MII_M1111_PHY_EXT_SR        0x1b
0080 
0081 #define MII_M1111_HWCFG_MODE_MASK       0xf
0082 #define MII_M1111_HWCFG_MODE_FIBER_RGMII    0x3
0083 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK   0x4
0084 #define MII_M1111_HWCFG_MODE_RTBI       0x7
0085 #define MII_M1111_HWCFG_MODE_COPPER_1000X_AN    0x8
0086 #define MII_M1111_HWCFG_MODE_COPPER_RTBI    0x9
0087 #define MII_M1111_HWCFG_MODE_COPPER_RGMII   0xb
0088 #define MII_M1111_HWCFG_MODE_COPPER_1000X_NOAN  0xc
0089 #define MII_M1111_HWCFG_SERIAL_AN_BYPASS    BIT(12)
0090 #define MII_M1111_HWCFG_FIBER_COPPER_RES    BIT(13)
0091 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO   BIT(15)
0092 
0093 #define MII_88E1121_PHY_MSCR_REG    21
0094 #define MII_88E1121_PHY_MSCR_RX_DELAY   BIT(5)
0095 #define MII_88E1121_PHY_MSCR_TX_DELAY   BIT(4)
0096 #define MII_88E1121_PHY_MSCR_DELAY_MASK (BIT(5) | BIT(4))
0097 
0098 #define MII_88E1121_MISC_TEST               0x1a
0099 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK   0x1f00
0100 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT  8
0101 #define MII_88E1510_MISC_TEST_TEMP_IRQ_EN       BIT(7)
0102 #define MII_88E1510_MISC_TEST_TEMP_IRQ          BIT(6)
0103 #define MII_88E1121_MISC_TEST_TEMP_SENSOR_EN        BIT(5)
0104 #define MII_88E1121_MISC_TEST_TEMP_MASK         0x1f
0105 
0106 #define MII_88E1510_TEMP_SENSOR     0x1b
0107 #define MII_88E1510_TEMP_SENSOR_MASK    0xff
0108 
0109 #define MII_88E1540_COPPER_CTRL3    0x1a
0110 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK   GENMASK(11, 10)
0111 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS   0
0112 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS   1
0113 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS   2
0114 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS   3
0115 #define MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN     BIT(9)
0116 
0117 #define MII_88E6390_MISC_TEST       0x1b
0118 #define MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE_SAMPLE_1S  (0x0 << 14)
0119 #define MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE        (0x1 << 14)
0120 #define MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE_ONESHOT    (0x2 << 14)
0121 #define MII_88E6390_MISC_TEST_TEMP_SENSOR_DISABLE       (0x3 << 14)
0122 #define MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK          (0x3 << 14)
0123 #define MII_88E6393_MISC_TEST_SAMPLES_2048  (0x0 << 11)
0124 #define MII_88E6393_MISC_TEST_SAMPLES_4096  (0x1 << 11)
0125 #define MII_88E6393_MISC_TEST_SAMPLES_8192  (0x2 << 11)
0126 #define MII_88E6393_MISC_TEST_SAMPLES_16384 (0x3 << 11)
0127 #define MII_88E6393_MISC_TEST_SAMPLES_MASK  (0x3 << 11)
0128 #define MII_88E6393_MISC_TEST_RATE_2_3MS    (0x5 << 8)
0129 #define MII_88E6393_MISC_TEST_RATE_6_4MS    (0x6 << 8)
0130 #define MII_88E6393_MISC_TEST_RATE_11_9MS   (0x7 << 8)
0131 #define MII_88E6393_MISC_TEST_RATE_MASK     (0x7 << 8)
0132 
0133 #define MII_88E6390_TEMP_SENSOR     0x1c
0134 #define MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK  0xff00
0135 #define MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT 8
0136 #define MII_88E6390_TEMP_SENSOR_MASK        0xff
0137 #define MII_88E6390_TEMP_SENSOR_SAMPLES     10
0138 
0139 #define MII_88E1318S_PHY_MSCR1_REG  16
0140 #define MII_88E1318S_PHY_MSCR1_PAD_ODD  BIT(6)
0141 
0142 /* Copper Specific Interrupt Enable Register */
0143 #define MII_88E1318S_PHY_CSIER              0x12
0144 /* WOL Event Interrupt Enable */
0145 #define MII_88E1318S_PHY_CSIER_WOL_EIE          BIT(7)
0146 
0147 /* LED Timer Control Register */
0148 #define MII_88E1318S_PHY_LED_TCR            0x12
0149 #define MII_88E1318S_PHY_LED_TCR_FORCE_INT      BIT(15)
0150 #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE        BIT(7)
0151 #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW     BIT(11)
0152 
0153 /* Magic Packet MAC address registers */
0154 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2     0x17
0155 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1     0x18
0156 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0     0x19
0157 
0158 #define MII_88E1318S_PHY_WOL_CTRL               0x10
0159 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS      BIT(12)
0160 #define MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE        BIT(13)
0161 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14)
0162 
0163 #define MII_PHY_LED_CTRL            16
0164 #define MII_88E1121_PHY_LED_DEF     0x0030
0165 #define MII_88E1510_PHY_LED_DEF     0x1177
0166 #define MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE   0x1040
0167 
0168 #define MII_M1011_PHY_STATUS        0x11
0169 #define MII_M1011_PHY_STATUS_1000   0x8000
0170 #define MII_M1011_PHY_STATUS_100    0x4000
0171 #define MII_M1011_PHY_STATUS_SPD_MASK   0xc000
0172 #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000
0173 #define MII_M1011_PHY_STATUS_RESOLVED   0x0800
0174 #define MII_M1011_PHY_STATUS_LINK   0x0400
0175 
0176 #define MII_88E3016_PHY_SPEC_CTRL   0x10
0177 #define MII_88E3016_DISABLE_SCRAMBLER   0x0200
0178 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030
0179 
0180 #define MII_88E1510_GEN_CTRL_REG_1      0x14
0181 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK    0x7
0182 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII   0x0 /* RGMII to copper */
0183 #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII   0x1 /* SGMII to copper */
0184 /* RGMII to 1000BASE-X */
0185 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X 0x2
0186 /* RGMII to 100BASE-FX */
0187 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX 0x3
0188 /* RGMII to SGMII */
0189 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII 0x4
0190 #define MII_88E1510_GEN_CTRL_REG_1_RESET    0x8000  /* Soft reset */
0191 
0192 #define MII_88E1510_MSCR_2      0x15
0193 
0194 #define MII_VCT5_TX_RX_MDI0_COUPLING    0x10
0195 #define MII_VCT5_TX_RX_MDI1_COUPLING    0x11
0196 #define MII_VCT5_TX_RX_MDI2_COUPLING    0x12
0197 #define MII_VCT5_TX_RX_MDI3_COUPLING    0x13
0198 #define MII_VCT5_TX_RX_AMPLITUDE_MASK   0x7f00
0199 #define MII_VCT5_TX_RX_AMPLITUDE_SHIFT  8
0200 #define MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION BIT(15)
0201 
0202 #define MII_VCT5_CTRL               0x17
0203 #define MII_VCT5_CTRL_ENABLE                BIT(15)
0204 #define MII_VCT5_CTRL_COMPLETE              BIT(14)
0205 #define MII_VCT5_CTRL_TX_SAME_CHANNEL           (0x0 << 11)
0206 #define MII_VCT5_CTRL_TX0_CHANNEL           (0x4 << 11)
0207 #define MII_VCT5_CTRL_TX1_CHANNEL           (0x5 << 11)
0208 #define MII_VCT5_CTRL_TX2_CHANNEL           (0x6 << 11)
0209 #define MII_VCT5_CTRL_TX3_CHANNEL           (0x7 << 11)
0210 #define MII_VCT5_CTRL_SAMPLES_2             (0x0 << 8)
0211 #define MII_VCT5_CTRL_SAMPLES_4             (0x1 << 8)
0212 #define MII_VCT5_CTRL_SAMPLES_8             (0x2 << 8)
0213 #define MII_VCT5_CTRL_SAMPLES_16            (0x3 << 8)
0214 #define MII_VCT5_CTRL_SAMPLES_32            (0x4 << 8)
0215 #define MII_VCT5_CTRL_SAMPLES_64            (0x5 << 8)
0216 #define MII_VCT5_CTRL_SAMPLES_128           (0x6 << 8)
0217 #define MII_VCT5_CTRL_SAMPLES_DEFAULT           (0x6 << 8)
0218 #define MII_VCT5_CTRL_SAMPLES_256           (0x7 << 8)
0219 #define MII_VCT5_CTRL_SAMPLES_SHIFT         8
0220 #define MII_VCT5_CTRL_MODE_MAXIMUM_PEEK         (0x0 << 6)
0221 #define MII_VCT5_CTRL_MODE_FIRST_LAST_PEEK      (0x1 << 6)
0222 #define MII_VCT5_CTRL_MODE_OFFSET           (0x2 << 6)
0223 #define MII_VCT5_CTRL_SAMPLE_POINT          (0x3 << 6)
0224 #define MII_VCT5_CTRL_PEEK_HYST_DEFAULT         3
0225 
0226 #define MII_VCT5_SAMPLE_POINT_DISTANCE      0x18
0227 #define MII_VCT5_SAMPLE_POINT_DISTANCE_MAX  511
0228 #define MII_VCT5_TX_PULSE_CTRL          0x1c
0229 #define MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN  BIT(12)
0230 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS    (0x0 << 10)
0231 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_96nS     (0x1 << 10)
0232 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_64nS     (0x2 << 10)
0233 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS     (0x3 << 10)
0234 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_SHIFT    10
0235 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_1000mV   (0x0 << 8)
0236 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_750mV    (0x1 << 8)
0237 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_500mV    (0x2 << 8)
0238 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_250mV    (0x3 << 8)
0239 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_SHIFT    8
0240 #define MII_VCT5_TX_PULSE_CTRL_MAX_AMP          BIT(7)
0241 #define MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV      (0x6 << 0)
0242 
0243 /* For TDR measurements less than 11 meters, a short pulse should be
0244  * used.
0245  */
0246 #define TDR_SHORT_CABLE_LENGTH  11
0247 
0248 #define MII_VCT7_PAIR_0_DISTANCE    0x10
0249 #define MII_VCT7_PAIR_1_DISTANCE    0x11
0250 #define MII_VCT7_PAIR_2_DISTANCE    0x12
0251 #define MII_VCT7_PAIR_3_DISTANCE    0x13
0252 
0253 #define MII_VCT7_RESULTS    0x14
0254 #define MII_VCT7_RESULTS_PAIR3_MASK 0xf000
0255 #define MII_VCT7_RESULTS_PAIR2_MASK 0x0f00
0256 #define MII_VCT7_RESULTS_PAIR1_MASK 0x00f0
0257 #define MII_VCT7_RESULTS_PAIR0_MASK 0x000f
0258 #define MII_VCT7_RESULTS_PAIR3_SHIFT    12
0259 #define MII_VCT7_RESULTS_PAIR2_SHIFT    8
0260 #define MII_VCT7_RESULTS_PAIR1_SHIFT    4
0261 #define MII_VCT7_RESULTS_PAIR0_SHIFT    0
0262 #define MII_VCT7_RESULTS_INVALID    0
0263 #define MII_VCT7_RESULTS_OK     1
0264 #define MII_VCT7_RESULTS_OPEN       2
0265 #define MII_VCT7_RESULTS_SAME_SHORT 3
0266 #define MII_VCT7_RESULTS_CROSS_SHORT    4
0267 #define MII_VCT7_RESULTS_BUSY       9
0268 
0269 #define MII_VCT7_CTRL       0x15
0270 #define MII_VCT7_CTRL_RUN_NOW           BIT(15)
0271 #define MII_VCT7_CTRL_RUN_ANEG          BIT(14)
0272 #define MII_VCT7_CTRL_DISABLE_CROSS     BIT(13)
0273 #define MII_VCT7_CTRL_RUN_AFTER_BREAK_LINK  BIT(12)
0274 #define MII_VCT7_CTRL_IN_PROGRESS       BIT(11)
0275 #define MII_VCT7_CTRL_METERS            BIT(10)
0276 #define MII_VCT7_CTRL_CENTIMETERS       0
0277 
0278 #define LPA_PAUSE_FIBER     0x180
0279 #define LPA_PAUSE_ASYM_FIBER    0x100
0280 
0281 #define NB_FIBER_STATS  1
0282 
0283 MODULE_DESCRIPTION("Marvell PHY driver");
0284 MODULE_AUTHOR("Andy Fleming");
0285 MODULE_LICENSE("GPL");
0286 
0287 struct marvell_hw_stat {
0288     const char *string;
0289     u8 page;
0290     u8 reg;
0291     u8 bits;
0292 };
0293 
0294 static struct marvell_hw_stat marvell_hw_stats[] = {
0295     { "phy_receive_errors_copper", 0, 21, 16},
0296     { "phy_idle_errors", 0, 10, 8 },
0297     { "phy_receive_errors_fiber", 1, 21, 16},
0298 };
0299 
0300 struct marvell_priv {
0301     u64 stats[ARRAY_SIZE(marvell_hw_stats)];
0302     char *hwmon_name;
0303     struct device *hwmon_dev;
0304     bool cable_test_tdr;
0305     u32 first;
0306     u32 last;
0307     u32 step;
0308     s8 pair;
0309 };
0310 
0311 static int marvell_read_page(struct phy_device *phydev)
0312 {
0313     return __phy_read(phydev, MII_MARVELL_PHY_PAGE);
0314 }
0315 
0316 static int marvell_write_page(struct phy_device *phydev, int page)
0317 {
0318     return __phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
0319 }
0320 
0321 static int marvell_set_page(struct phy_device *phydev, int page)
0322 {
0323     return phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
0324 }
0325 
0326 static int marvell_ack_interrupt(struct phy_device *phydev)
0327 {
0328     int err;
0329 
0330     /* Clear the interrupts by reading the reg */
0331     err = phy_read(phydev, MII_M1011_IEVENT);
0332 
0333     if (err < 0)
0334         return err;
0335 
0336     return 0;
0337 }
0338 
0339 static int marvell_config_intr(struct phy_device *phydev)
0340 {
0341     int err;
0342 
0343     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0344         err = marvell_ack_interrupt(phydev);
0345         if (err)
0346             return err;
0347 
0348         err = phy_write(phydev, MII_M1011_IMASK,
0349                 MII_M1011_IMASK_INIT);
0350     } else {
0351         err = phy_write(phydev, MII_M1011_IMASK,
0352                 MII_M1011_IMASK_CLEAR);
0353         if (err)
0354             return err;
0355 
0356         err = marvell_ack_interrupt(phydev);
0357     }
0358 
0359     return err;
0360 }
0361 
0362 static irqreturn_t marvell_handle_interrupt(struct phy_device *phydev)
0363 {
0364     int irq_status;
0365 
0366     irq_status = phy_read(phydev, MII_M1011_IEVENT);
0367     if (irq_status < 0) {
0368         phy_error(phydev);
0369         return IRQ_NONE;
0370     }
0371 
0372     if (!(irq_status & MII_M1011_IMASK_INIT))
0373         return IRQ_NONE;
0374 
0375     phy_trigger_machine(phydev);
0376 
0377     return IRQ_HANDLED;
0378 }
0379 
0380 static int marvell_set_polarity(struct phy_device *phydev, int polarity)
0381 {
0382     u16 val;
0383 
0384     switch (polarity) {
0385     case ETH_TP_MDI:
0386         val = MII_M1011_PHY_SCR_MDI;
0387         break;
0388     case ETH_TP_MDI_X:
0389         val = MII_M1011_PHY_SCR_MDI_X;
0390         break;
0391     case ETH_TP_MDI_AUTO:
0392     case ETH_TP_MDI_INVALID:
0393     default:
0394         val = MII_M1011_PHY_SCR_AUTO_CROSS;
0395         break;
0396     }
0397 
0398     return phy_modify_changed(phydev, MII_M1011_PHY_SCR,
0399                   MII_M1011_PHY_SCR_AUTO_CROSS, val);
0400 }
0401 
0402 static int marvell_config_aneg(struct phy_device *phydev)
0403 {
0404     int changed = 0;
0405     int err;
0406 
0407     err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
0408     if (err < 0)
0409         return err;
0410 
0411     changed = err;
0412 
0413     err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
0414             MII_M1111_PHY_LED_DIRECT);
0415     if (err < 0)
0416         return err;
0417 
0418     err = genphy_config_aneg(phydev);
0419     if (err < 0)
0420         return err;
0421 
0422     if (phydev->autoneg != AUTONEG_ENABLE || changed) {
0423         /* A write to speed/duplex bits (that is performed by
0424          * genphy_config_aneg() call above) must be followed by
0425          * a software reset. Otherwise, the write has no effect.
0426          */
0427         err = genphy_soft_reset(phydev);
0428         if (err < 0)
0429             return err;
0430     }
0431 
0432     return 0;
0433 }
0434 
0435 static int m88e1101_config_aneg(struct phy_device *phydev)
0436 {
0437     int err;
0438 
0439     /* This Marvell PHY has an errata which requires
0440      * that certain registers get written in order
0441      * to restart autonegotiation
0442      */
0443     err = genphy_soft_reset(phydev);
0444     if (err < 0)
0445         return err;
0446 
0447     err = phy_write(phydev, 0x1d, 0x1f);
0448     if (err < 0)
0449         return err;
0450 
0451     err = phy_write(phydev, 0x1e, 0x200c);
0452     if (err < 0)
0453         return err;
0454 
0455     err = phy_write(phydev, 0x1d, 0x5);
0456     if (err < 0)
0457         return err;
0458 
0459     err = phy_write(phydev, 0x1e, 0);
0460     if (err < 0)
0461         return err;
0462 
0463     err = phy_write(phydev, 0x1e, 0x100);
0464     if (err < 0)
0465         return err;
0466 
0467     return marvell_config_aneg(phydev);
0468 }
0469 
0470 #if IS_ENABLED(CONFIG_OF_MDIO)
0471 /* Set and/or override some configuration registers based on the
0472  * marvell,reg-init property stored in the of_node for the phydev.
0473  *
0474  * marvell,reg-init = <reg-page reg mask value>,...;
0475  *
0476  * There may be one or more sets of <reg-page reg mask value>:
0477  *
0478  * reg-page: which register bank to use.
0479  * reg: the register.
0480  * mask: if non-zero, ANDed with existing register value.
0481  * value: ORed with the masked value and written to the regiser.
0482  *
0483  */
0484 static int marvell_of_reg_init(struct phy_device *phydev)
0485 {
0486     const __be32 *paddr;
0487     int len, i, saved_page, current_page, ret = 0;
0488 
0489     if (!phydev->mdio.dev.of_node)
0490         return 0;
0491 
0492     paddr = of_get_property(phydev->mdio.dev.of_node,
0493                 "marvell,reg-init", &len);
0494     if (!paddr || len < (4 * sizeof(*paddr)))
0495         return 0;
0496 
0497     saved_page = phy_save_page(phydev);
0498     if (saved_page < 0)
0499         goto err;
0500     current_page = saved_page;
0501 
0502     len /= sizeof(*paddr);
0503     for (i = 0; i < len - 3; i += 4) {
0504         u16 page = be32_to_cpup(paddr + i);
0505         u16 reg = be32_to_cpup(paddr + i + 1);
0506         u16 mask = be32_to_cpup(paddr + i + 2);
0507         u16 val_bits = be32_to_cpup(paddr + i + 3);
0508         int val;
0509 
0510         if (page != current_page) {
0511             current_page = page;
0512             ret = marvell_write_page(phydev, page);
0513             if (ret < 0)
0514                 goto err;
0515         }
0516 
0517         val = 0;
0518         if (mask) {
0519             val = __phy_read(phydev, reg);
0520             if (val < 0) {
0521                 ret = val;
0522                 goto err;
0523             }
0524             val &= mask;
0525         }
0526         val |= val_bits;
0527 
0528         ret = __phy_write(phydev, reg, val);
0529         if (ret < 0)
0530             goto err;
0531     }
0532 err:
0533     return phy_restore_page(phydev, saved_page, ret);
0534 }
0535 #else
0536 static int marvell_of_reg_init(struct phy_device *phydev)
0537 {
0538     return 0;
0539 }
0540 #endif /* CONFIG_OF_MDIO */
0541 
0542 static int m88e1121_config_aneg_rgmii_delays(struct phy_device *phydev)
0543 {
0544     int mscr;
0545 
0546     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
0547         mscr = MII_88E1121_PHY_MSCR_RX_DELAY |
0548                MII_88E1121_PHY_MSCR_TX_DELAY;
0549     else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
0550         mscr = MII_88E1121_PHY_MSCR_RX_DELAY;
0551     else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
0552         mscr = MII_88E1121_PHY_MSCR_TX_DELAY;
0553     else
0554         mscr = 0;
0555 
0556     return phy_modify_paged_changed(phydev, MII_MARVELL_MSCR_PAGE,
0557                     MII_88E1121_PHY_MSCR_REG,
0558                     MII_88E1121_PHY_MSCR_DELAY_MASK, mscr);
0559 }
0560 
0561 static int m88e1121_config_aneg(struct phy_device *phydev)
0562 {
0563     int changed = 0;
0564     int err = 0;
0565 
0566     if (phy_interface_is_rgmii(phydev)) {
0567         err = m88e1121_config_aneg_rgmii_delays(phydev);
0568         if (err < 0)
0569             return err;
0570     }
0571 
0572     changed = err;
0573 
0574     err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
0575     if (err < 0)
0576         return err;
0577 
0578     changed |= err;
0579 
0580     err = genphy_config_aneg(phydev);
0581     if (err < 0)
0582         return err;
0583 
0584     if (phydev->autoneg != AUTONEG_ENABLE || changed) {
0585         /* A software reset is used to ensure a "commit" of the
0586          * changes is done.
0587          */
0588         err = genphy_soft_reset(phydev);
0589         if (err < 0)
0590             return err;
0591     }
0592 
0593     return 0;
0594 }
0595 
0596 static int m88e1318_config_aneg(struct phy_device *phydev)
0597 {
0598     int err;
0599 
0600     err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
0601                    MII_88E1318S_PHY_MSCR1_REG,
0602                    0, MII_88E1318S_PHY_MSCR1_PAD_ODD);
0603     if (err < 0)
0604         return err;
0605 
0606     return m88e1121_config_aneg(phydev);
0607 }
0608 
0609 /**
0610  * linkmode_adv_to_fiber_adv_t
0611  * @advertise: the linkmode advertisement settings
0612  *
0613  * A small helper function that translates linkmode advertisement
0614  * settings to phy autonegotiation advertisements for the MII_ADV
0615  * register for fiber link.
0616  */
0617 static inline u32 linkmode_adv_to_fiber_adv_t(unsigned long *advertise)
0618 {
0619     u32 result = 0;
0620 
0621     if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertise))
0622         result |= ADVERTISE_1000XHALF;
0623     if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertise))
0624         result |= ADVERTISE_1000XFULL;
0625 
0626     if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertise) &&
0627         linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
0628         result |= ADVERTISE_1000XPSE_ASYM;
0629     else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
0630         result |= ADVERTISE_1000XPAUSE;
0631 
0632     return result;
0633 }
0634 
0635 /**
0636  * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
0637  * @phydev: target phy_device struct
0638  *
0639  * Description: If auto-negotiation is enabled, we configure the
0640  *   advertising, and then restart auto-negotiation.  If it is not
0641  *   enabled, then we write the BMCR. Adapted for fiber link in
0642  *   some Marvell's devices.
0643  */
0644 static int marvell_config_aneg_fiber(struct phy_device *phydev)
0645 {
0646     int changed = 0;
0647     int err;
0648     u16 adv;
0649 
0650     if (phydev->autoneg != AUTONEG_ENABLE)
0651         return genphy_setup_forced(phydev);
0652 
0653     /* Only allow advertising what this PHY supports */
0654     linkmode_and(phydev->advertising, phydev->advertising,
0655              phydev->supported);
0656 
0657     adv = linkmode_adv_to_fiber_adv_t(phydev->advertising);
0658 
0659     /* Setup fiber advertisement */
0660     err = phy_modify_changed(phydev, MII_ADVERTISE,
0661                  ADVERTISE_1000XHALF | ADVERTISE_1000XFULL |
0662                  ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM,
0663                  adv);
0664     if (err < 0)
0665         return err;
0666     if (err > 0)
0667         changed = 1;
0668 
0669     return genphy_check_and_restart_aneg(phydev, changed);
0670 }
0671 
0672 static int m88e1111_config_aneg(struct phy_device *phydev)
0673 {
0674     int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR);
0675     int err;
0676 
0677     if (extsr < 0)
0678         return extsr;
0679 
0680     /* If not using SGMII or copper 1000BaseX modes, use normal process.
0681      * Steps below are only required for these modes.
0682      */
0683     if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
0684         (extsr & MII_M1111_HWCFG_MODE_MASK) !=
0685         MII_M1111_HWCFG_MODE_COPPER_1000X_AN)
0686         return marvell_config_aneg(phydev);
0687 
0688     err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
0689     if (err < 0)
0690         goto error;
0691 
0692     /* Configure the copper link first */
0693     err = marvell_config_aneg(phydev);
0694     if (err < 0)
0695         goto error;
0696 
0697     /* Then the fiber link */
0698     err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
0699     if (err < 0)
0700         goto error;
0701 
0702     if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
0703         /* Do not touch the fiber advertisement if we're in copper->sgmii mode.
0704          * Just ensure that SGMII-side autonegotiation is enabled.
0705          * If we switched from some other mode to SGMII it may not be.
0706          */
0707         err = genphy_check_and_restart_aneg(phydev, false);
0708     else
0709         err = marvell_config_aneg_fiber(phydev);
0710     if (err < 0)
0711         goto error;
0712 
0713     return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
0714 
0715 error:
0716     marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
0717     return err;
0718 }
0719 
0720 static int m88e1510_config_aneg(struct phy_device *phydev)
0721 {
0722     int err;
0723 
0724     err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
0725     if (err < 0)
0726         goto error;
0727 
0728     /* Configure the copper link first */
0729     err = m88e1318_config_aneg(phydev);
0730     if (err < 0)
0731         goto error;
0732 
0733     /* Do not touch the fiber page if we're in copper->sgmii mode */
0734     if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
0735         return 0;
0736 
0737     /* Then the fiber link */
0738     err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
0739     if (err < 0)
0740         goto error;
0741 
0742     err = marvell_config_aneg_fiber(phydev);
0743     if (err < 0)
0744         goto error;
0745 
0746     return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
0747 
0748 error:
0749     marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
0750     return err;
0751 }
0752 
0753 static void marvell_config_led(struct phy_device *phydev)
0754 {
0755     u16 def_config;
0756     int err;
0757 
0758     switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
0759     /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
0760     case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
0761     case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
0762         def_config = MII_88E1121_PHY_LED_DEF;
0763         break;
0764     /* Default PHY LED config:
0765      * LED[0] .. 1000Mbps Link
0766      * LED[1] .. 100Mbps Link
0767      * LED[2] .. Blink, Activity
0768      */
0769     case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
0770         if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
0771             def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
0772         else
0773             def_config = MII_88E1510_PHY_LED_DEF;
0774         break;
0775     default:
0776         return;
0777     }
0778 
0779     err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, MII_PHY_LED_CTRL,
0780                   def_config);
0781     if (err < 0)
0782         phydev_warn(phydev, "Fail to config marvell phy LED.\n");
0783 }
0784 
0785 static int marvell_config_init(struct phy_device *phydev)
0786 {
0787     /* Set default LED */
0788     marvell_config_led(phydev);
0789 
0790     /* Set registers from marvell,reg-init DT property */
0791     return marvell_of_reg_init(phydev);
0792 }
0793 
0794 static int m88e3016_config_init(struct phy_device *phydev)
0795 {
0796     int ret;
0797 
0798     /* Enable Scrambler and Auto-Crossover */
0799     ret = phy_modify(phydev, MII_88E3016_PHY_SPEC_CTRL,
0800              MII_88E3016_DISABLE_SCRAMBLER,
0801              MII_88E3016_AUTO_MDIX_CROSSOVER);
0802     if (ret < 0)
0803         return ret;
0804 
0805     return marvell_config_init(phydev);
0806 }
0807 
0808 static int m88e1111_config_init_hwcfg_mode(struct phy_device *phydev,
0809                        u16 mode,
0810                        int fibre_copper_auto)
0811 {
0812     if (fibre_copper_auto)
0813         mode |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
0814 
0815     return phy_modify(phydev, MII_M1111_PHY_EXT_SR,
0816               MII_M1111_HWCFG_MODE_MASK |
0817               MII_M1111_HWCFG_FIBER_COPPER_AUTO |
0818               MII_M1111_HWCFG_FIBER_COPPER_RES,
0819               mode);
0820 }
0821 
0822 static int m88e1111_config_init_rgmii_delays(struct phy_device *phydev)
0823 {
0824     int delay;
0825 
0826     switch (phydev->interface) {
0827     case PHY_INTERFACE_MODE_RGMII_ID:
0828         delay = MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY;
0829         break;
0830     case PHY_INTERFACE_MODE_RGMII_RXID:
0831         delay = MII_M1111_RGMII_RX_DELAY;
0832         break;
0833     case PHY_INTERFACE_MODE_RGMII_TXID:
0834         delay = MII_M1111_RGMII_TX_DELAY;
0835         break;
0836     default:
0837         delay = 0;
0838         break;
0839     }
0840 
0841     return phy_modify(phydev, MII_M1111_PHY_EXT_CR,
0842               MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY,
0843               delay);
0844 }
0845 
0846 static int m88e1111_config_init_rgmii(struct phy_device *phydev)
0847 {
0848     int temp;
0849     int err;
0850 
0851     err = m88e1111_config_init_rgmii_delays(phydev);
0852     if (err < 0)
0853         return err;
0854 
0855     temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
0856     if (temp < 0)
0857         return temp;
0858 
0859     temp &= ~(MII_M1111_HWCFG_MODE_MASK);
0860 
0861     if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
0862         temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
0863     else
0864         temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
0865 
0866     return phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
0867 }
0868 
0869 static int m88e1111_config_init_sgmii(struct phy_device *phydev)
0870 {
0871     int err;
0872 
0873     err = m88e1111_config_init_hwcfg_mode(
0874         phydev,
0875         MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
0876         MII_M1111_HWCFG_FIBER_COPPER_AUTO);
0877     if (err < 0)
0878         return err;
0879 
0880     /* make sure copper is selected */
0881     return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
0882 }
0883 
0884 static int m88e1111_config_init_rtbi(struct phy_device *phydev)
0885 {
0886     int err;
0887 
0888     err = m88e1111_config_init_rgmii_delays(phydev);
0889     if (err < 0)
0890         return err;
0891 
0892     err = m88e1111_config_init_hwcfg_mode(
0893         phydev,
0894         MII_M1111_HWCFG_MODE_RTBI,
0895         MII_M1111_HWCFG_FIBER_COPPER_AUTO);
0896     if (err < 0)
0897         return err;
0898 
0899     /* soft reset */
0900     err = genphy_soft_reset(phydev);
0901     if (err < 0)
0902         return err;
0903 
0904     return m88e1111_config_init_hwcfg_mode(
0905         phydev,
0906         MII_M1111_HWCFG_MODE_RTBI,
0907         MII_M1111_HWCFG_FIBER_COPPER_AUTO);
0908 }
0909 
0910 static int m88e1111_config_init_1000basex(struct phy_device *phydev)
0911 {
0912     int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR);
0913     int err, mode;
0914 
0915     if (extsr < 0)
0916         return extsr;
0917 
0918     /* If using copper mode, ensure 1000BaseX auto-negotiation is enabled */
0919     mode = extsr & MII_M1111_HWCFG_MODE_MASK;
0920     if (mode == MII_M1111_HWCFG_MODE_COPPER_1000X_NOAN) {
0921         err = phy_modify(phydev, MII_M1111_PHY_EXT_SR,
0922                  MII_M1111_HWCFG_MODE_MASK |
0923                  MII_M1111_HWCFG_SERIAL_AN_BYPASS,
0924                  MII_M1111_HWCFG_MODE_COPPER_1000X_AN |
0925                  MII_M1111_HWCFG_SERIAL_AN_BYPASS);
0926         if (err < 0)
0927             return err;
0928     }
0929     return 0;
0930 }
0931 
0932 static int m88e1111_config_init(struct phy_device *phydev)
0933 {
0934     int err;
0935 
0936     if (phy_interface_is_rgmii(phydev)) {
0937         err = m88e1111_config_init_rgmii(phydev);
0938         if (err < 0)
0939             return err;
0940     }
0941 
0942     if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
0943         err = m88e1111_config_init_sgmii(phydev);
0944         if (err < 0)
0945             return err;
0946     }
0947 
0948     if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
0949         err = m88e1111_config_init_rtbi(phydev);
0950         if (err < 0)
0951             return err;
0952     }
0953 
0954     if (phydev->interface == PHY_INTERFACE_MODE_1000BASEX) {
0955         err = m88e1111_config_init_1000basex(phydev);
0956         if (err < 0)
0957             return err;
0958     }
0959 
0960     err = marvell_of_reg_init(phydev);
0961     if (err < 0)
0962         return err;
0963 
0964     err = genphy_soft_reset(phydev);
0965     if (err < 0)
0966         return err;
0967 
0968     if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
0969         /* If the HWCFG_MODE was changed from another mode (such as
0970          * 1000BaseX) to SGMII, the state of the support bits may have
0971          * also changed now that the PHY has been reset.
0972          * Update the PHY abilities accordingly.
0973          */
0974         err = genphy_read_abilities(phydev);
0975         linkmode_or(phydev->advertising, phydev->advertising,
0976                 phydev->supported);
0977     }
0978     return err;
0979 }
0980 
0981 static int m88e1111_get_downshift(struct phy_device *phydev, u8 *data)
0982 {
0983     int val, cnt, enable;
0984 
0985     val = phy_read(phydev, MII_M1111_PHY_EXT_CR);
0986     if (val < 0)
0987         return val;
0988 
0989     enable = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN, val);
0990     cnt = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, val) + 1;
0991 
0992     *data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
0993 
0994     return 0;
0995 }
0996 
0997 static int m88e1111_set_downshift(struct phy_device *phydev, u8 cnt)
0998 {
0999     int val, err;
1000 
1001     if (cnt > MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX)
1002         return -E2BIG;
1003 
1004     if (!cnt) {
1005         err = phy_clear_bits(phydev, MII_M1111_PHY_EXT_CR,
1006                      MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN);
1007     } else {
1008         val = MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN;
1009         val |= FIELD_PREP(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, cnt - 1);
1010 
1011         err = phy_modify(phydev, MII_M1111_PHY_EXT_CR,
1012                  MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN |
1013                  MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK,
1014                  val);
1015     }
1016 
1017     if (err < 0)
1018         return err;
1019 
1020     return genphy_soft_reset(phydev);
1021 }
1022 
1023 static int m88e1111_get_tunable(struct phy_device *phydev,
1024                 struct ethtool_tunable *tuna, void *data)
1025 {
1026     switch (tuna->id) {
1027     case ETHTOOL_PHY_DOWNSHIFT:
1028         return m88e1111_get_downshift(phydev, data);
1029     default:
1030         return -EOPNOTSUPP;
1031     }
1032 }
1033 
1034 static int m88e1111_set_tunable(struct phy_device *phydev,
1035                 struct ethtool_tunable *tuna, const void *data)
1036 {
1037     switch (tuna->id) {
1038     case ETHTOOL_PHY_DOWNSHIFT:
1039         return m88e1111_set_downshift(phydev, *(const u8 *)data);
1040     default:
1041         return -EOPNOTSUPP;
1042     }
1043 }
1044 
1045 static int m88e1011_get_downshift(struct phy_device *phydev, u8 *data)
1046 {
1047     int val, cnt, enable;
1048 
1049     val = phy_read(phydev, MII_M1011_PHY_SCR);
1050     if (val < 0)
1051         return val;
1052 
1053     enable = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_EN, val);
1054     cnt = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, val) + 1;
1055 
1056     *data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
1057 
1058     return 0;
1059 }
1060 
1061 static int m88e1011_set_downshift(struct phy_device *phydev, u8 cnt)
1062 {
1063     int val, err;
1064 
1065     if (cnt > MII_M1011_PHY_SCR_DOWNSHIFT_MAX)
1066         return -E2BIG;
1067 
1068     if (!cnt) {
1069         err = phy_clear_bits(phydev, MII_M1011_PHY_SCR,
1070                      MII_M1011_PHY_SCR_DOWNSHIFT_EN);
1071     } else {
1072         val = MII_M1011_PHY_SCR_DOWNSHIFT_EN;
1073         val |= FIELD_PREP(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, cnt - 1);
1074 
1075         err = phy_modify(phydev, MII_M1011_PHY_SCR,
1076                  MII_M1011_PHY_SCR_DOWNSHIFT_EN |
1077                  MII_M1011_PHY_SCR_DOWNSHIFT_MASK,
1078                  val);
1079     }
1080 
1081     if (err < 0)
1082         return err;
1083 
1084     return genphy_soft_reset(phydev);
1085 }
1086 
1087 static int m88e1011_get_tunable(struct phy_device *phydev,
1088                 struct ethtool_tunable *tuna, void *data)
1089 {
1090     switch (tuna->id) {
1091     case ETHTOOL_PHY_DOWNSHIFT:
1092         return m88e1011_get_downshift(phydev, data);
1093     default:
1094         return -EOPNOTSUPP;
1095     }
1096 }
1097 
1098 static int m88e1011_set_tunable(struct phy_device *phydev,
1099                 struct ethtool_tunable *tuna, const void *data)
1100 {
1101     switch (tuna->id) {
1102     case ETHTOOL_PHY_DOWNSHIFT:
1103         return m88e1011_set_downshift(phydev, *(const u8 *)data);
1104     default:
1105         return -EOPNOTSUPP;
1106     }
1107 }
1108 
1109 static int m88e1112_config_init(struct phy_device *phydev)
1110 {
1111     int err;
1112 
1113     err = m88e1011_set_downshift(phydev, 3);
1114     if (err < 0)
1115         return err;
1116 
1117     return m88e1111_config_init(phydev);
1118 }
1119 
1120 static int m88e1111gbe_config_init(struct phy_device *phydev)
1121 {
1122     int err;
1123 
1124     err = m88e1111_set_downshift(phydev, 3);
1125     if (err < 0)
1126         return err;
1127 
1128     return m88e1111_config_init(phydev);
1129 }
1130 
1131 static int marvell_1011gbe_config_init(struct phy_device *phydev)
1132 {
1133     int err;
1134 
1135     err = m88e1011_set_downshift(phydev, 3);
1136     if (err < 0)
1137         return err;
1138 
1139     return marvell_config_init(phydev);
1140 }
1141 static int m88e1116r_config_init(struct phy_device *phydev)
1142 {
1143     int err;
1144 
1145     err = genphy_soft_reset(phydev);
1146     if (err < 0)
1147         return err;
1148 
1149     msleep(500);
1150 
1151     err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1152     if (err < 0)
1153         return err;
1154 
1155     err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
1156     if (err < 0)
1157         return err;
1158 
1159     err = m88e1011_set_downshift(phydev, 8);
1160     if (err < 0)
1161         return err;
1162 
1163     if (phy_interface_is_rgmii(phydev)) {
1164         err = m88e1121_config_aneg_rgmii_delays(phydev);
1165         if (err < 0)
1166             return err;
1167     }
1168 
1169     err = genphy_soft_reset(phydev);
1170     if (err < 0)
1171         return err;
1172 
1173     return marvell_config_init(phydev);
1174 }
1175 
1176 static int m88e1318_config_init(struct phy_device *phydev)
1177 {
1178     if (phy_interrupt_is_valid(phydev)) {
1179         int err = phy_modify_paged(
1180             phydev, MII_MARVELL_LED_PAGE,
1181             MII_88E1318S_PHY_LED_TCR,
1182             MII_88E1318S_PHY_LED_TCR_FORCE_INT,
1183             MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
1184             MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
1185         if (err < 0)
1186             return err;
1187     }
1188 
1189     return marvell_config_init(phydev);
1190 }
1191 
1192 static int m88e1510_config_init(struct phy_device *phydev)
1193 {
1194     static const struct {
1195         u16 reg17, reg16;
1196     } errata_vals[] = {
1197         { 0x214b, 0x2144 },
1198         { 0x0c28, 0x2146 },
1199         { 0xb233, 0x214d },
1200         { 0xcc0c, 0x2159 },
1201     };
1202     int err;
1203     int i;
1204 
1205     /* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512/
1206      * 88E1514 Rev A0, Errata Section 5.1:
1207      * If EEE is intended to be used, the following register writes
1208      * must be done once after every hardware reset.
1209      */
1210     err = marvell_set_page(phydev, 0x00FF);
1211     if (err < 0)
1212         return err;
1213 
1214     for (i = 0; i < ARRAY_SIZE(errata_vals); ++i) {
1215         err = phy_write(phydev, 17, errata_vals[i].reg17);
1216         if (err)
1217             return err;
1218         err = phy_write(phydev, 16, errata_vals[i].reg16);
1219         if (err)
1220             return err;
1221     }
1222 
1223     err = marvell_set_page(phydev, 0x00FB);
1224     if (err < 0)
1225         return err;
1226     err = phy_write(phydev, 07, 0xC00D);
1227     if (err < 0)
1228         return err;
1229     err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1230     if (err < 0)
1231         return err;
1232 
1233     /* SGMII-to-Copper mode initialization */
1234     if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1235         /* Select page 18 */
1236         err = marvell_set_page(phydev, 18);
1237         if (err < 0)
1238             return err;
1239 
1240         /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
1241         err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
1242                  MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
1243                  MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII);
1244         if (err < 0)
1245             return err;
1246 
1247         /* PHY reset is necessary after changing MODE[2:0] */
1248         err = phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
1249                    MII_88E1510_GEN_CTRL_REG_1_RESET);
1250         if (err < 0)
1251             return err;
1252 
1253         /* Reset page selection */
1254         err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1255         if (err < 0)
1256             return err;
1257     }
1258     err = m88e1011_set_downshift(phydev, 3);
1259     if (err < 0)
1260         return err;
1261 
1262     return m88e1318_config_init(phydev);
1263 }
1264 
1265 static int m88e1118_config_aneg(struct phy_device *phydev)
1266 {
1267     int err;
1268 
1269     err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
1270     if (err < 0)
1271         return err;
1272 
1273     err = genphy_config_aneg(phydev);
1274     if (err < 0)
1275         return err;
1276 
1277     return genphy_soft_reset(phydev);
1278 }
1279 
1280 static int m88e1118_config_init(struct phy_device *phydev)
1281 {
1282     u16 leds;
1283     int err;
1284 
1285     /* Enable 1000 Mbit */
1286     err = phy_write_paged(phydev, MII_MARVELL_MSCR_PAGE,
1287                   MII_88E1121_PHY_MSCR_REG, 0x1070);
1288     if (err < 0)
1289         return err;
1290 
1291     if (phy_interface_is_rgmii(phydev)) {
1292         err = m88e1121_config_aneg_rgmii_delays(phydev);
1293         if (err < 0)
1294             return err;
1295     }
1296 
1297     /* Adjust LED Control */
1298     if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS)
1299         leds = 0x1100;
1300     else
1301         leds = 0x021e;
1302 
1303     err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, 0x10, leds);
1304     if (err < 0)
1305         return err;
1306 
1307     err = marvell_of_reg_init(phydev);
1308     if (err < 0)
1309         return err;
1310 
1311     /* Reset page register */
1312     err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1313     if (err < 0)
1314         return err;
1315 
1316     return genphy_soft_reset(phydev);
1317 }
1318 
1319 static int m88e1149_config_init(struct phy_device *phydev)
1320 {
1321     int err;
1322 
1323     /* Change address */
1324     err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
1325     if (err < 0)
1326         return err;
1327 
1328     /* Enable 1000 Mbit */
1329     err = phy_write(phydev, 0x15, 0x1048);
1330     if (err < 0)
1331         return err;
1332 
1333     err = marvell_of_reg_init(phydev);
1334     if (err < 0)
1335         return err;
1336 
1337     /* Reset address */
1338     err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1339     if (err < 0)
1340         return err;
1341 
1342     return genphy_soft_reset(phydev);
1343 }
1344 
1345 static int m88e1145_config_init_rgmii(struct phy_device *phydev)
1346 {
1347     int err;
1348 
1349     err = m88e1111_config_init_rgmii_delays(phydev);
1350     if (err < 0)
1351         return err;
1352 
1353     if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
1354         err = phy_write(phydev, 0x1d, 0x0012);
1355         if (err < 0)
1356             return err;
1357 
1358         err = phy_modify(phydev, 0x1e, 0x0fc0,
1359                  2 << 9 | /* 36 ohm */
1360                  2 << 6); /* 39 ohm */
1361         if (err < 0)
1362             return err;
1363 
1364         err = phy_write(phydev, 0x1d, 0x3);
1365         if (err < 0)
1366             return err;
1367 
1368         err = phy_write(phydev, 0x1e, 0x8000);
1369     }
1370     return err;
1371 }
1372 
1373 static int m88e1145_config_init_sgmii(struct phy_device *phydev)
1374 {
1375     return m88e1111_config_init_hwcfg_mode(
1376         phydev, MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
1377         MII_M1111_HWCFG_FIBER_COPPER_AUTO);
1378 }
1379 
1380 static int m88e1145_config_init(struct phy_device *phydev)
1381 {
1382     int err;
1383 
1384     /* Take care of errata E0 & E1 */
1385     err = phy_write(phydev, 0x1d, 0x001b);
1386     if (err < 0)
1387         return err;
1388 
1389     err = phy_write(phydev, 0x1e, 0x418f);
1390     if (err < 0)
1391         return err;
1392 
1393     err = phy_write(phydev, 0x1d, 0x0016);
1394     if (err < 0)
1395         return err;
1396 
1397     err = phy_write(phydev, 0x1e, 0xa2da);
1398     if (err < 0)
1399         return err;
1400 
1401     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
1402         err = m88e1145_config_init_rgmii(phydev);
1403         if (err < 0)
1404             return err;
1405     }
1406 
1407     if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1408         err = m88e1145_config_init_sgmii(phydev);
1409         if (err < 0)
1410             return err;
1411     }
1412     err = m88e1111_set_downshift(phydev, 3);
1413     if (err < 0)
1414         return err;
1415 
1416     err = marvell_of_reg_init(phydev);
1417     if (err < 0)
1418         return err;
1419 
1420     return 0;
1421 }
1422 
1423 static int m88e1540_get_fld(struct phy_device *phydev, u8 *msecs)
1424 {
1425     int val;
1426 
1427     val = phy_read(phydev, MII_88E1540_COPPER_CTRL3);
1428     if (val < 0)
1429         return val;
1430 
1431     if (!(val & MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN)) {
1432         *msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF;
1433         return 0;
1434     }
1435 
1436     val = FIELD_GET(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1437 
1438     switch (val) {
1439     case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS:
1440         *msecs = 0;
1441         break;
1442     case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS:
1443         *msecs = 10;
1444         break;
1445     case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS:
1446         *msecs = 20;
1447         break;
1448     case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS:
1449         *msecs = 40;
1450         break;
1451     default:
1452         return -EINVAL;
1453     }
1454 
1455     return 0;
1456 }
1457 
1458 static int m88e1540_set_fld(struct phy_device *phydev, const u8 *msecs)
1459 {
1460     struct ethtool_eee eee;
1461     int val, ret;
1462 
1463     if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF)
1464         return phy_clear_bits(phydev, MII_88E1540_COPPER_CTRL3,
1465                       MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
1466 
1467     /* According to the Marvell data sheet EEE must be disabled for
1468      * Fast Link Down detection to work properly
1469      */
1470     ret = phy_ethtool_get_eee(phydev, &eee);
1471     if (!ret && eee.eee_enabled) {
1472         phydev_warn(phydev, "Fast Link Down detection requires EEE to be disabled!\n");
1473         return -EBUSY;
1474     }
1475 
1476     if (*msecs <= 5)
1477         val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS;
1478     else if (*msecs <= 15)
1479         val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS;
1480     else if (*msecs <= 30)
1481         val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS;
1482     else
1483         val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS;
1484 
1485     val = FIELD_PREP(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1486 
1487     ret = phy_modify(phydev, MII_88E1540_COPPER_CTRL3,
1488              MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1489     if (ret)
1490         return ret;
1491 
1492     return phy_set_bits(phydev, MII_88E1540_COPPER_CTRL3,
1493                 MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
1494 }
1495 
1496 static int m88e1540_get_tunable(struct phy_device *phydev,
1497                 struct ethtool_tunable *tuna, void *data)
1498 {
1499     switch (tuna->id) {
1500     case ETHTOOL_PHY_FAST_LINK_DOWN:
1501         return m88e1540_get_fld(phydev, data);
1502     case ETHTOOL_PHY_DOWNSHIFT:
1503         return m88e1011_get_downshift(phydev, data);
1504     default:
1505         return -EOPNOTSUPP;
1506     }
1507 }
1508 
1509 static int m88e1540_set_tunable(struct phy_device *phydev,
1510                 struct ethtool_tunable *tuna, const void *data)
1511 {
1512     switch (tuna->id) {
1513     case ETHTOOL_PHY_FAST_LINK_DOWN:
1514         return m88e1540_set_fld(phydev, data);
1515     case ETHTOOL_PHY_DOWNSHIFT:
1516         return m88e1011_set_downshift(phydev, *(const u8 *)data);
1517     default:
1518         return -EOPNOTSUPP;
1519     }
1520 }
1521 
1522 /* The VOD can be out of specification on link up. Poke an
1523  * undocumented register, in an undocumented page, with a magic value
1524  * to fix this.
1525  */
1526 static int m88e6390_errata(struct phy_device *phydev)
1527 {
1528     int err;
1529 
1530     err = phy_write(phydev, MII_BMCR,
1531             BMCR_ANENABLE | BMCR_SPEED1000 | BMCR_FULLDPLX);
1532     if (err)
1533         return err;
1534 
1535     usleep_range(300, 400);
1536 
1537     err = phy_write_paged(phydev, 0xf8, 0x08, 0x36);
1538     if (err)
1539         return err;
1540 
1541     return genphy_soft_reset(phydev);
1542 }
1543 
1544 static int m88e6390_config_aneg(struct phy_device *phydev)
1545 {
1546     int err;
1547 
1548     err = m88e6390_errata(phydev);
1549     if (err)
1550         return err;
1551 
1552     return m88e1510_config_aneg(phydev);
1553 }
1554 
1555 /**
1556  * fiber_lpa_mod_linkmode_lpa_t
1557  * @advertising: the linkmode advertisement settings
1558  * @lpa: value of the MII_LPA register for fiber link
1559  *
1560  * A small helper function that translates MII_LPA bits to linkmode LP
1561  * advertisement settings. Other bits in advertising are left
1562  * unchanged.
1563  */
1564 static void fiber_lpa_mod_linkmode_lpa_t(unsigned long *advertising, u32 lpa)
1565 {
1566     linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
1567              advertising, lpa & LPA_1000XHALF);
1568 
1569     linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
1570              advertising, lpa & LPA_1000XFULL);
1571 }
1572 
1573 static int marvell_read_status_page_an(struct phy_device *phydev,
1574                        int fiber, int status)
1575 {
1576     int lpa;
1577     int err;
1578 
1579     if (!(status & MII_M1011_PHY_STATUS_RESOLVED)) {
1580         phydev->link = 0;
1581         return 0;
1582     }
1583 
1584     if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
1585         phydev->duplex = DUPLEX_FULL;
1586     else
1587         phydev->duplex = DUPLEX_HALF;
1588 
1589     switch (status & MII_M1011_PHY_STATUS_SPD_MASK) {
1590     case MII_M1011_PHY_STATUS_1000:
1591         phydev->speed = SPEED_1000;
1592         break;
1593 
1594     case MII_M1011_PHY_STATUS_100:
1595         phydev->speed = SPEED_100;
1596         break;
1597 
1598     default:
1599         phydev->speed = SPEED_10;
1600         break;
1601     }
1602 
1603     if (!fiber) {
1604         err = genphy_read_lpa(phydev);
1605         if (err < 0)
1606             return err;
1607 
1608         phy_resolve_aneg_pause(phydev);
1609     } else {
1610         lpa = phy_read(phydev, MII_LPA);
1611         if (lpa < 0)
1612             return lpa;
1613 
1614         /* The fiber link is only 1000M capable */
1615         fiber_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
1616 
1617         if (phydev->duplex == DUPLEX_FULL) {
1618             if (!(lpa & LPA_PAUSE_FIBER)) {
1619                 phydev->pause = 0;
1620                 phydev->asym_pause = 0;
1621             } else if ((lpa & LPA_PAUSE_ASYM_FIBER)) {
1622                 phydev->pause = 1;
1623                 phydev->asym_pause = 1;
1624             } else {
1625                 phydev->pause = 1;
1626                 phydev->asym_pause = 0;
1627             }
1628         }
1629     }
1630 
1631     return 0;
1632 }
1633 
1634 /* marvell_read_status_page
1635  *
1636  * Description:
1637  *   Check the link, then figure out the current state
1638  *   by comparing what we advertise with what the link partner
1639  *   advertises.  Start by checking the gigabit possibilities,
1640  *   then move on to 10/100.
1641  */
1642 static int marvell_read_status_page(struct phy_device *phydev, int page)
1643 {
1644     int status;
1645     int fiber;
1646     int err;
1647 
1648     status = phy_read(phydev, MII_M1011_PHY_STATUS);
1649     if (status < 0)
1650         return status;
1651 
1652     /* Use the generic register for copper link status,
1653      * and the PHY status register for fiber link status.
1654      */
1655     if (page == MII_MARVELL_FIBER_PAGE) {
1656         phydev->link = !!(status & MII_M1011_PHY_STATUS_LINK);
1657     } else {
1658         err = genphy_update_link(phydev);
1659         if (err)
1660             return err;
1661     }
1662 
1663     if (page == MII_MARVELL_FIBER_PAGE)
1664         fiber = 1;
1665     else
1666         fiber = 0;
1667 
1668     linkmode_zero(phydev->lp_advertising);
1669     phydev->pause = 0;
1670     phydev->asym_pause = 0;
1671     phydev->speed = SPEED_UNKNOWN;
1672     phydev->duplex = DUPLEX_UNKNOWN;
1673     phydev->port = fiber ? PORT_FIBRE : PORT_TP;
1674 
1675     if (phydev->autoneg == AUTONEG_ENABLE)
1676         err = marvell_read_status_page_an(phydev, fiber, status);
1677     else
1678         err = genphy_read_status_fixed(phydev);
1679 
1680     return err;
1681 }
1682 
1683 /* marvell_read_status
1684  *
1685  * Some Marvell's phys have two modes: fiber and copper.
1686  * Both need status checked.
1687  * Description:
1688  *   First, check the fiber link and status.
1689  *   If the fiber link is down, check the copper link and status which
1690  *   will be the default value if both link are down.
1691  */
1692 static int marvell_read_status(struct phy_device *phydev)
1693 {
1694     int err;
1695 
1696     /* Check the fiber mode first */
1697     if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1698                   phydev->supported) &&
1699         phydev->interface != PHY_INTERFACE_MODE_SGMII) {
1700         err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1701         if (err < 0)
1702             goto error;
1703 
1704         err = marvell_read_status_page(phydev, MII_MARVELL_FIBER_PAGE);
1705         if (err < 0)
1706             goto error;
1707 
1708         /* If the fiber link is up, it is the selected and
1709          * used link. In this case, we need to stay in the
1710          * fiber page. Please to be careful about that, avoid
1711          * to restore Copper page in other functions which
1712          * could break the behaviour for some fiber phy like
1713          * 88E1512.
1714          */
1715         if (phydev->link)
1716             return 0;
1717 
1718         /* If fiber link is down, check and save copper mode state */
1719         err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1720         if (err < 0)
1721             goto error;
1722     }
1723 
1724     return marvell_read_status_page(phydev, MII_MARVELL_COPPER_PAGE);
1725 
1726 error:
1727     marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1728     return err;
1729 }
1730 
1731 /* marvell_suspend
1732  *
1733  * Some Marvell's phys have two modes: fiber and copper.
1734  * Both need to be suspended
1735  */
1736 static int marvell_suspend(struct phy_device *phydev)
1737 {
1738     int err;
1739 
1740     /* Suspend the fiber mode first */
1741     if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1742                   phydev->supported)) {
1743         err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1744         if (err < 0)
1745             goto error;
1746 
1747         /* With the page set, use the generic suspend */
1748         err = genphy_suspend(phydev);
1749         if (err < 0)
1750             goto error;
1751 
1752         /* Then, the copper link */
1753         err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1754         if (err < 0)
1755             goto error;
1756     }
1757 
1758     /* With the page set, use the generic suspend */
1759     return genphy_suspend(phydev);
1760 
1761 error:
1762     marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1763     return err;
1764 }
1765 
1766 /* marvell_resume
1767  *
1768  * Some Marvell's phys have two modes: fiber and copper.
1769  * Both need to be resumed
1770  */
1771 static int marvell_resume(struct phy_device *phydev)
1772 {
1773     int err;
1774 
1775     /* Resume the fiber mode first */
1776     if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1777                   phydev->supported)) {
1778         err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1779         if (err < 0)
1780             goto error;
1781 
1782         /* With the page set, use the generic resume */
1783         err = genphy_resume(phydev);
1784         if (err < 0)
1785             goto error;
1786 
1787         /* Then, the copper link */
1788         err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1789         if (err < 0)
1790             goto error;
1791     }
1792 
1793     /* With the page set, use the generic resume */
1794     return genphy_resume(phydev);
1795 
1796 error:
1797     marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1798     return err;
1799 }
1800 
1801 static int marvell_aneg_done(struct phy_device *phydev)
1802 {
1803     int retval = phy_read(phydev, MII_M1011_PHY_STATUS);
1804 
1805     return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED);
1806 }
1807 
1808 static void m88e1318_get_wol(struct phy_device *phydev,
1809                  struct ethtool_wolinfo *wol)
1810 {
1811     int ret;
1812 
1813     wol->supported = WAKE_MAGIC | WAKE_PHY;
1814     wol->wolopts = 0;
1815 
1816     ret = phy_read_paged(phydev, MII_MARVELL_WOL_PAGE,
1817                  MII_88E1318S_PHY_WOL_CTRL);
1818     if (ret < 0)
1819         return;
1820 
1821     if (ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
1822         wol->wolopts |= WAKE_MAGIC;
1823 
1824     if (ret & MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE)
1825         wol->wolopts |= WAKE_PHY;
1826 }
1827 
1828 static int m88e1318_set_wol(struct phy_device *phydev,
1829                 struct ethtool_wolinfo *wol)
1830 {
1831     int err = 0, oldpage;
1832 
1833     oldpage = phy_save_page(phydev);
1834     if (oldpage < 0)
1835         goto error;
1836 
1837     if (wol->wolopts & (WAKE_MAGIC | WAKE_PHY)) {
1838         /* Explicitly switch to page 0x00, just to be sure */
1839         err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
1840         if (err < 0)
1841             goto error;
1842 
1843         /* If WOL event happened once, the LED[2] interrupt pin
1844          * will not be cleared unless we reading the interrupt status
1845          * register. If interrupts are in use, the normal interrupt
1846          * handling will clear the WOL event. Clear the WOL event
1847          * before enabling it if !phy_interrupt_is_valid()
1848          */
1849         if (!phy_interrupt_is_valid(phydev))
1850             __phy_read(phydev, MII_M1011_IEVENT);
1851 
1852         /* Enable the WOL interrupt */
1853         err = __phy_set_bits(phydev, MII_88E1318S_PHY_CSIER,
1854                      MII_88E1318S_PHY_CSIER_WOL_EIE);
1855         if (err < 0)
1856             goto error;
1857 
1858         err = marvell_write_page(phydev, MII_MARVELL_LED_PAGE);
1859         if (err < 0)
1860             goto error;
1861 
1862         /* Setup LED[2] as interrupt pin (active low) */
1863         err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR,
1864                    MII_88E1318S_PHY_LED_TCR_FORCE_INT,
1865                    MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
1866                    MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
1867         if (err < 0)
1868             goto error;
1869     }
1870 
1871     if (wol->wolopts & WAKE_MAGIC) {
1872         err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
1873         if (err < 0)
1874             goto error;
1875 
1876         /* Store the device address for the magic packet */
1877         err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2,
1878                 ((phydev->attached_dev->dev_addr[5] << 8) |
1879                  phydev->attached_dev->dev_addr[4]));
1880         if (err < 0)
1881             goto error;
1882         err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1,
1883                 ((phydev->attached_dev->dev_addr[3] << 8) |
1884                  phydev->attached_dev->dev_addr[2]));
1885         if (err < 0)
1886             goto error;
1887         err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0,
1888                 ((phydev->attached_dev->dev_addr[1] << 8) |
1889                  phydev->attached_dev->dev_addr[0]));
1890         if (err < 0)
1891             goto error;
1892 
1893         /* Clear WOL status and enable magic packet matching */
1894         err = __phy_set_bits(phydev, MII_88E1318S_PHY_WOL_CTRL,
1895                      MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |
1896                      MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE);
1897         if (err < 0)
1898             goto error;
1899     } else {
1900         err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
1901         if (err < 0)
1902             goto error;
1903 
1904         /* Clear WOL status and disable magic packet matching */
1905         err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,
1906                    MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE,
1907                    MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
1908         if (err < 0)
1909             goto error;
1910     }
1911 
1912     if (wol->wolopts & WAKE_PHY) {
1913         err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
1914         if (err < 0)
1915             goto error;
1916 
1917         /* Clear WOL status and enable link up event */
1918         err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0,
1919                    MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |
1920                    MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE);
1921         if (err < 0)
1922             goto error;
1923     } else {
1924         err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
1925         if (err < 0)
1926             goto error;
1927 
1928         /* Clear WOL status and disable link up event */
1929         err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,
1930                    MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE,
1931                    MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
1932         if (err < 0)
1933             goto error;
1934     }
1935 
1936 error:
1937     return phy_restore_page(phydev, oldpage, err);
1938 }
1939 
1940 static int marvell_get_sset_count(struct phy_device *phydev)
1941 {
1942     if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1943                   phydev->supported))
1944         return ARRAY_SIZE(marvell_hw_stats);
1945     else
1946         return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS;
1947 }
1948 
1949 static void marvell_get_strings(struct phy_device *phydev, u8 *data)
1950 {
1951     int count = marvell_get_sset_count(phydev);
1952     int i;
1953 
1954     for (i = 0; i < count; i++) {
1955         strlcpy(data + i * ETH_GSTRING_LEN,
1956             marvell_hw_stats[i].string, ETH_GSTRING_LEN);
1957     }
1958 }
1959 
1960 static u64 marvell_get_stat(struct phy_device *phydev, int i)
1961 {
1962     struct marvell_hw_stat stat = marvell_hw_stats[i];
1963     struct marvell_priv *priv = phydev->priv;
1964     int val;
1965     u64 ret;
1966 
1967     val = phy_read_paged(phydev, stat.page, stat.reg);
1968     if (val < 0) {
1969         ret = U64_MAX;
1970     } else {
1971         val = val & ((1 << stat.bits) - 1);
1972         priv->stats[i] += val;
1973         ret = priv->stats[i];
1974     }
1975 
1976     return ret;
1977 }
1978 
1979 static void marvell_get_stats(struct phy_device *phydev,
1980                   struct ethtool_stats *stats, u64 *data)
1981 {
1982     int count = marvell_get_sset_count(phydev);
1983     int i;
1984 
1985     for (i = 0; i < count; i++)
1986         data[i] = marvell_get_stat(phydev, i);
1987 }
1988 
1989 static int m88e1510_loopback(struct phy_device *phydev, bool enable)
1990 {
1991     int err;
1992 
1993     if (enable) {
1994         u16 bmcr_ctl, mscr2_ctl = 0;
1995 
1996         bmcr_ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
1997 
1998         err = phy_write(phydev, MII_BMCR, bmcr_ctl);
1999         if (err < 0)
2000             return err;
2001 
2002         if (phydev->speed == SPEED_1000)
2003             mscr2_ctl = BMCR_SPEED1000;
2004         else if (phydev->speed == SPEED_100)
2005             mscr2_ctl = BMCR_SPEED100;
2006 
2007         err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
2008                        MII_88E1510_MSCR_2, BMCR_SPEED1000 |
2009                        BMCR_SPEED100, mscr2_ctl);
2010         if (err < 0)
2011             return err;
2012 
2013         /* Need soft reset to have speed configuration takes effect */
2014         err = genphy_soft_reset(phydev);
2015         if (err < 0)
2016             return err;
2017 
2018         /* FIXME: Based on trial and error test, it seem 1G need to have
2019          * delay between soft reset and loopback enablement.
2020          */
2021         if (phydev->speed == SPEED_1000)
2022             msleep(1000);
2023 
2024         return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK,
2025                   BMCR_LOOPBACK);
2026     } else {
2027         err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, 0);
2028         if (err < 0)
2029             return err;
2030 
2031         return phy_config_aneg(phydev);
2032     }
2033 }
2034 
2035 static int marvell_vct5_wait_complete(struct phy_device *phydev)
2036 {
2037     int i;
2038     int val;
2039 
2040     for (i = 0; i < 32; i++) {
2041         val = __phy_read(phydev, MII_VCT5_CTRL);
2042         if (val < 0)
2043             return val;
2044 
2045         if (val & MII_VCT5_CTRL_COMPLETE)
2046             return 0;
2047     }
2048 
2049     phydev_err(phydev, "Timeout while waiting for cable test to finish\n");
2050     return -ETIMEDOUT;
2051 }
2052 
2053 static int marvell_vct5_amplitude(struct phy_device *phydev, int pair)
2054 {
2055     int amplitude;
2056     int val;
2057     int reg;
2058 
2059     reg = MII_VCT5_TX_RX_MDI0_COUPLING + pair;
2060     val = __phy_read(phydev, reg);
2061 
2062     if (val < 0)
2063         return 0;
2064 
2065     amplitude = (val & MII_VCT5_TX_RX_AMPLITUDE_MASK) >>
2066         MII_VCT5_TX_RX_AMPLITUDE_SHIFT;
2067 
2068     if (!(val & MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION))
2069         amplitude = -amplitude;
2070 
2071     return 1000 * amplitude / 128;
2072 }
2073 
2074 static u32 marvell_vct5_distance2cm(int distance)
2075 {
2076     return distance * 805 / 10;
2077 }
2078 
2079 static u32 marvell_vct5_cm2distance(int cm)
2080 {
2081     return cm * 10 / 805;
2082 }
2083 
2084 static int marvell_vct5_amplitude_distance(struct phy_device *phydev,
2085                        int distance, int pair)
2086 {
2087     u16 reg;
2088     int err;
2089     int mV;
2090     int i;
2091 
2092     err = __phy_write(phydev, MII_VCT5_SAMPLE_POINT_DISTANCE,
2093               distance);
2094     if (err)
2095         return err;
2096 
2097     reg = MII_VCT5_CTRL_ENABLE |
2098         MII_VCT5_CTRL_TX_SAME_CHANNEL |
2099         MII_VCT5_CTRL_SAMPLES_DEFAULT |
2100         MII_VCT5_CTRL_SAMPLE_POINT |
2101         MII_VCT5_CTRL_PEEK_HYST_DEFAULT;
2102     err = __phy_write(phydev, MII_VCT5_CTRL, reg);
2103     if (err)
2104         return err;
2105 
2106     err = marvell_vct5_wait_complete(phydev);
2107     if (err)
2108         return err;
2109 
2110     for (i = 0; i < 4; i++) {
2111         if (pair != PHY_PAIR_ALL && i != pair)
2112             continue;
2113 
2114         mV = marvell_vct5_amplitude(phydev, i);
2115         ethnl_cable_test_amplitude(phydev, i, mV);
2116     }
2117 
2118     return 0;
2119 }
2120 
2121 static int marvell_vct5_amplitude_graph(struct phy_device *phydev)
2122 {
2123     struct marvell_priv *priv = phydev->priv;
2124     int distance;
2125     u16 width;
2126     int page;
2127     int err;
2128     u16 reg;
2129 
2130     if (priv->first <= TDR_SHORT_CABLE_LENGTH)
2131         width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS;
2132     else
2133         width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS;
2134 
2135     reg = MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV |
2136         MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN |
2137         MII_VCT5_TX_PULSE_CTRL_MAX_AMP | width;
2138 
2139     err = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
2140                   MII_VCT5_TX_PULSE_CTRL, reg);
2141     if (err)
2142         return err;
2143 
2144     /* Reading the TDR data is very MDIO heavy. We need to optimize
2145      * access to keep the time to a minimum. So lock the bus once,
2146      * and don't release it until complete. We can then avoid having
2147      * to change the page for every access, greatly speeding things
2148      * up.
2149      */
2150     page = phy_select_page(phydev, MII_MARVELL_VCT5_PAGE);
2151     if (page < 0)
2152         goto restore_page;
2153 
2154     for (distance = priv->first;
2155          distance <= priv->last;
2156          distance += priv->step) {
2157         err = marvell_vct5_amplitude_distance(phydev, distance,
2158                               priv->pair);
2159         if (err)
2160             goto restore_page;
2161 
2162         if (distance > TDR_SHORT_CABLE_LENGTH &&
2163             width == MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS) {
2164             width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS;
2165             reg = MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV |
2166                 MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN |
2167                 MII_VCT5_TX_PULSE_CTRL_MAX_AMP | width;
2168             err = __phy_write(phydev, MII_VCT5_TX_PULSE_CTRL, reg);
2169             if (err)
2170                 goto restore_page;
2171         }
2172     }
2173 
2174 restore_page:
2175     return phy_restore_page(phydev, page, err);
2176 }
2177 
2178 static int marvell_cable_test_start_common(struct phy_device *phydev)
2179 {
2180     int bmcr, bmsr, ret;
2181 
2182     /* If auto-negotiation is enabled, but not complete, the cable
2183      * test never completes. So disable auto-neg.
2184      */
2185     bmcr = phy_read(phydev, MII_BMCR);
2186     if (bmcr < 0)
2187         return bmcr;
2188 
2189     bmsr = phy_read(phydev, MII_BMSR);
2190 
2191     if (bmsr < 0)
2192         return bmsr;
2193 
2194     if (bmcr & BMCR_ANENABLE) {
2195         ret =  phy_clear_bits(phydev, MII_BMCR, BMCR_ANENABLE);
2196         if (ret < 0)
2197             return ret;
2198         ret = genphy_soft_reset(phydev);
2199         if (ret < 0)
2200             return ret;
2201     }
2202 
2203     /* If the link is up, allow it some time to go down */
2204     if (bmsr & BMSR_LSTATUS)
2205         msleep(1500);
2206 
2207     return 0;
2208 }
2209 
2210 static int marvell_vct7_cable_test_start(struct phy_device *phydev)
2211 {
2212     struct marvell_priv *priv = phydev->priv;
2213     int ret;
2214 
2215     ret = marvell_cable_test_start_common(phydev);
2216     if (ret)
2217         return ret;
2218 
2219     priv->cable_test_tdr = false;
2220 
2221     /* Reset the VCT5 API control to defaults, otherwise
2222      * VCT7 does not work correctly.
2223      */
2224     ret = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
2225                   MII_VCT5_CTRL,
2226                   MII_VCT5_CTRL_TX_SAME_CHANNEL |
2227                   MII_VCT5_CTRL_SAMPLES_DEFAULT |
2228                   MII_VCT5_CTRL_MODE_MAXIMUM_PEEK |
2229                   MII_VCT5_CTRL_PEEK_HYST_DEFAULT);
2230     if (ret)
2231         return ret;
2232 
2233     ret = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
2234                   MII_VCT5_SAMPLE_POINT_DISTANCE, 0);
2235     if (ret)
2236         return ret;
2237 
2238     return phy_write_paged(phydev, MII_MARVELL_VCT7_PAGE,
2239                    MII_VCT7_CTRL,
2240                    MII_VCT7_CTRL_RUN_NOW |
2241                    MII_VCT7_CTRL_CENTIMETERS);
2242 }
2243 
2244 static int marvell_vct5_cable_test_tdr_start(struct phy_device *phydev,
2245                          const struct phy_tdr_config *cfg)
2246 {
2247     struct marvell_priv *priv = phydev->priv;
2248     int ret;
2249 
2250     priv->cable_test_tdr = true;
2251     priv->first = marvell_vct5_cm2distance(cfg->first);
2252     priv->last = marvell_vct5_cm2distance(cfg->last);
2253     priv->step = marvell_vct5_cm2distance(cfg->step);
2254     priv->pair = cfg->pair;
2255 
2256     if (priv->first > MII_VCT5_SAMPLE_POINT_DISTANCE_MAX)
2257         return -EINVAL;
2258 
2259     if (priv->last > MII_VCT5_SAMPLE_POINT_DISTANCE_MAX)
2260         return -EINVAL;
2261 
2262     /* Disable  VCT7 */
2263     ret = phy_write_paged(phydev, MII_MARVELL_VCT7_PAGE,
2264                   MII_VCT7_CTRL, 0);
2265     if (ret)
2266         return ret;
2267 
2268     ret = marvell_cable_test_start_common(phydev);
2269     if (ret)
2270         return ret;
2271 
2272     ret = ethnl_cable_test_pulse(phydev, 1000);
2273     if (ret)
2274         return ret;
2275 
2276     return ethnl_cable_test_step(phydev,
2277                      marvell_vct5_distance2cm(priv->first),
2278                      marvell_vct5_distance2cm(priv->last),
2279                      marvell_vct5_distance2cm(priv->step));
2280 }
2281 
2282 static int marvell_vct7_distance_to_length(int distance, bool meter)
2283 {
2284     if (meter)
2285         distance *= 100;
2286 
2287     return distance;
2288 }
2289 
2290 static bool marvell_vct7_distance_valid(int result)
2291 {
2292     switch (result) {
2293     case MII_VCT7_RESULTS_OPEN:
2294     case MII_VCT7_RESULTS_SAME_SHORT:
2295     case MII_VCT7_RESULTS_CROSS_SHORT:
2296         return true;
2297     }
2298     return false;
2299 }
2300 
2301 static int marvell_vct7_report_length(struct phy_device *phydev,
2302                       int pair, bool meter)
2303 {
2304     int length;
2305     int ret;
2306 
2307     ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2308                  MII_VCT7_PAIR_0_DISTANCE + pair);
2309     if (ret < 0)
2310         return ret;
2311 
2312     length = marvell_vct7_distance_to_length(ret, meter);
2313 
2314     ethnl_cable_test_fault_length(phydev, pair, length);
2315 
2316     return 0;
2317 }
2318 
2319 static int marvell_vct7_cable_test_report_trans(int result)
2320 {
2321     switch (result) {
2322     case MII_VCT7_RESULTS_OK:
2323         return ETHTOOL_A_CABLE_RESULT_CODE_OK;
2324     case MII_VCT7_RESULTS_OPEN:
2325         return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
2326     case MII_VCT7_RESULTS_SAME_SHORT:
2327         return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
2328     case MII_VCT7_RESULTS_CROSS_SHORT:
2329         return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
2330     default:
2331         return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
2332     }
2333 }
2334 
2335 static int marvell_vct7_cable_test_report(struct phy_device *phydev)
2336 {
2337     int pair0, pair1, pair2, pair3;
2338     bool meter;
2339     int ret;
2340 
2341     ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2342                  MII_VCT7_RESULTS);
2343     if (ret < 0)
2344         return ret;
2345 
2346     pair3 = (ret & MII_VCT7_RESULTS_PAIR3_MASK) >>
2347         MII_VCT7_RESULTS_PAIR3_SHIFT;
2348     pair2 = (ret & MII_VCT7_RESULTS_PAIR2_MASK) >>
2349         MII_VCT7_RESULTS_PAIR2_SHIFT;
2350     pair1 = (ret & MII_VCT7_RESULTS_PAIR1_MASK) >>
2351         MII_VCT7_RESULTS_PAIR1_SHIFT;
2352     pair0 = (ret & MII_VCT7_RESULTS_PAIR0_MASK) >>
2353         MII_VCT7_RESULTS_PAIR0_SHIFT;
2354 
2355     ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
2356                 marvell_vct7_cable_test_report_trans(pair0));
2357     ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
2358                 marvell_vct7_cable_test_report_trans(pair1));
2359     ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C,
2360                 marvell_vct7_cable_test_report_trans(pair2));
2361     ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
2362                 marvell_vct7_cable_test_report_trans(pair3));
2363 
2364     ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE, MII_VCT7_CTRL);
2365     if (ret < 0)
2366         return ret;
2367 
2368     meter = ret & MII_VCT7_CTRL_METERS;
2369 
2370     if (marvell_vct7_distance_valid(pair0))
2371         marvell_vct7_report_length(phydev, 0, meter);
2372     if (marvell_vct7_distance_valid(pair1))
2373         marvell_vct7_report_length(phydev, 1, meter);
2374     if (marvell_vct7_distance_valid(pair2))
2375         marvell_vct7_report_length(phydev, 2, meter);
2376     if (marvell_vct7_distance_valid(pair3))
2377         marvell_vct7_report_length(phydev, 3, meter);
2378 
2379     return 0;
2380 }
2381 
2382 static int marvell_vct7_cable_test_get_status(struct phy_device *phydev,
2383                           bool *finished)
2384 {
2385     struct marvell_priv *priv = phydev->priv;
2386     int ret;
2387 
2388     if (priv->cable_test_tdr) {
2389         ret = marvell_vct5_amplitude_graph(phydev);
2390         *finished = true;
2391         return ret;
2392     }
2393 
2394     *finished = false;
2395 
2396     ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2397                  MII_VCT7_CTRL);
2398 
2399     if (ret < 0)
2400         return ret;
2401 
2402     if (!(ret & MII_VCT7_CTRL_IN_PROGRESS)) {
2403         *finished = true;
2404 
2405         return marvell_vct7_cable_test_report(phydev);
2406     }
2407 
2408     return 0;
2409 }
2410 
2411 #ifdef CONFIG_HWMON
2412 struct marvell_hwmon_ops {
2413     int (*config)(struct phy_device *phydev);
2414     int (*get_temp)(struct phy_device *phydev, long *temp);
2415     int (*get_temp_critical)(struct phy_device *phydev, long *temp);
2416     int (*set_temp_critical)(struct phy_device *phydev, long temp);
2417     int (*get_temp_alarm)(struct phy_device *phydev, long *alarm);
2418 };
2419 
2420 static const struct marvell_hwmon_ops *
2421 to_marvell_hwmon_ops(const struct phy_device *phydev)
2422 {
2423     return phydev->drv->driver_data;
2424 }
2425 
2426 static int m88e1121_get_temp(struct phy_device *phydev, long *temp)
2427 {
2428     int oldpage;
2429     int ret = 0;
2430     int val;
2431 
2432     *temp = 0;
2433 
2434     oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
2435     if (oldpage < 0)
2436         goto error;
2437 
2438     /* Enable temperature sensor */
2439     ret = __phy_read(phydev, MII_88E1121_MISC_TEST);
2440     if (ret < 0)
2441         goto error;
2442 
2443     ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
2444               ret | MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
2445     if (ret < 0)
2446         goto error;
2447 
2448     /* Wait for temperature to stabilize */
2449     usleep_range(10000, 12000);
2450 
2451     val = __phy_read(phydev, MII_88E1121_MISC_TEST);
2452     if (val < 0) {
2453         ret = val;
2454         goto error;
2455     }
2456 
2457     /* Disable temperature sensor */
2458     ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
2459               ret & ~MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
2460     if (ret < 0)
2461         goto error;
2462 
2463     *temp = ((val & MII_88E1121_MISC_TEST_TEMP_MASK) - 5) * 5000;
2464 
2465 error:
2466     return phy_restore_page(phydev, oldpage, ret);
2467 }
2468 
2469 static int m88e1510_get_temp(struct phy_device *phydev, long *temp)
2470 {
2471     int ret;
2472 
2473     *temp = 0;
2474 
2475     ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2476                  MII_88E1510_TEMP_SENSOR);
2477     if (ret < 0)
2478         return ret;
2479 
2480     *temp = ((ret & MII_88E1510_TEMP_SENSOR_MASK) - 25) * 1000;
2481 
2482     return 0;
2483 }
2484 
2485 static int m88e1510_get_temp_critical(struct phy_device *phydev, long *temp)
2486 {
2487     int ret;
2488 
2489     *temp = 0;
2490 
2491     ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2492                  MII_88E1121_MISC_TEST);
2493     if (ret < 0)
2494         return ret;
2495 
2496     *temp = (((ret & MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK) >>
2497           MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT) * 5) - 25;
2498     /* convert to mC */
2499     *temp *= 1000;
2500 
2501     return 0;
2502 }
2503 
2504 static int m88e1510_set_temp_critical(struct phy_device *phydev, long temp)
2505 {
2506     temp = temp / 1000;
2507     temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
2508 
2509     return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2510                 MII_88E1121_MISC_TEST,
2511                 MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK,
2512                 temp << MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT);
2513 }
2514 
2515 static int m88e1510_get_temp_alarm(struct phy_device *phydev, long *alarm)
2516 {
2517     int ret;
2518 
2519     *alarm = false;
2520 
2521     ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2522                  MII_88E1121_MISC_TEST);
2523     if (ret < 0)
2524         return ret;
2525 
2526     *alarm = !!(ret & MII_88E1510_MISC_TEST_TEMP_IRQ);
2527 
2528     return 0;
2529 }
2530 
2531 static int m88e6390_get_temp(struct phy_device *phydev, long *temp)
2532 {
2533     int sum = 0;
2534     int oldpage;
2535     int ret = 0;
2536     int i;
2537 
2538     *temp = 0;
2539 
2540     oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
2541     if (oldpage < 0)
2542         goto error;
2543 
2544     /* Enable temperature sensor */
2545     ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
2546     if (ret < 0)
2547         goto error;
2548 
2549     ret &= ~MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK;
2550     ret |= MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE_SAMPLE_1S;
2551 
2552     ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
2553     if (ret < 0)
2554         goto error;
2555 
2556     /* Wait for temperature to stabilize */
2557     usleep_range(10000, 12000);
2558 
2559     /* Reading the temperature sense has an errata. You need to read
2560      * a number of times and take an average.
2561      */
2562     for (i = 0; i < MII_88E6390_TEMP_SENSOR_SAMPLES; i++) {
2563         ret = __phy_read(phydev, MII_88E6390_TEMP_SENSOR);
2564         if (ret < 0)
2565             goto error;
2566         sum += ret & MII_88E6390_TEMP_SENSOR_MASK;
2567     }
2568 
2569     sum /= MII_88E6390_TEMP_SENSOR_SAMPLES;
2570     *temp = (sum  - 75) * 1000;
2571 
2572     /* Disable temperature sensor */
2573     ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
2574     if (ret < 0)
2575         goto error;
2576 
2577     ret = ret & ~MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK;
2578     ret |= MII_88E6390_MISC_TEST_TEMP_SENSOR_DISABLE;
2579 
2580     ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
2581 
2582 error:
2583     phy_restore_page(phydev, oldpage, ret);
2584 
2585     return ret;
2586 }
2587 
2588 static int m88e6393_get_temp(struct phy_device *phydev, long *temp)
2589 {
2590     int err;
2591 
2592     err = m88e1510_get_temp(phydev, temp);
2593 
2594     /* 88E1510 measures T + 25, while the PHY on 88E6393X switch
2595      * T + 75, so we have to subtract another 50
2596      */
2597     *temp -= 50000;
2598 
2599     return err;
2600 }
2601 
2602 static int m88e6393_get_temp_critical(struct phy_device *phydev, long *temp)
2603 {
2604     int ret;
2605 
2606     *temp = 0;
2607 
2608     ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2609                  MII_88E6390_TEMP_SENSOR);
2610     if (ret < 0)
2611         return ret;
2612 
2613     *temp = (((ret & MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK) >>
2614           MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT) - 75) * 1000;
2615 
2616     return 0;
2617 }
2618 
2619 static int m88e6393_set_temp_critical(struct phy_device *phydev, long temp)
2620 {
2621     temp = (temp / 1000) + 75;
2622 
2623     return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2624                 MII_88E6390_TEMP_SENSOR,
2625                 MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK,
2626                 temp << MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT);
2627 }
2628 
2629 static int m88e6393_hwmon_config(struct phy_device *phydev)
2630 {
2631     int err;
2632 
2633     err = m88e6393_set_temp_critical(phydev, 100000);
2634     if (err)
2635         return err;
2636 
2637     return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2638                 MII_88E6390_MISC_TEST,
2639                 MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK |
2640                 MII_88E6393_MISC_TEST_SAMPLES_MASK |
2641                 MII_88E6393_MISC_TEST_RATE_MASK,
2642                 MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE |
2643                 MII_88E6393_MISC_TEST_SAMPLES_2048 |
2644                 MII_88E6393_MISC_TEST_RATE_2_3MS);
2645 }
2646 
2647 static int marvell_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
2648                   u32 attr, int channel, long *temp)
2649 {
2650     struct phy_device *phydev = dev_get_drvdata(dev);
2651     const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
2652     int err = -EOPNOTSUPP;
2653 
2654     switch (attr) {
2655     case hwmon_temp_input:
2656         if (ops->get_temp)
2657             err = ops->get_temp(phydev, temp);
2658         break;
2659     case hwmon_temp_crit:
2660         if (ops->get_temp_critical)
2661             err = ops->get_temp_critical(phydev, temp);
2662         break;
2663     case hwmon_temp_max_alarm:
2664         if (ops->get_temp_alarm)
2665             err = ops->get_temp_alarm(phydev, temp);
2666         break;
2667     }
2668 
2669     return err;
2670 }
2671 
2672 static int marvell_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
2673                    u32 attr, int channel, long temp)
2674 {
2675     struct phy_device *phydev = dev_get_drvdata(dev);
2676     const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
2677     int err = -EOPNOTSUPP;
2678 
2679     switch (attr) {
2680     case hwmon_temp_crit:
2681         if (ops->set_temp_critical)
2682             err = ops->set_temp_critical(phydev, temp);
2683         break;
2684     }
2685 
2686     return err;
2687 }
2688 
2689 static umode_t marvell_hwmon_is_visible(const void *data,
2690                     enum hwmon_sensor_types type,
2691                     u32 attr, int channel)
2692 {
2693     const struct phy_device *phydev = data;
2694     const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
2695 
2696     if (type != hwmon_temp)
2697         return 0;
2698 
2699     switch (attr) {
2700     case hwmon_temp_input:
2701         return ops->get_temp ? 0444 : 0;
2702     case hwmon_temp_max_alarm:
2703         return ops->get_temp_alarm ? 0444 : 0;
2704     case hwmon_temp_crit:
2705         return (ops->get_temp_critical ? 0444 : 0) |
2706                (ops->set_temp_critical ? 0200 : 0);
2707     default:
2708         return 0;
2709     }
2710 }
2711 
2712 static u32 marvell_hwmon_chip_config[] = {
2713     HWMON_C_REGISTER_TZ,
2714     0
2715 };
2716 
2717 static const struct hwmon_channel_info marvell_hwmon_chip = {
2718     .type = hwmon_chip,
2719     .config = marvell_hwmon_chip_config,
2720 };
2721 
2722 /* we can define HWMON_T_CRIT and HWMON_T_MAX_ALARM even though these are not
2723  * defined for all PHYs, because the hwmon code checks whether the attributes
2724  * exists via the .is_visible method
2725  */
2726 static u32 marvell_hwmon_temp_config[] = {
2727     HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM,
2728     0
2729 };
2730 
2731 static const struct hwmon_channel_info marvell_hwmon_temp = {
2732     .type = hwmon_temp,
2733     .config = marvell_hwmon_temp_config,
2734 };
2735 
2736 static const struct hwmon_channel_info *marvell_hwmon_info[] = {
2737     &marvell_hwmon_chip,
2738     &marvell_hwmon_temp,
2739     NULL
2740 };
2741 
2742 static const struct hwmon_ops marvell_hwmon_hwmon_ops = {
2743     .is_visible = marvell_hwmon_is_visible,
2744     .read = marvell_hwmon_read,
2745     .write = marvell_hwmon_write,
2746 };
2747 
2748 static const struct hwmon_chip_info marvell_hwmon_chip_info = {
2749     .ops = &marvell_hwmon_hwmon_ops,
2750     .info = marvell_hwmon_info,
2751 };
2752 
2753 static int marvell_hwmon_name(struct phy_device *phydev)
2754 {
2755     struct marvell_priv *priv = phydev->priv;
2756     struct device *dev = &phydev->mdio.dev;
2757     const char *devname = dev_name(dev);
2758     size_t len = strlen(devname);
2759     int i, j;
2760 
2761     priv->hwmon_name = devm_kzalloc(dev, len, GFP_KERNEL);
2762     if (!priv->hwmon_name)
2763         return -ENOMEM;
2764 
2765     for (i = j = 0; i < len && devname[i]; i++) {
2766         if (isalnum(devname[i]))
2767             priv->hwmon_name[j++] = devname[i];
2768     }
2769 
2770     return 0;
2771 }
2772 
2773 static int marvell_hwmon_probe(struct phy_device *phydev)
2774 {
2775     const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
2776     struct marvell_priv *priv = phydev->priv;
2777     struct device *dev = &phydev->mdio.dev;
2778     int err;
2779 
2780     if (!ops)
2781         return 0;
2782 
2783     err = marvell_hwmon_name(phydev);
2784     if (err)
2785         return err;
2786 
2787     priv->hwmon_dev = devm_hwmon_device_register_with_info(
2788         dev, priv->hwmon_name, phydev, &marvell_hwmon_chip_info, NULL);
2789     if (IS_ERR(priv->hwmon_dev))
2790         return PTR_ERR(priv->hwmon_dev);
2791 
2792     if (ops->config)
2793         err = ops->config(phydev);
2794 
2795     return err;
2796 }
2797 
2798 static const struct marvell_hwmon_ops m88e1121_hwmon_ops = {
2799     .get_temp = m88e1121_get_temp,
2800 };
2801 
2802 static const struct marvell_hwmon_ops m88e1510_hwmon_ops = {
2803     .get_temp = m88e1510_get_temp,
2804     .get_temp_critical = m88e1510_get_temp_critical,
2805     .set_temp_critical = m88e1510_set_temp_critical,
2806     .get_temp_alarm = m88e1510_get_temp_alarm,
2807 };
2808 
2809 static const struct marvell_hwmon_ops m88e6390_hwmon_ops = {
2810     .get_temp = m88e6390_get_temp,
2811 };
2812 
2813 static const struct marvell_hwmon_ops m88e6393_hwmon_ops = {
2814     .config = m88e6393_hwmon_config,
2815     .get_temp = m88e6393_get_temp,
2816     .get_temp_critical = m88e6393_get_temp_critical,
2817     .set_temp_critical = m88e6393_set_temp_critical,
2818     .get_temp_alarm = m88e1510_get_temp_alarm,
2819 };
2820 
2821 #define DEF_MARVELL_HWMON_OPS(s) (&(s))
2822 
2823 #else
2824 
2825 #define DEF_MARVELL_HWMON_OPS(s) NULL
2826 
2827 static int marvell_hwmon_probe(struct phy_device *phydev)
2828 {
2829     return 0;
2830 }
2831 #endif
2832 
2833 static int marvell_probe(struct phy_device *phydev)
2834 {
2835     struct marvell_priv *priv;
2836 
2837     priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
2838     if (!priv)
2839         return -ENOMEM;
2840 
2841     phydev->priv = priv;
2842 
2843     return marvell_hwmon_probe(phydev);
2844 }
2845 
2846 static int m88e1510_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
2847 {
2848     struct phy_device *phydev = upstream;
2849     phy_interface_t interface;
2850     struct device *dev;
2851     int oldpage;
2852     int ret = 0;
2853     u16 mode;
2854 
2855     __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
2856 
2857     dev = &phydev->mdio.dev;
2858 
2859     sfp_parse_support(phydev->sfp_bus, id, supported);
2860     interface = sfp_select_interface(phydev->sfp_bus, supported);
2861 
2862     dev_info(dev, "%s SFP module inserted\n", phy_modes(interface));
2863 
2864     switch (interface) {
2865     case PHY_INTERFACE_MODE_1000BASEX:
2866         mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X;
2867 
2868         break;
2869     case PHY_INTERFACE_MODE_100BASEX:
2870         mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX;
2871 
2872         break;
2873     case PHY_INTERFACE_MODE_SGMII:
2874         mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII;
2875 
2876         break;
2877     default:
2878         dev_err(dev, "Incompatible SFP module inserted\n");
2879 
2880         return -EINVAL;
2881     }
2882 
2883     oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
2884     if (oldpage < 0)
2885         goto error;
2886 
2887     ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
2888                MII_88E1510_GEN_CTRL_REG_1_MODE_MASK, mode);
2889     if (ret < 0)
2890         goto error;
2891 
2892     ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
2893                  MII_88E1510_GEN_CTRL_REG_1_RESET);
2894 
2895 error:
2896     return phy_restore_page(phydev, oldpage, ret);
2897 }
2898 
2899 static void m88e1510_sfp_remove(void *upstream)
2900 {
2901     struct phy_device *phydev = upstream;
2902     int oldpage;
2903     int ret = 0;
2904 
2905     oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
2906     if (oldpage < 0)
2907         goto error;
2908 
2909     ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
2910                MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
2911                MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII);
2912     if (ret < 0)
2913         goto error;
2914 
2915     ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
2916                  MII_88E1510_GEN_CTRL_REG_1_RESET);
2917 
2918 error:
2919     phy_restore_page(phydev, oldpage, ret);
2920 }
2921 
2922 static const struct sfp_upstream_ops m88e1510_sfp_ops = {
2923     .module_insert = m88e1510_sfp_insert,
2924     .module_remove = m88e1510_sfp_remove,
2925     .attach = phy_sfp_attach,
2926     .detach = phy_sfp_detach,
2927 };
2928 
2929 static int m88e1510_probe(struct phy_device *phydev)
2930 {
2931     int err;
2932 
2933     err = marvell_probe(phydev);
2934     if (err)
2935         return err;
2936 
2937     return phy_sfp_probe(phydev, &m88e1510_sfp_ops);
2938 }
2939 
2940 static struct phy_driver marvell_drivers[] = {
2941     {
2942         .phy_id = MARVELL_PHY_ID_88E1101,
2943         .phy_id_mask = MARVELL_PHY_ID_MASK,
2944         .name = "Marvell 88E1101",
2945         /* PHY_GBIT_FEATURES */
2946         .probe = marvell_probe,
2947         .config_init = marvell_config_init,
2948         .config_aneg = m88e1101_config_aneg,
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     },
2959     {
2960         .phy_id = MARVELL_PHY_ID_88E1112,
2961         .phy_id_mask = MARVELL_PHY_ID_MASK,
2962         .name = "Marvell 88E1112",
2963         /* PHY_GBIT_FEATURES */
2964         .probe = marvell_probe,
2965         .config_init = m88e1112_config_init,
2966         .config_aneg = marvell_config_aneg,
2967         .config_intr = marvell_config_intr,
2968         .handle_interrupt = marvell_handle_interrupt,
2969         .resume = genphy_resume,
2970         .suspend = genphy_suspend,
2971         .read_page = marvell_read_page,
2972         .write_page = marvell_write_page,
2973         .get_sset_count = marvell_get_sset_count,
2974         .get_strings = marvell_get_strings,
2975         .get_stats = marvell_get_stats,
2976         .get_tunable = m88e1011_get_tunable,
2977         .set_tunable = m88e1011_set_tunable,
2978     },
2979     {
2980         .phy_id = MARVELL_PHY_ID_88E1111,
2981         .phy_id_mask = MARVELL_PHY_ID_MASK,
2982         .name = "Marvell 88E1111",
2983         /* PHY_GBIT_FEATURES */
2984         .probe = marvell_probe,
2985         .config_init = m88e1111gbe_config_init,
2986         .config_aneg = m88e1111_config_aneg,
2987         .read_status = marvell_read_status,
2988         .config_intr = marvell_config_intr,
2989         .handle_interrupt = marvell_handle_interrupt,
2990         .resume = genphy_resume,
2991         .suspend = genphy_suspend,
2992         .read_page = marvell_read_page,
2993         .write_page = marvell_write_page,
2994         .get_sset_count = marvell_get_sset_count,
2995         .get_strings = marvell_get_strings,
2996         .get_stats = marvell_get_stats,
2997         .get_tunable = m88e1111_get_tunable,
2998         .set_tunable = m88e1111_set_tunable,
2999     },
3000     {
3001         .phy_id = MARVELL_PHY_ID_88E1111_FINISAR,
3002         .phy_id_mask = MARVELL_PHY_ID_MASK,
3003         .name = "Marvell 88E1111 (Finisar)",
3004         /* PHY_GBIT_FEATURES */
3005         .probe = marvell_probe,
3006         .config_init = m88e1111gbe_config_init,
3007         .config_aneg = m88e1111_config_aneg,
3008         .read_status = marvell_read_status,
3009         .config_intr = marvell_config_intr,
3010         .handle_interrupt = marvell_handle_interrupt,
3011         .resume = genphy_resume,
3012         .suspend = genphy_suspend,
3013         .read_page = marvell_read_page,
3014         .write_page = marvell_write_page,
3015         .get_sset_count = marvell_get_sset_count,
3016         .get_strings = marvell_get_strings,
3017         .get_stats = marvell_get_stats,
3018         .get_tunable = m88e1111_get_tunable,
3019         .set_tunable = m88e1111_set_tunable,
3020     },
3021     {
3022         .phy_id = MARVELL_PHY_ID_88E1118,
3023         .phy_id_mask = MARVELL_PHY_ID_MASK,
3024         .name = "Marvell 88E1118",
3025         /* PHY_GBIT_FEATURES */
3026         .probe = marvell_probe,
3027         .config_init = m88e1118_config_init,
3028         .config_aneg = m88e1118_config_aneg,
3029         .config_intr = marvell_config_intr,
3030         .handle_interrupt = marvell_handle_interrupt,
3031         .resume = genphy_resume,
3032         .suspend = genphy_suspend,
3033         .read_page = marvell_read_page,
3034         .write_page = marvell_write_page,
3035         .get_sset_count = marvell_get_sset_count,
3036         .get_strings = marvell_get_strings,
3037         .get_stats = marvell_get_stats,
3038     },
3039     {
3040         .phy_id = MARVELL_PHY_ID_88E1121R,
3041         .phy_id_mask = MARVELL_PHY_ID_MASK,
3042         .name = "Marvell 88E1121R",
3043         .driver_data = DEF_MARVELL_HWMON_OPS(m88e1121_hwmon_ops),
3044         /* PHY_GBIT_FEATURES */
3045         .probe = marvell_probe,
3046         .config_init = marvell_1011gbe_config_init,
3047         .config_aneg = m88e1121_config_aneg,
3048         .read_status = marvell_read_status,
3049         .config_intr = marvell_config_intr,
3050         .handle_interrupt = marvell_handle_interrupt,
3051         .resume = genphy_resume,
3052         .suspend = genphy_suspend,
3053         .read_page = marvell_read_page,
3054         .write_page = marvell_write_page,
3055         .get_sset_count = marvell_get_sset_count,
3056         .get_strings = marvell_get_strings,
3057         .get_stats = marvell_get_stats,
3058         .get_tunable = m88e1011_get_tunable,
3059         .set_tunable = m88e1011_set_tunable,
3060     },
3061     {
3062         .phy_id = MARVELL_PHY_ID_88E1318S,
3063         .phy_id_mask = MARVELL_PHY_ID_MASK,
3064         .name = "Marvell 88E1318S",
3065         /* PHY_GBIT_FEATURES */
3066         .probe = marvell_probe,
3067         .config_init = m88e1318_config_init,
3068         .config_aneg = m88e1318_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 = genphy_resume,
3075         .suspend = genphy_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     },
3082     {
3083         .phy_id = MARVELL_PHY_ID_88E1145,
3084         .phy_id_mask = MARVELL_PHY_ID_MASK,
3085         .name = "Marvell 88E1145",
3086         /* PHY_GBIT_FEATURES */
3087         .probe = marvell_probe,
3088         .config_init = m88e1145_config_init,
3089         .config_aneg = m88e1101_config_aneg,
3090         .config_intr = marvell_config_intr,
3091         .handle_interrupt = marvell_handle_interrupt,
3092         .resume = genphy_resume,
3093         .suspend = genphy_suspend,
3094         .read_page = marvell_read_page,
3095         .write_page = marvell_write_page,
3096         .get_sset_count = marvell_get_sset_count,
3097         .get_strings = marvell_get_strings,
3098         .get_stats = marvell_get_stats,
3099         .get_tunable = m88e1111_get_tunable,
3100         .set_tunable = m88e1111_set_tunable,
3101     },
3102     {
3103         .phy_id = MARVELL_PHY_ID_88E1149R,
3104         .phy_id_mask = MARVELL_PHY_ID_MASK,
3105         .name = "Marvell 88E1149R",
3106         /* PHY_GBIT_FEATURES */
3107         .probe = marvell_probe,
3108         .config_init = m88e1149_config_init,
3109         .config_aneg = m88e1118_config_aneg,
3110         .config_intr = marvell_config_intr,
3111         .handle_interrupt = marvell_handle_interrupt,
3112         .resume = genphy_resume,
3113         .suspend = genphy_suspend,
3114         .read_page = marvell_read_page,
3115         .write_page = marvell_write_page,
3116         .get_sset_count = marvell_get_sset_count,
3117         .get_strings = marvell_get_strings,
3118         .get_stats = marvell_get_stats,
3119     },
3120     {
3121         .phy_id = MARVELL_PHY_ID_88E1240,
3122         .phy_id_mask = MARVELL_PHY_ID_MASK,
3123         .name = "Marvell 88E1240",
3124         /* PHY_GBIT_FEATURES */
3125         .probe = marvell_probe,
3126         .config_init = m88e1112_config_init,
3127         .config_aneg = marvell_config_aneg,
3128         .config_intr = marvell_config_intr,
3129         .handle_interrupt = marvell_handle_interrupt,
3130         .resume = genphy_resume,
3131         .suspend = genphy_suspend,
3132         .read_page = marvell_read_page,
3133         .write_page = marvell_write_page,
3134         .get_sset_count = marvell_get_sset_count,
3135         .get_strings = marvell_get_strings,
3136         .get_stats = marvell_get_stats,
3137         .get_tunable = m88e1011_get_tunable,
3138         .set_tunable = m88e1011_set_tunable,
3139     },
3140     {
3141         .phy_id = MARVELL_PHY_ID_88E1116R,
3142         .phy_id_mask = MARVELL_PHY_ID_MASK,
3143         .name = "Marvell 88E1116R",
3144         /* PHY_GBIT_FEATURES */
3145         .probe = marvell_probe,
3146         .config_init = m88e1116r_config_init,
3147         .config_intr = marvell_config_intr,
3148         .handle_interrupt = marvell_handle_interrupt,
3149         .resume = genphy_resume,
3150         .suspend = genphy_suspend,
3151         .read_page = marvell_read_page,
3152         .write_page = marvell_write_page,
3153         .get_sset_count = marvell_get_sset_count,
3154         .get_strings = marvell_get_strings,
3155         .get_stats = marvell_get_stats,
3156         .get_tunable = m88e1011_get_tunable,
3157         .set_tunable = m88e1011_set_tunable,
3158     },
3159     {
3160         .phy_id = MARVELL_PHY_ID_88E1510,
3161         .phy_id_mask = MARVELL_PHY_ID_MASK,
3162         .name = "Marvell 88E1510",
3163         .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3164         .features = PHY_GBIT_FIBRE_FEATURES,
3165         .flags = PHY_POLL_CABLE_TEST,
3166         .probe = m88e1510_probe,
3167         .config_init = m88e1510_config_init,
3168         .config_aneg = m88e1510_config_aneg,
3169         .read_status = marvell_read_status,
3170         .config_intr = marvell_config_intr,
3171         .handle_interrupt = marvell_handle_interrupt,
3172         .get_wol = m88e1318_get_wol,
3173         .set_wol = m88e1318_set_wol,
3174         .resume = marvell_resume,
3175         .suspend = marvell_suspend,
3176         .read_page = marvell_read_page,
3177         .write_page = marvell_write_page,
3178         .get_sset_count = marvell_get_sset_count,
3179         .get_strings = marvell_get_strings,
3180         .get_stats = marvell_get_stats,
3181         .set_loopback = m88e1510_loopback,
3182         .get_tunable = m88e1011_get_tunable,
3183         .set_tunable = m88e1011_set_tunable,
3184         .cable_test_start = marvell_vct7_cable_test_start,
3185         .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
3186         .cable_test_get_status = marvell_vct7_cable_test_get_status,
3187     },
3188     {
3189         .phy_id = MARVELL_PHY_ID_88E1540,
3190         .phy_id_mask = MARVELL_PHY_ID_MASK,
3191         .name = "Marvell 88E1540",
3192         .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3193         /* PHY_GBIT_FEATURES */
3194         .flags = PHY_POLL_CABLE_TEST,
3195         .probe = marvell_probe,
3196         .config_init = marvell_1011gbe_config_init,
3197         .config_aneg = m88e1510_config_aneg,
3198         .read_status = marvell_read_status,
3199         .config_intr = marvell_config_intr,
3200         .handle_interrupt = marvell_handle_interrupt,
3201         .resume = genphy_resume,
3202         .suspend = genphy_suspend,
3203         .read_page = marvell_read_page,
3204         .write_page = marvell_write_page,
3205         .get_sset_count = marvell_get_sset_count,
3206         .get_strings = marvell_get_strings,
3207         .get_stats = marvell_get_stats,
3208         .get_tunable = m88e1540_get_tunable,
3209         .set_tunable = m88e1540_set_tunable,
3210         .cable_test_start = marvell_vct7_cable_test_start,
3211         .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
3212         .cable_test_get_status = marvell_vct7_cable_test_get_status,
3213     },
3214     {
3215         .phy_id = MARVELL_PHY_ID_88E1545,
3216         .phy_id_mask = MARVELL_PHY_ID_MASK,
3217         .name = "Marvell 88E1545",
3218         .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3219         .probe = marvell_probe,
3220         /* PHY_GBIT_FEATURES */
3221         .flags = PHY_POLL_CABLE_TEST,
3222         .config_init = marvell_1011gbe_config_init,
3223         .config_aneg = m88e1510_config_aneg,
3224         .read_status = marvell_read_status,
3225         .config_intr = marvell_config_intr,
3226         .handle_interrupt = marvell_handle_interrupt,
3227         .resume = genphy_resume,
3228         .suspend = genphy_suspend,
3229         .read_page = marvell_read_page,
3230         .write_page = marvell_write_page,
3231         .get_sset_count = marvell_get_sset_count,
3232         .get_strings = marvell_get_strings,
3233         .get_stats = marvell_get_stats,
3234         .get_tunable = m88e1540_get_tunable,
3235         .set_tunable = m88e1540_set_tunable,
3236         .cable_test_start = marvell_vct7_cable_test_start,
3237         .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
3238         .cable_test_get_status = marvell_vct7_cable_test_get_status,
3239     },
3240     {
3241         .phy_id = MARVELL_PHY_ID_88E3016,
3242         .phy_id_mask = MARVELL_PHY_ID_MASK,
3243         .name = "Marvell 88E3016",
3244         /* PHY_BASIC_FEATURES */
3245         .probe = marvell_probe,
3246         .config_init = m88e3016_config_init,
3247         .aneg_done = marvell_aneg_done,
3248         .read_status = marvell_read_status,
3249         .config_intr = marvell_config_intr,
3250         .handle_interrupt = marvell_handle_interrupt,
3251         .resume = genphy_resume,
3252         .suspend = genphy_suspend,
3253         .read_page = marvell_read_page,
3254         .write_page = marvell_write_page,
3255         .get_sset_count = marvell_get_sset_count,
3256         .get_strings = marvell_get_strings,
3257         .get_stats = marvell_get_stats,
3258     },
3259     {
3260         .phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
3261         .phy_id_mask = MARVELL_PHY_ID_MASK,
3262         .name = "Marvell 88E6341 Family",
3263         .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3264         /* PHY_GBIT_FEATURES */
3265         .flags = PHY_POLL_CABLE_TEST,
3266         .probe = marvell_probe,
3267         .config_init = marvell_1011gbe_config_init,
3268         .config_aneg = m88e6390_config_aneg,
3269         .read_status = marvell_read_status,
3270         .config_intr = marvell_config_intr,
3271         .handle_interrupt = marvell_handle_interrupt,
3272         .resume = genphy_resume,
3273         .suspend = genphy_suspend,
3274         .read_page = marvell_read_page,
3275         .write_page = marvell_write_page,
3276         .get_sset_count = marvell_get_sset_count,
3277         .get_strings = marvell_get_strings,
3278         .get_stats = marvell_get_stats,
3279         .get_tunable = m88e1540_get_tunable,
3280         .set_tunable = m88e1540_set_tunable,
3281         .cable_test_start = marvell_vct7_cable_test_start,
3282         .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
3283         .cable_test_get_status = marvell_vct7_cable_test_get_status,
3284     },
3285     {
3286         .phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
3287         .phy_id_mask = MARVELL_PHY_ID_MASK,
3288         .name = "Marvell 88E6390 Family",
3289         .driver_data = DEF_MARVELL_HWMON_OPS(m88e6390_hwmon_ops),
3290         /* PHY_GBIT_FEATURES */
3291         .flags = PHY_POLL_CABLE_TEST,
3292         .probe = marvell_probe,
3293         .config_init = marvell_1011gbe_config_init,
3294         .config_aneg = m88e6390_config_aneg,
3295         .read_status = marvell_read_status,
3296         .config_intr = marvell_config_intr,
3297         .handle_interrupt = marvell_handle_interrupt,
3298         .resume = genphy_resume,
3299         .suspend = genphy_suspend,
3300         .read_page = marvell_read_page,
3301         .write_page = marvell_write_page,
3302         .get_sset_count = marvell_get_sset_count,
3303         .get_strings = marvell_get_strings,
3304         .get_stats = marvell_get_stats,
3305         .get_tunable = m88e1540_get_tunable,
3306         .set_tunable = m88e1540_set_tunable,
3307         .cable_test_start = marvell_vct7_cable_test_start,
3308         .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
3309         .cable_test_get_status = marvell_vct7_cable_test_get_status,
3310     },
3311     {
3312         .phy_id = MARVELL_PHY_ID_88E6393_FAMILY,
3313         .phy_id_mask = MARVELL_PHY_ID_MASK,
3314         .name = "Marvell 88E6393 Family",
3315         .driver_data = DEF_MARVELL_HWMON_OPS(m88e6393_hwmon_ops),
3316         /* PHY_GBIT_FEATURES */
3317         .flags = PHY_POLL_CABLE_TEST,
3318         .probe = marvell_probe,
3319         .config_init = marvell_1011gbe_config_init,
3320         .config_aneg = m88e1510_config_aneg,
3321         .read_status = marvell_read_status,
3322         .config_intr = marvell_config_intr,
3323         .handle_interrupt = marvell_handle_interrupt,
3324         .resume = genphy_resume,
3325         .suspend = genphy_suspend,
3326         .read_page = marvell_read_page,
3327         .write_page = marvell_write_page,
3328         .get_sset_count = marvell_get_sset_count,
3329         .get_strings = marvell_get_strings,
3330         .get_stats = marvell_get_stats,
3331         .get_tunable = m88e1540_get_tunable,
3332         .set_tunable = m88e1540_set_tunable,
3333         .cable_test_start = marvell_vct7_cable_test_start,
3334         .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
3335         .cable_test_get_status = marvell_vct7_cable_test_get_status,
3336     },
3337     {
3338         .phy_id = MARVELL_PHY_ID_88E1340S,
3339         .phy_id_mask = MARVELL_PHY_ID_MASK,
3340         .name = "Marvell 88E1340S",
3341         .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3342         .probe = marvell_probe,
3343         /* PHY_GBIT_FEATURES */
3344         .config_init = marvell_1011gbe_config_init,
3345         .config_aneg = m88e1510_config_aneg,
3346         .read_status = marvell_read_status,
3347         .config_intr = marvell_config_intr,
3348         .handle_interrupt = marvell_handle_interrupt,
3349         .resume = genphy_resume,
3350         .suspend = genphy_suspend,
3351         .read_page = marvell_read_page,
3352         .write_page = marvell_write_page,
3353         .get_sset_count = marvell_get_sset_count,
3354         .get_strings = marvell_get_strings,
3355         .get_stats = marvell_get_stats,
3356         .get_tunable = m88e1540_get_tunable,
3357         .set_tunable = m88e1540_set_tunable,
3358     },
3359     {
3360         .phy_id = MARVELL_PHY_ID_88E1548P,
3361         .phy_id_mask = MARVELL_PHY_ID_MASK,
3362         .name = "Marvell 88E1548P",
3363         .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3364         .probe = marvell_probe,
3365         .features = PHY_GBIT_FIBRE_FEATURES,
3366         .config_init = marvell_1011gbe_config_init,
3367         .config_aneg = m88e1510_config_aneg,
3368         .read_status = marvell_read_status,
3369         .config_intr = marvell_config_intr,
3370         .handle_interrupt = marvell_handle_interrupt,
3371         .resume = genphy_resume,
3372         .suspend = genphy_suspend,
3373         .read_page = marvell_read_page,
3374         .write_page = marvell_write_page,
3375         .get_sset_count = marvell_get_sset_count,
3376         .get_strings = marvell_get_strings,
3377         .get_stats = marvell_get_stats,
3378         .get_tunable = m88e1540_get_tunable,
3379         .set_tunable = m88e1540_set_tunable,
3380     },
3381 };
3382 
3383 module_phy_driver(marvell_drivers);
3384 
3385 static struct mdio_device_id __maybe_unused marvell_tbl[] = {
3386     { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
3387     { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
3388     { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
3389     { MARVELL_PHY_ID_88E1111_FINISAR, MARVELL_PHY_ID_MASK },
3390     { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
3391     { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
3392     { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
3393     { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
3394     { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
3395     { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
3396     { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
3397     { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
3398     { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
3399     { MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
3400     { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
3401     { MARVELL_PHY_ID_88E6341_FAMILY, MARVELL_PHY_ID_MASK },
3402     { MARVELL_PHY_ID_88E6390_FAMILY, MARVELL_PHY_ID_MASK },
3403     { MARVELL_PHY_ID_88E6393_FAMILY, MARVELL_PHY_ID_MASK },
3404     { MARVELL_PHY_ID_88E1340S, MARVELL_PHY_ID_MASK },
3405     { MARVELL_PHY_ID_88E1548P, MARVELL_PHY_ID_MASK },
3406     { }
3407 };
3408 
3409 MODULE_DEVICE_TABLE(mdio, marvell_tbl);