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