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