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