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