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