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