1 // SPDX-License-Identifier: GPL-2.0+
3 * drivers/net/phy/marvell.c
5 * Driver for Marvell PHYs
9 * Copyright (c) 2004 Freescale Semiconductor, Inc.
11 * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de>
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>
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>
35 #include <linux/sfp.h>
39 #include <linux/uaccess.h>
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
52 #define MII_M1011_IEVENT 0x13
53 #define MII_M1011_IEVENT_CLEAR 0x0000
55 #define MII_M1011_IMASK 0x12
56 #define MII_M1011_IMASK_INIT 0x6400
57 #define MII_M1011_IMASK_CLEAR 0x0000
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)
67 #define MII_M1011_PHY_SSR 0x11
68 #define MII_M1011_PHY_SSR_DOWNSHIFT BIT(5)
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
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)
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))
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
106 #define MII_88E1510_TEMP_SENSOR 0x1b
107 #define MII_88E1510_TEMP_SENSOR_MASK 0xff
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)
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)
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
139 #define MII_88E1318S_PHY_MSCR1_REG 16
140 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6)
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)
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)
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
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)
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
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 #define MII_M1011_PHY_STATUS_MDIX BIT(6)
181 #define MII_88E3016_PHY_SPEC_CTRL 0x10
182 #define MII_88E3016_DISABLE_SCRAMBLER 0x0200
183 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030
185 #define MII_88E1510_GEN_CTRL_REG_1 0x14
186 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7
187 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII 0x0 /* RGMII to copper */
188 #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1 /* SGMII to copper */
189 /* RGMII to 1000BASE-X */
190 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X 0x2
191 /* RGMII to 100BASE-FX */
192 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX 0x3
194 #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII 0x4
195 #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */
197 #define MII_88E1510_MSCR_2 0x15
199 #define MII_VCT5_TX_RX_MDI0_COUPLING 0x10
200 #define MII_VCT5_TX_RX_MDI1_COUPLING 0x11
201 #define MII_VCT5_TX_RX_MDI2_COUPLING 0x12
202 #define MII_VCT5_TX_RX_MDI3_COUPLING 0x13
203 #define MII_VCT5_TX_RX_AMPLITUDE_MASK 0x7f00
204 #define MII_VCT5_TX_RX_AMPLITUDE_SHIFT 8
205 #define MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION BIT(15)
207 #define MII_VCT5_CTRL 0x17
208 #define MII_VCT5_CTRL_ENABLE BIT(15)
209 #define MII_VCT5_CTRL_COMPLETE BIT(14)
210 #define MII_VCT5_CTRL_TX_SAME_CHANNEL (0x0 << 11)
211 #define MII_VCT5_CTRL_TX0_CHANNEL (0x4 << 11)
212 #define MII_VCT5_CTRL_TX1_CHANNEL (0x5 << 11)
213 #define MII_VCT5_CTRL_TX2_CHANNEL (0x6 << 11)
214 #define MII_VCT5_CTRL_TX3_CHANNEL (0x7 << 11)
215 #define MII_VCT5_CTRL_SAMPLES_2 (0x0 << 8)
216 #define MII_VCT5_CTRL_SAMPLES_4 (0x1 << 8)
217 #define MII_VCT5_CTRL_SAMPLES_8 (0x2 << 8)
218 #define MII_VCT5_CTRL_SAMPLES_16 (0x3 << 8)
219 #define MII_VCT5_CTRL_SAMPLES_32 (0x4 << 8)
220 #define MII_VCT5_CTRL_SAMPLES_64 (0x5 << 8)
221 #define MII_VCT5_CTRL_SAMPLES_128 (0x6 << 8)
222 #define MII_VCT5_CTRL_SAMPLES_DEFAULT (0x6 << 8)
223 #define MII_VCT5_CTRL_SAMPLES_256 (0x7 << 8)
224 #define MII_VCT5_CTRL_SAMPLES_SHIFT 8
225 #define MII_VCT5_CTRL_MODE_MAXIMUM_PEEK (0x0 << 6)
226 #define MII_VCT5_CTRL_MODE_FIRST_LAST_PEEK (0x1 << 6)
227 #define MII_VCT5_CTRL_MODE_OFFSET (0x2 << 6)
228 #define MII_VCT5_CTRL_SAMPLE_POINT (0x3 << 6)
229 #define MII_VCT5_CTRL_PEEK_HYST_DEFAULT 3
231 #define MII_VCT5_SAMPLE_POINT_DISTANCE 0x18
232 #define MII_VCT5_SAMPLE_POINT_DISTANCE_MAX 511
233 #define MII_VCT5_TX_PULSE_CTRL 0x1c
234 #define MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN BIT(12)
235 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS (0x0 << 10)
236 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_96nS (0x1 << 10)
237 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_64nS (0x2 << 10)
238 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS (0x3 << 10)
239 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_SHIFT 10
240 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_1000mV (0x0 << 8)
241 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_750mV (0x1 << 8)
242 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_500mV (0x2 << 8)
243 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_250mV (0x3 << 8)
244 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_SHIFT 8
245 #define MII_VCT5_TX_PULSE_CTRL_MAX_AMP BIT(7)
246 #define MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV (0x6 << 0)
248 /* For TDR measurements less than 11 meters, a short pulse should be
251 #define TDR_SHORT_CABLE_LENGTH 11
253 #define MII_VCT7_PAIR_0_DISTANCE 0x10
254 #define MII_VCT7_PAIR_1_DISTANCE 0x11
255 #define MII_VCT7_PAIR_2_DISTANCE 0x12
256 #define MII_VCT7_PAIR_3_DISTANCE 0x13
258 #define MII_VCT7_RESULTS 0x14
259 #define MII_VCT7_RESULTS_PAIR3_MASK 0xf000
260 #define MII_VCT7_RESULTS_PAIR2_MASK 0x0f00
261 #define MII_VCT7_RESULTS_PAIR1_MASK 0x00f0
262 #define MII_VCT7_RESULTS_PAIR0_MASK 0x000f
263 #define MII_VCT7_RESULTS_PAIR3_SHIFT 12
264 #define MII_VCT7_RESULTS_PAIR2_SHIFT 8
265 #define MII_VCT7_RESULTS_PAIR1_SHIFT 4
266 #define MII_VCT7_RESULTS_PAIR0_SHIFT 0
267 #define MII_VCT7_RESULTS_INVALID 0
268 #define MII_VCT7_RESULTS_OK 1
269 #define MII_VCT7_RESULTS_OPEN 2
270 #define MII_VCT7_RESULTS_SAME_SHORT 3
271 #define MII_VCT7_RESULTS_CROSS_SHORT 4
272 #define MII_VCT7_RESULTS_BUSY 9
274 #define MII_VCT7_CTRL 0x15
275 #define MII_VCT7_CTRL_RUN_NOW BIT(15)
276 #define MII_VCT7_CTRL_RUN_ANEG BIT(14)
277 #define MII_VCT7_CTRL_DISABLE_CROSS BIT(13)
278 #define MII_VCT7_CTRL_RUN_AFTER_BREAK_LINK BIT(12)
279 #define MII_VCT7_CTRL_IN_PROGRESS BIT(11)
280 #define MII_VCT7_CTRL_METERS BIT(10)
281 #define MII_VCT7_CTRL_CENTIMETERS 0
283 #define MII_VCT_TXPINS 0x1A
284 #define MII_VCT_RXPINS 0x1B
285 #define MII_VCT_SR 0x1C
286 #define MII_VCT_TXPINS_ENVCT BIT(15)
287 #define MII_VCT_TXRXPINS_VCTTST GENMASK(14, 13)
288 #define MII_VCT_TXRXPINS_VCTTST_SHIFT 13
289 #define MII_VCT_TXRXPINS_VCTTST_OK 0
290 #define MII_VCT_TXRXPINS_VCTTST_SHORT 1
291 #define MII_VCT_TXRXPINS_VCTTST_OPEN 2
292 #define MII_VCT_TXRXPINS_VCTTST_FAIL 3
293 #define MII_VCT_TXRXPINS_AMPRFLN GENMASK(12, 8)
294 #define MII_VCT_TXRXPINS_AMPRFLN_SHIFT 8
295 #define MII_VCT_TXRXPINS_DISTRFLN GENMASK(7, 0)
296 #define MII_VCT_TXRXPINS_DISTRFLN_MAX 0xff
298 #define M88E3082_PAIR_A BIT(0)
299 #define M88E3082_PAIR_B BIT(1)
301 #define LPA_PAUSE_FIBER 0x180
302 #define LPA_PAUSE_ASYM_FIBER 0x100
304 #define NB_FIBER_STATS 1
305 #define NB_STAT_MAX 3
307 MODULE_DESCRIPTION("Marvell PHY driver");
308 MODULE_AUTHOR("Andy Fleming");
309 MODULE_LICENSE("GPL");
311 struct marvell_hw_stat
{
318 static const struct marvell_hw_stat marvell_hw_stats
[] = {
319 { "phy_receive_errors_copper", 0, 21, 16},
320 { "phy_idle_errors", 0, 10, 8 },
321 { "phy_receive_errors_fiber", 1, 21, 16},
324 static_assert(ARRAY_SIZE(marvell_hw_stats
) <= NB_STAT_MAX
);
326 /* "simple" stat list + corresponding marvell_get_*_simple functions are used
327 * on PHYs without a page register
329 struct marvell_hw_stat_simple
{
335 static const struct marvell_hw_stat_simple marvell_hw_stats_simple
[] = {
336 { "phy_receive_errors", 21, 16},
339 static_assert(ARRAY_SIZE(marvell_hw_stats_simple
) <= NB_STAT_MAX
);
347 struct marvell_priv
{
348 u64 stats
[NB_STAT_MAX
];
350 struct device
*hwmon_dev
;
359 static int marvell_read_page(struct phy_device
*phydev
)
361 return __phy_read(phydev
, MII_MARVELL_PHY_PAGE
);
364 static int marvell_write_page(struct phy_device
*phydev
, int page
)
366 return __phy_write(phydev
, MII_MARVELL_PHY_PAGE
, page
);
369 static int marvell_set_page(struct phy_device
*phydev
, int page
)
371 return phy_write(phydev
, MII_MARVELL_PHY_PAGE
, page
);
374 static int marvell_ack_interrupt(struct phy_device
*phydev
)
378 /* Clear the interrupts by reading the reg */
379 err
= phy_read(phydev
, MII_M1011_IEVENT
);
387 static int marvell_config_intr(struct phy_device
*phydev
)
391 if (phydev
->interrupts
== PHY_INTERRUPT_ENABLED
) {
392 err
= marvell_ack_interrupt(phydev
);
396 err
= phy_write(phydev
, MII_M1011_IMASK
,
397 MII_M1011_IMASK_INIT
);
399 err
= phy_write(phydev
, MII_M1011_IMASK
,
400 MII_M1011_IMASK_CLEAR
);
404 err
= marvell_ack_interrupt(phydev
);
410 static irqreturn_t
marvell_handle_interrupt(struct phy_device
*phydev
)
414 irq_status
= phy_read(phydev
, MII_M1011_IEVENT
);
415 if (irq_status
< 0) {
420 if (!(irq_status
& MII_M1011_IMASK_INIT
))
423 phy_trigger_machine(phydev
);
428 static int marvell_set_polarity(struct phy_device
*phydev
, int polarity
)
434 val
= MII_M1011_PHY_SCR_MDI
;
437 val
= MII_M1011_PHY_SCR_MDI_X
;
439 case ETH_TP_MDI_AUTO
:
440 case ETH_TP_MDI_INVALID
:
442 val
= MII_M1011_PHY_SCR_AUTO_CROSS
;
446 return phy_modify_changed(phydev
, MII_M1011_PHY_SCR
,
447 MII_M1011_PHY_SCR_AUTO_CROSS
, val
);
450 static int marvell_config_aneg(struct phy_device
*phydev
)
455 err
= marvell_set_polarity(phydev
, phydev
->mdix_ctrl
);
461 err
= phy_write(phydev
, MII_M1111_PHY_LED_CONTROL
,
462 MII_M1111_PHY_LED_DIRECT
);
466 err
= genphy_config_aneg(phydev
);
470 if (phydev
->autoneg
!= AUTONEG_ENABLE
|| changed
) {
471 /* A write to speed/duplex bits (that is performed by
472 * genphy_config_aneg() call above) must be followed by
473 * a software reset. Otherwise, the write has no effect.
475 err
= genphy_soft_reset(phydev
);
483 static int m88e1101_config_aneg(struct phy_device
*phydev
)
487 /* This Marvell PHY has an errata which requires
488 * that certain registers get written in order
489 * to restart autonegotiation
491 err
= genphy_soft_reset(phydev
);
495 err
= phy_write(phydev
, 0x1d, 0x1f);
499 err
= phy_write(phydev
, 0x1e, 0x200c);
503 err
= phy_write(phydev
, 0x1d, 0x5);
507 err
= phy_write(phydev
, 0x1e, 0);
511 err
= phy_write(phydev
, 0x1e, 0x100);
515 return marvell_config_aneg(phydev
);
518 #if IS_ENABLED(CONFIG_OF_MDIO)
519 /* Set and/or override some configuration registers based on the
520 * marvell,reg-init property stored in the of_node for the phydev.
522 * marvell,reg-init = <reg-page reg mask value>,...;
524 * There may be one or more sets of <reg-page reg mask value>:
526 * reg-page: which register bank to use.
528 * mask: if non-zero, ANDed with existing register value.
529 * value: ORed with the masked value and written to the regiser.
532 static int marvell_of_reg_init(struct phy_device
*phydev
)
535 int len
, i
, saved_page
, current_page
, ret
= 0;
537 if (!phydev
->mdio
.dev
.of_node
)
540 paddr
= of_get_property(phydev
->mdio
.dev
.of_node
,
541 "marvell,reg-init", &len
);
542 if (!paddr
|| len
< (4 * sizeof(*paddr
)))
545 saved_page
= phy_save_page(phydev
);
548 current_page
= saved_page
;
550 len
/= sizeof(*paddr
);
551 for (i
= 0; i
< len
- 3; i
+= 4) {
552 u16 page
= be32_to_cpup(paddr
+ i
);
553 u16 reg
= be32_to_cpup(paddr
+ i
+ 1);
554 u16 mask
= be32_to_cpup(paddr
+ i
+ 2);
555 u16 val_bits
= be32_to_cpup(paddr
+ i
+ 3);
558 if (page
!= current_page
) {
560 ret
= marvell_write_page(phydev
, page
);
567 val
= __phy_read(phydev
, reg
);
576 ret
= __phy_write(phydev
, reg
, val
);
581 return phy_restore_page(phydev
, saved_page
, ret
);
584 static int marvell_of_reg_init(struct phy_device
*phydev
)
588 #endif /* CONFIG_OF_MDIO */
590 static int m88e1121_config_aneg_rgmii_delays(struct phy_device
*phydev
)
594 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
)
595 mscr
= MII_88E1121_PHY_MSCR_RX_DELAY
|
596 MII_88E1121_PHY_MSCR_TX_DELAY
;
597 else if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_RXID
)
598 mscr
= MII_88E1121_PHY_MSCR_RX_DELAY
;
599 else if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_TXID
)
600 mscr
= MII_88E1121_PHY_MSCR_TX_DELAY
;
604 return phy_modify_paged_changed(phydev
, MII_MARVELL_MSCR_PAGE
,
605 MII_88E1121_PHY_MSCR_REG
,
606 MII_88E1121_PHY_MSCR_DELAY_MASK
, mscr
);
609 static int m88e1121_config_aneg(struct phy_device
*phydev
)
614 if (phy_interface_is_rgmii(phydev
)) {
615 err
= m88e1121_config_aneg_rgmii_delays(phydev
);
622 err
= marvell_set_polarity(phydev
, phydev
->mdix_ctrl
);
628 err
= genphy_config_aneg(phydev
);
632 if (phydev
->autoneg
!= AUTONEG_ENABLE
|| changed
) {
633 /* A software reset is used to ensure a "commit" of the
636 err
= genphy_soft_reset(phydev
);
644 static int m88e1318_config_aneg(struct phy_device
*phydev
)
648 err
= phy_modify_paged(phydev
, MII_MARVELL_MSCR_PAGE
,
649 MII_88E1318S_PHY_MSCR1_REG
,
650 0, MII_88E1318S_PHY_MSCR1_PAD_ODD
);
654 return m88e1121_config_aneg(phydev
);
658 * linkmode_adv_to_fiber_adv_t
659 * @advertise: the linkmode advertisement settings
661 * A small helper function that translates linkmode advertisement
662 * settings to phy autonegotiation advertisements for the MII_ADV
663 * register for fiber link.
665 static inline u32
linkmode_adv_to_fiber_adv_t(unsigned long *advertise
)
669 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT
, advertise
))
670 result
|= ADVERTISE_1000XHALF
;
671 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT
, advertise
))
672 result
|= ADVERTISE_1000XFULL
;
674 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT
, advertise
) &&
675 linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT
, advertise
))
676 result
|= ADVERTISE_1000XPSE_ASYM
;
677 else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT
, advertise
))
678 result
|= ADVERTISE_1000XPAUSE
;
684 * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
685 * @phydev: target phy_device struct
687 * Description: If auto-negotiation is enabled, we configure the
688 * advertising, and then restart auto-negotiation. If it is not
689 * enabled, then we write the BMCR. Adapted for fiber link in
690 * some Marvell's devices.
692 static int marvell_config_aneg_fiber(struct phy_device
*phydev
)
698 if (phydev
->autoneg
!= AUTONEG_ENABLE
)
699 return genphy_setup_forced(phydev
);
701 /* Only allow advertising what this PHY supports */
702 linkmode_and(phydev
->advertising
, phydev
->advertising
,
705 adv
= linkmode_adv_to_fiber_adv_t(phydev
->advertising
);
707 /* Setup fiber advertisement */
708 err
= phy_modify_changed(phydev
, MII_ADVERTISE
,
709 ADVERTISE_1000XHALF
| ADVERTISE_1000XFULL
|
710 ADVERTISE_1000XPAUSE
| ADVERTISE_1000XPSE_ASYM
,
717 return genphy_check_and_restart_aneg(phydev
, changed
);
720 static int m88e1111_config_aneg(struct phy_device
*phydev
)
722 int extsr
= phy_read(phydev
, MII_M1111_PHY_EXT_SR
);
728 /* If not using SGMII or copper 1000BaseX modes, use normal process.
729 * Steps below are only required for these modes.
731 if (phydev
->interface
!= PHY_INTERFACE_MODE_SGMII
&&
732 (extsr
& MII_M1111_HWCFG_MODE_MASK
) !=
733 MII_M1111_HWCFG_MODE_COPPER_1000X_AN
)
734 return marvell_config_aneg(phydev
);
736 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
740 /* Configure the copper link first */
741 err
= marvell_config_aneg(phydev
);
745 /* Then the fiber link */
746 err
= marvell_set_page(phydev
, MII_MARVELL_FIBER_PAGE
);
750 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
)
751 /* Do not touch the fiber advertisement if we're in copper->sgmii mode.
752 * Just ensure that SGMII-side autonegotiation is enabled.
753 * If we switched from some other mode to SGMII it may not be.
755 err
= genphy_check_and_restart_aneg(phydev
, false);
757 err
= marvell_config_aneg_fiber(phydev
);
761 return marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
764 marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
768 static int m88e1510_config_aneg(struct phy_device
*phydev
)
772 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
776 /* Configure the copper link first */
777 err
= m88e1318_config_aneg(phydev
);
781 /* Do not touch the fiber page if we're in copper->sgmii mode */
782 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
)
785 /* Then the fiber link */
786 err
= marvell_set_page(phydev
, MII_MARVELL_FIBER_PAGE
);
790 err
= marvell_config_aneg_fiber(phydev
);
794 return marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
797 marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
801 static void marvell_config_led(struct phy_device
*phydev
)
806 switch (MARVELL_PHY_FAMILY_ID(phydev
->phy_id
)) {
807 /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
808 case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R
):
809 case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S
):
810 def_config
= MII_88E1121_PHY_LED_DEF
;
812 /* Default PHY LED config:
813 * LED[0] .. 1000Mbps Link
814 * LED[1] .. 100Mbps Link
815 * LED[2] .. Blink, Activity
817 case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510
):
818 if (phydev
->dev_flags
& MARVELL_PHY_LED0_LINK_LED1_ACTIVE
)
819 def_config
= MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE
;
821 def_config
= MII_88E1510_PHY_LED_DEF
;
827 err
= phy_write_paged(phydev
, MII_MARVELL_LED_PAGE
, MII_PHY_LED_CTRL
,
830 phydev_warn(phydev
, "Fail to config marvell phy LED.\n");
833 static int marvell_config_init(struct phy_device
*phydev
)
835 /* Set default LED */
836 marvell_config_led(phydev
);
838 /* Set registers from marvell,reg-init DT property */
839 return marvell_of_reg_init(phydev
);
842 static int m88e3016_config_init(struct phy_device
*phydev
)
846 /* Enable Scrambler and Auto-Crossover */
847 ret
= phy_modify(phydev
, MII_88E3016_PHY_SPEC_CTRL
,
848 MII_88E3016_DISABLE_SCRAMBLER
,
849 MII_88E3016_AUTO_MDIX_CROSSOVER
);
853 return marvell_config_init(phydev
);
856 static int m88e1111_config_init_hwcfg_mode(struct phy_device
*phydev
,
858 int fibre_copper_auto
)
860 if (fibre_copper_auto
)
861 mode
|= MII_M1111_HWCFG_FIBER_COPPER_AUTO
;
863 return phy_modify(phydev
, MII_M1111_PHY_EXT_SR
,
864 MII_M1111_HWCFG_MODE_MASK
|
865 MII_M1111_HWCFG_FIBER_COPPER_AUTO
|
866 MII_M1111_HWCFG_FIBER_COPPER_RES
,
870 static int m88e1111_config_init_rgmii_delays(struct phy_device
*phydev
)
874 switch (phydev
->interface
) {
875 case PHY_INTERFACE_MODE_RGMII_ID
:
876 delay
= MII_M1111_RGMII_RX_DELAY
| MII_M1111_RGMII_TX_DELAY
;
878 case PHY_INTERFACE_MODE_RGMII_RXID
:
879 delay
= MII_M1111_RGMII_RX_DELAY
;
881 case PHY_INTERFACE_MODE_RGMII_TXID
:
882 delay
= MII_M1111_RGMII_TX_DELAY
;
889 return phy_modify(phydev
, MII_M1111_PHY_EXT_CR
,
890 MII_M1111_RGMII_RX_DELAY
| MII_M1111_RGMII_TX_DELAY
,
894 static int m88e1111_config_init_rgmii(struct phy_device
*phydev
)
899 err
= m88e1111_config_init_rgmii_delays(phydev
);
903 temp
= phy_read(phydev
, MII_M1111_PHY_EXT_SR
);
907 temp
&= ~(MII_M1111_HWCFG_MODE_MASK
);
909 if (temp
& MII_M1111_HWCFG_FIBER_COPPER_RES
)
910 temp
|= MII_M1111_HWCFG_MODE_FIBER_RGMII
;
912 temp
|= MII_M1111_HWCFG_MODE_COPPER_RGMII
;
914 return phy_write(phydev
, MII_M1111_PHY_EXT_SR
, temp
);
917 static int m88e1111_config_init_sgmii(struct phy_device
*phydev
)
921 err
= m88e1111_config_init_hwcfg_mode(
923 MII_M1111_HWCFG_MODE_SGMII_NO_CLK
,
924 MII_M1111_HWCFG_FIBER_COPPER_AUTO
);
928 /* make sure copper is selected */
929 return marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
932 static int m88e1111_config_init_rtbi(struct phy_device
*phydev
)
936 err
= m88e1111_config_init_rgmii_delays(phydev
);
940 err
= m88e1111_config_init_hwcfg_mode(
942 MII_M1111_HWCFG_MODE_RTBI
,
943 MII_M1111_HWCFG_FIBER_COPPER_AUTO
);
948 err
= genphy_soft_reset(phydev
);
952 return m88e1111_config_init_hwcfg_mode(
954 MII_M1111_HWCFG_MODE_RTBI
,
955 MII_M1111_HWCFG_FIBER_COPPER_AUTO
);
958 static int m88e1111_config_init_1000basex(struct phy_device
*phydev
)
960 int extsr
= phy_read(phydev
, MII_M1111_PHY_EXT_SR
);
966 /* If using copper mode, ensure 1000BaseX auto-negotiation is enabled.
967 * FIXME: this does not actually enable 1000BaseX auto-negotiation if
968 * it was previously disabled in the Fiber BMCR!
970 mode
= extsr
& MII_M1111_HWCFG_MODE_MASK
;
971 if (mode
== MII_M1111_HWCFG_MODE_COPPER_1000X_NOAN
) {
972 err
= phy_modify(phydev
, MII_M1111_PHY_EXT_SR
,
973 MII_M1111_HWCFG_MODE_MASK
|
974 MII_M1111_HWCFG_SERIAL_AN_BYPASS
,
975 MII_M1111_HWCFG_MODE_COPPER_1000X_AN
|
976 MII_M1111_HWCFG_SERIAL_AN_BYPASS
);
983 static int m88e1111_config_init(struct phy_device
*phydev
)
987 if (phy_interface_is_rgmii(phydev
)) {
988 err
= m88e1111_config_init_rgmii(phydev
);
993 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
994 err
= m88e1111_config_init_sgmii(phydev
);
999 if (phydev
->interface
== PHY_INTERFACE_MODE_RTBI
) {
1000 err
= m88e1111_config_init_rtbi(phydev
);
1005 if (phydev
->interface
== PHY_INTERFACE_MODE_1000BASEX
) {
1006 err
= m88e1111_config_init_1000basex(phydev
);
1011 err
= marvell_of_reg_init(phydev
);
1015 err
= genphy_soft_reset(phydev
);
1019 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
1020 /* If the HWCFG_MODE was changed from another mode (such as
1021 * 1000BaseX) to SGMII, the state of the support bits may have
1022 * also changed now that the PHY has been reset.
1023 * Update the PHY abilities accordingly.
1025 err
= genphy_read_abilities(phydev
);
1026 linkmode_or(phydev
->advertising
, phydev
->advertising
,
1032 static int m88e1111_get_downshift(struct phy_device
*phydev
, u8
*data
)
1034 int val
, cnt
, enable
;
1036 val
= phy_read(phydev
, MII_M1111_PHY_EXT_CR
);
1040 enable
= FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN
, val
);
1041 cnt
= FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK
, val
) + 1;
1043 *data
= enable
? cnt
: DOWNSHIFT_DEV_DISABLE
;
1048 static int m88e1111_set_downshift(struct phy_device
*phydev
, u8 cnt
)
1052 if (cnt
> MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX
)
1056 err
= phy_clear_bits(phydev
, MII_M1111_PHY_EXT_CR
,
1057 MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN
);
1059 val
= MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN
;
1060 val
|= FIELD_PREP(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK
, cnt
- 1);
1062 err
= phy_modify(phydev
, MII_M1111_PHY_EXT_CR
,
1063 MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN
|
1064 MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK
,
1071 return genphy_soft_reset(phydev
);
1074 static int m88e1111_get_tunable(struct phy_device
*phydev
,
1075 struct ethtool_tunable
*tuna
, void *data
)
1078 case ETHTOOL_PHY_DOWNSHIFT
:
1079 return m88e1111_get_downshift(phydev
, data
);
1085 static int m88e1111_set_tunable(struct phy_device
*phydev
,
1086 struct ethtool_tunable
*tuna
, const void *data
)
1089 case ETHTOOL_PHY_DOWNSHIFT
:
1090 return m88e1111_set_downshift(phydev
, *(const u8
*)data
);
1096 static int m88e1011_get_downshift(struct phy_device
*phydev
, u8
*data
)
1098 int val
, cnt
, enable
;
1100 val
= phy_read(phydev
, MII_M1011_PHY_SCR
);
1104 enable
= FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_EN
, val
);
1105 cnt
= FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_MASK
, val
) + 1;
1107 *data
= enable
? cnt
: DOWNSHIFT_DEV_DISABLE
;
1112 static int m88e1011_set_downshift(struct phy_device
*phydev
, u8 cnt
)
1116 if (cnt
> MII_M1011_PHY_SCR_DOWNSHIFT_MAX
)
1120 err
= phy_clear_bits(phydev
, MII_M1011_PHY_SCR
,
1121 MII_M1011_PHY_SCR_DOWNSHIFT_EN
);
1123 val
= MII_M1011_PHY_SCR_DOWNSHIFT_EN
;
1124 val
|= FIELD_PREP(MII_M1011_PHY_SCR_DOWNSHIFT_MASK
, cnt
- 1);
1126 err
= phy_modify(phydev
, MII_M1011_PHY_SCR
,
1127 MII_M1011_PHY_SCR_DOWNSHIFT_EN
|
1128 MII_M1011_PHY_SCR_DOWNSHIFT_MASK
,
1135 return genphy_soft_reset(phydev
);
1138 static int m88e1011_get_tunable(struct phy_device
*phydev
,
1139 struct ethtool_tunable
*tuna
, void *data
)
1142 case ETHTOOL_PHY_DOWNSHIFT
:
1143 return m88e1011_get_downshift(phydev
, data
);
1149 static int m88e1011_set_tunable(struct phy_device
*phydev
,
1150 struct ethtool_tunable
*tuna
, const void *data
)
1153 case ETHTOOL_PHY_DOWNSHIFT
:
1154 return m88e1011_set_downshift(phydev
, *(const u8
*)data
);
1160 static int m88e1112_config_init(struct phy_device
*phydev
)
1164 err
= m88e1011_set_downshift(phydev
, 3);
1168 return m88e1111_config_init(phydev
);
1171 static int m88e1111gbe_config_init(struct phy_device
*phydev
)
1175 err
= m88e1111_set_downshift(phydev
, 3);
1179 return m88e1111_config_init(phydev
);
1182 static int marvell_1011gbe_config_init(struct phy_device
*phydev
)
1186 err
= m88e1011_set_downshift(phydev
, 3);
1190 return marvell_config_init(phydev
);
1192 static int m88e1116r_config_init(struct phy_device
*phydev
)
1196 err
= genphy_soft_reset(phydev
);
1202 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1206 err
= marvell_set_polarity(phydev
, phydev
->mdix_ctrl
);
1210 err
= m88e1011_set_downshift(phydev
, 8);
1214 if (phy_interface_is_rgmii(phydev
)) {
1215 err
= m88e1121_config_aneg_rgmii_delays(phydev
);
1220 err
= genphy_soft_reset(phydev
);
1224 return marvell_config_init(phydev
);
1227 static int m88e1318_config_init(struct phy_device
*phydev
)
1229 if (phy_interrupt_is_valid(phydev
)) {
1230 int err
= phy_modify_paged(
1231 phydev
, MII_MARVELL_LED_PAGE
,
1232 MII_88E1318S_PHY_LED_TCR
,
1233 MII_88E1318S_PHY_LED_TCR_FORCE_INT
,
1234 MII_88E1318S_PHY_LED_TCR_INTn_ENABLE
|
1235 MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW
);
1240 return marvell_config_init(phydev
);
1243 static int m88e1510_config_init(struct phy_device
*phydev
)
1245 static const struct {
1256 /* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512/
1257 * 88E1514 Rev A0, Errata Section 5.1:
1258 * If EEE is intended to be used, the following register writes
1259 * must be done once after every hardware reset.
1261 err
= marvell_set_page(phydev
, 0x00FF);
1265 for (i
= 0; i
< ARRAY_SIZE(errata_vals
); ++i
) {
1266 err
= phy_write(phydev
, 17, errata_vals
[i
].reg17
);
1269 err
= phy_write(phydev
, 16, errata_vals
[i
].reg16
);
1274 err
= marvell_set_page(phydev
, 0x00FB);
1277 err
= phy_write(phydev
, 07, 0xC00D);
1280 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1284 /* SGMII-to-Copper mode initialization */
1285 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
1286 /* Select page 18 */
1287 err
= marvell_set_page(phydev
, 18);
1291 /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
1292 err
= phy_modify(phydev
, MII_88E1510_GEN_CTRL_REG_1
,
1293 MII_88E1510_GEN_CTRL_REG_1_MODE_MASK
,
1294 MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII
);
1298 /* PHY reset is necessary after changing MODE[2:0] */
1299 err
= phy_set_bits(phydev
, MII_88E1510_GEN_CTRL_REG_1
,
1300 MII_88E1510_GEN_CTRL_REG_1_RESET
);
1304 /* Reset page selection */
1305 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1309 err
= m88e1011_set_downshift(phydev
, 3);
1313 return m88e1318_config_init(phydev
);
1316 static int m88e1118_config_aneg(struct phy_device
*phydev
)
1320 err
= marvell_set_polarity(phydev
, phydev
->mdix_ctrl
);
1324 err
= genphy_config_aneg(phydev
);
1328 return genphy_soft_reset(phydev
);
1331 static int m88e1118_config_init(struct phy_device
*phydev
)
1336 /* Enable 1000 Mbit */
1337 err
= phy_write_paged(phydev
, MII_MARVELL_MSCR_PAGE
,
1338 MII_88E1121_PHY_MSCR_REG
, 0x1070);
1342 if (phy_interface_is_rgmii(phydev
)) {
1343 err
= m88e1121_config_aneg_rgmii_delays(phydev
);
1348 /* Adjust LED Control */
1349 if (phydev
->dev_flags
& MARVELL_PHY_M1118_DNS323_LEDS
)
1354 err
= phy_write_paged(phydev
, MII_MARVELL_LED_PAGE
, 0x10, leds
);
1358 err
= marvell_of_reg_init(phydev
);
1362 /* Reset page register */
1363 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1367 return genphy_soft_reset(phydev
);
1370 static int m88e1149_config_init(struct phy_device
*phydev
)
1374 /* Change address */
1375 err
= marvell_set_page(phydev
, MII_MARVELL_MSCR_PAGE
);
1379 /* Enable 1000 Mbit */
1380 err
= phy_write(phydev
, 0x15, 0x1048);
1384 err
= marvell_of_reg_init(phydev
);
1389 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1393 return genphy_soft_reset(phydev
);
1396 static int m88e1145_config_init_rgmii(struct phy_device
*phydev
)
1400 err
= m88e1111_config_init_rgmii_delays(phydev
);
1404 if (phydev
->dev_flags
& MARVELL_PHY_M1145_FLAGS_RESISTANCE
) {
1405 err
= phy_write(phydev
, 0x1d, 0x0012);
1409 err
= phy_modify(phydev
, 0x1e, 0x0fc0,
1410 2 << 9 | /* 36 ohm */
1411 2 << 6); /* 39 ohm */
1415 err
= phy_write(phydev
, 0x1d, 0x3);
1419 err
= phy_write(phydev
, 0x1e, 0x8000);
1424 static int m88e1145_config_init_sgmii(struct phy_device
*phydev
)
1426 return m88e1111_config_init_hwcfg_mode(
1427 phydev
, MII_M1111_HWCFG_MODE_SGMII_NO_CLK
,
1428 MII_M1111_HWCFG_FIBER_COPPER_AUTO
);
1431 static int m88e1145_config_init(struct phy_device
*phydev
)
1435 /* Take care of errata E0 & E1 */
1436 err
= phy_write(phydev
, 0x1d, 0x001b);
1440 err
= phy_write(phydev
, 0x1e, 0x418f);
1444 err
= phy_write(phydev
, 0x1d, 0x0016);
1448 err
= phy_write(phydev
, 0x1e, 0xa2da);
1452 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
) {
1453 err
= m88e1145_config_init_rgmii(phydev
);
1458 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
1459 err
= m88e1145_config_init_sgmii(phydev
);
1463 err
= m88e1111_set_downshift(phydev
, 3);
1467 err
= marvell_of_reg_init(phydev
);
1474 static int m88e1540_get_fld(struct phy_device
*phydev
, u8
*msecs
)
1478 val
= phy_read(phydev
, MII_88E1540_COPPER_CTRL3
);
1482 if (!(val
& MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN
)) {
1483 *msecs
= ETHTOOL_PHY_FAST_LINK_DOWN_OFF
;
1487 val
= FIELD_GET(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK
, val
);
1490 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS
:
1493 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS
:
1496 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS
:
1499 case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS
:
1509 static int m88e1540_set_fld(struct phy_device
*phydev
, const u8
*msecs
)
1511 struct ethtool_keee eee
;
1514 if (*msecs
== ETHTOOL_PHY_FAST_LINK_DOWN_OFF
)
1515 return phy_clear_bits(phydev
, MII_88E1540_COPPER_CTRL3
,
1516 MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN
);
1518 /* According to the Marvell data sheet EEE must be disabled for
1519 * Fast Link Down detection to work properly
1521 ret
= genphy_c45_ethtool_get_eee(phydev
, &eee
);
1522 if (!ret
&& eee
.eee_enabled
) {
1523 phydev_warn(phydev
, "Fast Link Down detection requires EEE to be disabled!\n");
1528 val
= MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS
;
1529 else if (*msecs
<= 15)
1530 val
= MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS
;
1531 else if (*msecs
<= 30)
1532 val
= MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS
;
1534 val
= MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS
;
1536 val
= FIELD_PREP(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK
, val
);
1538 ret
= phy_modify(phydev
, MII_88E1540_COPPER_CTRL3
,
1539 MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK
, val
);
1543 return phy_set_bits(phydev
, MII_88E1540_COPPER_CTRL3
,
1544 MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN
);
1547 static int m88e1540_get_tunable(struct phy_device
*phydev
,
1548 struct ethtool_tunable
*tuna
, void *data
)
1551 case ETHTOOL_PHY_FAST_LINK_DOWN
:
1552 return m88e1540_get_fld(phydev
, data
);
1553 case ETHTOOL_PHY_DOWNSHIFT
:
1554 return m88e1011_get_downshift(phydev
, data
);
1560 static int m88e1540_set_tunable(struct phy_device
*phydev
,
1561 struct ethtool_tunable
*tuna
, const void *data
)
1564 case ETHTOOL_PHY_FAST_LINK_DOWN
:
1565 return m88e1540_set_fld(phydev
, data
);
1566 case ETHTOOL_PHY_DOWNSHIFT
:
1567 return m88e1011_set_downshift(phydev
, *(const u8
*)data
);
1573 /* The VOD can be out of specification on link up. Poke an
1574 * undocumented register, in an undocumented page, with a magic value
1577 static int m88e6390_errata(struct phy_device
*phydev
)
1581 err
= phy_write(phydev
, MII_BMCR
,
1582 BMCR_ANENABLE
| BMCR_SPEED1000
| BMCR_FULLDPLX
);
1586 usleep_range(300, 400);
1588 err
= phy_write_paged(phydev
, 0xf8, 0x08, 0x36);
1592 return genphy_soft_reset(phydev
);
1595 static int m88e6390_config_aneg(struct phy_device
*phydev
)
1599 err
= m88e6390_errata(phydev
);
1603 return m88e1510_config_aneg(phydev
);
1607 * fiber_lpa_mod_linkmode_lpa_t
1608 * @advertising: the linkmode advertisement settings
1609 * @lpa: value of the MII_LPA register for fiber link
1611 * A small helper function that translates MII_LPA bits to linkmode LP
1612 * advertisement settings. Other bits in advertising are left
1615 static void fiber_lpa_mod_linkmode_lpa_t(unsigned long *advertising
, u32 lpa
)
1617 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT
,
1618 advertising
, lpa
& LPA_1000XHALF
);
1620 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT
,
1621 advertising
, lpa
& LPA_1000XFULL
);
1624 static int marvell_read_status_page_an(struct phy_device
*phydev
,
1625 int fiber
, int status
)
1630 if (!(status
& MII_M1011_PHY_STATUS_RESOLVED
)) {
1635 if (status
& MII_M1011_PHY_STATUS_FULLDUPLEX
)
1636 phydev
->duplex
= DUPLEX_FULL
;
1638 phydev
->duplex
= DUPLEX_HALF
;
1640 switch (status
& MII_M1011_PHY_STATUS_SPD_MASK
) {
1641 case MII_M1011_PHY_STATUS_1000
:
1642 phydev
->speed
= SPEED_1000
;
1645 case MII_M1011_PHY_STATUS_100
:
1646 phydev
->speed
= SPEED_100
;
1650 phydev
->speed
= SPEED_10
;
1655 err
= genphy_read_lpa(phydev
);
1659 phy_resolve_aneg_pause(phydev
);
1661 lpa
= phy_read(phydev
, MII_LPA
);
1665 /* The fiber link is only 1000M capable */
1666 fiber_lpa_mod_linkmode_lpa_t(phydev
->lp_advertising
, lpa
);
1668 if (phydev
->duplex
== DUPLEX_FULL
) {
1669 if (!(lpa
& LPA_PAUSE_FIBER
)) {
1671 phydev
->asym_pause
= 0;
1672 } else if ((lpa
& LPA_PAUSE_ASYM_FIBER
)) {
1674 phydev
->asym_pause
= 1;
1677 phydev
->asym_pause
= 0;
1685 /* marvell_read_status_page
1688 * Check the link, then figure out the current state
1689 * by comparing what we advertise with what the link partner
1690 * advertises. Start by checking the gigabit possibilities,
1691 * then move on to 10/100.
1693 static int marvell_read_status_page(struct phy_device
*phydev
, int page
)
1699 status
= phy_read(phydev
, MII_M1011_PHY_STATUS
);
1703 /* Use the generic register for copper link status,
1704 * and the PHY status register for fiber link status.
1706 if (page
== MII_MARVELL_FIBER_PAGE
) {
1707 phydev
->link
= !!(status
& MII_M1011_PHY_STATUS_LINK
);
1709 err
= genphy_update_link(phydev
);
1714 if (page
== MII_MARVELL_FIBER_PAGE
)
1719 linkmode_zero(phydev
->lp_advertising
);
1721 phydev
->asym_pause
= 0;
1722 phydev
->speed
= SPEED_UNKNOWN
;
1723 phydev
->duplex
= DUPLEX_UNKNOWN
;
1724 phydev
->port
= fiber
? PORT_FIBRE
: PORT_TP
;
1727 phydev
->mdix
= ETH_TP_MDI_INVALID
;
1729 /* The MDI-X state is set regardless of Autoneg being enabled
1730 * and reflects forced MDI-X state as well as auto resolution
1732 if (status
& MII_M1011_PHY_STATUS_RESOLVED
)
1733 phydev
->mdix
= status
& MII_M1011_PHY_STATUS_MDIX
?
1734 ETH_TP_MDI_X
: ETH_TP_MDI
;
1736 phydev
->mdix
= ETH_TP_MDI_INVALID
;
1739 if (phydev
->autoneg
== AUTONEG_ENABLE
)
1740 err
= marvell_read_status_page_an(phydev
, fiber
, status
);
1742 err
= genphy_read_status_fixed(phydev
);
1747 /* marvell_read_status
1749 * Some Marvell's phys have two modes: fiber and copper.
1750 * Both need status checked.
1752 * First, check the fiber link and status.
1753 * If the fiber link is down, check the copper link and status which
1754 * will be the default value if both link are down.
1756 static int marvell_read_status(struct phy_device
*phydev
)
1760 /* Check the fiber mode first */
1761 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT
,
1762 phydev
->supported
) &&
1763 phydev
->interface
!= PHY_INTERFACE_MODE_SGMII
) {
1764 err
= marvell_set_page(phydev
, MII_MARVELL_FIBER_PAGE
);
1768 err
= marvell_read_status_page(phydev
, MII_MARVELL_FIBER_PAGE
);
1772 /* If the fiber link is up, it is the selected and
1773 * used link. In this case, we need to stay in the
1774 * fiber page. Please to be careful about that, avoid
1775 * to restore Copper page in other functions which
1776 * could break the behaviour for some fiber phy like
1782 /* If fiber link is down, check and save copper mode state */
1783 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1788 return marvell_read_status_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1791 marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1797 * Some Marvell's phys have two modes: fiber and copper.
1798 * Both need to be suspended
1800 static int marvell_suspend(struct phy_device
*phydev
)
1804 /* Suspend the fiber mode first */
1805 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT
,
1806 phydev
->supported
)) {
1807 err
= marvell_set_page(phydev
, MII_MARVELL_FIBER_PAGE
);
1811 /* With the page set, use the generic suspend */
1812 err
= genphy_suspend(phydev
);
1816 /* Then, the copper link */
1817 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1822 /* With the page set, use the generic suspend */
1823 return genphy_suspend(phydev
);
1826 marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1832 * Some Marvell's phys have two modes: fiber and copper.
1833 * Both need to be resumed
1835 static int marvell_resume(struct phy_device
*phydev
)
1839 /* Resume the fiber mode first */
1840 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT
,
1841 phydev
->supported
)) {
1842 err
= marvell_set_page(phydev
, MII_MARVELL_FIBER_PAGE
);
1846 /* With the page set, use the generic resume */
1847 err
= genphy_resume(phydev
);
1851 /* Then, the copper link */
1852 err
= marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1857 /* With the page set, use the generic resume */
1858 return genphy_resume(phydev
);
1861 marvell_set_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1865 static int marvell_aneg_done(struct phy_device
*phydev
)
1867 int retval
= phy_read(phydev
, MII_M1011_PHY_STATUS
);
1869 return (retval
< 0) ? retval
: (retval
& MII_M1011_PHY_STATUS_RESOLVED
);
1872 static void m88e1318_get_wol(struct phy_device
*phydev
,
1873 struct ethtool_wolinfo
*wol
)
1877 wol
->supported
= WAKE_MAGIC
| WAKE_PHY
;
1880 ret
= phy_read_paged(phydev
, MII_MARVELL_WOL_PAGE
,
1881 MII_88E1318S_PHY_WOL_CTRL
);
1885 if (ret
& MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE
)
1886 wol
->wolopts
|= WAKE_MAGIC
;
1888 if (ret
& MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE
)
1889 wol
->wolopts
|= WAKE_PHY
;
1892 static int m88e1318_set_wol(struct phy_device
*phydev
,
1893 struct ethtool_wolinfo
*wol
)
1895 int err
= 0, oldpage
;
1897 oldpage
= phy_save_page(phydev
);
1901 if (wol
->wolopts
& (WAKE_MAGIC
| WAKE_PHY
)) {
1902 /* Explicitly switch to page 0x00, just to be sure */
1903 err
= marvell_write_page(phydev
, MII_MARVELL_COPPER_PAGE
);
1907 /* If WOL event happened once, the LED[2] interrupt pin
1908 * will not be cleared unless we reading the interrupt status
1909 * register. If interrupts are in use, the normal interrupt
1910 * handling will clear the WOL event. Clear the WOL event
1911 * before enabling it if !phy_interrupt_is_valid()
1913 if (!phy_interrupt_is_valid(phydev
))
1914 __phy_read(phydev
, MII_M1011_IEVENT
);
1916 /* Enable the WOL interrupt */
1917 err
= __phy_set_bits(phydev
, MII_88E1318S_PHY_CSIER
,
1918 MII_88E1318S_PHY_CSIER_WOL_EIE
);
1922 err
= marvell_write_page(phydev
, MII_MARVELL_LED_PAGE
);
1926 /* Setup LED[2] as interrupt pin (active low) */
1927 err
= __phy_modify(phydev
, MII_88E1318S_PHY_LED_TCR
,
1928 MII_88E1318S_PHY_LED_TCR_FORCE_INT
,
1929 MII_88E1318S_PHY_LED_TCR_INTn_ENABLE
|
1930 MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW
);
1935 if (wol
->wolopts
& WAKE_MAGIC
) {
1936 err
= marvell_write_page(phydev
, MII_MARVELL_WOL_PAGE
);
1940 /* Store the device address for the magic packet */
1941 err
= __phy_write(phydev
, MII_88E1318S_PHY_MAGIC_PACKET_WORD2
,
1942 ((phydev
->attached_dev
->dev_addr
[5] << 8) |
1943 phydev
->attached_dev
->dev_addr
[4]));
1946 err
= __phy_write(phydev
, MII_88E1318S_PHY_MAGIC_PACKET_WORD1
,
1947 ((phydev
->attached_dev
->dev_addr
[3] << 8) |
1948 phydev
->attached_dev
->dev_addr
[2]));
1951 err
= __phy_write(phydev
, MII_88E1318S_PHY_MAGIC_PACKET_WORD0
,
1952 ((phydev
->attached_dev
->dev_addr
[1] << 8) |
1953 phydev
->attached_dev
->dev_addr
[0]));
1957 /* Clear WOL status and enable magic packet matching */
1958 err
= __phy_set_bits(phydev
, MII_88E1318S_PHY_WOL_CTRL
,
1959 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS
|
1960 MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE
);
1964 err
= marvell_write_page(phydev
, MII_MARVELL_WOL_PAGE
);
1968 /* Clear WOL status and disable magic packet matching */
1969 err
= __phy_modify(phydev
, MII_88E1318S_PHY_WOL_CTRL
,
1970 MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE
,
1971 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS
);
1976 if (wol
->wolopts
& WAKE_PHY
) {
1977 err
= marvell_write_page(phydev
, MII_MARVELL_WOL_PAGE
);
1981 /* Clear WOL status and enable link up event */
1982 err
= __phy_modify(phydev
, MII_88E1318S_PHY_WOL_CTRL
, 0,
1983 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS
|
1984 MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE
);
1988 err
= marvell_write_page(phydev
, MII_MARVELL_WOL_PAGE
);
1992 /* Clear WOL status and disable link up event */
1993 err
= __phy_modify(phydev
, MII_88E1318S_PHY_WOL_CTRL
,
1994 MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE
,
1995 MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS
);
2001 return phy_restore_page(phydev
, oldpage
, err
);
2004 static int marvell_get_sset_count(struct phy_device
*phydev
)
2006 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT
,
2008 return ARRAY_SIZE(marvell_hw_stats
);
2010 return ARRAY_SIZE(marvell_hw_stats
) - NB_FIBER_STATS
;
2013 static int marvell_get_sset_count_simple(struct phy_device
*phydev
)
2015 return ARRAY_SIZE(marvell_hw_stats_simple
);
2018 static void marvell_get_strings(struct phy_device
*phydev
, u8
*data
)
2020 int count
= marvell_get_sset_count(phydev
);
2023 for (i
= 0; i
< count
; i
++)
2024 ethtool_puts(&data
, marvell_hw_stats
[i
].string
);
2027 static void marvell_get_strings_simple(struct phy_device
*phydev
, u8
*data
)
2029 int count
= marvell_get_sset_count_simple(phydev
);
2032 for (i
= 0; i
< count
; i
++)
2033 ethtool_puts(&data
, marvell_hw_stats_simple
[i
].string
);
2036 static u64
marvell_get_stat(struct phy_device
*phydev
, int i
)
2038 struct marvell_hw_stat stat
= marvell_hw_stats
[i
];
2039 struct marvell_priv
*priv
= phydev
->priv
;
2043 val
= phy_read_paged(phydev
, stat
.page
, stat
.reg
);
2047 val
= val
& ((1 << stat
.bits
) - 1);
2048 priv
->stats
[i
] += val
;
2049 ret
= priv
->stats
[i
];
2055 static u64
marvell_get_stat_simple(struct phy_device
*phydev
, int i
)
2057 struct marvell_hw_stat_simple stat
= marvell_hw_stats_simple
[i
];
2058 struct marvell_priv
*priv
= phydev
->priv
;
2062 val
= phy_read(phydev
, stat
.reg
);
2066 val
= val
& ((1 << stat
.bits
) - 1);
2067 priv
->stats
[i
] += val
;
2068 ret
= priv
->stats
[i
];
2074 static void marvell_get_stats(struct phy_device
*phydev
,
2075 struct ethtool_stats
*stats
, u64
*data
)
2077 int count
= marvell_get_sset_count(phydev
);
2080 for (i
= 0; i
< count
; i
++)
2081 data
[i
] = marvell_get_stat(phydev
, i
);
2084 static void marvell_get_stats_simple(struct phy_device
*phydev
,
2085 struct ethtool_stats
*stats
, u64
*data
)
2087 int count
= marvell_get_sset_count_simple(phydev
);
2090 for (i
= 0; i
< count
; i
++)
2091 data
[i
] = marvell_get_stat_simple(phydev
, i
);
2094 static int m88e1510_loopback(struct phy_device
*phydev
, bool enable
)
2099 u16 bmcr_ctl
, mscr2_ctl
= 0;
2101 bmcr_ctl
= mii_bmcr_encode_fixed(phydev
->speed
, phydev
->duplex
);
2103 err
= phy_write(phydev
, MII_BMCR
, bmcr_ctl
);
2107 if (phydev
->speed
== SPEED_1000
)
2108 mscr2_ctl
= BMCR_SPEED1000
;
2109 else if (phydev
->speed
== SPEED_100
)
2110 mscr2_ctl
= BMCR_SPEED100
;
2112 err
= phy_modify_paged(phydev
, MII_MARVELL_MSCR_PAGE
,
2113 MII_88E1510_MSCR_2
, BMCR_SPEED1000
|
2114 BMCR_SPEED100
, mscr2_ctl
);
2118 /* Need soft reset to have speed configuration takes effect */
2119 err
= genphy_soft_reset(phydev
);
2123 err
= phy_modify(phydev
, MII_BMCR
, BMCR_LOOPBACK
,
2127 /* It takes some time for PHY device to switch
2128 * into/out-of loopback mode.
2134 err
= phy_modify(phydev
, MII_BMCR
, BMCR_LOOPBACK
, 0);
2138 return phy_config_aneg(phydev
);
2142 static int marvell_vct5_wait_complete(struct phy_device
*phydev
)
2147 for (i
= 0; i
< 32; i
++) {
2148 val
= __phy_read(phydev
, MII_VCT5_CTRL
);
2152 if (val
& MII_VCT5_CTRL_COMPLETE
)
2156 phydev_err(phydev
, "Timeout while waiting for cable test to finish\n");
2160 static int marvell_vct5_amplitude(struct phy_device
*phydev
, int pair
)
2166 reg
= MII_VCT5_TX_RX_MDI0_COUPLING
+ pair
;
2167 val
= __phy_read(phydev
, reg
);
2172 amplitude
= (val
& MII_VCT5_TX_RX_AMPLITUDE_MASK
) >>
2173 MII_VCT5_TX_RX_AMPLITUDE_SHIFT
;
2175 if (!(val
& MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION
))
2176 amplitude
= -amplitude
;
2178 return 1000 * amplitude
/ 128;
2181 static u32
marvell_vct5_distance2cm(int distance
)
2183 return distance
* 805 / 10;
2186 static u32
marvell_vct5_cm2distance(int cm
)
2188 return cm
* 10 / 805;
2191 static int marvell_vct5_amplitude_distance(struct phy_device
*phydev
,
2192 int distance
, int pair
)
2199 err
= __phy_write(phydev
, MII_VCT5_SAMPLE_POINT_DISTANCE
,
2204 reg
= MII_VCT5_CTRL_ENABLE
|
2205 MII_VCT5_CTRL_TX_SAME_CHANNEL
|
2206 MII_VCT5_CTRL_SAMPLES_DEFAULT
|
2207 MII_VCT5_CTRL_SAMPLE_POINT
|
2208 MII_VCT5_CTRL_PEEK_HYST_DEFAULT
;
2209 err
= __phy_write(phydev
, MII_VCT5_CTRL
, reg
);
2213 err
= marvell_vct5_wait_complete(phydev
);
2217 for (i
= 0; i
< 4; i
++) {
2218 if (pair
!= PHY_PAIR_ALL
&& i
!= pair
)
2221 mV
= marvell_vct5_amplitude(phydev
, i
);
2222 ethnl_cable_test_amplitude(phydev
, i
, mV
);
2228 static int marvell_vct5_amplitude_graph(struct phy_device
*phydev
)
2230 struct marvell_priv
*priv
= phydev
->priv
;
2237 if (priv
->first
<= TDR_SHORT_CABLE_LENGTH
)
2238 width
= MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS
;
2240 width
= MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS
;
2242 reg
= MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV
|
2243 MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN
|
2244 MII_VCT5_TX_PULSE_CTRL_MAX_AMP
| width
;
2246 err
= phy_write_paged(phydev
, MII_MARVELL_VCT5_PAGE
,
2247 MII_VCT5_TX_PULSE_CTRL
, reg
);
2251 /* Reading the TDR data is very MDIO heavy. We need to optimize
2252 * access to keep the time to a minimum. So lock the bus once,
2253 * and don't release it until complete. We can then avoid having
2254 * to change the page for every access, greatly speeding things
2257 page
= phy_select_page(phydev
, MII_MARVELL_VCT5_PAGE
);
2261 for (distance
= priv
->first
;
2262 distance
<= priv
->last
;
2263 distance
+= priv
->step
) {
2264 err
= marvell_vct5_amplitude_distance(phydev
, distance
,
2269 if (distance
> TDR_SHORT_CABLE_LENGTH
&&
2270 width
== MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS
) {
2271 width
= MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS
;
2272 reg
= MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV
|
2273 MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN
|
2274 MII_VCT5_TX_PULSE_CTRL_MAX_AMP
| width
;
2275 err
= __phy_write(phydev
, MII_VCT5_TX_PULSE_CTRL
, reg
);
2282 return phy_restore_page(phydev
, page
, err
);
2285 static int marvell_cable_test_start_common(struct phy_device
*phydev
)
2287 int bmcr
, bmsr
, ret
;
2289 /* If auto-negotiation is enabled, but not complete, the cable
2290 * test never completes. So disable auto-neg.
2292 bmcr
= phy_read(phydev
, MII_BMCR
);
2296 bmsr
= phy_read(phydev
, MII_BMSR
);
2301 if (bmcr
& BMCR_ANENABLE
) {
2302 ret
= phy_clear_bits(phydev
, MII_BMCR
, BMCR_ANENABLE
);
2305 ret
= genphy_soft_reset(phydev
);
2310 /* If the link is up, allow it some time to go down */
2311 if (bmsr
& BMSR_LSTATUS
)
2317 static int marvell_vct7_cable_test_start(struct phy_device
*phydev
)
2319 struct marvell_priv
*priv
= phydev
->priv
;
2322 ret
= marvell_cable_test_start_common(phydev
);
2326 priv
->cable_test_tdr
= false;
2328 /* Reset the VCT5 API control to defaults, otherwise
2329 * VCT7 does not work correctly.
2331 ret
= phy_write_paged(phydev
, MII_MARVELL_VCT5_PAGE
,
2333 MII_VCT5_CTRL_TX_SAME_CHANNEL
|
2334 MII_VCT5_CTRL_SAMPLES_DEFAULT
|
2335 MII_VCT5_CTRL_MODE_MAXIMUM_PEEK
|
2336 MII_VCT5_CTRL_PEEK_HYST_DEFAULT
);
2340 ret
= phy_write_paged(phydev
, MII_MARVELL_VCT5_PAGE
,
2341 MII_VCT5_SAMPLE_POINT_DISTANCE
, 0);
2345 return phy_write_paged(phydev
, MII_MARVELL_VCT7_PAGE
,
2347 MII_VCT7_CTRL_RUN_NOW
|
2348 MII_VCT7_CTRL_CENTIMETERS
);
2351 static int marvell_vct5_cable_test_tdr_start(struct phy_device
*phydev
,
2352 const struct phy_tdr_config
*cfg
)
2354 struct marvell_priv
*priv
= phydev
->priv
;
2357 priv
->cable_test_tdr
= true;
2358 priv
->first
= marvell_vct5_cm2distance(cfg
->first
);
2359 priv
->last
= marvell_vct5_cm2distance(cfg
->last
);
2360 priv
->step
= marvell_vct5_cm2distance(cfg
->step
);
2361 priv
->pair
= cfg
->pair
;
2363 if (priv
->first
> MII_VCT5_SAMPLE_POINT_DISTANCE_MAX
)
2366 if (priv
->last
> MII_VCT5_SAMPLE_POINT_DISTANCE_MAX
)
2370 ret
= phy_write_paged(phydev
, MII_MARVELL_VCT7_PAGE
,
2375 ret
= marvell_cable_test_start_common(phydev
);
2379 ret
= ethnl_cable_test_pulse(phydev
, 1000);
2383 return ethnl_cable_test_step(phydev
,
2384 marvell_vct5_distance2cm(priv
->first
),
2385 marvell_vct5_distance2cm(priv
->last
),
2386 marvell_vct5_distance2cm(priv
->step
));
2389 static int marvell_vct7_distance_to_length(int distance
, bool meter
)
2397 static bool marvell_vct7_distance_valid(int result
)
2400 case MII_VCT7_RESULTS_OPEN
:
2401 case MII_VCT7_RESULTS_SAME_SHORT
:
2402 case MII_VCT7_RESULTS_CROSS_SHORT
:
2408 static int marvell_vct7_report_length(struct phy_device
*phydev
,
2409 int pair
, bool meter
)
2414 ret
= phy_read_paged(phydev
, MII_MARVELL_VCT7_PAGE
,
2415 MII_VCT7_PAIR_0_DISTANCE
+ pair
);
2419 length
= marvell_vct7_distance_to_length(ret
, meter
);
2421 ethnl_cable_test_fault_length(phydev
, pair
, length
);
2426 static int marvell_vct7_cable_test_report_trans(int result
)
2429 case MII_VCT7_RESULTS_OK
:
2430 return ETHTOOL_A_CABLE_RESULT_CODE_OK
;
2431 case MII_VCT7_RESULTS_OPEN
:
2432 return ETHTOOL_A_CABLE_RESULT_CODE_OPEN
;
2433 case MII_VCT7_RESULTS_SAME_SHORT
:
2434 return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT
;
2435 case MII_VCT7_RESULTS_CROSS_SHORT
:
2436 return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT
;
2438 return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC
;
2442 static int marvell_vct7_cable_test_report(struct phy_device
*phydev
)
2444 int pair0
, pair1
, pair2
, pair3
;
2448 ret
= phy_read_paged(phydev
, MII_MARVELL_VCT7_PAGE
,
2453 pair3
= (ret
& MII_VCT7_RESULTS_PAIR3_MASK
) >>
2454 MII_VCT7_RESULTS_PAIR3_SHIFT
;
2455 pair2
= (ret
& MII_VCT7_RESULTS_PAIR2_MASK
) >>
2456 MII_VCT7_RESULTS_PAIR2_SHIFT
;
2457 pair1
= (ret
& MII_VCT7_RESULTS_PAIR1_MASK
) >>
2458 MII_VCT7_RESULTS_PAIR1_SHIFT
;
2459 pair0
= (ret
& MII_VCT7_RESULTS_PAIR0_MASK
) >>
2460 MII_VCT7_RESULTS_PAIR0_SHIFT
;
2462 ethnl_cable_test_result(phydev
, ETHTOOL_A_CABLE_PAIR_A
,
2463 marvell_vct7_cable_test_report_trans(pair0
));
2464 ethnl_cable_test_result(phydev
, ETHTOOL_A_CABLE_PAIR_B
,
2465 marvell_vct7_cable_test_report_trans(pair1
));
2466 ethnl_cable_test_result(phydev
, ETHTOOL_A_CABLE_PAIR_C
,
2467 marvell_vct7_cable_test_report_trans(pair2
));
2468 ethnl_cable_test_result(phydev
, ETHTOOL_A_CABLE_PAIR_D
,
2469 marvell_vct7_cable_test_report_trans(pair3
));
2471 ret
= phy_read_paged(phydev
, MII_MARVELL_VCT7_PAGE
, MII_VCT7_CTRL
);
2475 meter
= ret
& MII_VCT7_CTRL_METERS
;
2477 if (marvell_vct7_distance_valid(pair0
))
2478 marvell_vct7_report_length(phydev
, 0, meter
);
2479 if (marvell_vct7_distance_valid(pair1
))
2480 marvell_vct7_report_length(phydev
, 1, meter
);
2481 if (marvell_vct7_distance_valid(pair2
))
2482 marvell_vct7_report_length(phydev
, 2, meter
);
2483 if (marvell_vct7_distance_valid(pair3
))
2484 marvell_vct7_report_length(phydev
, 3, meter
);
2489 static int marvell_vct7_cable_test_get_status(struct phy_device
*phydev
,
2492 struct marvell_priv
*priv
= phydev
->priv
;
2495 if (priv
->cable_test_tdr
) {
2496 ret
= marvell_vct5_amplitude_graph(phydev
);
2503 ret
= phy_read_paged(phydev
, MII_MARVELL_VCT7_PAGE
,
2509 if (!(ret
& MII_VCT7_CTRL_IN_PROGRESS
)) {
2512 return marvell_vct7_cable_test_report(phydev
);
2518 static int m88e3082_vct_cable_test_start(struct phy_device
*phydev
)
2520 struct marvell_priv
*priv
= phydev
->priv
;
2523 /* It needs some magic workarounds described in VCT manual for this PHY.
2525 ret
= phy_write(phydev
, 29, 0x0003);
2529 ret
= phy_write(phydev
, 30, 0x6440);
2533 if (priv
->vct_phase
== M88E3082_VCT_PHASE1
) {
2534 ret
= phy_write(phydev
, 29, 0x000a);
2538 ret
= phy_write(phydev
, 30, 0x0002);
2543 ret
= phy_write(phydev
, MII_BMCR
,
2544 BMCR_RESET
| BMCR_SPEED100
| BMCR_FULLDPLX
);
2548 ret
= phy_write(phydev
, MII_VCT_TXPINS
, MII_VCT_TXPINS_ENVCT
);
2552 ret
= phy_write(phydev
, 29, 0x0003);
2556 ret
= phy_write(phydev
, 30, 0x0);
2560 if (priv
->vct_phase
== M88E3082_VCT_OFF
) {
2561 priv
->vct_phase
= M88E3082_VCT_PHASE1
;
2567 ret
= phy_write(phydev
, 29, 0x000a);
2571 ret
= phy_write(phydev
, 30, 0x0);
2575 priv
->vct_phase
= M88E3082_VCT_PHASE2
;
2580 static int m88e3082_vct_cable_test_report_trans(int result
, u8 distance
)
2583 case MII_VCT_TXRXPINS_VCTTST_OK
:
2584 if (distance
== MII_VCT_TXRXPINS_DISTRFLN_MAX
)
2585 return ETHTOOL_A_CABLE_RESULT_CODE_OK
;
2586 return ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH
;
2587 case MII_VCT_TXRXPINS_VCTTST_SHORT
:
2588 return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT
;
2589 case MII_VCT_TXRXPINS_VCTTST_OPEN
:
2590 return ETHTOOL_A_CABLE_RESULT_CODE_OPEN
;
2592 return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC
;
2596 static u32
m88e3082_vct_distrfln_2_cm(u8 distrfln
)
2601 /* Original function for meters: y = 0.7861x - 18.862 */
2602 return (7861 * distrfln
- 188620) / 100;
2605 static int m88e3082_vct_cable_test_get_status(struct phy_device
*phydev
,
2608 u8 tx_vcttst_res
, rx_vcttst_res
, tx_distrfln
, rx_distrfln
;
2609 struct marvell_priv
*priv
= phydev
->priv
;
2610 int ret
, tx_result
, rx_result
;
2611 bool done_phase
= true;
2615 ret
= phy_read(phydev
, MII_VCT_TXPINS
);
2618 else if (ret
& MII_VCT_TXPINS_ENVCT
)
2621 tx_distrfln
= ret
& MII_VCT_TXRXPINS_DISTRFLN
;
2622 tx_vcttst_res
= (ret
& MII_VCT_TXRXPINS_VCTTST
) >>
2623 MII_VCT_TXRXPINS_VCTTST_SHIFT
;
2625 ret
= phy_read(phydev
, MII_VCT_RXPINS
);
2629 rx_distrfln
= ret
& MII_VCT_TXRXPINS_DISTRFLN
;
2630 rx_vcttst_res
= (ret
& MII_VCT_TXRXPINS_VCTTST
) >>
2631 MII_VCT_TXRXPINS_VCTTST_SHIFT
;
2635 switch (priv
->vct_phase
) {
2636 case M88E3082_VCT_PHASE1
:
2637 tx_result
= m88e3082_vct_cable_test_report_trans(tx_vcttst_res
,
2639 rx_result
= m88e3082_vct_cable_test_report_trans(rx_vcttst_res
,
2642 ethnl_cable_test_result(phydev
, ETHTOOL_A_CABLE_PAIR_A
,
2644 ethnl_cable_test_result(phydev
, ETHTOOL_A_CABLE_PAIR_B
,
2647 if (tx_vcttst_res
== MII_VCT_TXRXPINS_VCTTST_OPEN
) {
2649 priv
->pair
|= M88E3082_PAIR_A
;
2650 } else if (tx_distrfln
< MII_VCT_TXRXPINS_DISTRFLN_MAX
) {
2651 u8 pair
= ETHTOOL_A_CABLE_PAIR_A
;
2652 u32 cm
= m88e3082_vct_distrfln_2_cm(tx_distrfln
);
2654 ethnl_cable_test_fault_length(phydev
, pair
, cm
);
2657 if (rx_vcttst_res
== MII_VCT_TXRXPINS_VCTTST_OPEN
) {
2659 priv
->pair
|= M88E3082_PAIR_B
;
2660 } else if (rx_distrfln
< MII_VCT_TXRXPINS_DISTRFLN_MAX
) {
2661 u8 pair
= ETHTOOL_A_CABLE_PAIR_B
;
2662 u32 cm
= m88e3082_vct_distrfln_2_cm(rx_distrfln
);
2664 ethnl_cable_test_fault_length(phydev
, pair
, cm
);
2668 case M88E3082_VCT_PHASE2
:
2669 if (priv
->pair
& M88E3082_PAIR_A
&&
2670 tx_vcttst_res
== MII_VCT_TXRXPINS_VCTTST_OPEN
&&
2671 tx_distrfln
< MII_VCT_TXRXPINS_DISTRFLN_MAX
) {
2672 u8 pair
= ETHTOOL_A_CABLE_PAIR_A
;
2673 u32 cm
= m88e3082_vct_distrfln_2_cm(tx_distrfln
);
2675 ethnl_cable_test_fault_length(phydev
, pair
, cm
);
2677 if (priv
->pair
& M88E3082_PAIR_B
&&
2678 rx_vcttst_res
== MII_VCT_TXRXPINS_VCTTST_OPEN
&&
2679 rx_distrfln
< MII_VCT_TXRXPINS_DISTRFLN_MAX
) {
2680 u8 pair
= ETHTOOL_A_CABLE_PAIR_B
;
2681 u32 cm
= m88e3082_vct_distrfln_2_cm(rx_distrfln
);
2683 ethnl_cable_test_fault_length(phydev
, pair
, cm
);
2693 return m88e3082_vct_cable_test_start(phydev
);
2696 priv
->vct_phase
= M88E3082_VCT_OFF
;
2700 static int m88e1111_vct_cable_test_start(struct phy_device
*phydev
)
2704 ret
= marvell_cable_test_start_common(phydev
);
2708 /* It needs some magic workarounds described in VCT manual for this PHY.
2710 ret
= phy_write(phydev
, 29, 0x0018);
2714 ret
= phy_write(phydev
, 30, 0x00c2);
2718 ret
= phy_write(phydev
, 30, 0x00ca);
2722 ret
= phy_write(phydev
, 30, 0x00c2);
2726 ret
= phy_write_paged(phydev
, MII_MARVELL_COPPER_PAGE
, MII_VCT_SR
,
2727 MII_VCT_TXPINS_ENVCT
);
2731 ret
= phy_write(phydev
, 29, 0x0018);
2735 ret
= phy_write(phydev
, 30, 0x0042);
2742 static u32
m88e1111_vct_distrfln_2_cm(u8 distrfln
)
2747 /* Original function for meters: y = 0.8018x - 28.751 */
2748 return (8018 * distrfln
- 287510) / 100;
2751 static int m88e1111_vct_cable_test_get_status(struct phy_device
*phydev
,
2754 u8 vcttst_res
, distrfln
;
2759 /* Each pair use one page: A-0, B-1, C-2, D-3 */
2760 for (u8 i
= 0; i
< 4; i
++) {
2761 ret
= phy_read_paged(phydev
, i
, MII_VCT_SR
);
2764 else if (i
== 0 && ret
& MII_VCT_TXPINS_ENVCT
)
2767 distrfln
= ret
& MII_VCT_TXRXPINS_DISTRFLN
;
2768 vcttst_res
= (ret
& MII_VCT_TXRXPINS_VCTTST
) >>
2769 MII_VCT_TXRXPINS_VCTTST_SHIFT
;
2771 result
= m88e3082_vct_cable_test_report_trans(vcttst_res
,
2773 ethnl_cable_test_result(phydev
, i
, result
);
2775 if (distrfln
< MII_VCT_TXRXPINS_DISTRFLN_MAX
) {
2776 u32 cm
= m88e1111_vct_distrfln_2_cm(distrfln
);
2778 ethnl_cable_test_fault_length(phydev
, i
, cm
);
2787 struct marvell_hwmon_ops
{
2788 int (*config
)(struct phy_device
*phydev
);
2789 int (*get_temp
)(struct phy_device
*phydev
, long *temp
);
2790 int (*get_temp_critical
)(struct phy_device
*phydev
, long *temp
);
2791 int (*set_temp_critical
)(struct phy_device
*phydev
, long temp
);
2792 int (*get_temp_alarm
)(struct phy_device
*phydev
, long *alarm
);
2795 static const struct marvell_hwmon_ops
*
2796 to_marvell_hwmon_ops(const struct phy_device
*phydev
)
2798 return phydev
->drv
->driver_data
;
2801 static int m88e1121_get_temp(struct phy_device
*phydev
, long *temp
)
2809 oldpage
= phy_select_page(phydev
, MII_MARVELL_MISC_TEST_PAGE
);
2813 /* Enable temperature sensor */
2814 ret
= __phy_read(phydev
, MII_88E1121_MISC_TEST
);
2818 ret
= __phy_write(phydev
, MII_88E1121_MISC_TEST
,
2819 ret
| MII_88E1121_MISC_TEST_TEMP_SENSOR_EN
);
2823 /* Wait for temperature to stabilize */
2824 usleep_range(10000, 12000);
2826 val
= __phy_read(phydev
, MII_88E1121_MISC_TEST
);
2832 /* Disable temperature sensor */
2833 ret
= __phy_write(phydev
, MII_88E1121_MISC_TEST
,
2834 ret
& ~MII_88E1121_MISC_TEST_TEMP_SENSOR_EN
);
2838 *temp
= ((val
& MII_88E1121_MISC_TEST_TEMP_MASK
) - 5) * 5000;
2841 return phy_restore_page(phydev
, oldpage
, ret
);
2844 static int m88e1510_get_temp(struct phy_device
*phydev
, long *temp
)
2850 ret
= phy_read_paged(phydev
, MII_MARVELL_MISC_TEST_PAGE
,
2851 MII_88E1510_TEMP_SENSOR
);
2855 *temp
= ((ret
& MII_88E1510_TEMP_SENSOR_MASK
) - 25) * 1000;
2860 static int m88e1510_get_temp_critical(struct phy_device
*phydev
, long *temp
)
2866 ret
= phy_read_paged(phydev
, MII_MARVELL_MISC_TEST_PAGE
,
2867 MII_88E1121_MISC_TEST
);
2871 *temp
= (((ret
& MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK
) >>
2872 MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT
) * 5) - 25;
2879 static int m88e1510_set_temp_critical(struct phy_device
*phydev
, long temp
)
2882 temp
= clamp_val(DIV_ROUND_CLOSEST(temp
, 5) + 5, 0, 0x1f);
2884 return phy_modify_paged(phydev
, MII_MARVELL_MISC_TEST_PAGE
,
2885 MII_88E1121_MISC_TEST
,
2886 MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK
,
2887 temp
<< MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT
);
2890 static int m88e1510_get_temp_alarm(struct phy_device
*phydev
, long *alarm
)
2896 ret
= phy_read_paged(phydev
, MII_MARVELL_MISC_TEST_PAGE
,
2897 MII_88E1121_MISC_TEST
);
2901 *alarm
= !!(ret
& MII_88E1510_MISC_TEST_TEMP_IRQ
);
2906 static int m88e6390_get_temp(struct phy_device
*phydev
, long *temp
)
2915 oldpage
= phy_select_page(phydev
, MII_MARVELL_MISC_TEST_PAGE
);
2919 /* Enable temperature sensor */
2920 ret
= __phy_read(phydev
, MII_88E6390_MISC_TEST
);
2924 ret
&= ~MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK
;
2925 ret
|= MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE_SAMPLE_1S
;
2927 ret
= __phy_write(phydev
, MII_88E6390_MISC_TEST
, ret
);
2931 /* Wait for temperature to stabilize */
2932 usleep_range(10000, 12000);
2934 /* Reading the temperature sense has an errata. You need to read
2935 * a number of times and take an average.
2937 for (i
= 0; i
< MII_88E6390_TEMP_SENSOR_SAMPLES
; i
++) {
2938 ret
= __phy_read(phydev
, MII_88E6390_TEMP_SENSOR
);
2941 sum
+= ret
& MII_88E6390_TEMP_SENSOR_MASK
;
2944 sum
/= MII_88E6390_TEMP_SENSOR_SAMPLES
;
2945 *temp
= (sum
- 75) * 1000;
2947 /* Disable temperature sensor */
2948 ret
= __phy_read(phydev
, MII_88E6390_MISC_TEST
);
2952 ret
= ret
& ~MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK
;
2953 ret
|= MII_88E6390_MISC_TEST_TEMP_SENSOR_DISABLE
;
2955 ret
= __phy_write(phydev
, MII_88E6390_MISC_TEST
, ret
);
2958 phy_restore_page(phydev
, oldpage
, ret
);
2963 static int m88e6393_get_temp(struct phy_device
*phydev
, long *temp
)
2967 err
= m88e1510_get_temp(phydev
, temp
);
2969 /* 88E1510 measures T + 25, while the PHY on 88E6393X switch
2970 * T + 75, so we have to subtract another 50
2977 static int m88e6393_get_temp_critical(struct phy_device
*phydev
, long *temp
)
2983 ret
= phy_read_paged(phydev
, MII_MARVELL_MISC_TEST_PAGE
,
2984 MII_88E6390_TEMP_SENSOR
);
2988 *temp
= (((ret
& MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK
) >>
2989 MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT
) - 75) * 1000;
2994 static int m88e6393_set_temp_critical(struct phy_device
*phydev
, long temp
)
2996 temp
= (temp
/ 1000) + 75;
2998 return phy_modify_paged(phydev
, MII_MARVELL_MISC_TEST_PAGE
,
2999 MII_88E6390_TEMP_SENSOR
,
3000 MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK
,
3001 temp
<< MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT
);
3004 static int m88e6393_hwmon_config(struct phy_device
*phydev
)
3008 err
= m88e6393_set_temp_critical(phydev
, 100000);
3012 return phy_modify_paged(phydev
, MII_MARVELL_MISC_TEST_PAGE
,
3013 MII_88E6390_MISC_TEST
,
3014 MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK
|
3015 MII_88E6393_MISC_TEST_SAMPLES_MASK
|
3016 MII_88E6393_MISC_TEST_RATE_MASK
,
3017 MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE
|
3018 MII_88E6393_MISC_TEST_SAMPLES_2048
|
3019 MII_88E6393_MISC_TEST_RATE_2_3MS
);
3022 static int marvell_hwmon_read(struct device
*dev
, enum hwmon_sensor_types type
,
3023 u32 attr
, int channel
, long *temp
)
3025 struct phy_device
*phydev
= dev_get_drvdata(dev
);
3026 const struct marvell_hwmon_ops
*ops
= to_marvell_hwmon_ops(phydev
);
3027 int err
= -EOPNOTSUPP
;
3030 case hwmon_temp_input
:
3032 err
= ops
->get_temp(phydev
, temp
);
3034 case hwmon_temp_crit
:
3035 if (ops
->get_temp_critical
)
3036 err
= ops
->get_temp_critical(phydev
, temp
);
3038 case hwmon_temp_max_alarm
:
3039 if (ops
->get_temp_alarm
)
3040 err
= ops
->get_temp_alarm(phydev
, temp
);
3047 static int marvell_hwmon_write(struct device
*dev
, enum hwmon_sensor_types type
,
3048 u32 attr
, int channel
, long temp
)
3050 struct phy_device
*phydev
= dev_get_drvdata(dev
);
3051 const struct marvell_hwmon_ops
*ops
= to_marvell_hwmon_ops(phydev
);
3052 int err
= -EOPNOTSUPP
;
3055 case hwmon_temp_crit
:
3056 if (ops
->set_temp_critical
)
3057 err
= ops
->set_temp_critical(phydev
, temp
);
3064 static umode_t
marvell_hwmon_is_visible(const void *data
,
3065 enum hwmon_sensor_types type
,
3066 u32 attr
, int channel
)
3068 const struct phy_device
*phydev
= data
;
3069 const struct marvell_hwmon_ops
*ops
= to_marvell_hwmon_ops(phydev
);
3071 if (type
!= hwmon_temp
)
3075 case hwmon_temp_input
:
3076 return ops
->get_temp
? 0444 : 0;
3077 case hwmon_temp_max_alarm
:
3078 return ops
->get_temp_alarm
? 0444 : 0;
3079 case hwmon_temp_crit
:
3080 return (ops
->get_temp_critical
? 0444 : 0) |
3081 (ops
->set_temp_critical
? 0200 : 0);
3087 static u32 marvell_hwmon_chip_config
[] = {
3088 HWMON_C_REGISTER_TZ
,
3092 static const struct hwmon_channel_info marvell_hwmon_chip
= {
3094 .config
= marvell_hwmon_chip_config
,
3097 /* we can define HWMON_T_CRIT and HWMON_T_MAX_ALARM even though these are not
3098 * defined for all PHYs, because the hwmon code checks whether the attributes
3099 * exists via the .is_visible method
3101 static u32 marvell_hwmon_temp_config
[] = {
3102 HWMON_T_INPUT
| HWMON_T_CRIT
| HWMON_T_MAX_ALARM
,
3106 static const struct hwmon_channel_info marvell_hwmon_temp
= {
3108 .config
= marvell_hwmon_temp_config
,
3111 static const struct hwmon_channel_info
* const marvell_hwmon_info
[] = {
3112 &marvell_hwmon_chip
,
3113 &marvell_hwmon_temp
,
3117 static const struct hwmon_ops marvell_hwmon_hwmon_ops
= {
3118 .is_visible
= marvell_hwmon_is_visible
,
3119 .read
= marvell_hwmon_read
,
3120 .write
= marvell_hwmon_write
,
3123 static const struct hwmon_chip_info marvell_hwmon_chip_info
= {
3124 .ops
= &marvell_hwmon_hwmon_ops
,
3125 .info
= marvell_hwmon_info
,
3128 static int marvell_hwmon_name(struct phy_device
*phydev
)
3130 struct marvell_priv
*priv
= phydev
->priv
;
3131 struct device
*dev
= &phydev
->mdio
.dev
;
3132 const char *devname
= dev_name(dev
);
3133 size_t len
= strlen(devname
);
3136 priv
->hwmon_name
= devm_kzalloc(dev
, len
, GFP_KERNEL
);
3137 if (!priv
->hwmon_name
)
3140 for (i
= j
= 0; i
< len
&& devname
[i
]; i
++) {
3141 if (isalnum(devname
[i
]))
3142 priv
->hwmon_name
[j
++] = devname
[i
];
3148 static int marvell_hwmon_probe(struct phy_device
*phydev
)
3150 const struct marvell_hwmon_ops
*ops
= to_marvell_hwmon_ops(phydev
);
3151 struct marvell_priv
*priv
= phydev
->priv
;
3152 struct device
*dev
= &phydev
->mdio
.dev
;
3158 err
= marvell_hwmon_name(phydev
);
3162 priv
->hwmon_dev
= devm_hwmon_device_register_with_info(
3163 dev
, priv
->hwmon_name
, phydev
, &marvell_hwmon_chip_info
, NULL
);
3164 if (IS_ERR(priv
->hwmon_dev
))
3165 return PTR_ERR(priv
->hwmon_dev
);
3168 err
= ops
->config(phydev
);
3173 static const struct marvell_hwmon_ops m88e1121_hwmon_ops
= {
3174 .get_temp
= m88e1121_get_temp
,
3177 static const struct marvell_hwmon_ops m88e1510_hwmon_ops
= {
3178 .get_temp
= m88e1510_get_temp
,
3179 .get_temp_critical
= m88e1510_get_temp_critical
,
3180 .set_temp_critical
= m88e1510_set_temp_critical
,
3181 .get_temp_alarm
= m88e1510_get_temp_alarm
,
3184 static const struct marvell_hwmon_ops m88e6390_hwmon_ops
= {
3185 .get_temp
= m88e6390_get_temp
,
3188 static const struct marvell_hwmon_ops m88e6393_hwmon_ops
= {
3189 .config
= m88e6393_hwmon_config
,
3190 .get_temp
= m88e6393_get_temp
,
3191 .get_temp_critical
= m88e6393_get_temp_critical
,
3192 .set_temp_critical
= m88e6393_set_temp_critical
,
3193 .get_temp_alarm
= m88e1510_get_temp_alarm
,
3196 #define DEF_MARVELL_HWMON_OPS(s) (&(s))
3200 #define DEF_MARVELL_HWMON_OPS(s) NULL
3202 static int marvell_hwmon_probe(struct phy_device
*phydev
)
3208 static int m88e1318_led_brightness_set(struct phy_device
*phydev
,
3209 u8 index
, enum led_brightness value
)
3213 reg
= phy_read_paged(phydev
, MII_MARVELL_LED_PAGE
,
3214 MII_88E1318S_PHY_LED_FUNC
);
3222 reg
&= ~(0xf << (4 * index
));
3223 if (value
== LED_OFF
)
3224 reg
|= MII_88E1318S_PHY_LED_FUNC_OFF
<< (4 * index
);
3226 reg
|= MII_88E1318S_PHY_LED_FUNC_ON
<< (4 * index
);
3232 return phy_write_paged(phydev
, MII_MARVELL_LED_PAGE
,
3233 MII_88E1318S_PHY_LED_FUNC
, reg
);
3236 static int m88e1318_led_blink_set(struct phy_device
*phydev
, u8 index
,
3237 unsigned long *delay_on
,
3238 unsigned long *delay_off
)
3242 reg
= phy_read_paged(phydev
, MII_MARVELL_LED_PAGE
,
3243 MII_88E1318S_PHY_LED_FUNC
);
3251 reg
&= ~(0xf << (4 * index
));
3252 reg
|= MII_88E1318S_PHY_LED_FUNC_BLINK
<< (4 * index
);
3253 /* Reset default is 84ms */
3255 *delay_off
= 84 / 2;
3261 return phy_write_paged(phydev
, MII_MARVELL_LED_PAGE
,
3262 MII_88E1318S_PHY_LED_FUNC
, reg
);
3265 struct marvell_led_rules
{
3267 unsigned long rules
;
3270 static const struct marvell_led_rules marvell_led0
[] = {
3273 .rules
= BIT(TRIGGER_NETDEV_LINK
),
3277 .rules
= (BIT(TRIGGER_NETDEV_LINK
) |
3278 BIT(TRIGGER_NETDEV_RX
) |
3279 BIT(TRIGGER_NETDEV_TX
)),
3283 .rules
= (BIT(TRIGGER_NETDEV_RX
) |
3284 BIT(TRIGGER_NETDEV_TX
)),
3288 .rules
= (BIT(TRIGGER_NETDEV_RX
) |
3289 BIT(TRIGGER_NETDEV_TX
)),
3293 .rules
= BIT(TRIGGER_NETDEV_TX
),
3297 .rules
= BIT(TRIGGER_NETDEV_LINK
),
3301 .rules
= BIT(TRIGGER_NETDEV_LINK_1000
),
3309 static const struct marvell_led_rules marvell_led1
[] = {
3312 .rules
= (BIT(TRIGGER_NETDEV_LINK
) |
3313 BIT(TRIGGER_NETDEV_RX
) |
3314 BIT(TRIGGER_NETDEV_TX
)),
3318 .rules
= (BIT(TRIGGER_NETDEV_LINK
) |
3319 BIT(TRIGGER_NETDEV_RX
)),
3323 .rules
= (BIT(TRIGGER_NETDEV_RX
) |
3324 BIT(TRIGGER_NETDEV_TX
)),
3328 .rules
= (BIT(TRIGGER_NETDEV_RX
) |
3329 BIT(TRIGGER_NETDEV_TX
)),
3333 .rules
= (BIT(TRIGGER_NETDEV_LINK_100
) |
3334 BIT(TRIGGER_NETDEV_LINK_1000
)),
3338 .rules
= BIT(TRIGGER_NETDEV_LINK_100
),
3346 static const struct marvell_led_rules marvell_led2
[] = {
3349 .rules
= BIT(TRIGGER_NETDEV_LINK
),
3353 .rules
= (BIT(TRIGGER_NETDEV_LINK
) |
3354 BIT(TRIGGER_NETDEV_RX
) |
3355 BIT(TRIGGER_NETDEV_TX
)),
3359 .rules
= (BIT(TRIGGER_NETDEV_RX
) |
3360 BIT(TRIGGER_NETDEV_TX
)),
3364 .rules
= (BIT(TRIGGER_NETDEV_RX
) |
3365 BIT(TRIGGER_NETDEV_TX
)),
3369 .rules
= BIT(TRIGGER_NETDEV_TX
),
3373 .rules
= (BIT(TRIGGER_NETDEV_LINK_10
) |
3374 BIT(TRIGGER_NETDEV_LINK_1000
)),
3378 .rules
= BIT(TRIGGER_NETDEV_LINK_10
),
3386 static int marvell_find_led_mode(unsigned long rules
,
3387 const struct marvell_led_rules
*marvell_rules
,
3393 for (i
= 0; i
< count
; i
++) {
3394 if (marvell_rules
[i
].rules
== rules
) {
3395 *mode
= marvell_rules
[i
].mode
;
3402 static int marvell_get_led_mode(u8 index
, unsigned long rules
, int *mode
)
3408 ret
= marvell_find_led_mode(rules
, marvell_led0
,
3409 ARRAY_SIZE(marvell_led0
), mode
);
3412 ret
= marvell_find_led_mode(rules
, marvell_led1
,
3413 ARRAY_SIZE(marvell_led1
), mode
);
3416 ret
= marvell_find_led_mode(rules
, marvell_led2
,
3417 ARRAY_SIZE(marvell_led2
), mode
);
3426 static int marvell_find_led_rules(unsigned long *rules
,
3427 const struct marvell_led_rules
*marvell_rules
,
3433 for (i
= 0; i
< count
; i
++) {
3434 if (marvell_rules
[i
].mode
== mode
) {
3435 *rules
= marvell_rules
[i
].rules
;
3442 static int marvell_get_led_rules(u8 index
, unsigned long *rules
, int mode
)
3448 ret
= marvell_find_led_rules(rules
, marvell_led0
,
3449 ARRAY_SIZE(marvell_led0
), mode
);
3452 ret
= marvell_find_led_rules(rules
, marvell_led1
,
3453 ARRAY_SIZE(marvell_led1
), mode
);
3456 ret
= marvell_find_led_rules(rules
, marvell_led2
,
3457 ARRAY_SIZE(marvell_led2
), mode
);
3466 static int m88e1318_led_hw_is_supported(struct phy_device
*phydev
, u8 index
,
3467 unsigned long rules
)
3475 ret
= marvell_get_led_mode(index
, rules
, &mode
);
3484 static int m88e1318_led_hw_control_set(struct phy_device
*phydev
, u8 index
,
3485 unsigned long rules
)
3493 ret
= marvell_get_led_mode(index
, rules
, &mode
);
3502 reg
= phy_read_paged(phydev
, MII_MARVELL_LED_PAGE
,
3503 MII_88E1318S_PHY_LED_FUNC
);
3507 reg
&= ~(0xf << (4 * index
));
3508 reg
|= mode
<< (4 * index
);
3509 return phy_write_paged(phydev
, MII_MARVELL_LED_PAGE
,
3510 MII_88E1318S_PHY_LED_FUNC
, reg
);
3513 static int m88e1318_led_hw_control_get(struct phy_device
*phydev
, u8 index
,
3514 unsigned long *rules
)
3521 reg
= phy_read_paged(phydev
, MII_MARVELL_LED_PAGE
,
3522 MII_88E1318S_PHY_LED_FUNC
);
3526 mode
= (reg
>> (4 * index
)) & 0xf;
3528 return marvell_get_led_rules(index
, rules
, mode
);
3531 static int marvell_probe(struct phy_device
*phydev
)
3533 struct marvell_priv
*priv
;
3535 priv
= devm_kzalloc(&phydev
->mdio
.dev
, sizeof(*priv
), GFP_KERNEL
);
3539 phydev
->priv
= priv
;
3541 return marvell_hwmon_probe(phydev
);
3544 static int m88e1510_sfp_insert(void *upstream
, const struct sfp_eeprom_id
*id
)
3546 DECLARE_PHY_INTERFACE_MASK(interfaces
);
3547 struct phy_device
*phydev
= upstream
;
3548 phy_interface_t interface
;
3554 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported
) = { 0, };
3556 dev
= &phydev
->mdio
.dev
;
3558 sfp_parse_support(phydev
->sfp_bus
, id
, supported
, interfaces
);
3559 interface
= sfp_select_interface(phydev
->sfp_bus
, supported
);
3561 dev_info(dev
, "%s SFP module inserted\n", phy_modes(interface
));
3563 switch (interface
) {
3564 case PHY_INTERFACE_MODE_1000BASEX
:
3565 mode
= MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X
;
3568 case PHY_INTERFACE_MODE_100BASEX
:
3569 mode
= MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX
;
3572 case PHY_INTERFACE_MODE_SGMII
:
3573 mode
= MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII
;
3577 dev_err(dev
, "Incompatible SFP module inserted\n");
3582 oldpage
= phy_select_page(phydev
, MII_MARVELL_MODE_PAGE
);
3586 ret
= __phy_modify(phydev
, MII_88E1510_GEN_CTRL_REG_1
,
3587 MII_88E1510_GEN_CTRL_REG_1_MODE_MASK
, mode
);
3591 ret
= __phy_set_bits(phydev
, MII_88E1510_GEN_CTRL_REG_1
,
3592 MII_88E1510_GEN_CTRL_REG_1_RESET
);
3595 return phy_restore_page(phydev
, oldpage
, ret
);
3598 static void m88e1510_sfp_remove(void *upstream
)
3600 struct phy_device
*phydev
= upstream
;
3604 oldpage
= phy_select_page(phydev
, MII_MARVELL_MODE_PAGE
);
3608 ret
= __phy_modify(phydev
, MII_88E1510_GEN_CTRL_REG_1
,
3609 MII_88E1510_GEN_CTRL_REG_1_MODE_MASK
,
3610 MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII
);
3614 ret
= __phy_set_bits(phydev
, MII_88E1510_GEN_CTRL_REG_1
,
3615 MII_88E1510_GEN_CTRL_REG_1_RESET
);
3618 phy_restore_page(phydev
, oldpage
, ret
);
3621 static const struct sfp_upstream_ops m88e1510_sfp_ops
= {
3622 .module_insert
= m88e1510_sfp_insert
,
3623 .module_remove
= m88e1510_sfp_remove
,
3624 .attach
= phy_sfp_attach
,
3625 .detach
= phy_sfp_detach
,
3626 .connect_phy
= phy_sfp_connect_phy
,
3627 .disconnect_phy
= phy_sfp_disconnect_phy
,
3630 static int m88e1510_probe(struct phy_device
*phydev
)
3634 err
= marvell_probe(phydev
);
3638 return phy_sfp_probe(phydev
, &m88e1510_sfp_ops
);
3641 static struct phy_driver marvell_drivers
[] = {
3643 .phy_id
= MARVELL_PHY_ID_88E1101
,
3644 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3645 .name
= "Marvell 88E1101",
3646 /* PHY_GBIT_FEATURES */
3647 .probe
= marvell_probe
,
3648 .config_init
= marvell_config_init
,
3649 .config_aneg
= m88e1101_config_aneg
,
3650 .config_intr
= marvell_config_intr
,
3651 .handle_interrupt
= marvell_handle_interrupt
,
3652 .resume
= genphy_resume
,
3653 .suspend
= genphy_suspend
,
3654 .read_page
= marvell_read_page
,
3655 .write_page
= marvell_write_page
,
3656 .get_sset_count
= marvell_get_sset_count
,
3657 .get_strings
= marvell_get_strings
,
3658 .get_stats
= marvell_get_stats
,
3661 .phy_id
= MARVELL_PHY_ID_88E3082
,
3662 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3663 .name
= "Marvell 88E308X/88E609X Family",
3664 /* PHY_BASIC_FEATURES */
3665 .probe
= marvell_probe
,
3666 .config_init
= marvell_config_init
,
3667 .aneg_done
= marvell_aneg_done
,
3668 .read_status
= marvell_read_status
,
3669 .resume
= genphy_resume
,
3670 .suspend
= genphy_suspend
,
3671 .cable_test_start
= m88e3082_vct_cable_test_start
,
3672 .cable_test_get_status
= m88e3082_vct_cable_test_get_status
,
3675 .phy_id
= MARVELL_PHY_ID_88E1112
,
3676 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3677 .name
= "Marvell 88E1112",
3678 /* PHY_GBIT_FEATURES */
3679 .probe
= marvell_probe
,
3680 .config_init
= m88e1112_config_init
,
3681 .config_aneg
= marvell_config_aneg
,
3682 .config_intr
= marvell_config_intr
,
3683 .handle_interrupt
= marvell_handle_interrupt
,
3684 .resume
= genphy_resume
,
3685 .suspend
= genphy_suspend
,
3686 .read_page
= marvell_read_page
,
3687 .write_page
= marvell_write_page
,
3688 .get_sset_count
= marvell_get_sset_count
,
3689 .get_strings
= marvell_get_strings
,
3690 .get_stats
= marvell_get_stats
,
3691 .get_tunable
= m88e1011_get_tunable
,
3692 .set_tunable
= m88e1011_set_tunable
,
3695 .phy_id
= MARVELL_PHY_ID_88E1111
,
3696 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3697 .name
= "Marvell 88E1111",
3698 /* PHY_GBIT_FEATURES */
3699 .flags
= PHY_POLL_CABLE_TEST
,
3700 .probe
= marvell_probe
,
3701 .config_init
= m88e1111gbe_config_init
,
3702 .config_aneg
= m88e1111_config_aneg
,
3703 .read_status
= marvell_read_status
,
3704 .config_intr
= marvell_config_intr
,
3705 .handle_interrupt
= marvell_handle_interrupt
,
3706 .resume
= genphy_resume
,
3707 .suspend
= genphy_suspend
,
3708 .read_page
= marvell_read_page
,
3709 .write_page
= marvell_write_page
,
3710 .get_sset_count
= marvell_get_sset_count
,
3711 .get_strings
= marvell_get_strings
,
3712 .get_stats
= marvell_get_stats
,
3713 .get_tunable
= m88e1111_get_tunable
,
3714 .set_tunable
= m88e1111_set_tunable
,
3715 .cable_test_start
= m88e1111_vct_cable_test_start
,
3716 .cable_test_get_status
= m88e1111_vct_cable_test_get_status
,
3719 .phy_id
= MARVELL_PHY_ID_88E1111_FINISAR
,
3720 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3721 .name
= "Marvell 88E1111 (Finisar)",
3722 /* PHY_GBIT_FEATURES */
3723 .probe
= marvell_probe
,
3724 .config_init
= m88e1111gbe_config_init
,
3725 .config_aneg
= m88e1111_config_aneg
,
3726 .read_status
= marvell_read_status
,
3727 .config_intr
= marvell_config_intr
,
3728 .handle_interrupt
= marvell_handle_interrupt
,
3729 .resume
= genphy_resume
,
3730 .suspend
= genphy_suspend
,
3731 .read_page
= marvell_read_page
,
3732 .write_page
= marvell_write_page
,
3733 .get_sset_count
= marvell_get_sset_count
,
3734 .get_strings
= marvell_get_strings
,
3735 .get_stats
= marvell_get_stats
,
3736 .get_tunable
= m88e1111_get_tunable
,
3737 .set_tunable
= m88e1111_set_tunable
,
3740 .phy_id
= MARVELL_PHY_ID_88E1118
,
3741 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3742 .name
= "Marvell 88E1118",
3743 /* PHY_GBIT_FEATURES */
3744 .probe
= marvell_probe
,
3745 .config_init
= m88e1118_config_init
,
3746 .config_aneg
= m88e1118_config_aneg
,
3747 .config_intr
= marvell_config_intr
,
3748 .handle_interrupt
= marvell_handle_interrupt
,
3749 .resume
= genphy_resume
,
3750 .suspend
= genphy_suspend
,
3751 .read_page
= marvell_read_page
,
3752 .write_page
= marvell_write_page
,
3753 .get_sset_count
= marvell_get_sset_count
,
3754 .get_strings
= marvell_get_strings
,
3755 .get_stats
= marvell_get_stats
,
3758 .phy_id
= MARVELL_PHY_ID_88E1121R
,
3759 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3760 .name
= "Marvell 88E1121R",
3761 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e1121_hwmon_ops
),
3762 /* PHY_GBIT_FEATURES */
3763 .probe
= marvell_probe
,
3764 .config_init
= marvell_1011gbe_config_init
,
3765 .config_aneg
= m88e1121_config_aneg
,
3766 .read_status
= marvell_read_status
,
3767 .config_intr
= marvell_config_intr
,
3768 .handle_interrupt
= marvell_handle_interrupt
,
3769 .resume
= genphy_resume
,
3770 .suspend
= genphy_suspend
,
3771 .read_page
= marvell_read_page
,
3772 .write_page
= marvell_write_page
,
3773 .get_sset_count
= marvell_get_sset_count
,
3774 .get_strings
= marvell_get_strings
,
3775 .get_stats
= marvell_get_stats
,
3776 .get_tunable
= m88e1011_get_tunable
,
3777 .set_tunable
= m88e1011_set_tunable
,
3780 .phy_id
= MARVELL_PHY_ID_88E1318S
,
3781 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3782 .name
= "Marvell 88E1318S",
3783 /* PHY_GBIT_FEATURES */
3784 .probe
= marvell_probe
,
3785 .config_init
= m88e1318_config_init
,
3786 .config_aneg
= m88e1318_config_aneg
,
3787 .read_status
= marvell_read_status
,
3788 .config_intr
= marvell_config_intr
,
3789 .handle_interrupt
= marvell_handle_interrupt
,
3790 .get_wol
= m88e1318_get_wol
,
3791 .set_wol
= m88e1318_set_wol
,
3792 .resume
= genphy_resume
,
3793 .suspend
= genphy_suspend
,
3794 .read_page
= marvell_read_page
,
3795 .write_page
= marvell_write_page
,
3796 .get_sset_count
= marvell_get_sset_count
,
3797 .get_strings
= marvell_get_strings
,
3798 .get_stats
= marvell_get_stats
,
3799 .led_brightness_set
= m88e1318_led_brightness_set
,
3800 .led_blink_set
= m88e1318_led_blink_set
,
3801 .led_hw_is_supported
= m88e1318_led_hw_is_supported
,
3802 .led_hw_control_set
= m88e1318_led_hw_control_set
,
3803 .led_hw_control_get
= m88e1318_led_hw_control_get
,
3806 .phy_id
= MARVELL_PHY_ID_88E1145
,
3807 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3808 .name
= "Marvell 88E1145",
3809 /* PHY_GBIT_FEATURES */
3810 .flags
= PHY_POLL_CABLE_TEST
,
3811 .probe
= marvell_probe
,
3812 .config_init
= m88e1145_config_init
,
3813 .config_aneg
= m88e1101_config_aneg
,
3814 .config_intr
= marvell_config_intr
,
3815 .handle_interrupt
= marvell_handle_interrupt
,
3816 .resume
= genphy_resume
,
3817 .suspend
= genphy_suspend
,
3818 .read_page
= marvell_read_page
,
3819 .write_page
= marvell_write_page
,
3820 .get_sset_count
= marvell_get_sset_count
,
3821 .get_strings
= marvell_get_strings
,
3822 .get_stats
= marvell_get_stats
,
3823 .get_tunable
= m88e1111_get_tunable
,
3824 .set_tunable
= m88e1111_set_tunable
,
3825 .cable_test_start
= m88e1111_vct_cable_test_start
,
3826 .cable_test_get_status
= m88e1111_vct_cable_test_get_status
,
3829 .phy_id
= MARVELL_PHY_ID_88E1149R
,
3830 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3831 .name
= "Marvell 88E1149R",
3832 /* PHY_GBIT_FEATURES */
3833 .probe
= marvell_probe
,
3834 .config_init
= m88e1149_config_init
,
3835 .config_aneg
= m88e1118_config_aneg
,
3836 .config_intr
= marvell_config_intr
,
3837 .handle_interrupt
= marvell_handle_interrupt
,
3838 .resume
= genphy_resume
,
3839 .suspend
= genphy_suspend
,
3840 .read_page
= marvell_read_page
,
3841 .write_page
= marvell_write_page
,
3842 .get_sset_count
= marvell_get_sset_count
,
3843 .get_strings
= marvell_get_strings
,
3844 .get_stats
= marvell_get_stats
,
3847 .phy_id
= MARVELL_PHY_ID_88E1240
,
3848 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3849 .name
= "Marvell 88E1240",
3850 /* PHY_GBIT_FEATURES */
3851 .probe
= marvell_probe
,
3852 .config_init
= m88e1112_config_init
,
3853 .config_aneg
= marvell_config_aneg
,
3854 .config_intr
= marvell_config_intr
,
3855 .handle_interrupt
= marvell_handle_interrupt
,
3856 .resume
= genphy_resume
,
3857 .suspend
= genphy_suspend
,
3858 .read_page
= marvell_read_page
,
3859 .write_page
= marvell_write_page
,
3860 .get_sset_count
= marvell_get_sset_count
,
3861 .get_strings
= marvell_get_strings
,
3862 .get_stats
= marvell_get_stats
,
3863 .get_tunable
= m88e1011_get_tunable
,
3864 .set_tunable
= m88e1011_set_tunable
,
3867 .phy_id
= MARVELL_PHY_ID_88E1116R
,
3868 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3869 .name
= "Marvell 88E1116R",
3870 /* PHY_GBIT_FEATURES */
3871 .probe
= marvell_probe
,
3872 .config_init
= m88e1116r_config_init
,
3873 .config_intr
= marvell_config_intr
,
3874 .handle_interrupt
= marvell_handle_interrupt
,
3875 .resume
= genphy_resume
,
3876 .suspend
= genphy_suspend
,
3877 .read_page
= marvell_read_page
,
3878 .write_page
= marvell_write_page
,
3879 .get_sset_count
= marvell_get_sset_count
,
3880 .get_strings
= marvell_get_strings
,
3881 .get_stats
= marvell_get_stats
,
3882 .get_tunable
= m88e1011_get_tunable
,
3883 .set_tunable
= m88e1011_set_tunable
,
3886 .phy_id
= MARVELL_PHY_ID_88E1510
,
3887 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3888 .name
= "Marvell 88E1510",
3889 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops
),
3890 .features
= PHY_GBIT_FIBRE_FEATURES
,
3891 .flags
= PHY_POLL_CABLE_TEST
,
3892 .probe
= m88e1510_probe
,
3893 .config_init
= m88e1510_config_init
,
3894 .config_aneg
= m88e1510_config_aneg
,
3895 .read_status
= marvell_read_status
,
3896 .config_intr
= marvell_config_intr
,
3897 .handle_interrupt
= marvell_handle_interrupt
,
3898 .get_wol
= m88e1318_get_wol
,
3899 .set_wol
= m88e1318_set_wol
,
3900 .resume
= marvell_resume
,
3901 .suspend
= marvell_suspend
,
3902 .read_page
= marvell_read_page
,
3903 .write_page
= marvell_write_page
,
3904 .get_sset_count
= marvell_get_sset_count
,
3905 .get_strings
= marvell_get_strings
,
3906 .get_stats
= marvell_get_stats
,
3907 .set_loopback
= m88e1510_loopback
,
3908 .get_tunable
= m88e1011_get_tunable
,
3909 .set_tunable
= m88e1011_set_tunable
,
3910 .cable_test_start
= marvell_vct7_cable_test_start
,
3911 .cable_test_tdr_start
= marvell_vct5_cable_test_tdr_start
,
3912 .cable_test_get_status
= marvell_vct7_cable_test_get_status
,
3913 .led_brightness_set
= m88e1318_led_brightness_set
,
3914 .led_blink_set
= m88e1318_led_blink_set
,
3915 .led_hw_is_supported
= m88e1318_led_hw_is_supported
,
3916 .led_hw_control_set
= m88e1318_led_hw_control_set
,
3917 .led_hw_control_get
= m88e1318_led_hw_control_get
,
3920 .phy_id
= MARVELL_PHY_ID_88E1540
,
3921 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3922 .name
= "Marvell 88E1540",
3923 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops
),
3924 /* PHY_GBIT_FEATURES */
3925 .flags
= PHY_POLL_CABLE_TEST
,
3926 .probe
= marvell_probe
,
3927 .config_init
= marvell_1011gbe_config_init
,
3928 .config_aneg
= m88e1510_config_aneg
,
3929 .read_status
= marvell_read_status
,
3930 .config_intr
= marvell_config_intr
,
3931 .handle_interrupt
= marvell_handle_interrupt
,
3932 .resume
= genphy_resume
,
3933 .suspend
= genphy_suspend
,
3934 .read_page
= marvell_read_page
,
3935 .write_page
= marvell_write_page
,
3936 .get_sset_count
= marvell_get_sset_count
,
3937 .get_strings
= marvell_get_strings
,
3938 .get_stats
= marvell_get_stats
,
3939 .get_tunable
= m88e1540_get_tunable
,
3940 .set_tunable
= m88e1540_set_tunable
,
3941 .cable_test_start
= marvell_vct7_cable_test_start
,
3942 .cable_test_tdr_start
= marvell_vct5_cable_test_tdr_start
,
3943 .cable_test_get_status
= marvell_vct7_cable_test_get_status
,
3944 .led_brightness_set
= m88e1318_led_brightness_set
,
3945 .led_blink_set
= m88e1318_led_blink_set
,
3946 .led_hw_is_supported
= m88e1318_led_hw_is_supported
,
3947 .led_hw_control_set
= m88e1318_led_hw_control_set
,
3948 .led_hw_control_get
= m88e1318_led_hw_control_get
,
3951 .phy_id
= MARVELL_PHY_ID_88E1545
,
3952 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3953 .name
= "Marvell 88E1545",
3954 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops
),
3955 .probe
= marvell_probe
,
3956 /* PHY_GBIT_FEATURES */
3957 .flags
= PHY_POLL_CABLE_TEST
,
3958 .config_init
= marvell_1011gbe_config_init
,
3959 .config_aneg
= m88e1510_config_aneg
,
3960 .read_status
= marvell_read_status
,
3961 .config_intr
= marvell_config_intr
,
3962 .handle_interrupt
= marvell_handle_interrupt
,
3963 .resume
= genphy_resume
,
3964 .suspend
= genphy_suspend
,
3965 .read_page
= marvell_read_page
,
3966 .write_page
= marvell_write_page
,
3967 .get_sset_count
= marvell_get_sset_count
,
3968 .get_strings
= marvell_get_strings
,
3969 .get_stats
= marvell_get_stats
,
3970 .get_tunable
= m88e1540_get_tunable
,
3971 .set_tunable
= m88e1540_set_tunable
,
3972 .cable_test_start
= marvell_vct7_cable_test_start
,
3973 .cable_test_tdr_start
= marvell_vct5_cable_test_tdr_start
,
3974 .cable_test_get_status
= marvell_vct7_cable_test_get_status
,
3975 .led_brightness_set
= m88e1318_led_brightness_set
,
3976 .led_blink_set
= m88e1318_led_blink_set
,
3977 .led_hw_is_supported
= m88e1318_led_hw_is_supported
,
3978 .led_hw_control_set
= m88e1318_led_hw_control_set
,
3979 .led_hw_control_get
= m88e1318_led_hw_control_get
,
3982 .phy_id
= MARVELL_PHY_ID_88E3016
,
3983 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
3984 .name
= "Marvell 88E3016",
3985 /* PHY_BASIC_FEATURES */
3986 .probe
= marvell_probe
,
3987 .config_init
= m88e3016_config_init
,
3988 .aneg_done
= marvell_aneg_done
,
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
,
4001 .phy_id
= MARVELL_PHY_ID_88E6250_FAMILY
,
4002 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
4003 .name
= "Marvell 88E6250 Family",
4004 /* PHY_BASIC_FEATURES */
4005 .probe
= marvell_probe
,
4006 .aneg_done
= marvell_aneg_done
,
4007 .config_intr
= marvell_config_intr
,
4008 .handle_interrupt
= marvell_handle_interrupt
,
4009 .resume
= genphy_resume
,
4010 .suspend
= genphy_suspend
,
4011 .get_sset_count
= marvell_get_sset_count_simple
,
4012 .get_strings
= marvell_get_strings_simple
,
4013 .get_stats
= marvell_get_stats_simple
,
4016 .phy_id
= MARVELL_PHY_ID_88E6341_FAMILY
,
4017 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
4018 .name
= "Marvell 88E6341 Family",
4019 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops
),
4020 /* PHY_GBIT_FEATURES */
4021 .flags
= PHY_POLL_CABLE_TEST
,
4022 .probe
= marvell_probe
,
4023 .config_init
= marvell_1011gbe_config_init
,
4024 .config_aneg
= m88e6390_config_aneg
,
4025 .read_status
= marvell_read_status
,
4026 .config_intr
= marvell_config_intr
,
4027 .handle_interrupt
= marvell_handle_interrupt
,
4028 .resume
= genphy_resume
,
4029 .suspend
= genphy_suspend
,
4030 .read_page
= marvell_read_page
,
4031 .write_page
= marvell_write_page
,
4032 .get_sset_count
= marvell_get_sset_count
,
4033 .get_strings
= marvell_get_strings
,
4034 .get_stats
= marvell_get_stats
,
4035 .get_tunable
= m88e1540_get_tunable
,
4036 .set_tunable
= m88e1540_set_tunable
,
4037 .cable_test_start
= marvell_vct7_cable_test_start
,
4038 .cable_test_tdr_start
= marvell_vct5_cable_test_tdr_start
,
4039 .cable_test_get_status
= marvell_vct7_cable_test_get_status
,
4042 .phy_id
= MARVELL_PHY_ID_88E6390_FAMILY
,
4043 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
4044 .name
= "Marvell 88E6390 Family",
4045 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e6390_hwmon_ops
),
4046 /* PHY_GBIT_FEATURES */
4047 .flags
= PHY_POLL_CABLE_TEST
,
4048 .probe
= marvell_probe
,
4049 .config_init
= marvell_1011gbe_config_init
,
4050 .config_aneg
= m88e6390_config_aneg
,
4051 .read_status
= marvell_read_status
,
4052 .config_intr
= marvell_config_intr
,
4053 .handle_interrupt
= marvell_handle_interrupt
,
4054 .resume
= genphy_resume
,
4055 .suspend
= genphy_suspend
,
4056 .read_page
= marvell_read_page
,
4057 .write_page
= marvell_write_page
,
4058 .get_sset_count
= marvell_get_sset_count
,
4059 .get_strings
= marvell_get_strings
,
4060 .get_stats
= marvell_get_stats
,
4061 .get_tunable
= m88e1540_get_tunable
,
4062 .set_tunable
= m88e1540_set_tunable
,
4063 .cable_test_start
= marvell_vct7_cable_test_start
,
4064 .cable_test_tdr_start
= marvell_vct5_cable_test_tdr_start
,
4065 .cable_test_get_status
= marvell_vct7_cable_test_get_status
,
4068 .phy_id
= MARVELL_PHY_ID_88E6393_FAMILY
,
4069 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
4070 .name
= "Marvell 88E6393 Family",
4071 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e6393_hwmon_ops
),
4072 /* PHY_GBIT_FEATURES */
4073 .flags
= PHY_POLL_CABLE_TEST
,
4074 .probe
= marvell_probe
,
4075 .config_init
= marvell_1011gbe_config_init
,
4076 .config_aneg
= m88e1510_config_aneg
,
4077 .read_status
= marvell_read_status
,
4078 .config_intr
= marvell_config_intr
,
4079 .handle_interrupt
= marvell_handle_interrupt
,
4080 .resume
= genphy_resume
,
4081 .suspend
= genphy_suspend
,
4082 .read_page
= marvell_read_page
,
4083 .write_page
= marvell_write_page
,
4084 .get_sset_count
= marvell_get_sset_count
,
4085 .get_strings
= marvell_get_strings
,
4086 .get_stats
= marvell_get_stats
,
4087 .get_tunable
= m88e1540_get_tunable
,
4088 .set_tunable
= m88e1540_set_tunable
,
4089 .cable_test_start
= marvell_vct7_cable_test_start
,
4090 .cable_test_tdr_start
= marvell_vct5_cable_test_tdr_start
,
4091 .cable_test_get_status
= marvell_vct7_cable_test_get_status
,
4094 .phy_id
= MARVELL_PHY_ID_88E1340S
,
4095 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
4096 .name
= "Marvell 88E1340S",
4097 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops
),
4098 .probe
= marvell_probe
,
4099 /* PHY_GBIT_FEATURES */
4100 .config_init
= marvell_1011gbe_config_init
,
4101 .config_aneg
= m88e1510_config_aneg
,
4102 .read_status
= marvell_read_status
,
4103 .config_intr
= marvell_config_intr
,
4104 .handle_interrupt
= marvell_handle_interrupt
,
4105 .resume
= genphy_resume
,
4106 .suspend
= genphy_suspend
,
4107 .read_page
= marvell_read_page
,
4108 .write_page
= marvell_write_page
,
4109 .get_sset_count
= marvell_get_sset_count
,
4110 .get_strings
= marvell_get_strings
,
4111 .get_stats
= marvell_get_stats
,
4112 .get_tunable
= m88e1540_get_tunable
,
4113 .set_tunable
= m88e1540_set_tunable
,
4116 .phy_id
= MARVELL_PHY_ID_88E1548P
,
4117 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
4118 .name
= "Marvell 88E1548P",
4119 .driver_data
= DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops
),
4120 .probe
= marvell_probe
,
4121 .features
= PHY_GBIT_FIBRE_FEATURES
,
4122 .config_init
= marvell_1011gbe_config_init
,
4123 .config_aneg
= m88e1510_config_aneg
,
4124 .read_status
= marvell_read_status
,
4125 .config_intr
= marvell_config_intr
,
4126 .handle_interrupt
= marvell_handle_interrupt
,
4127 .resume
= genphy_resume
,
4128 .suspend
= genphy_suspend
,
4129 .read_page
= marvell_read_page
,
4130 .write_page
= marvell_write_page
,
4131 .get_sset_count
= marvell_get_sset_count
,
4132 .get_strings
= marvell_get_strings
,
4133 .get_stats
= marvell_get_stats
,
4134 .get_tunable
= m88e1540_get_tunable
,
4135 .set_tunable
= m88e1540_set_tunable
,
4136 .led_brightness_set
= m88e1318_led_brightness_set
,
4137 .led_blink_set
= m88e1318_led_blink_set
,
4138 .led_hw_is_supported
= m88e1318_led_hw_is_supported
,
4139 .led_hw_control_set
= m88e1318_led_hw_control_set
,
4140 .led_hw_control_get
= m88e1318_led_hw_control_get
,
4144 module_phy_driver(marvell_drivers
);
4146 static struct mdio_device_id __maybe_unused marvell_tbl
[] = {
4147 { MARVELL_PHY_ID_88E1101
, MARVELL_PHY_ID_MASK
},
4148 { MARVELL_PHY_ID_88E3082
, MARVELL_PHY_ID_MASK
},
4149 { MARVELL_PHY_ID_88E1112
, MARVELL_PHY_ID_MASK
},
4150 { MARVELL_PHY_ID_88E1111
, MARVELL_PHY_ID_MASK
},
4151 { MARVELL_PHY_ID_88E1111_FINISAR
, MARVELL_PHY_ID_MASK
},
4152 { MARVELL_PHY_ID_88E1118
, MARVELL_PHY_ID_MASK
},
4153 { MARVELL_PHY_ID_88E1121R
, MARVELL_PHY_ID_MASK
},
4154 { MARVELL_PHY_ID_88E1145
, MARVELL_PHY_ID_MASK
},
4155 { MARVELL_PHY_ID_88E1149R
, MARVELL_PHY_ID_MASK
},
4156 { MARVELL_PHY_ID_88E1240
, MARVELL_PHY_ID_MASK
},
4157 { MARVELL_PHY_ID_88E1318S
, MARVELL_PHY_ID_MASK
},
4158 { MARVELL_PHY_ID_88E1116R
, MARVELL_PHY_ID_MASK
},
4159 { MARVELL_PHY_ID_88E1510
, MARVELL_PHY_ID_MASK
},
4160 { MARVELL_PHY_ID_88E1540
, MARVELL_PHY_ID_MASK
},
4161 { MARVELL_PHY_ID_88E1545
, MARVELL_PHY_ID_MASK
},
4162 { MARVELL_PHY_ID_88E3016
, MARVELL_PHY_ID_MASK
},
4163 { MARVELL_PHY_ID_88E6250_FAMILY
, MARVELL_PHY_ID_MASK
},
4164 { MARVELL_PHY_ID_88E6341_FAMILY
, MARVELL_PHY_ID_MASK
},
4165 { MARVELL_PHY_ID_88E6390_FAMILY
, MARVELL_PHY_ID_MASK
},
4166 { MARVELL_PHY_ID_88E6393_FAMILY
, MARVELL_PHY_ID_MASK
},
4167 { MARVELL_PHY_ID_88E1340S
, MARVELL_PHY_ID_MASK
},
4168 { MARVELL_PHY_ID_88E1548P
, MARVELL_PHY_ID_MASK
},
4172 MODULE_DEVICE_TABLE(mdio
, marvell_tbl
);