• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
36 #include <linux/io.h>
37 #include <asm/irq.h>
38 #include <linux/uaccess.h>
39 
40 #define MII_MARVELL_PHY_PAGE		22
41 #define MII_MARVELL_COPPER_PAGE		0x00
42 #define MII_MARVELL_FIBER_PAGE		0x01
43 #define MII_MARVELL_MSCR_PAGE		0x02
44 #define MII_MARVELL_LED_PAGE		0x03
45 #define MII_MARVELL_VCT5_PAGE		0x05
46 #define MII_MARVELL_MISC_TEST_PAGE	0x06
47 #define MII_MARVELL_VCT7_PAGE		0x07
48 #define MII_MARVELL_WOL_PAGE		0x11
49 
50 #define MII_M1011_IEVENT		0x13
51 #define MII_M1011_IEVENT_CLEAR		0x0000
52 
53 #define MII_M1011_IMASK			0x12
54 #define MII_M1011_IMASK_INIT		0x6400
55 #define MII_M1011_IMASK_CLEAR		0x0000
56 
57 #define MII_M1011_PHY_SCR			0x10
58 #define MII_M1011_PHY_SCR_DOWNSHIFT_EN		BIT(11)
59 #define MII_M1011_PHY_SCR_DOWNSHIFT_MASK	GENMASK(14, 12)
60 #define MII_M1011_PHY_SCR_DOWNSHIFT_MAX		8
61 #define MII_M1011_PHY_SCR_MDI			(0x0 << 5)
62 #define MII_M1011_PHY_SCR_MDI_X			(0x1 << 5)
63 #define MII_M1011_PHY_SCR_AUTO_CROSS		(0x3 << 5)
64 
65 #define MII_M1011_PHY_SSR			0x11
66 #define MII_M1011_PHY_SSR_DOWNSHIFT		BIT(5)
67 
68 #define MII_M1111_PHY_LED_CONTROL	0x18
69 #define MII_M1111_PHY_LED_DIRECT	0x4100
70 #define MII_M1111_PHY_LED_COMBINE	0x411c
71 #define MII_M1111_PHY_EXT_CR		0x14
72 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK	GENMASK(11, 9)
73 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX	8
74 #define MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN	BIT(8)
75 #define MII_M1111_RGMII_RX_DELAY	BIT(7)
76 #define MII_M1111_RGMII_TX_DELAY	BIT(1)
77 #define MII_M1111_PHY_EXT_SR		0x1b
78 
79 #define MII_M1111_HWCFG_MODE_MASK		0xf
80 #define MII_M1111_HWCFG_MODE_FIBER_RGMII	0x3
81 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK	0x4
82 #define MII_M1111_HWCFG_MODE_RTBI		0x7
83 #define MII_M1111_HWCFG_MODE_COPPER_RTBI	0x9
84 #define MII_M1111_HWCFG_MODE_COPPER_RGMII	0xb
85 #define MII_M1111_HWCFG_FIBER_COPPER_RES	BIT(13)
86 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO	BIT(15)
87 
88 #define MII_88E1121_PHY_MSCR_REG	21
89 #define MII_88E1121_PHY_MSCR_RX_DELAY	BIT(5)
90 #define MII_88E1121_PHY_MSCR_TX_DELAY	BIT(4)
91 #define MII_88E1121_PHY_MSCR_DELAY_MASK	(BIT(5) | BIT(4))
92 
93 #define MII_88E1121_MISC_TEST				0x1a
94 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK	0x1f00
95 #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT	8
96 #define MII_88E1510_MISC_TEST_TEMP_IRQ_EN		BIT(7)
97 #define MII_88E1510_MISC_TEST_TEMP_IRQ			BIT(6)
98 #define MII_88E1121_MISC_TEST_TEMP_SENSOR_EN		BIT(5)
99 #define MII_88E1121_MISC_TEST_TEMP_MASK			0x1f
100 
101 #define MII_88E1510_TEMP_SENSOR		0x1b
102 #define MII_88E1510_TEMP_SENSOR_MASK	0xff
103 
104 #define MII_88E1540_COPPER_CTRL3	0x1a
105 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK	GENMASK(11, 10)
106 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS	0
107 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS	1
108 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS	2
109 #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS	3
110 #define MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN		BIT(9)
111 
112 #define MII_88E6390_MISC_TEST		0x1b
113 #define MII_88E6390_MISC_TEST_SAMPLE_1S		0
114 #define MII_88E6390_MISC_TEST_SAMPLE_10MS	BIT(14)
115 #define MII_88E6390_MISC_TEST_SAMPLE_DISABLE	BIT(15)
116 #define MII_88E6390_MISC_TEST_SAMPLE_ENABLE	0
117 #define MII_88E6390_MISC_TEST_SAMPLE_MASK	(0x3 << 14)
118 
119 #define MII_88E6390_TEMP_SENSOR		0x1c
120 #define MII_88E6390_TEMP_SENSOR_MASK	0xff
121 #define MII_88E6390_TEMP_SENSOR_SAMPLES 10
122 
123 #define MII_88E1318S_PHY_MSCR1_REG	16
124 #define MII_88E1318S_PHY_MSCR1_PAD_ODD	BIT(6)
125 
126 /* Copper Specific Interrupt Enable Register */
127 #define MII_88E1318S_PHY_CSIER				0x12
128 /* WOL Event Interrupt Enable */
129 #define MII_88E1318S_PHY_CSIER_WOL_EIE			BIT(7)
130 
131 /* LED Timer Control Register */
132 #define MII_88E1318S_PHY_LED_TCR			0x12
133 #define MII_88E1318S_PHY_LED_TCR_FORCE_INT		BIT(15)
134 #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE		BIT(7)
135 #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW		BIT(11)
136 
137 /* Magic Packet MAC address registers */
138 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2		0x17
139 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1		0x18
140 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0		0x19
141 
142 #define MII_88E1318S_PHY_WOL_CTRL				0x10
143 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS		BIT(12)
144 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE	BIT(14)
145 
146 #define MII_PHY_LED_CTRL	        16
147 #define MII_88E1121_PHY_LED_DEF		0x0030
148 #define MII_88E1510_PHY_LED_DEF		0x1177
149 #define MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE	0x1040
150 
151 #define MII_M1011_PHY_STATUS		0x11
152 #define MII_M1011_PHY_STATUS_1000	0x8000
153 #define MII_M1011_PHY_STATUS_100	0x4000
154 #define MII_M1011_PHY_STATUS_SPD_MASK	0xc000
155 #define MII_M1011_PHY_STATUS_FULLDUPLEX	0x2000
156 #define MII_M1011_PHY_STATUS_RESOLVED	0x0800
157 #define MII_M1011_PHY_STATUS_LINK	0x0400
158 
159 #define MII_88E3016_PHY_SPEC_CTRL	0x10
160 #define MII_88E3016_DISABLE_SCRAMBLER	0x0200
161 #define MII_88E3016_AUTO_MDIX_CROSSOVER	0x0030
162 
163 #define MII_88E1510_GEN_CTRL_REG_1		0x14
164 #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK	0x7
165 #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII	0x1	/* SGMII to copper */
166 #define MII_88E1510_GEN_CTRL_REG_1_RESET	0x8000	/* Soft reset */
167 
168 #define MII_VCT5_TX_RX_MDI0_COUPLING	0x10
169 #define MII_VCT5_TX_RX_MDI1_COUPLING	0x11
170 #define MII_VCT5_TX_RX_MDI2_COUPLING	0x12
171 #define MII_VCT5_TX_RX_MDI3_COUPLING	0x13
172 #define MII_VCT5_TX_RX_AMPLITUDE_MASK	0x7f00
173 #define MII_VCT5_TX_RX_AMPLITUDE_SHIFT	8
174 #define MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION	BIT(15)
175 
176 #define MII_VCT5_CTRL				0x17
177 #define MII_VCT5_CTRL_ENABLE				BIT(15)
178 #define MII_VCT5_CTRL_COMPLETE				BIT(14)
179 #define MII_VCT5_CTRL_TX_SAME_CHANNEL			(0x0 << 11)
180 #define MII_VCT5_CTRL_TX0_CHANNEL			(0x4 << 11)
181 #define MII_VCT5_CTRL_TX1_CHANNEL			(0x5 << 11)
182 #define MII_VCT5_CTRL_TX2_CHANNEL			(0x6 << 11)
183 #define MII_VCT5_CTRL_TX3_CHANNEL			(0x7 << 11)
184 #define MII_VCT5_CTRL_SAMPLES_2				(0x0 << 8)
185 #define MII_VCT5_CTRL_SAMPLES_4				(0x1 << 8)
186 #define MII_VCT5_CTRL_SAMPLES_8				(0x2 << 8)
187 #define MII_VCT5_CTRL_SAMPLES_16			(0x3 << 8)
188 #define MII_VCT5_CTRL_SAMPLES_32			(0x4 << 8)
189 #define MII_VCT5_CTRL_SAMPLES_64			(0x5 << 8)
190 #define MII_VCT5_CTRL_SAMPLES_128			(0x6 << 8)
191 #define MII_VCT5_CTRL_SAMPLES_DEFAULT			(0x6 << 8)
192 #define MII_VCT5_CTRL_SAMPLES_256			(0x7 << 8)
193 #define MII_VCT5_CTRL_SAMPLES_SHIFT			8
194 #define MII_VCT5_CTRL_MODE_MAXIMUM_PEEK			(0x0 << 6)
195 #define MII_VCT5_CTRL_MODE_FIRST_LAST_PEEK		(0x1 << 6)
196 #define MII_VCT5_CTRL_MODE_OFFSET			(0x2 << 6)
197 #define MII_VCT5_CTRL_SAMPLE_POINT			(0x3 << 6)
198 #define MII_VCT5_CTRL_PEEK_HYST_DEFAULT			3
199 
200 #define MII_VCT5_SAMPLE_POINT_DISTANCE		0x18
201 #define MII_VCT5_SAMPLE_POINT_DISTANCE_MAX	511
202 #define MII_VCT5_TX_PULSE_CTRL			0x1c
203 #define MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN	BIT(12)
204 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS	(0x0 << 10)
205 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_96nS		(0x1 << 10)
206 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_64nS		(0x2 << 10)
207 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS		(0x3 << 10)
208 #define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_SHIFT	10
209 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_1000mV	(0x0 << 8)
210 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_750mV	(0x1 << 8)
211 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_500mV	(0x2 << 8)
212 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_250mV	(0x3 << 8)
213 #define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_SHIFT	8
214 #define MII_VCT5_TX_PULSE_CTRL_MAX_AMP			BIT(7)
215 #define MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV		(0x6 << 0)
216 
217 /* For TDR measurements less than 11 meters, a short pulse should be
218  * used.
219  */
220 #define TDR_SHORT_CABLE_LENGTH	11
221 
222 #define MII_VCT7_PAIR_0_DISTANCE	0x10
223 #define MII_VCT7_PAIR_1_DISTANCE	0x11
224 #define MII_VCT7_PAIR_2_DISTANCE	0x12
225 #define MII_VCT7_PAIR_3_DISTANCE	0x13
226 
227 #define MII_VCT7_RESULTS	0x14
228 #define MII_VCT7_RESULTS_PAIR3_MASK	0xf000
229 #define MII_VCT7_RESULTS_PAIR2_MASK	0x0f00
230 #define MII_VCT7_RESULTS_PAIR1_MASK	0x00f0
231 #define MII_VCT7_RESULTS_PAIR0_MASK	0x000f
232 #define MII_VCT7_RESULTS_PAIR3_SHIFT	12
233 #define MII_VCT7_RESULTS_PAIR2_SHIFT	8
234 #define MII_VCT7_RESULTS_PAIR1_SHIFT	4
235 #define MII_VCT7_RESULTS_PAIR0_SHIFT	0
236 #define MII_VCT7_RESULTS_INVALID	0
237 #define MII_VCT7_RESULTS_OK		1
238 #define MII_VCT7_RESULTS_OPEN		2
239 #define MII_VCT7_RESULTS_SAME_SHORT	3
240 #define MII_VCT7_RESULTS_CROSS_SHORT	4
241 #define MII_VCT7_RESULTS_BUSY		9
242 
243 #define MII_VCT7_CTRL		0x15
244 #define MII_VCT7_CTRL_RUN_NOW			BIT(15)
245 #define MII_VCT7_CTRL_RUN_ANEG			BIT(14)
246 #define MII_VCT7_CTRL_DISABLE_CROSS		BIT(13)
247 #define MII_VCT7_CTRL_RUN_AFTER_BREAK_LINK	BIT(12)
248 #define MII_VCT7_CTRL_IN_PROGRESS		BIT(11)
249 #define MII_VCT7_CTRL_METERS			BIT(10)
250 #define MII_VCT7_CTRL_CENTIMETERS		0
251 
252 #define LPA_PAUSE_FIBER		0x180
253 #define LPA_PAUSE_ASYM_FIBER	0x100
254 
255 #define NB_FIBER_STATS	1
256 
257 MODULE_DESCRIPTION("Marvell PHY driver");
258 MODULE_AUTHOR("Andy Fleming");
259 MODULE_LICENSE("GPL");
260 
261 struct marvell_hw_stat {
262 	const char *string;
263 	u8 page;
264 	u8 reg;
265 	u8 bits;
266 };
267 
268 static struct marvell_hw_stat marvell_hw_stats[] = {
269 	{ "phy_receive_errors_copper", 0, 21, 16},
270 	{ "phy_idle_errors", 0, 10, 8 },
271 	{ "phy_receive_errors_fiber", 1, 21, 16},
272 };
273 
274 struct marvell_priv {
275 	u64 stats[ARRAY_SIZE(marvell_hw_stats)];
276 	char *hwmon_name;
277 	struct device *hwmon_dev;
278 	bool cable_test_tdr;
279 	u32 first;
280 	u32 last;
281 	u32 step;
282 	s8 pair;
283 };
284 
marvell_read_page(struct phy_device * phydev)285 static int marvell_read_page(struct phy_device *phydev)
286 {
287 	return __phy_read(phydev, MII_MARVELL_PHY_PAGE);
288 }
289 
marvell_write_page(struct phy_device * phydev,int page)290 static int marvell_write_page(struct phy_device *phydev, int page)
291 {
292 	return __phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
293 }
294 
marvell_set_page(struct phy_device * phydev,int page)295 static int marvell_set_page(struct phy_device *phydev, int page)
296 {
297 	return phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
298 }
299 
marvell_ack_interrupt(struct phy_device * phydev)300 static int marvell_ack_interrupt(struct phy_device *phydev)
301 {
302 	int err;
303 
304 	/* Clear the interrupts by reading the reg */
305 	err = phy_read(phydev, MII_M1011_IEVENT);
306 
307 	if (err < 0)
308 		return err;
309 
310 	return 0;
311 }
312 
marvell_config_intr(struct phy_device * phydev)313 static int marvell_config_intr(struct phy_device *phydev)
314 {
315 	int err;
316 
317 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
318 		err = phy_write(phydev, MII_M1011_IMASK,
319 				MII_M1011_IMASK_INIT);
320 	else
321 		err = phy_write(phydev, MII_M1011_IMASK,
322 				MII_M1011_IMASK_CLEAR);
323 
324 	return err;
325 }
326 
marvell_set_polarity(struct phy_device * phydev,int polarity)327 static int marvell_set_polarity(struct phy_device *phydev, int polarity)
328 {
329 	int reg;
330 	int err;
331 	int val;
332 
333 	/* get the current settings */
334 	reg = phy_read(phydev, MII_M1011_PHY_SCR);
335 	if (reg < 0)
336 		return reg;
337 
338 	val = reg;
339 	val &= ~MII_M1011_PHY_SCR_AUTO_CROSS;
340 	switch (polarity) {
341 	case ETH_TP_MDI:
342 		val |= MII_M1011_PHY_SCR_MDI;
343 		break;
344 	case ETH_TP_MDI_X:
345 		val |= MII_M1011_PHY_SCR_MDI_X;
346 		break;
347 	case ETH_TP_MDI_AUTO:
348 	case ETH_TP_MDI_INVALID:
349 	default:
350 		val |= MII_M1011_PHY_SCR_AUTO_CROSS;
351 		break;
352 	}
353 
354 	if (val != reg) {
355 		/* Set the new polarity value in the register */
356 		err = phy_write(phydev, MII_M1011_PHY_SCR, val);
357 		if (err)
358 			return err;
359 	}
360 
361 	return val != reg;
362 }
363 
marvell_config_aneg(struct phy_device * phydev)364 static int marvell_config_aneg(struct phy_device *phydev)
365 {
366 	int changed = 0;
367 	int err;
368 
369 	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
370 	if (err < 0)
371 		return err;
372 
373 	changed = err;
374 
375 	err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
376 			MII_M1111_PHY_LED_DIRECT);
377 	if (err < 0)
378 		return err;
379 
380 	err = genphy_config_aneg(phydev);
381 	if (err < 0)
382 		return err;
383 
384 	if (phydev->autoneg != AUTONEG_ENABLE || changed) {
385 		/* A write to speed/duplex bits (that is performed by
386 		 * genphy_config_aneg() call above) must be followed by
387 		 * a software reset. Otherwise, the write has no effect.
388 		 */
389 		err = genphy_soft_reset(phydev);
390 		if (err < 0)
391 			return err;
392 	}
393 
394 	return 0;
395 }
396 
m88e1101_config_aneg(struct phy_device * phydev)397 static int m88e1101_config_aneg(struct phy_device *phydev)
398 {
399 	int err;
400 
401 	/* This Marvell PHY has an errata which requires
402 	 * that certain registers get written in order
403 	 * to restart autonegotiation
404 	 */
405 	err = genphy_soft_reset(phydev);
406 	if (err < 0)
407 		return err;
408 
409 	err = phy_write(phydev, 0x1d, 0x1f);
410 	if (err < 0)
411 		return err;
412 
413 	err = phy_write(phydev, 0x1e, 0x200c);
414 	if (err < 0)
415 		return err;
416 
417 	err = phy_write(phydev, 0x1d, 0x5);
418 	if (err < 0)
419 		return err;
420 
421 	err = phy_write(phydev, 0x1e, 0);
422 	if (err < 0)
423 		return err;
424 
425 	err = phy_write(phydev, 0x1e, 0x100);
426 	if (err < 0)
427 		return err;
428 
429 	return marvell_config_aneg(phydev);
430 }
431 
432 #if IS_ENABLED(CONFIG_OF_MDIO)
433 /* Set and/or override some configuration registers based on the
434  * marvell,reg-init property stored in the of_node for the phydev.
435  *
436  * marvell,reg-init = <reg-page reg mask value>,...;
437  *
438  * There may be one or more sets of <reg-page reg mask value>:
439  *
440  * reg-page: which register bank to use.
441  * reg: the register.
442  * mask: if non-zero, ANDed with existing register value.
443  * value: ORed with the masked value and written to the regiser.
444  *
445  */
marvell_of_reg_init(struct phy_device * phydev)446 static int marvell_of_reg_init(struct phy_device *phydev)
447 {
448 	const __be32 *paddr;
449 	int len, i, saved_page, current_page, ret = 0;
450 
451 	if (!phydev->mdio.dev.of_node)
452 		return 0;
453 
454 	paddr = of_get_property(phydev->mdio.dev.of_node,
455 				"marvell,reg-init", &len);
456 	if (!paddr || len < (4 * sizeof(*paddr)))
457 		return 0;
458 
459 	saved_page = phy_save_page(phydev);
460 	if (saved_page < 0)
461 		goto err;
462 	current_page = saved_page;
463 
464 	len /= sizeof(*paddr);
465 	for (i = 0; i < len - 3; i += 4) {
466 		u16 page = be32_to_cpup(paddr + i);
467 		u16 reg = be32_to_cpup(paddr + i + 1);
468 		u16 mask = be32_to_cpup(paddr + i + 2);
469 		u16 val_bits = be32_to_cpup(paddr + i + 3);
470 		int val;
471 
472 		if (page != current_page) {
473 			current_page = page;
474 			ret = marvell_write_page(phydev, page);
475 			if (ret < 0)
476 				goto err;
477 		}
478 
479 		val = 0;
480 		if (mask) {
481 			val = __phy_read(phydev, reg);
482 			if (val < 0) {
483 				ret = val;
484 				goto err;
485 			}
486 			val &= mask;
487 		}
488 		val |= val_bits;
489 
490 		ret = __phy_write(phydev, reg, val);
491 		if (ret < 0)
492 			goto err;
493 	}
494 err:
495 	return phy_restore_page(phydev, saved_page, ret);
496 }
497 #else
marvell_of_reg_init(struct phy_device * phydev)498 static int marvell_of_reg_init(struct phy_device *phydev)
499 {
500 	return 0;
501 }
502 #endif /* CONFIG_OF_MDIO */
503 
m88e1121_config_aneg_rgmii_delays(struct phy_device * phydev)504 static int m88e1121_config_aneg_rgmii_delays(struct phy_device *phydev)
505 {
506 	int mscr;
507 
508 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
509 		mscr = MII_88E1121_PHY_MSCR_RX_DELAY |
510 		       MII_88E1121_PHY_MSCR_TX_DELAY;
511 	else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
512 		mscr = MII_88E1121_PHY_MSCR_RX_DELAY;
513 	else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
514 		mscr = MII_88E1121_PHY_MSCR_TX_DELAY;
515 	else
516 		mscr = 0;
517 
518 	return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
519 				MII_88E1121_PHY_MSCR_REG,
520 				MII_88E1121_PHY_MSCR_DELAY_MASK, mscr);
521 }
522 
m88e1121_config_aneg(struct phy_device * phydev)523 static int m88e1121_config_aneg(struct phy_device *phydev)
524 {
525 	int changed = 0;
526 	int err = 0;
527 
528 	if (phy_interface_is_rgmii(phydev)) {
529 		err = m88e1121_config_aneg_rgmii_delays(phydev);
530 		if (err < 0)
531 			return err;
532 	}
533 
534 	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
535 	if (err < 0)
536 		return err;
537 
538 	changed = err;
539 
540 	err = genphy_config_aneg(phydev);
541 	if (err < 0)
542 		return err;
543 
544 	if (phydev->autoneg != AUTONEG_ENABLE || changed) {
545 		/* A software reset is used to ensure a "commit" of the
546 		 * changes is done.
547 		 */
548 		err = genphy_soft_reset(phydev);
549 		if (err < 0)
550 			return err;
551 	}
552 
553 	return 0;
554 }
555 
m88e1318_config_aneg(struct phy_device * phydev)556 static int m88e1318_config_aneg(struct phy_device *phydev)
557 {
558 	int err;
559 
560 	err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
561 			       MII_88E1318S_PHY_MSCR1_REG,
562 			       0, MII_88E1318S_PHY_MSCR1_PAD_ODD);
563 	if (err < 0)
564 		return err;
565 
566 	return m88e1121_config_aneg(phydev);
567 }
568 
569 /**
570  * linkmode_adv_to_fiber_adv_t
571  * @advertise: the linkmode advertisement settings
572  *
573  * A small helper function that translates linkmode advertisement
574  * settings to phy autonegotiation advertisements for the MII_ADV
575  * register for fiber link.
576  */
linkmode_adv_to_fiber_adv_t(unsigned long * advertise)577 static inline u32 linkmode_adv_to_fiber_adv_t(unsigned long *advertise)
578 {
579 	u32 result = 0;
580 
581 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertise))
582 		result |= ADVERTISE_1000XHALF;
583 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertise))
584 		result |= ADVERTISE_1000XFULL;
585 
586 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertise) &&
587 	    linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
588 		result |= ADVERTISE_1000XPSE_ASYM;
589 	else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
590 		result |= ADVERTISE_1000XPAUSE;
591 
592 	return result;
593 }
594 
595 /**
596  * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
597  * @phydev: target phy_device struct
598  *
599  * Description: If auto-negotiation is enabled, we configure the
600  *   advertising, and then restart auto-negotiation.  If it is not
601  *   enabled, then we write the BMCR. Adapted for fiber link in
602  *   some Marvell's devices.
603  */
marvell_config_aneg_fiber(struct phy_device * phydev)604 static int marvell_config_aneg_fiber(struct phy_device *phydev)
605 {
606 	int changed = 0;
607 	int err;
608 	u16 adv;
609 
610 	if (phydev->autoneg != AUTONEG_ENABLE)
611 		return genphy_setup_forced(phydev);
612 
613 	/* Only allow advertising what this PHY supports */
614 	linkmode_and(phydev->advertising, phydev->advertising,
615 		     phydev->supported);
616 
617 	adv = linkmode_adv_to_fiber_adv_t(phydev->advertising);
618 
619 	/* Setup fiber advertisement */
620 	err = phy_modify_changed(phydev, MII_ADVERTISE,
621 				 ADVERTISE_1000XHALF | ADVERTISE_1000XFULL |
622 				 ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM,
623 				 adv);
624 	if (err < 0)
625 		return err;
626 	if (err > 0)
627 		changed = 1;
628 
629 	return genphy_check_and_restart_aneg(phydev, changed);
630 }
631 
m88e1510_config_aneg(struct phy_device * phydev)632 static int m88e1510_config_aneg(struct phy_device *phydev)
633 {
634 	int err;
635 
636 	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
637 	if (err < 0)
638 		goto error;
639 
640 	/* Configure the copper link first */
641 	err = m88e1318_config_aneg(phydev);
642 	if (err < 0)
643 		goto error;
644 
645 	/* Do not touch the fiber page if we're in copper->sgmii mode */
646 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
647 		return 0;
648 
649 	/* Then the fiber link */
650 	err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
651 	if (err < 0)
652 		goto error;
653 
654 	err = marvell_config_aneg_fiber(phydev);
655 	if (err < 0)
656 		goto error;
657 
658 	return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
659 
660 error:
661 	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
662 	return err;
663 }
664 
marvell_config_led(struct phy_device * phydev)665 static void marvell_config_led(struct phy_device *phydev)
666 {
667 	u16 def_config;
668 	int err;
669 
670 	switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
671 	/* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
672 	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
673 	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
674 		def_config = MII_88E1121_PHY_LED_DEF;
675 		break;
676 	/* Default PHY LED config:
677 	 * LED[0] .. 1000Mbps Link
678 	 * LED[1] .. 100Mbps Link
679 	 * LED[2] .. Blink, Activity
680 	 */
681 	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
682 		if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
683 			def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
684 		else
685 			def_config = MII_88E1510_PHY_LED_DEF;
686 		break;
687 	default:
688 		return;
689 	}
690 
691 	err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, MII_PHY_LED_CTRL,
692 			      def_config);
693 	if (err < 0)
694 		phydev_warn(phydev, "Fail to config marvell phy LED.\n");
695 }
696 
marvell_config_init(struct phy_device * phydev)697 static int marvell_config_init(struct phy_device *phydev)
698 {
699 	/* Set defalut LED */
700 	marvell_config_led(phydev);
701 
702 	/* Set registers from marvell,reg-init DT property */
703 	return marvell_of_reg_init(phydev);
704 }
705 
m88e3016_config_init(struct phy_device * phydev)706 static int m88e3016_config_init(struct phy_device *phydev)
707 {
708 	int ret;
709 
710 	/* Enable Scrambler and Auto-Crossover */
711 	ret = phy_modify(phydev, MII_88E3016_PHY_SPEC_CTRL,
712 			 MII_88E3016_DISABLE_SCRAMBLER,
713 			 MII_88E3016_AUTO_MDIX_CROSSOVER);
714 	if (ret < 0)
715 		return ret;
716 
717 	return marvell_config_init(phydev);
718 }
719 
m88e1111_config_init_hwcfg_mode(struct phy_device * phydev,u16 mode,int fibre_copper_auto)720 static int m88e1111_config_init_hwcfg_mode(struct phy_device *phydev,
721 					   u16 mode,
722 					   int fibre_copper_auto)
723 {
724 	if (fibre_copper_auto)
725 		mode |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
726 
727 	return phy_modify(phydev, MII_M1111_PHY_EXT_SR,
728 			  MII_M1111_HWCFG_MODE_MASK |
729 			  MII_M1111_HWCFG_FIBER_COPPER_AUTO |
730 			  MII_M1111_HWCFG_FIBER_COPPER_RES,
731 			  mode);
732 }
733 
m88e1111_config_init_rgmii_delays(struct phy_device * phydev)734 static int m88e1111_config_init_rgmii_delays(struct phy_device *phydev)
735 {
736 	int delay;
737 
738 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
739 		delay = MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY;
740 	} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
741 		delay = MII_M1111_RGMII_RX_DELAY;
742 	} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
743 		delay = MII_M1111_RGMII_TX_DELAY;
744 	} else {
745 		delay = 0;
746 	}
747 
748 	return phy_modify(phydev, MII_M1111_PHY_EXT_CR,
749 			  MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY,
750 			  delay);
751 }
752 
m88e1111_config_init_rgmii(struct phy_device * phydev)753 static int m88e1111_config_init_rgmii(struct phy_device *phydev)
754 {
755 	int temp;
756 	int err;
757 
758 	err = m88e1111_config_init_rgmii_delays(phydev);
759 	if (err < 0)
760 		return err;
761 
762 	temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
763 	if (temp < 0)
764 		return temp;
765 
766 	temp &= ~(MII_M1111_HWCFG_MODE_MASK);
767 
768 	if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
769 		temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
770 	else
771 		temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
772 
773 	return phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
774 }
775 
m88e1111_config_init_sgmii(struct phy_device * phydev)776 static int m88e1111_config_init_sgmii(struct phy_device *phydev)
777 {
778 	int err;
779 
780 	err = m88e1111_config_init_hwcfg_mode(
781 		phydev,
782 		MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
783 		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
784 	if (err < 0)
785 		return err;
786 
787 	/* make sure copper is selected */
788 	return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
789 }
790 
m88e1111_config_init_rtbi(struct phy_device * phydev)791 static int m88e1111_config_init_rtbi(struct phy_device *phydev)
792 {
793 	int err;
794 
795 	err = m88e1111_config_init_rgmii_delays(phydev);
796 	if (err < 0)
797 		return err;
798 
799 	err = m88e1111_config_init_hwcfg_mode(
800 		phydev,
801 		MII_M1111_HWCFG_MODE_RTBI,
802 		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
803 	if (err < 0)
804 		return err;
805 
806 	/* soft reset */
807 	err = genphy_soft_reset(phydev);
808 	if (err < 0)
809 		return err;
810 
811 	return m88e1111_config_init_hwcfg_mode(
812 		phydev,
813 		MII_M1111_HWCFG_MODE_RTBI,
814 		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
815 }
816 
m88e1111_config_init(struct phy_device * phydev)817 static int m88e1111_config_init(struct phy_device *phydev)
818 {
819 	int err;
820 
821 	if (phy_interface_is_rgmii(phydev)) {
822 		err = m88e1111_config_init_rgmii(phydev);
823 		if (err < 0)
824 			return err;
825 	}
826 
827 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
828 		err = m88e1111_config_init_sgmii(phydev);
829 		if (err < 0)
830 			return err;
831 	}
832 
833 	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
834 		err = m88e1111_config_init_rtbi(phydev);
835 		if (err < 0)
836 			return err;
837 	}
838 
839 	err = marvell_of_reg_init(phydev);
840 	if (err < 0)
841 		return err;
842 
843 	return genphy_soft_reset(phydev);
844 }
845 
m88e1111_get_downshift(struct phy_device * phydev,u8 * data)846 static int m88e1111_get_downshift(struct phy_device *phydev, u8 *data)
847 {
848 	int val, cnt, enable;
849 
850 	val = phy_read(phydev, MII_M1111_PHY_EXT_CR);
851 	if (val < 0)
852 		return val;
853 
854 	enable = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN, val);
855 	cnt = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, val) + 1;
856 
857 	*data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
858 
859 	return 0;
860 }
861 
m88e1111_set_downshift(struct phy_device * phydev,u8 cnt)862 static int m88e1111_set_downshift(struct phy_device *phydev, u8 cnt)
863 {
864 	int val, err;
865 
866 	if (cnt > MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX)
867 		return -E2BIG;
868 
869 	if (!cnt) {
870 		err = phy_clear_bits(phydev, MII_M1111_PHY_EXT_CR,
871 				     MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN);
872 	} else {
873 		val = MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN;
874 		val |= FIELD_PREP(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, cnt - 1);
875 
876 		err = phy_modify(phydev, MII_M1111_PHY_EXT_CR,
877 				 MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN |
878 				 MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK,
879 				 val);
880 	}
881 
882 	if (err < 0)
883 		return err;
884 
885 	return genphy_soft_reset(phydev);
886 }
887 
m88e1111_get_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,void * data)888 static int m88e1111_get_tunable(struct phy_device *phydev,
889 				struct ethtool_tunable *tuna, void *data)
890 {
891 	switch (tuna->id) {
892 	case ETHTOOL_PHY_DOWNSHIFT:
893 		return m88e1111_get_downshift(phydev, data);
894 	default:
895 		return -EOPNOTSUPP;
896 	}
897 }
898 
m88e1111_set_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,const void * data)899 static int m88e1111_set_tunable(struct phy_device *phydev,
900 				struct ethtool_tunable *tuna, const void *data)
901 {
902 	switch (tuna->id) {
903 	case ETHTOOL_PHY_DOWNSHIFT:
904 		return m88e1111_set_downshift(phydev, *(const u8 *)data);
905 	default:
906 		return -EOPNOTSUPP;
907 	}
908 }
909 
m88e1011_get_downshift(struct phy_device * phydev,u8 * data)910 static int m88e1011_get_downshift(struct phy_device *phydev, u8 *data)
911 {
912 	int val, cnt, enable;
913 
914 	val = phy_read(phydev, MII_M1011_PHY_SCR);
915 	if (val < 0)
916 		return val;
917 
918 	enable = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_EN, val);
919 	cnt = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, val) + 1;
920 
921 	*data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
922 
923 	return 0;
924 }
925 
m88e1011_set_downshift(struct phy_device * phydev,u8 cnt)926 static int m88e1011_set_downshift(struct phy_device *phydev, u8 cnt)
927 {
928 	int val, err;
929 
930 	if (cnt > MII_M1011_PHY_SCR_DOWNSHIFT_MAX)
931 		return -E2BIG;
932 
933 	if (!cnt) {
934 		err = phy_clear_bits(phydev, MII_M1011_PHY_SCR,
935 				     MII_M1011_PHY_SCR_DOWNSHIFT_EN);
936 	} else {
937 		val = MII_M1011_PHY_SCR_DOWNSHIFT_EN;
938 		val |= FIELD_PREP(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, cnt - 1);
939 
940 		err = phy_modify(phydev, MII_M1011_PHY_SCR,
941 				 MII_M1011_PHY_SCR_DOWNSHIFT_EN |
942 				 MII_M1011_PHY_SCR_DOWNSHIFT_MASK,
943 				 val);
944 	}
945 
946 	if (err < 0)
947 		return err;
948 
949 	return genphy_soft_reset(phydev);
950 }
951 
m88e1011_get_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,void * data)952 static int m88e1011_get_tunable(struct phy_device *phydev,
953 				struct ethtool_tunable *tuna, void *data)
954 {
955 	switch (tuna->id) {
956 	case ETHTOOL_PHY_DOWNSHIFT:
957 		return m88e1011_get_downshift(phydev, data);
958 	default:
959 		return -EOPNOTSUPP;
960 	}
961 }
962 
m88e1011_set_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,const void * data)963 static int m88e1011_set_tunable(struct phy_device *phydev,
964 				struct ethtool_tunable *tuna, const void *data)
965 {
966 	switch (tuna->id) {
967 	case ETHTOOL_PHY_DOWNSHIFT:
968 		return m88e1011_set_downshift(phydev, *(const u8 *)data);
969 	default:
970 		return -EOPNOTSUPP;
971 	}
972 }
973 
m88e1116r_config_init(struct phy_device * phydev)974 static int m88e1116r_config_init(struct phy_device *phydev)
975 {
976 	int err;
977 
978 	err = genphy_soft_reset(phydev);
979 	if (err < 0)
980 		return err;
981 
982 	msleep(500);
983 
984 	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
985 	if (err < 0)
986 		return err;
987 
988 	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
989 	if (err < 0)
990 		return err;
991 
992 	err = m88e1011_set_downshift(phydev, 8);
993 	if (err < 0)
994 		return err;
995 
996 	if (phy_interface_is_rgmii(phydev)) {
997 		err = m88e1121_config_aneg_rgmii_delays(phydev);
998 		if (err < 0)
999 			return err;
1000 	}
1001 
1002 	err = genphy_soft_reset(phydev);
1003 	if (err < 0)
1004 		return err;
1005 
1006 	return marvell_config_init(phydev);
1007 }
1008 
m88e1318_config_init(struct phy_device * phydev)1009 static int m88e1318_config_init(struct phy_device *phydev)
1010 {
1011 	if (phy_interrupt_is_valid(phydev)) {
1012 		int err = phy_modify_paged(
1013 			phydev, MII_MARVELL_LED_PAGE,
1014 			MII_88E1318S_PHY_LED_TCR,
1015 			MII_88E1318S_PHY_LED_TCR_FORCE_INT,
1016 			MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
1017 			MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
1018 		if (err < 0)
1019 			return err;
1020 	}
1021 
1022 	return marvell_config_init(phydev);
1023 }
1024 
m88e1510_config_init(struct phy_device * phydev)1025 static int m88e1510_config_init(struct phy_device *phydev)
1026 {
1027 	int err;
1028 
1029 	/* SGMII-to-Copper mode initialization */
1030 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1031 		/* Select page 18 */
1032 		err = marvell_set_page(phydev, 18);
1033 		if (err < 0)
1034 			return err;
1035 
1036 		/* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
1037 		err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
1038 				 MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
1039 				 MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII);
1040 		if (err < 0)
1041 			return err;
1042 
1043 		/* PHY reset is necessary after changing MODE[2:0] */
1044 		err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1, 0,
1045 				 MII_88E1510_GEN_CTRL_REG_1_RESET);
1046 		if (err < 0)
1047 			return err;
1048 
1049 		/* Reset page selection */
1050 		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1051 		if (err < 0)
1052 			return err;
1053 	}
1054 
1055 	return m88e1318_config_init(phydev);
1056 }
1057 
m88e1118_config_aneg(struct phy_device * phydev)1058 static int m88e1118_config_aneg(struct phy_device *phydev)
1059 {
1060 	int err;
1061 
1062 	err = genphy_soft_reset(phydev);
1063 	if (err < 0)
1064 		return err;
1065 
1066 	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
1067 	if (err < 0)
1068 		return err;
1069 
1070 	err = genphy_config_aneg(phydev);
1071 	return 0;
1072 }
1073 
m88e1118_config_init(struct phy_device * phydev)1074 static int m88e1118_config_init(struct phy_device *phydev)
1075 {
1076 	int err;
1077 
1078 	/* Change address */
1079 	err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
1080 	if (err < 0)
1081 		return err;
1082 
1083 	/* Enable 1000 Mbit */
1084 	err = phy_write(phydev, 0x15, 0x1070);
1085 	if (err < 0)
1086 		return err;
1087 
1088 	/* Change address */
1089 	err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE);
1090 	if (err < 0)
1091 		return err;
1092 
1093 	if (phy_interface_is_rgmii(phydev)) {
1094 		err = m88e1121_config_aneg_rgmii_delays(phydev);
1095 		if (err < 0)
1096 			return err;
1097 	}
1098 
1099 	/* Adjust LED Control */
1100 	if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS)
1101 		err = phy_write(phydev, 0x10, 0x1100);
1102 	else
1103 		err = phy_write(phydev, 0x10, 0x021e);
1104 	if (err < 0)
1105 		return err;
1106 
1107 	err = marvell_of_reg_init(phydev);
1108 	if (err < 0)
1109 		return err;
1110 
1111 	/* Reset address */
1112 	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1113 	if (err < 0)
1114 		return err;
1115 
1116 	return genphy_soft_reset(phydev);
1117 }
1118 
m88e1149_config_init(struct phy_device * phydev)1119 static int m88e1149_config_init(struct phy_device *phydev)
1120 {
1121 	int err;
1122 
1123 	/* Change address */
1124 	err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
1125 	if (err < 0)
1126 		return err;
1127 
1128 	/* Enable 1000 Mbit */
1129 	err = phy_write(phydev, 0x15, 0x1048);
1130 	if (err < 0)
1131 		return err;
1132 
1133 	err = marvell_of_reg_init(phydev);
1134 	if (err < 0)
1135 		return err;
1136 
1137 	/* Reset address */
1138 	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1139 	if (err < 0)
1140 		return err;
1141 
1142 	return genphy_soft_reset(phydev);
1143 }
1144 
m88e1145_config_init_rgmii(struct phy_device * phydev)1145 static int m88e1145_config_init_rgmii(struct phy_device *phydev)
1146 {
1147 	int err;
1148 
1149 	err = m88e1111_config_init_rgmii_delays(phydev);
1150 	if (err < 0)
1151 		return err;
1152 
1153 	if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
1154 		err = phy_write(phydev, 0x1d, 0x0012);
1155 		if (err < 0)
1156 			return err;
1157 
1158 		err = phy_modify(phydev, 0x1e, 0x0fc0,
1159 				 2 << 9 | /* 36 ohm */
1160 				 2 << 6); /* 39 ohm */
1161 		if (err < 0)
1162 			return err;
1163 
1164 		err = phy_write(phydev, 0x1d, 0x3);
1165 		if (err < 0)
1166 			return err;
1167 
1168 		err = phy_write(phydev, 0x1e, 0x8000);
1169 	}
1170 	return err;
1171 }
1172 
m88e1145_config_init_sgmii(struct phy_device * phydev)1173 static int m88e1145_config_init_sgmii(struct phy_device *phydev)
1174 {
1175 	return m88e1111_config_init_hwcfg_mode(
1176 		phydev, MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
1177 		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
1178 }
1179 
m88e1145_config_init(struct phy_device * phydev)1180 static int m88e1145_config_init(struct phy_device *phydev)
1181 {
1182 	int err;
1183 
1184 	/* Take care of errata E0 & E1 */
1185 	err = phy_write(phydev, 0x1d, 0x001b);
1186 	if (err < 0)
1187 		return err;
1188 
1189 	err = phy_write(phydev, 0x1e, 0x418f);
1190 	if (err < 0)
1191 		return err;
1192 
1193 	err = phy_write(phydev, 0x1d, 0x0016);
1194 	if (err < 0)
1195 		return err;
1196 
1197 	err = phy_write(phydev, 0x1e, 0xa2da);
1198 	if (err < 0)
1199 		return err;
1200 
1201 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
1202 		err = m88e1145_config_init_rgmii(phydev);
1203 		if (err < 0)
1204 			return err;
1205 	}
1206 
1207 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1208 		err = m88e1145_config_init_sgmii(phydev);
1209 		if (err < 0)
1210 			return err;
1211 	}
1212 
1213 	err = marvell_of_reg_init(phydev);
1214 	if (err < 0)
1215 		return err;
1216 
1217 	return 0;
1218 }
1219 
m88e1540_get_fld(struct phy_device * phydev,u8 * msecs)1220 static int m88e1540_get_fld(struct phy_device *phydev, u8 *msecs)
1221 {
1222 	int val;
1223 
1224 	val = phy_read(phydev, MII_88E1540_COPPER_CTRL3);
1225 	if (val < 0)
1226 		return val;
1227 
1228 	if (!(val & MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN)) {
1229 		*msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF;
1230 		return 0;
1231 	}
1232 
1233 	val = FIELD_GET(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1234 
1235 	switch (val) {
1236 	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS:
1237 		*msecs = 0;
1238 		break;
1239 	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS:
1240 		*msecs = 10;
1241 		break;
1242 	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS:
1243 		*msecs = 20;
1244 		break;
1245 	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS:
1246 		*msecs = 40;
1247 		break;
1248 	default:
1249 		return -EINVAL;
1250 	}
1251 
1252 	return 0;
1253 }
1254 
m88e1540_set_fld(struct phy_device * phydev,const u8 * msecs)1255 static int m88e1540_set_fld(struct phy_device *phydev, const u8 *msecs)
1256 {
1257 	struct ethtool_eee eee;
1258 	int val, ret;
1259 
1260 	if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF)
1261 		return phy_clear_bits(phydev, MII_88E1540_COPPER_CTRL3,
1262 				      MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
1263 
1264 	/* According to the Marvell data sheet EEE must be disabled for
1265 	 * Fast Link Down detection to work properly
1266 	 */
1267 	ret = phy_ethtool_get_eee(phydev, &eee);
1268 	if (!ret && eee.eee_enabled) {
1269 		phydev_warn(phydev, "Fast Link Down detection requires EEE to be disabled!\n");
1270 		return -EBUSY;
1271 	}
1272 
1273 	if (*msecs <= 5)
1274 		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS;
1275 	else if (*msecs <= 15)
1276 		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS;
1277 	else if (*msecs <= 30)
1278 		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS;
1279 	else
1280 		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS;
1281 
1282 	val = FIELD_PREP(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1283 
1284 	ret = phy_modify(phydev, MII_88E1540_COPPER_CTRL3,
1285 			 MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1286 	if (ret)
1287 		return ret;
1288 
1289 	return phy_set_bits(phydev, MII_88E1540_COPPER_CTRL3,
1290 			    MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
1291 }
1292 
m88e1540_get_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,void * data)1293 static int m88e1540_get_tunable(struct phy_device *phydev,
1294 				struct ethtool_tunable *tuna, void *data)
1295 {
1296 	switch (tuna->id) {
1297 	case ETHTOOL_PHY_FAST_LINK_DOWN:
1298 		return m88e1540_get_fld(phydev, data);
1299 	case ETHTOOL_PHY_DOWNSHIFT:
1300 		return m88e1011_get_downshift(phydev, data);
1301 	default:
1302 		return -EOPNOTSUPP;
1303 	}
1304 }
1305 
m88e1540_set_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,const void * data)1306 static int m88e1540_set_tunable(struct phy_device *phydev,
1307 				struct ethtool_tunable *tuna, const void *data)
1308 {
1309 	switch (tuna->id) {
1310 	case ETHTOOL_PHY_FAST_LINK_DOWN:
1311 		return m88e1540_set_fld(phydev, data);
1312 	case ETHTOOL_PHY_DOWNSHIFT:
1313 		return m88e1011_set_downshift(phydev, *(const u8 *)data);
1314 	default:
1315 		return -EOPNOTSUPP;
1316 	}
1317 }
1318 
1319 /* The VOD can be out of specification on link up. Poke an
1320  * undocumented register, in an undocumented page, with a magic value
1321  * to fix this.
1322  */
m88e6390_errata(struct phy_device * phydev)1323 static int m88e6390_errata(struct phy_device *phydev)
1324 {
1325 	int err;
1326 
1327 	err = phy_write(phydev, MII_BMCR,
1328 			BMCR_ANENABLE | BMCR_SPEED1000 | BMCR_FULLDPLX);
1329 	if (err)
1330 		return err;
1331 
1332 	usleep_range(300, 400);
1333 
1334 	err = phy_write_paged(phydev, 0xf8, 0x08, 0x36);
1335 	if (err)
1336 		return err;
1337 
1338 	return genphy_soft_reset(phydev);
1339 }
1340 
m88e6390_config_aneg(struct phy_device * phydev)1341 static int m88e6390_config_aneg(struct phy_device *phydev)
1342 {
1343 	int err;
1344 
1345 	err = m88e6390_errata(phydev);
1346 	if (err)
1347 		return err;
1348 
1349 	return m88e1510_config_aneg(phydev);
1350 }
1351 
1352 /**
1353  * fiber_lpa_mod_linkmode_lpa_t
1354  * @advertising: the linkmode advertisement settings
1355  * @lpa: value of the MII_LPA register for fiber link
1356  *
1357  * A small helper function that translates MII_LPA bits to linkmode LP
1358  * advertisement settings. Other bits in advertising are left
1359  * unchanged.
1360  */
fiber_lpa_mod_linkmode_lpa_t(unsigned long * advertising,u32 lpa)1361 static void fiber_lpa_mod_linkmode_lpa_t(unsigned long *advertising, u32 lpa)
1362 {
1363 	linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
1364 			 advertising, lpa & LPA_1000XHALF);
1365 
1366 	linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
1367 			 advertising, lpa & LPA_1000XFULL);
1368 }
1369 
marvell_read_status_page_an(struct phy_device * phydev,int fiber,int status)1370 static int marvell_read_status_page_an(struct phy_device *phydev,
1371 				       int fiber, int status)
1372 {
1373 	int lpa;
1374 	int err;
1375 
1376 	if (!(status & MII_M1011_PHY_STATUS_RESOLVED)) {
1377 		phydev->link = 0;
1378 		return 0;
1379 	}
1380 
1381 	if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
1382 		phydev->duplex = DUPLEX_FULL;
1383 	else
1384 		phydev->duplex = DUPLEX_HALF;
1385 
1386 	switch (status & MII_M1011_PHY_STATUS_SPD_MASK) {
1387 	case MII_M1011_PHY_STATUS_1000:
1388 		phydev->speed = SPEED_1000;
1389 		break;
1390 
1391 	case MII_M1011_PHY_STATUS_100:
1392 		phydev->speed = SPEED_100;
1393 		break;
1394 
1395 	default:
1396 		phydev->speed = SPEED_10;
1397 		break;
1398 	}
1399 
1400 	if (!fiber) {
1401 		err = genphy_read_lpa(phydev);
1402 		if (err < 0)
1403 			return err;
1404 
1405 		phy_resolve_aneg_pause(phydev);
1406 	} else {
1407 		lpa = phy_read(phydev, MII_LPA);
1408 		if (lpa < 0)
1409 			return lpa;
1410 
1411 		/* The fiber link is only 1000M capable */
1412 		fiber_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
1413 
1414 		if (phydev->duplex == DUPLEX_FULL) {
1415 			if (!(lpa & LPA_PAUSE_FIBER)) {
1416 				phydev->pause = 0;
1417 				phydev->asym_pause = 0;
1418 			} else if ((lpa & LPA_PAUSE_ASYM_FIBER)) {
1419 				phydev->pause = 1;
1420 				phydev->asym_pause = 1;
1421 			} else {
1422 				phydev->pause = 1;
1423 				phydev->asym_pause = 0;
1424 			}
1425 		}
1426 	}
1427 
1428 	return 0;
1429 }
1430 
1431 /* marvell_read_status_page
1432  *
1433  * Description:
1434  *   Check the link, then figure out the current state
1435  *   by comparing what we advertise with what the link partner
1436  *   advertises.  Start by checking the gigabit possibilities,
1437  *   then move on to 10/100.
1438  */
marvell_read_status_page(struct phy_device * phydev,int page)1439 static int marvell_read_status_page(struct phy_device *phydev, int page)
1440 {
1441 	int status;
1442 	int fiber;
1443 	int err;
1444 
1445 	status = phy_read(phydev, MII_M1011_PHY_STATUS);
1446 	if (status < 0)
1447 		return status;
1448 
1449 	/* Use the generic register for copper link status,
1450 	 * and the PHY status register for fiber link status.
1451 	 */
1452 	if (page == MII_MARVELL_FIBER_PAGE) {
1453 		phydev->link = !!(status & MII_M1011_PHY_STATUS_LINK);
1454 	} else {
1455 		err = genphy_update_link(phydev);
1456 		if (err)
1457 			return err;
1458 	}
1459 
1460 	if (page == MII_MARVELL_FIBER_PAGE)
1461 		fiber = 1;
1462 	else
1463 		fiber = 0;
1464 
1465 	linkmode_zero(phydev->lp_advertising);
1466 	phydev->pause = 0;
1467 	phydev->asym_pause = 0;
1468 	phydev->speed = SPEED_UNKNOWN;
1469 	phydev->duplex = DUPLEX_UNKNOWN;
1470 	phydev->port = fiber ? PORT_FIBRE : PORT_TP;
1471 
1472 	if (phydev->autoneg == AUTONEG_ENABLE)
1473 		err = marvell_read_status_page_an(phydev, fiber, status);
1474 	else
1475 		err = genphy_read_status_fixed(phydev);
1476 
1477 	return err;
1478 }
1479 
1480 /* marvell_read_status
1481  *
1482  * Some Marvell's phys have two modes: fiber and copper.
1483  * Both need status checked.
1484  * Description:
1485  *   First, check the fiber link and status.
1486  *   If the fiber link is down, check the copper link and status which
1487  *   will be the default value if both link are down.
1488  */
marvell_read_status(struct phy_device * phydev)1489 static int marvell_read_status(struct phy_device *phydev)
1490 {
1491 	int err;
1492 
1493 	/* Check the fiber mode first */
1494 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1495 			      phydev->supported) &&
1496 	    phydev->interface != PHY_INTERFACE_MODE_SGMII) {
1497 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1498 		if (err < 0)
1499 			goto error;
1500 
1501 		err = marvell_read_status_page(phydev, MII_MARVELL_FIBER_PAGE);
1502 		if (err < 0)
1503 			goto error;
1504 
1505 		/* If the fiber link is up, it is the selected and
1506 		 * used link. In this case, we need to stay in the
1507 		 * fiber page. Please to be careful about that, avoid
1508 		 * to restore Copper page in other functions which
1509 		 * could break the behaviour for some fiber phy like
1510 		 * 88E1512.
1511 		 */
1512 		if (phydev->link)
1513 			return 0;
1514 
1515 		/* If fiber link is down, check and save copper mode state */
1516 		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1517 		if (err < 0)
1518 			goto error;
1519 	}
1520 
1521 	return marvell_read_status_page(phydev, MII_MARVELL_COPPER_PAGE);
1522 
1523 error:
1524 	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1525 	return err;
1526 }
1527 
1528 /* marvell_suspend
1529  *
1530  * Some Marvell's phys have two modes: fiber and copper.
1531  * Both need to be suspended
1532  */
marvell_suspend(struct phy_device * phydev)1533 static int marvell_suspend(struct phy_device *phydev)
1534 {
1535 	int err;
1536 
1537 	/* Suspend the fiber mode first */
1538 	if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1539 			       phydev->supported)) {
1540 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1541 		if (err < 0)
1542 			goto error;
1543 
1544 		/* With the page set, use the generic suspend */
1545 		err = genphy_suspend(phydev);
1546 		if (err < 0)
1547 			goto error;
1548 
1549 		/* Then, the copper link */
1550 		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1551 		if (err < 0)
1552 			goto error;
1553 	}
1554 
1555 	/* With the page set, use the generic suspend */
1556 	return genphy_suspend(phydev);
1557 
1558 error:
1559 	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1560 	return err;
1561 }
1562 
1563 /* marvell_resume
1564  *
1565  * Some Marvell's phys have two modes: fiber and copper.
1566  * Both need to be resumed
1567  */
marvell_resume(struct phy_device * phydev)1568 static int marvell_resume(struct phy_device *phydev)
1569 {
1570 	int err;
1571 
1572 	/* Resume the fiber mode first */
1573 	if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1574 			       phydev->supported)) {
1575 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1576 		if (err < 0)
1577 			goto error;
1578 
1579 		/* With the page set, use the generic resume */
1580 		err = genphy_resume(phydev);
1581 		if (err < 0)
1582 			goto error;
1583 
1584 		/* Then, the copper link */
1585 		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1586 		if (err < 0)
1587 			goto error;
1588 	}
1589 
1590 	/* With the page set, use the generic resume */
1591 	return genphy_resume(phydev);
1592 
1593 error:
1594 	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1595 	return err;
1596 }
1597 
marvell_aneg_done(struct phy_device * phydev)1598 static int marvell_aneg_done(struct phy_device *phydev)
1599 {
1600 	int retval = phy_read(phydev, MII_M1011_PHY_STATUS);
1601 
1602 	return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED);
1603 }
1604 
m88e1121_did_interrupt(struct phy_device * phydev)1605 static int m88e1121_did_interrupt(struct phy_device *phydev)
1606 {
1607 	int imask;
1608 
1609 	imask = phy_read(phydev, MII_M1011_IEVENT);
1610 
1611 	if (imask & MII_M1011_IMASK_INIT)
1612 		return 1;
1613 
1614 	return 0;
1615 }
1616 
m88e1318_get_wol(struct phy_device * phydev,struct ethtool_wolinfo * wol)1617 static void m88e1318_get_wol(struct phy_device *phydev,
1618 			     struct ethtool_wolinfo *wol)
1619 {
1620 	int ret;
1621 
1622 	wol->supported = WAKE_MAGIC;
1623 	wol->wolopts = 0;
1624 
1625 	ret = phy_read_paged(phydev, MII_MARVELL_WOL_PAGE,
1626 			     MII_88E1318S_PHY_WOL_CTRL);
1627 	if (ret >= 0 && ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
1628 		wol->wolopts |= WAKE_MAGIC;
1629 }
1630 
m88e1318_set_wol(struct phy_device * phydev,struct ethtool_wolinfo * wol)1631 static int m88e1318_set_wol(struct phy_device *phydev,
1632 			    struct ethtool_wolinfo *wol)
1633 {
1634 	int err = 0, oldpage;
1635 
1636 	oldpage = phy_save_page(phydev);
1637 	if (oldpage < 0)
1638 		goto error;
1639 
1640 	if (wol->wolopts & WAKE_MAGIC) {
1641 		/* Explicitly switch to page 0x00, just to be sure */
1642 		err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
1643 		if (err < 0)
1644 			goto error;
1645 
1646 		/* If WOL event happened once, the LED[2] interrupt pin
1647 		 * will not be cleared unless we reading the interrupt status
1648 		 * register. If interrupts are in use, the normal interrupt
1649 		 * handling will clear the WOL event. Clear the WOL event
1650 		 * before enabling it if !phy_interrupt_is_valid()
1651 		 */
1652 		if (!phy_interrupt_is_valid(phydev))
1653 			__phy_read(phydev, MII_M1011_IEVENT);
1654 
1655 		/* Enable the WOL interrupt */
1656 		err = __phy_modify(phydev, MII_88E1318S_PHY_CSIER, 0,
1657 				   MII_88E1318S_PHY_CSIER_WOL_EIE);
1658 		if (err < 0)
1659 			goto error;
1660 
1661 		err = marvell_write_page(phydev, MII_MARVELL_LED_PAGE);
1662 		if (err < 0)
1663 			goto error;
1664 
1665 		/* Setup LED[2] as interrupt pin (active low) */
1666 		err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR,
1667 				   MII_88E1318S_PHY_LED_TCR_FORCE_INT,
1668 				   MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
1669 				   MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
1670 		if (err < 0)
1671 			goto error;
1672 
1673 		err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
1674 		if (err < 0)
1675 			goto error;
1676 
1677 		/* Store the device address for the magic packet */
1678 		err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2,
1679 				((phydev->attached_dev->dev_addr[5] << 8) |
1680 				 phydev->attached_dev->dev_addr[4]));
1681 		if (err < 0)
1682 			goto error;
1683 		err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1,
1684 				((phydev->attached_dev->dev_addr[3] << 8) |
1685 				 phydev->attached_dev->dev_addr[2]));
1686 		if (err < 0)
1687 			goto error;
1688 		err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0,
1689 				((phydev->attached_dev->dev_addr[1] << 8) |
1690 				 phydev->attached_dev->dev_addr[0]));
1691 		if (err < 0)
1692 			goto error;
1693 
1694 		/* Clear WOL status and enable magic packet matching */
1695 		err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0,
1696 				   MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |
1697 				   MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE);
1698 		if (err < 0)
1699 			goto error;
1700 	} else {
1701 		err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
1702 		if (err < 0)
1703 			goto error;
1704 
1705 		/* Clear WOL status and disable magic packet matching */
1706 		err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,
1707 				   MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE,
1708 				   MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
1709 		if (err < 0)
1710 			goto error;
1711 	}
1712 
1713 error:
1714 	return phy_restore_page(phydev, oldpage, err);
1715 }
1716 
marvell_get_sset_count(struct phy_device * phydev)1717 static int marvell_get_sset_count(struct phy_device *phydev)
1718 {
1719 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1720 			      phydev->supported))
1721 		return ARRAY_SIZE(marvell_hw_stats);
1722 	else
1723 		return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS;
1724 }
1725 
marvell_get_strings(struct phy_device * phydev,u8 * data)1726 static void marvell_get_strings(struct phy_device *phydev, u8 *data)
1727 {
1728 	int count = marvell_get_sset_count(phydev);
1729 	int i;
1730 
1731 	for (i = 0; i < count; i++) {
1732 		strlcpy(data + i * ETH_GSTRING_LEN,
1733 			marvell_hw_stats[i].string, ETH_GSTRING_LEN);
1734 	}
1735 }
1736 
marvell_get_stat(struct phy_device * phydev,int i)1737 static u64 marvell_get_stat(struct phy_device *phydev, int i)
1738 {
1739 	struct marvell_hw_stat stat = marvell_hw_stats[i];
1740 	struct marvell_priv *priv = phydev->priv;
1741 	int val;
1742 	u64 ret;
1743 
1744 	val = phy_read_paged(phydev, stat.page, stat.reg);
1745 	if (val < 0) {
1746 		ret = U64_MAX;
1747 	} else {
1748 		val = val & ((1 << stat.bits) - 1);
1749 		priv->stats[i] += val;
1750 		ret = priv->stats[i];
1751 	}
1752 
1753 	return ret;
1754 }
1755 
marvell_get_stats(struct phy_device * phydev,struct ethtool_stats * stats,u64 * data)1756 static void marvell_get_stats(struct phy_device *phydev,
1757 			      struct ethtool_stats *stats, u64 *data)
1758 {
1759 	int count = marvell_get_sset_count(phydev);
1760 	int i;
1761 
1762 	for (i = 0; i < count; i++)
1763 		data[i] = marvell_get_stat(phydev, i);
1764 }
1765 
marvell_vct5_wait_complete(struct phy_device * phydev)1766 static int marvell_vct5_wait_complete(struct phy_device *phydev)
1767 {
1768 	int i;
1769 	int val;
1770 
1771 	for (i = 0; i < 32; i++) {
1772 		val = __phy_read(phydev, MII_VCT5_CTRL);
1773 		if (val < 0)
1774 			return val;
1775 
1776 		if (val & MII_VCT5_CTRL_COMPLETE)
1777 			return 0;
1778 	}
1779 
1780 	phydev_err(phydev, "Timeout while waiting for cable test to finish\n");
1781 	return -ETIMEDOUT;
1782 }
1783 
marvell_vct5_amplitude(struct phy_device * phydev,int pair)1784 static int marvell_vct5_amplitude(struct phy_device *phydev, int pair)
1785 {
1786 	int amplitude;
1787 	int val;
1788 	int reg;
1789 
1790 	reg = MII_VCT5_TX_RX_MDI0_COUPLING + pair;
1791 	val = __phy_read(phydev, reg);
1792 
1793 	if (val < 0)
1794 		return 0;
1795 
1796 	amplitude = (val & MII_VCT5_TX_RX_AMPLITUDE_MASK) >>
1797 		MII_VCT5_TX_RX_AMPLITUDE_SHIFT;
1798 
1799 	if (!(val & MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION))
1800 		amplitude = -amplitude;
1801 
1802 	return 1000 * amplitude / 128;
1803 }
1804 
marvell_vct5_distance2cm(int distance)1805 static u32 marvell_vct5_distance2cm(int distance)
1806 {
1807 	return distance * 805 / 10;
1808 }
1809 
marvell_vct5_cm2distance(int cm)1810 static u32 marvell_vct5_cm2distance(int cm)
1811 {
1812 	return cm * 10 / 805;
1813 }
1814 
marvell_vct5_amplitude_distance(struct phy_device * phydev,int distance,int pair)1815 static int marvell_vct5_amplitude_distance(struct phy_device *phydev,
1816 					   int distance, int pair)
1817 {
1818 	u16 reg;
1819 	int err;
1820 	int mV;
1821 	int i;
1822 
1823 	err = __phy_write(phydev, MII_VCT5_SAMPLE_POINT_DISTANCE,
1824 			  distance);
1825 	if (err)
1826 		return err;
1827 
1828 	reg = MII_VCT5_CTRL_ENABLE |
1829 		MII_VCT5_CTRL_TX_SAME_CHANNEL |
1830 		MII_VCT5_CTRL_SAMPLES_DEFAULT |
1831 		MII_VCT5_CTRL_SAMPLE_POINT |
1832 		MII_VCT5_CTRL_PEEK_HYST_DEFAULT;
1833 	err = __phy_write(phydev, MII_VCT5_CTRL, reg);
1834 	if (err)
1835 		return err;
1836 
1837 	err = marvell_vct5_wait_complete(phydev);
1838 	if (err)
1839 		return err;
1840 
1841 	for (i = 0; i < 4; i++) {
1842 		if (pair != PHY_PAIR_ALL && i != pair)
1843 			continue;
1844 
1845 		mV = marvell_vct5_amplitude(phydev, i);
1846 		ethnl_cable_test_amplitude(phydev, i, mV);
1847 	}
1848 
1849 	return 0;
1850 }
1851 
marvell_vct5_amplitude_graph(struct phy_device * phydev)1852 static int marvell_vct5_amplitude_graph(struct phy_device *phydev)
1853 {
1854 	struct marvell_priv *priv = phydev->priv;
1855 	int distance;
1856 	u16 width;
1857 	int page;
1858 	int err;
1859 	u16 reg;
1860 
1861 	if (priv->first <= TDR_SHORT_CABLE_LENGTH)
1862 		width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS;
1863 	else
1864 		width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS;
1865 
1866 	reg = MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV |
1867 		MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN |
1868 		MII_VCT5_TX_PULSE_CTRL_MAX_AMP | width;
1869 
1870 	err = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
1871 			      MII_VCT5_TX_PULSE_CTRL, reg);
1872 	if (err)
1873 		return err;
1874 
1875 	/* Reading the TDR data is very MDIO heavy. We need to optimize
1876 	 * access to keep the time to a minimum. So lock the bus once,
1877 	 * and don't release it until complete. We can then avoid having
1878 	 * to change the page for every access, greatly speeding things
1879 	 * up.
1880 	 */
1881 	page = phy_select_page(phydev, MII_MARVELL_VCT5_PAGE);
1882 	if (page < 0)
1883 		goto restore_page;
1884 
1885 	for (distance = priv->first;
1886 	     distance <= priv->last;
1887 	     distance += priv->step) {
1888 		err = marvell_vct5_amplitude_distance(phydev, distance,
1889 						      priv->pair);
1890 		if (err)
1891 			goto restore_page;
1892 
1893 		if (distance > TDR_SHORT_CABLE_LENGTH &&
1894 		    width == MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS) {
1895 			width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS;
1896 			reg = MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV |
1897 				MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN |
1898 				MII_VCT5_TX_PULSE_CTRL_MAX_AMP | width;
1899 			err = __phy_write(phydev, MII_VCT5_TX_PULSE_CTRL, reg);
1900 			if (err)
1901 				goto restore_page;
1902 		}
1903 	}
1904 
1905 restore_page:
1906 	return phy_restore_page(phydev, page, err);
1907 }
1908 
marvell_cable_test_start_common(struct phy_device * phydev)1909 static int marvell_cable_test_start_common(struct phy_device *phydev)
1910 {
1911 	int bmcr, bmsr, ret;
1912 
1913 	/* If auto-negotiation is enabled, but not complete, the cable
1914 	 * test never completes. So disable auto-neg.
1915 	 */
1916 	bmcr = phy_read(phydev, MII_BMCR);
1917 	if (bmcr < 0)
1918 		return bmcr;
1919 
1920 	bmsr = phy_read(phydev, MII_BMSR);
1921 
1922 	if (bmsr < 0)
1923 		return bmsr;
1924 
1925 	if (bmcr & BMCR_ANENABLE) {
1926 		ret =  phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
1927 		if (ret < 0)
1928 			return ret;
1929 		ret = genphy_soft_reset(phydev);
1930 		if (ret < 0)
1931 			return ret;
1932 	}
1933 
1934 	/* If the link is up, allow it some time to go down */
1935 	if (bmsr & BMSR_LSTATUS)
1936 		msleep(1500);
1937 
1938 	return 0;
1939 }
1940 
marvell_vct7_cable_test_start(struct phy_device * phydev)1941 static int marvell_vct7_cable_test_start(struct phy_device *phydev)
1942 {
1943 	struct marvell_priv *priv = phydev->priv;
1944 	int ret;
1945 
1946 	ret = marvell_cable_test_start_common(phydev);
1947 	if (ret)
1948 		return ret;
1949 
1950 	priv->cable_test_tdr = false;
1951 
1952 	/* Reset the VCT5 API control to defaults, otherwise
1953 	 * VCT7 does not work correctly.
1954 	 */
1955 	ret = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
1956 			      MII_VCT5_CTRL,
1957 			      MII_VCT5_CTRL_TX_SAME_CHANNEL |
1958 			      MII_VCT5_CTRL_SAMPLES_DEFAULT |
1959 			      MII_VCT5_CTRL_MODE_MAXIMUM_PEEK |
1960 			      MII_VCT5_CTRL_PEEK_HYST_DEFAULT);
1961 	if (ret)
1962 		return ret;
1963 
1964 	ret = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
1965 			      MII_VCT5_SAMPLE_POINT_DISTANCE, 0);
1966 	if (ret)
1967 		return ret;
1968 
1969 	return phy_write_paged(phydev, MII_MARVELL_VCT7_PAGE,
1970 			       MII_VCT7_CTRL,
1971 			       MII_VCT7_CTRL_RUN_NOW |
1972 			       MII_VCT7_CTRL_CENTIMETERS);
1973 }
1974 
marvell_vct5_cable_test_tdr_start(struct phy_device * phydev,const struct phy_tdr_config * cfg)1975 static int marvell_vct5_cable_test_tdr_start(struct phy_device *phydev,
1976 					     const struct phy_tdr_config *cfg)
1977 {
1978 	struct marvell_priv *priv = phydev->priv;
1979 	int ret;
1980 
1981 	priv->cable_test_tdr = true;
1982 	priv->first = marvell_vct5_cm2distance(cfg->first);
1983 	priv->last = marvell_vct5_cm2distance(cfg->last);
1984 	priv->step = marvell_vct5_cm2distance(cfg->step);
1985 	priv->pair = cfg->pair;
1986 
1987 	if (priv->first > MII_VCT5_SAMPLE_POINT_DISTANCE_MAX)
1988 		return -EINVAL;
1989 
1990 	if (priv->last > MII_VCT5_SAMPLE_POINT_DISTANCE_MAX)
1991 		return -EINVAL;
1992 
1993 	/* Disable  VCT7 */
1994 	ret = phy_write_paged(phydev, MII_MARVELL_VCT7_PAGE,
1995 			      MII_VCT7_CTRL, 0);
1996 	if (ret)
1997 		return ret;
1998 
1999 	ret = marvell_cable_test_start_common(phydev);
2000 	if (ret)
2001 		return ret;
2002 
2003 	ret = ethnl_cable_test_pulse(phydev, 1000);
2004 	if (ret)
2005 		return ret;
2006 
2007 	return ethnl_cable_test_step(phydev,
2008 				     marvell_vct5_distance2cm(priv->first),
2009 				     marvell_vct5_distance2cm(priv->last),
2010 				     marvell_vct5_distance2cm(priv->step));
2011 }
2012 
marvell_vct7_distance_to_length(int distance,bool meter)2013 static int marvell_vct7_distance_to_length(int distance, bool meter)
2014 {
2015 	if (meter)
2016 		distance *= 100;
2017 
2018 	return distance;
2019 }
2020 
marvell_vct7_distance_valid(int result)2021 static bool marvell_vct7_distance_valid(int result)
2022 {
2023 	switch (result) {
2024 	case MII_VCT7_RESULTS_OPEN:
2025 	case MII_VCT7_RESULTS_SAME_SHORT:
2026 	case MII_VCT7_RESULTS_CROSS_SHORT:
2027 		return true;
2028 	}
2029 	return false;
2030 }
2031 
marvell_vct7_report_length(struct phy_device * phydev,int pair,bool meter)2032 static int marvell_vct7_report_length(struct phy_device *phydev,
2033 				      int pair, bool meter)
2034 {
2035 	int length;
2036 	int ret;
2037 
2038 	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2039 			     MII_VCT7_PAIR_0_DISTANCE + pair);
2040 	if (ret < 0)
2041 		return ret;
2042 
2043 	length = marvell_vct7_distance_to_length(ret, meter);
2044 
2045 	ethnl_cable_test_fault_length(phydev, pair, length);
2046 
2047 	return 0;
2048 }
2049 
marvell_vct7_cable_test_report_trans(int result)2050 static int marvell_vct7_cable_test_report_trans(int result)
2051 {
2052 	switch (result) {
2053 	case MII_VCT7_RESULTS_OK:
2054 		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
2055 	case MII_VCT7_RESULTS_OPEN:
2056 		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
2057 	case MII_VCT7_RESULTS_SAME_SHORT:
2058 		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
2059 	case MII_VCT7_RESULTS_CROSS_SHORT:
2060 		return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
2061 	default:
2062 		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
2063 	}
2064 }
2065 
marvell_vct7_cable_test_report(struct phy_device * phydev)2066 static int marvell_vct7_cable_test_report(struct phy_device *phydev)
2067 {
2068 	int pair0, pair1, pair2, pair3;
2069 	bool meter;
2070 	int ret;
2071 
2072 	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2073 			     MII_VCT7_RESULTS);
2074 	if (ret < 0)
2075 		return ret;
2076 
2077 	pair3 = (ret & MII_VCT7_RESULTS_PAIR3_MASK) >>
2078 		MII_VCT7_RESULTS_PAIR3_SHIFT;
2079 	pair2 = (ret & MII_VCT7_RESULTS_PAIR2_MASK) >>
2080 		MII_VCT7_RESULTS_PAIR2_SHIFT;
2081 	pair1 = (ret & MII_VCT7_RESULTS_PAIR1_MASK) >>
2082 		MII_VCT7_RESULTS_PAIR1_SHIFT;
2083 	pair0 = (ret & MII_VCT7_RESULTS_PAIR0_MASK) >>
2084 		MII_VCT7_RESULTS_PAIR0_SHIFT;
2085 
2086 	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
2087 				marvell_vct7_cable_test_report_trans(pair0));
2088 	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
2089 				marvell_vct7_cable_test_report_trans(pair1));
2090 	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C,
2091 				marvell_vct7_cable_test_report_trans(pair2));
2092 	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
2093 				marvell_vct7_cable_test_report_trans(pair3));
2094 
2095 	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE, MII_VCT7_CTRL);
2096 	if (ret < 0)
2097 		return ret;
2098 
2099 	meter = ret & MII_VCT7_CTRL_METERS;
2100 
2101 	if (marvell_vct7_distance_valid(pair0))
2102 		marvell_vct7_report_length(phydev, 0, meter);
2103 	if (marvell_vct7_distance_valid(pair1))
2104 		marvell_vct7_report_length(phydev, 1, meter);
2105 	if (marvell_vct7_distance_valid(pair2))
2106 		marvell_vct7_report_length(phydev, 2, meter);
2107 	if (marvell_vct7_distance_valid(pair3))
2108 		marvell_vct7_report_length(phydev, 3, meter);
2109 
2110 	return 0;
2111 }
2112 
marvell_vct7_cable_test_get_status(struct phy_device * phydev,bool * finished)2113 static int marvell_vct7_cable_test_get_status(struct phy_device *phydev,
2114 					      bool *finished)
2115 {
2116 	struct marvell_priv *priv = phydev->priv;
2117 	int ret;
2118 
2119 	if (priv->cable_test_tdr) {
2120 		ret = marvell_vct5_amplitude_graph(phydev);
2121 		*finished = true;
2122 		return ret;
2123 	}
2124 
2125 	*finished = false;
2126 
2127 	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2128 			     MII_VCT7_CTRL);
2129 
2130 	if (ret < 0)
2131 		return ret;
2132 
2133 	if (!(ret & MII_VCT7_CTRL_IN_PROGRESS)) {
2134 		*finished = true;
2135 
2136 		return marvell_vct7_cable_test_report(phydev);
2137 	}
2138 
2139 	return 0;
2140 }
2141 
2142 #ifdef CONFIG_HWMON
m88e1121_get_temp(struct phy_device * phydev,long * temp)2143 static int m88e1121_get_temp(struct phy_device *phydev, long *temp)
2144 {
2145 	int oldpage;
2146 	int ret = 0;
2147 	int val;
2148 
2149 	*temp = 0;
2150 
2151 	oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
2152 	if (oldpage < 0)
2153 		goto error;
2154 
2155 	/* Enable temperature sensor */
2156 	ret = __phy_read(phydev, MII_88E1121_MISC_TEST);
2157 	if (ret < 0)
2158 		goto error;
2159 
2160 	ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
2161 			  ret | MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
2162 	if (ret < 0)
2163 		goto error;
2164 
2165 	/* Wait for temperature to stabilize */
2166 	usleep_range(10000, 12000);
2167 
2168 	val = __phy_read(phydev, MII_88E1121_MISC_TEST);
2169 	if (val < 0) {
2170 		ret = val;
2171 		goto error;
2172 	}
2173 
2174 	/* Disable temperature sensor */
2175 	ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
2176 			  ret & ~MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
2177 	if (ret < 0)
2178 		goto error;
2179 
2180 	*temp = ((val & MII_88E1121_MISC_TEST_TEMP_MASK) - 5) * 5000;
2181 
2182 error:
2183 	return phy_restore_page(phydev, oldpage, ret);
2184 }
2185 
m88e1121_hwmon_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * temp)2186 static int m88e1121_hwmon_read(struct device *dev,
2187 			       enum hwmon_sensor_types type,
2188 			       u32 attr, int channel, long *temp)
2189 {
2190 	struct phy_device *phydev = dev_get_drvdata(dev);
2191 	int err;
2192 
2193 	switch (attr) {
2194 	case hwmon_temp_input:
2195 		err = m88e1121_get_temp(phydev, temp);
2196 		break;
2197 	default:
2198 		return -EOPNOTSUPP;
2199 	}
2200 
2201 	return err;
2202 }
2203 
m88e1121_hwmon_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)2204 static umode_t m88e1121_hwmon_is_visible(const void *data,
2205 					 enum hwmon_sensor_types type,
2206 					 u32 attr, int channel)
2207 {
2208 	if (type != hwmon_temp)
2209 		return 0;
2210 
2211 	switch (attr) {
2212 	case hwmon_temp_input:
2213 		return 0444;
2214 	default:
2215 		return 0;
2216 	}
2217 }
2218 
2219 static u32 m88e1121_hwmon_chip_config[] = {
2220 	HWMON_C_REGISTER_TZ,
2221 	0
2222 };
2223 
2224 static const struct hwmon_channel_info m88e1121_hwmon_chip = {
2225 	.type = hwmon_chip,
2226 	.config = m88e1121_hwmon_chip_config,
2227 };
2228 
2229 static u32 m88e1121_hwmon_temp_config[] = {
2230 	HWMON_T_INPUT,
2231 	0
2232 };
2233 
2234 static const struct hwmon_channel_info m88e1121_hwmon_temp = {
2235 	.type = hwmon_temp,
2236 	.config = m88e1121_hwmon_temp_config,
2237 };
2238 
2239 static const struct hwmon_channel_info *m88e1121_hwmon_info[] = {
2240 	&m88e1121_hwmon_chip,
2241 	&m88e1121_hwmon_temp,
2242 	NULL
2243 };
2244 
2245 static const struct hwmon_ops m88e1121_hwmon_hwmon_ops = {
2246 	.is_visible = m88e1121_hwmon_is_visible,
2247 	.read = m88e1121_hwmon_read,
2248 };
2249 
2250 static const struct hwmon_chip_info m88e1121_hwmon_chip_info = {
2251 	.ops = &m88e1121_hwmon_hwmon_ops,
2252 	.info = m88e1121_hwmon_info,
2253 };
2254 
m88e1510_get_temp(struct phy_device * phydev,long * temp)2255 static int m88e1510_get_temp(struct phy_device *phydev, long *temp)
2256 {
2257 	int ret;
2258 
2259 	*temp = 0;
2260 
2261 	ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2262 			     MII_88E1510_TEMP_SENSOR);
2263 	if (ret < 0)
2264 		return ret;
2265 
2266 	*temp = ((ret & MII_88E1510_TEMP_SENSOR_MASK) - 25) * 1000;
2267 
2268 	return 0;
2269 }
2270 
m88e1510_get_temp_critical(struct phy_device * phydev,long * temp)2271 static int m88e1510_get_temp_critical(struct phy_device *phydev, long *temp)
2272 {
2273 	int ret;
2274 
2275 	*temp = 0;
2276 
2277 	ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2278 			     MII_88E1121_MISC_TEST);
2279 	if (ret < 0)
2280 		return ret;
2281 
2282 	*temp = (((ret & MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK) >>
2283 		  MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT) * 5) - 25;
2284 	/* convert to mC */
2285 	*temp *= 1000;
2286 
2287 	return 0;
2288 }
2289 
m88e1510_set_temp_critical(struct phy_device * phydev,long temp)2290 static int m88e1510_set_temp_critical(struct phy_device *phydev, long temp)
2291 {
2292 	temp = temp / 1000;
2293 	temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
2294 
2295 	return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2296 				MII_88E1121_MISC_TEST,
2297 				MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK,
2298 				temp << MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT);
2299 }
2300 
m88e1510_get_temp_alarm(struct phy_device * phydev,long * alarm)2301 static int m88e1510_get_temp_alarm(struct phy_device *phydev, long *alarm)
2302 {
2303 	int ret;
2304 
2305 	*alarm = false;
2306 
2307 	ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2308 			     MII_88E1121_MISC_TEST);
2309 	if (ret < 0)
2310 		return ret;
2311 
2312 	*alarm = !!(ret & MII_88E1510_MISC_TEST_TEMP_IRQ);
2313 
2314 	return 0;
2315 }
2316 
m88e1510_hwmon_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * temp)2317 static int m88e1510_hwmon_read(struct device *dev,
2318 			       enum hwmon_sensor_types type,
2319 			       u32 attr, int channel, long *temp)
2320 {
2321 	struct phy_device *phydev = dev_get_drvdata(dev);
2322 	int err;
2323 
2324 	switch (attr) {
2325 	case hwmon_temp_input:
2326 		err = m88e1510_get_temp(phydev, temp);
2327 		break;
2328 	case hwmon_temp_crit:
2329 		err = m88e1510_get_temp_critical(phydev, temp);
2330 		break;
2331 	case hwmon_temp_max_alarm:
2332 		err = m88e1510_get_temp_alarm(phydev, temp);
2333 		break;
2334 	default:
2335 		return -EOPNOTSUPP;
2336 	}
2337 
2338 	return err;
2339 }
2340 
m88e1510_hwmon_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long temp)2341 static int m88e1510_hwmon_write(struct device *dev,
2342 				enum hwmon_sensor_types type,
2343 				u32 attr, int channel, long temp)
2344 {
2345 	struct phy_device *phydev = dev_get_drvdata(dev);
2346 	int err;
2347 
2348 	switch (attr) {
2349 	case hwmon_temp_crit:
2350 		err = m88e1510_set_temp_critical(phydev, temp);
2351 		break;
2352 	default:
2353 		return -EOPNOTSUPP;
2354 	}
2355 	return err;
2356 }
2357 
m88e1510_hwmon_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)2358 static umode_t m88e1510_hwmon_is_visible(const void *data,
2359 					 enum hwmon_sensor_types type,
2360 					 u32 attr, int channel)
2361 {
2362 	if (type != hwmon_temp)
2363 		return 0;
2364 
2365 	switch (attr) {
2366 	case hwmon_temp_input:
2367 	case hwmon_temp_max_alarm:
2368 		return 0444;
2369 	case hwmon_temp_crit:
2370 		return 0644;
2371 	default:
2372 		return 0;
2373 	}
2374 }
2375 
2376 static u32 m88e1510_hwmon_temp_config[] = {
2377 	HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM,
2378 	0
2379 };
2380 
2381 static const struct hwmon_channel_info m88e1510_hwmon_temp = {
2382 	.type = hwmon_temp,
2383 	.config = m88e1510_hwmon_temp_config,
2384 };
2385 
2386 static const struct hwmon_channel_info *m88e1510_hwmon_info[] = {
2387 	&m88e1121_hwmon_chip,
2388 	&m88e1510_hwmon_temp,
2389 	NULL
2390 };
2391 
2392 static const struct hwmon_ops m88e1510_hwmon_hwmon_ops = {
2393 	.is_visible = m88e1510_hwmon_is_visible,
2394 	.read = m88e1510_hwmon_read,
2395 	.write = m88e1510_hwmon_write,
2396 };
2397 
2398 static const struct hwmon_chip_info m88e1510_hwmon_chip_info = {
2399 	.ops = &m88e1510_hwmon_hwmon_ops,
2400 	.info = m88e1510_hwmon_info,
2401 };
2402 
m88e6390_get_temp(struct phy_device * phydev,long * temp)2403 static int m88e6390_get_temp(struct phy_device *phydev, long *temp)
2404 {
2405 	int sum = 0;
2406 	int oldpage;
2407 	int ret = 0;
2408 	int i;
2409 
2410 	*temp = 0;
2411 
2412 	oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
2413 	if (oldpage < 0)
2414 		goto error;
2415 
2416 	/* Enable temperature sensor */
2417 	ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
2418 	if (ret < 0)
2419 		goto error;
2420 
2421 	ret = ret & ~MII_88E6390_MISC_TEST_SAMPLE_MASK;
2422 	ret |= MII_88E6390_MISC_TEST_SAMPLE_ENABLE |
2423 		MII_88E6390_MISC_TEST_SAMPLE_1S;
2424 
2425 	ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
2426 	if (ret < 0)
2427 		goto error;
2428 
2429 	/* Wait for temperature to stabilize */
2430 	usleep_range(10000, 12000);
2431 
2432 	/* Reading the temperature sense has an errata. You need to read
2433 	 * a number of times and take an average.
2434 	 */
2435 	for (i = 0; i < MII_88E6390_TEMP_SENSOR_SAMPLES; i++) {
2436 		ret = __phy_read(phydev, MII_88E6390_TEMP_SENSOR);
2437 		if (ret < 0)
2438 			goto error;
2439 		sum += ret & MII_88E6390_TEMP_SENSOR_MASK;
2440 	}
2441 
2442 	sum /= MII_88E6390_TEMP_SENSOR_SAMPLES;
2443 	*temp = (sum  - 75) * 1000;
2444 
2445 	/* Disable temperature sensor */
2446 	ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
2447 	if (ret < 0)
2448 		goto error;
2449 
2450 	ret = ret & ~MII_88E6390_MISC_TEST_SAMPLE_MASK;
2451 	ret |= MII_88E6390_MISC_TEST_SAMPLE_DISABLE;
2452 
2453 	ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
2454 
2455 error:
2456 	phy_restore_page(phydev, oldpage, ret);
2457 
2458 	return ret;
2459 }
2460 
m88e6390_hwmon_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * temp)2461 static int m88e6390_hwmon_read(struct device *dev,
2462 			       enum hwmon_sensor_types type,
2463 			       u32 attr, int channel, long *temp)
2464 {
2465 	struct phy_device *phydev = dev_get_drvdata(dev);
2466 	int err;
2467 
2468 	switch (attr) {
2469 	case hwmon_temp_input:
2470 		err = m88e6390_get_temp(phydev, temp);
2471 		break;
2472 	default:
2473 		return -EOPNOTSUPP;
2474 	}
2475 
2476 	return err;
2477 }
2478 
m88e6390_hwmon_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)2479 static umode_t m88e6390_hwmon_is_visible(const void *data,
2480 					 enum hwmon_sensor_types type,
2481 					 u32 attr, int channel)
2482 {
2483 	if (type != hwmon_temp)
2484 		return 0;
2485 
2486 	switch (attr) {
2487 	case hwmon_temp_input:
2488 		return 0444;
2489 	default:
2490 		return 0;
2491 	}
2492 }
2493 
2494 static u32 m88e6390_hwmon_temp_config[] = {
2495 	HWMON_T_INPUT,
2496 	0
2497 };
2498 
2499 static const struct hwmon_channel_info m88e6390_hwmon_temp = {
2500 	.type = hwmon_temp,
2501 	.config = m88e6390_hwmon_temp_config,
2502 };
2503 
2504 static const struct hwmon_channel_info *m88e6390_hwmon_info[] = {
2505 	&m88e1121_hwmon_chip,
2506 	&m88e6390_hwmon_temp,
2507 	NULL
2508 };
2509 
2510 static const struct hwmon_ops m88e6390_hwmon_hwmon_ops = {
2511 	.is_visible = m88e6390_hwmon_is_visible,
2512 	.read = m88e6390_hwmon_read,
2513 };
2514 
2515 static const struct hwmon_chip_info m88e6390_hwmon_chip_info = {
2516 	.ops = &m88e6390_hwmon_hwmon_ops,
2517 	.info = m88e6390_hwmon_info,
2518 };
2519 
marvell_hwmon_name(struct phy_device * phydev)2520 static int marvell_hwmon_name(struct phy_device *phydev)
2521 {
2522 	struct marvell_priv *priv = phydev->priv;
2523 	struct device *dev = &phydev->mdio.dev;
2524 	const char *devname = dev_name(dev);
2525 	size_t len = strlen(devname);
2526 	int i, j;
2527 
2528 	priv->hwmon_name = devm_kzalloc(dev, len, GFP_KERNEL);
2529 	if (!priv->hwmon_name)
2530 		return -ENOMEM;
2531 
2532 	for (i = j = 0; i < len && devname[i]; i++) {
2533 		if (isalnum(devname[i]))
2534 			priv->hwmon_name[j++] = devname[i];
2535 	}
2536 
2537 	return 0;
2538 }
2539 
marvell_hwmon_probe(struct phy_device * phydev,const struct hwmon_chip_info * chip)2540 static int marvell_hwmon_probe(struct phy_device *phydev,
2541 			       const struct hwmon_chip_info *chip)
2542 {
2543 	struct marvell_priv *priv = phydev->priv;
2544 	struct device *dev = &phydev->mdio.dev;
2545 	int err;
2546 
2547 	err = marvell_hwmon_name(phydev);
2548 	if (err)
2549 		return err;
2550 
2551 	priv->hwmon_dev = devm_hwmon_device_register_with_info(
2552 		dev, priv->hwmon_name, phydev, chip, NULL);
2553 
2554 	return PTR_ERR_OR_ZERO(priv->hwmon_dev);
2555 }
2556 
m88e1121_hwmon_probe(struct phy_device * phydev)2557 static int m88e1121_hwmon_probe(struct phy_device *phydev)
2558 {
2559 	return marvell_hwmon_probe(phydev, &m88e1121_hwmon_chip_info);
2560 }
2561 
m88e1510_hwmon_probe(struct phy_device * phydev)2562 static int m88e1510_hwmon_probe(struct phy_device *phydev)
2563 {
2564 	return marvell_hwmon_probe(phydev, &m88e1510_hwmon_chip_info);
2565 }
2566 
m88e6390_hwmon_probe(struct phy_device * phydev)2567 static int m88e6390_hwmon_probe(struct phy_device *phydev)
2568 {
2569 	return marvell_hwmon_probe(phydev, &m88e6390_hwmon_chip_info);
2570 }
2571 #else
m88e1121_hwmon_probe(struct phy_device * phydev)2572 static int m88e1121_hwmon_probe(struct phy_device *phydev)
2573 {
2574 	return 0;
2575 }
2576 
m88e1510_hwmon_probe(struct phy_device * phydev)2577 static int m88e1510_hwmon_probe(struct phy_device *phydev)
2578 {
2579 	return 0;
2580 }
2581 
m88e6390_hwmon_probe(struct phy_device * phydev)2582 static int m88e6390_hwmon_probe(struct phy_device *phydev)
2583 {
2584 	return 0;
2585 }
2586 #endif
2587 
marvell_probe(struct phy_device * phydev)2588 static int marvell_probe(struct phy_device *phydev)
2589 {
2590 	struct marvell_priv *priv;
2591 
2592 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
2593 	if (!priv)
2594 		return -ENOMEM;
2595 
2596 	phydev->priv = priv;
2597 
2598 	return 0;
2599 }
2600 
m88e1121_probe(struct phy_device * phydev)2601 static int m88e1121_probe(struct phy_device *phydev)
2602 {
2603 	int err;
2604 
2605 	err = marvell_probe(phydev);
2606 	if (err)
2607 		return err;
2608 
2609 	return m88e1121_hwmon_probe(phydev);
2610 }
2611 
m88e1510_probe(struct phy_device * phydev)2612 static int m88e1510_probe(struct phy_device *phydev)
2613 {
2614 	int err;
2615 
2616 	err = marvell_probe(phydev);
2617 	if (err)
2618 		return err;
2619 
2620 	return m88e1510_hwmon_probe(phydev);
2621 }
2622 
m88e6390_probe(struct phy_device * phydev)2623 static int m88e6390_probe(struct phy_device *phydev)
2624 {
2625 	int err;
2626 
2627 	err = marvell_probe(phydev);
2628 	if (err)
2629 		return err;
2630 
2631 	return m88e6390_hwmon_probe(phydev);
2632 }
2633 
2634 static struct phy_driver marvell_drivers[] = {
2635 	{
2636 		.phy_id = MARVELL_PHY_ID_88E1101,
2637 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2638 		.name = "Marvell 88E1101",
2639 		/* PHY_GBIT_FEATURES */
2640 		.probe = marvell_probe,
2641 		.config_init = marvell_config_init,
2642 		.config_aneg = m88e1101_config_aneg,
2643 		.ack_interrupt = marvell_ack_interrupt,
2644 		.config_intr = marvell_config_intr,
2645 		.resume = genphy_resume,
2646 		.suspend = genphy_suspend,
2647 		.read_page = marvell_read_page,
2648 		.write_page = marvell_write_page,
2649 		.get_sset_count = marvell_get_sset_count,
2650 		.get_strings = marvell_get_strings,
2651 		.get_stats = marvell_get_stats,
2652 	},
2653 	{
2654 		.phy_id = MARVELL_PHY_ID_88E1112,
2655 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2656 		.name = "Marvell 88E1112",
2657 		/* PHY_GBIT_FEATURES */
2658 		.probe = marvell_probe,
2659 		.config_init = m88e1111_config_init,
2660 		.config_aneg = marvell_config_aneg,
2661 		.ack_interrupt = marvell_ack_interrupt,
2662 		.config_intr = marvell_config_intr,
2663 		.resume = genphy_resume,
2664 		.suspend = genphy_suspend,
2665 		.read_page = marvell_read_page,
2666 		.write_page = marvell_write_page,
2667 		.get_sset_count = marvell_get_sset_count,
2668 		.get_strings = marvell_get_strings,
2669 		.get_stats = marvell_get_stats,
2670 		.get_tunable = m88e1011_get_tunable,
2671 		.set_tunable = m88e1011_set_tunable,
2672 	},
2673 	{
2674 		.phy_id = MARVELL_PHY_ID_88E1111,
2675 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2676 		.name = "Marvell 88E1111",
2677 		/* PHY_GBIT_FEATURES */
2678 		.probe = marvell_probe,
2679 		.config_init = m88e1111_config_init,
2680 		.config_aneg = marvell_config_aneg,
2681 		.read_status = marvell_read_status,
2682 		.ack_interrupt = marvell_ack_interrupt,
2683 		.config_intr = marvell_config_intr,
2684 		.resume = genphy_resume,
2685 		.suspend = genphy_suspend,
2686 		.read_page = marvell_read_page,
2687 		.write_page = marvell_write_page,
2688 		.get_sset_count = marvell_get_sset_count,
2689 		.get_strings = marvell_get_strings,
2690 		.get_stats = marvell_get_stats,
2691 		.get_tunable = m88e1111_get_tunable,
2692 		.set_tunable = m88e1111_set_tunable,
2693 	},
2694 	{
2695 		.phy_id = MARVELL_PHY_ID_88E1118,
2696 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2697 		.name = "Marvell 88E1118",
2698 		/* PHY_GBIT_FEATURES */
2699 		.probe = marvell_probe,
2700 		.config_init = m88e1118_config_init,
2701 		.config_aneg = m88e1118_config_aneg,
2702 		.ack_interrupt = marvell_ack_interrupt,
2703 		.config_intr = marvell_config_intr,
2704 		.resume = genphy_resume,
2705 		.suspend = genphy_suspend,
2706 		.read_page = marvell_read_page,
2707 		.write_page = marvell_write_page,
2708 		.get_sset_count = marvell_get_sset_count,
2709 		.get_strings = marvell_get_strings,
2710 		.get_stats = marvell_get_stats,
2711 	},
2712 	{
2713 		.phy_id = MARVELL_PHY_ID_88E1121R,
2714 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2715 		.name = "Marvell 88E1121R",
2716 		/* PHY_GBIT_FEATURES */
2717 		.probe = m88e1121_probe,
2718 		.config_init = marvell_config_init,
2719 		.config_aneg = m88e1121_config_aneg,
2720 		.read_status = marvell_read_status,
2721 		.ack_interrupt = marvell_ack_interrupt,
2722 		.config_intr = marvell_config_intr,
2723 		.did_interrupt = m88e1121_did_interrupt,
2724 		.resume = genphy_resume,
2725 		.suspend = genphy_suspend,
2726 		.read_page = marvell_read_page,
2727 		.write_page = marvell_write_page,
2728 		.get_sset_count = marvell_get_sset_count,
2729 		.get_strings = marvell_get_strings,
2730 		.get_stats = marvell_get_stats,
2731 		.get_tunable = m88e1011_get_tunable,
2732 		.set_tunable = m88e1011_set_tunable,
2733 	},
2734 	{
2735 		.phy_id = MARVELL_PHY_ID_88E1318S,
2736 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2737 		.name = "Marvell 88E1318S",
2738 		/* PHY_GBIT_FEATURES */
2739 		.probe = marvell_probe,
2740 		.config_init = m88e1318_config_init,
2741 		.config_aneg = m88e1318_config_aneg,
2742 		.read_status = marvell_read_status,
2743 		.ack_interrupt = marvell_ack_interrupt,
2744 		.config_intr = marvell_config_intr,
2745 		.did_interrupt = m88e1121_did_interrupt,
2746 		.get_wol = m88e1318_get_wol,
2747 		.set_wol = m88e1318_set_wol,
2748 		.resume = genphy_resume,
2749 		.suspend = genphy_suspend,
2750 		.read_page = marvell_read_page,
2751 		.write_page = marvell_write_page,
2752 		.get_sset_count = marvell_get_sset_count,
2753 		.get_strings = marvell_get_strings,
2754 		.get_stats = marvell_get_stats,
2755 	},
2756 	{
2757 		.phy_id = MARVELL_PHY_ID_88E1145,
2758 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2759 		.name = "Marvell 88E1145",
2760 		/* PHY_GBIT_FEATURES */
2761 		.probe = marvell_probe,
2762 		.config_init = m88e1145_config_init,
2763 		.config_aneg = m88e1101_config_aneg,
2764 		.read_status = genphy_read_status,
2765 		.ack_interrupt = marvell_ack_interrupt,
2766 		.config_intr = marvell_config_intr,
2767 		.resume = genphy_resume,
2768 		.suspend = genphy_suspend,
2769 		.read_page = marvell_read_page,
2770 		.write_page = marvell_write_page,
2771 		.get_sset_count = marvell_get_sset_count,
2772 		.get_strings = marvell_get_strings,
2773 		.get_stats = marvell_get_stats,
2774 		.get_tunable = m88e1111_get_tunable,
2775 		.set_tunable = m88e1111_set_tunable,
2776 	},
2777 	{
2778 		.phy_id = MARVELL_PHY_ID_88E1149R,
2779 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2780 		.name = "Marvell 88E1149R",
2781 		/* PHY_GBIT_FEATURES */
2782 		.probe = marvell_probe,
2783 		.config_init = m88e1149_config_init,
2784 		.config_aneg = m88e1118_config_aneg,
2785 		.ack_interrupt = marvell_ack_interrupt,
2786 		.config_intr = marvell_config_intr,
2787 		.resume = genphy_resume,
2788 		.suspend = genphy_suspend,
2789 		.read_page = marvell_read_page,
2790 		.write_page = marvell_write_page,
2791 		.get_sset_count = marvell_get_sset_count,
2792 		.get_strings = marvell_get_strings,
2793 		.get_stats = marvell_get_stats,
2794 	},
2795 	{
2796 		.phy_id = MARVELL_PHY_ID_88E1240,
2797 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2798 		.name = "Marvell 88E1240",
2799 		/* PHY_GBIT_FEATURES */
2800 		.probe = marvell_probe,
2801 		.config_init = m88e1111_config_init,
2802 		.config_aneg = marvell_config_aneg,
2803 		.ack_interrupt = marvell_ack_interrupt,
2804 		.config_intr = marvell_config_intr,
2805 		.resume = genphy_resume,
2806 		.suspend = genphy_suspend,
2807 		.read_page = marvell_read_page,
2808 		.write_page = marvell_write_page,
2809 		.get_sset_count = marvell_get_sset_count,
2810 		.get_strings = marvell_get_strings,
2811 		.get_stats = marvell_get_stats,
2812 	},
2813 	{
2814 		.phy_id = MARVELL_PHY_ID_88E1116R,
2815 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2816 		.name = "Marvell 88E1116R",
2817 		/* PHY_GBIT_FEATURES */
2818 		.probe = marvell_probe,
2819 		.config_init = m88e1116r_config_init,
2820 		.ack_interrupt = marvell_ack_interrupt,
2821 		.config_intr = marvell_config_intr,
2822 		.resume = genphy_resume,
2823 		.suspend = genphy_suspend,
2824 		.read_page = marvell_read_page,
2825 		.write_page = marvell_write_page,
2826 		.get_sset_count = marvell_get_sset_count,
2827 		.get_strings = marvell_get_strings,
2828 		.get_stats = marvell_get_stats,
2829 		.get_tunable = m88e1011_get_tunable,
2830 		.set_tunable = m88e1011_set_tunable,
2831 	},
2832 	{
2833 		.phy_id = MARVELL_PHY_ID_88E1510,
2834 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2835 		.name = "Marvell 88E1510",
2836 		.features = PHY_GBIT_FIBRE_FEATURES,
2837 		.flags = PHY_POLL_CABLE_TEST,
2838 		.probe = m88e1510_probe,
2839 		.config_init = m88e1510_config_init,
2840 		.config_aneg = m88e1510_config_aneg,
2841 		.read_status = marvell_read_status,
2842 		.ack_interrupt = marvell_ack_interrupt,
2843 		.config_intr = marvell_config_intr,
2844 		.did_interrupt = m88e1121_did_interrupt,
2845 		.get_wol = m88e1318_get_wol,
2846 		.set_wol = m88e1318_set_wol,
2847 		.resume = marvell_resume,
2848 		.suspend = marvell_suspend,
2849 		.read_page = marvell_read_page,
2850 		.write_page = marvell_write_page,
2851 		.get_sset_count = marvell_get_sset_count,
2852 		.get_strings = marvell_get_strings,
2853 		.get_stats = marvell_get_stats,
2854 		.set_loopback = genphy_loopback,
2855 		.get_tunable = m88e1011_get_tunable,
2856 		.set_tunable = m88e1011_set_tunable,
2857 		.cable_test_start = marvell_vct7_cable_test_start,
2858 		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
2859 		.cable_test_get_status = marvell_vct7_cable_test_get_status,
2860 	},
2861 	{
2862 		.phy_id = MARVELL_PHY_ID_88E1540,
2863 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2864 		.name = "Marvell 88E1540",
2865 		/* PHY_GBIT_FEATURES */
2866 		.flags = PHY_POLL_CABLE_TEST,
2867 		.probe = m88e1510_probe,
2868 		.config_init = marvell_config_init,
2869 		.config_aneg = m88e1510_config_aneg,
2870 		.read_status = marvell_read_status,
2871 		.ack_interrupt = marvell_ack_interrupt,
2872 		.config_intr = marvell_config_intr,
2873 		.did_interrupt = m88e1121_did_interrupt,
2874 		.resume = genphy_resume,
2875 		.suspend = genphy_suspend,
2876 		.read_page = marvell_read_page,
2877 		.write_page = marvell_write_page,
2878 		.get_sset_count = marvell_get_sset_count,
2879 		.get_strings = marvell_get_strings,
2880 		.get_stats = marvell_get_stats,
2881 		.get_tunable = m88e1540_get_tunable,
2882 		.set_tunable = m88e1540_set_tunable,
2883 		.cable_test_start = marvell_vct7_cable_test_start,
2884 		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
2885 		.cable_test_get_status = marvell_vct7_cable_test_get_status,
2886 	},
2887 	{
2888 		.phy_id = MARVELL_PHY_ID_88E1545,
2889 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2890 		.name = "Marvell 88E1545",
2891 		.probe = m88e1510_probe,
2892 		/* PHY_GBIT_FEATURES */
2893 		.flags = PHY_POLL_CABLE_TEST,
2894 		.config_init = marvell_config_init,
2895 		.config_aneg = m88e1510_config_aneg,
2896 		.read_status = marvell_read_status,
2897 		.ack_interrupt = marvell_ack_interrupt,
2898 		.config_intr = marvell_config_intr,
2899 		.did_interrupt = m88e1121_did_interrupt,
2900 		.resume = genphy_resume,
2901 		.suspend = genphy_suspend,
2902 		.read_page = marvell_read_page,
2903 		.write_page = marvell_write_page,
2904 		.get_sset_count = marvell_get_sset_count,
2905 		.get_strings = marvell_get_strings,
2906 		.get_stats = marvell_get_stats,
2907 		.get_tunable = m88e1540_get_tunable,
2908 		.set_tunable = m88e1540_set_tunable,
2909 		.cable_test_start = marvell_vct7_cable_test_start,
2910 		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
2911 		.cable_test_get_status = marvell_vct7_cable_test_get_status,
2912 	},
2913 	{
2914 		.phy_id = MARVELL_PHY_ID_88E3016,
2915 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2916 		.name = "Marvell 88E3016",
2917 		/* PHY_BASIC_FEATURES */
2918 		.probe = marvell_probe,
2919 		.config_init = m88e3016_config_init,
2920 		.aneg_done = marvell_aneg_done,
2921 		.read_status = marvell_read_status,
2922 		.ack_interrupt = marvell_ack_interrupt,
2923 		.config_intr = marvell_config_intr,
2924 		.did_interrupt = m88e1121_did_interrupt,
2925 		.resume = genphy_resume,
2926 		.suspend = genphy_suspend,
2927 		.read_page = marvell_read_page,
2928 		.write_page = marvell_write_page,
2929 		.get_sset_count = marvell_get_sset_count,
2930 		.get_strings = marvell_get_strings,
2931 		.get_stats = marvell_get_stats,
2932 	},
2933 	{
2934 		.phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
2935 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2936 		.name = "Marvell 88E6341 Family",
2937 		/* PHY_GBIT_FEATURES */
2938 		.flags = PHY_POLL_CABLE_TEST,
2939 		.probe = m88e1510_probe,
2940 		.config_init = marvell_config_init,
2941 		.config_aneg = m88e6390_config_aneg,
2942 		.read_status = marvell_read_status,
2943 		.ack_interrupt = marvell_ack_interrupt,
2944 		.config_intr = marvell_config_intr,
2945 		.did_interrupt = m88e1121_did_interrupt,
2946 		.resume = genphy_resume,
2947 		.suspend = genphy_suspend,
2948 		.read_page = marvell_read_page,
2949 		.write_page = marvell_write_page,
2950 		.get_sset_count = marvell_get_sset_count,
2951 		.get_strings = marvell_get_strings,
2952 		.get_stats = marvell_get_stats,
2953 		.get_tunable = m88e1540_get_tunable,
2954 		.set_tunable = m88e1540_set_tunable,
2955 		.cable_test_start = marvell_vct7_cable_test_start,
2956 		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
2957 		.cable_test_get_status = marvell_vct7_cable_test_get_status,
2958 	},
2959 	{
2960 		.phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
2961 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2962 		.name = "Marvell 88E6390 Family",
2963 		/* PHY_GBIT_FEATURES */
2964 		.flags = PHY_POLL_CABLE_TEST,
2965 		.probe = m88e6390_probe,
2966 		.config_init = marvell_config_init,
2967 		.config_aneg = m88e6390_config_aneg,
2968 		.read_status = marvell_read_status,
2969 		.ack_interrupt = marvell_ack_interrupt,
2970 		.config_intr = marvell_config_intr,
2971 		.did_interrupt = m88e1121_did_interrupt,
2972 		.resume = genphy_resume,
2973 		.suspend = genphy_suspend,
2974 		.read_page = marvell_read_page,
2975 		.write_page = marvell_write_page,
2976 		.get_sset_count = marvell_get_sset_count,
2977 		.get_strings = marvell_get_strings,
2978 		.get_stats = marvell_get_stats,
2979 		.get_tunable = m88e1540_get_tunable,
2980 		.set_tunable = m88e1540_set_tunable,
2981 		.cable_test_start = marvell_vct7_cable_test_start,
2982 		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
2983 		.cable_test_get_status = marvell_vct7_cable_test_get_status,
2984 	},
2985 	{
2986 		.phy_id = MARVELL_PHY_ID_88E1340S,
2987 		.phy_id_mask = MARVELL_PHY_ID_MASK,
2988 		.name = "Marvell 88E1340S",
2989 		.probe = m88e1510_probe,
2990 		/* PHY_GBIT_FEATURES */
2991 		.config_init = marvell_config_init,
2992 		.config_aneg = m88e1510_config_aneg,
2993 		.read_status = marvell_read_status,
2994 		.ack_interrupt = marvell_ack_interrupt,
2995 		.config_intr = marvell_config_intr,
2996 		.did_interrupt = m88e1121_did_interrupt,
2997 		.resume = genphy_resume,
2998 		.suspend = genphy_suspend,
2999 		.read_page = marvell_read_page,
3000 		.write_page = marvell_write_page,
3001 		.get_sset_count = marvell_get_sset_count,
3002 		.get_strings = marvell_get_strings,
3003 		.get_stats = marvell_get_stats,
3004 		.get_tunable = m88e1540_get_tunable,
3005 		.set_tunable = m88e1540_set_tunable,
3006 	},
3007 	{
3008 		.phy_id = MARVELL_PHY_ID_88E1548P,
3009 		.phy_id_mask = MARVELL_PHY_ID_MASK,
3010 		.name = "Marvell 88E1548P",
3011 		.probe = m88e1510_probe,
3012 		.features = PHY_GBIT_FIBRE_FEATURES,
3013 		.config_init = marvell_config_init,
3014 		.config_aneg = m88e1510_config_aneg,
3015 		.read_status = marvell_read_status,
3016 		.ack_interrupt = marvell_ack_interrupt,
3017 		.config_intr = marvell_config_intr,
3018 		.did_interrupt = m88e1121_did_interrupt,
3019 		.resume = genphy_resume,
3020 		.suspend = genphy_suspend,
3021 		.read_page = marvell_read_page,
3022 		.write_page = marvell_write_page,
3023 		.get_sset_count = marvell_get_sset_count,
3024 		.get_strings = marvell_get_strings,
3025 		.get_stats = marvell_get_stats,
3026 		.get_tunable = m88e1540_get_tunable,
3027 		.set_tunable = m88e1540_set_tunable,
3028 	},
3029 };
3030 
3031 module_phy_driver(marvell_drivers);
3032 
3033 static struct mdio_device_id __maybe_unused marvell_tbl[] = {
3034 	{ MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
3035 	{ MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
3036 	{ MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
3037 	{ MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
3038 	{ MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
3039 	{ MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
3040 	{ MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
3041 	{ MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
3042 	{ MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
3043 	{ MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
3044 	{ MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
3045 	{ MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
3046 	{ MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
3047 	{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
3048 	{ MARVELL_PHY_ID_88E6341_FAMILY, MARVELL_PHY_ID_MASK },
3049 	{ MARVELL_PHY_ID_88E6390_FAMILY, MARVELL_PHY_ID_MASK },
3050 	{ MARVELL_PHY_ID_88E1340S, MARVELL_PHY_ID_MASK },
3051 	{ MARVELL_PHY_ID_88E1548P, MARVELL_PHY_ID_MASK },
3052 	{ }
3053 };
3054 
3055 MODULE_DEVICE_TABLE(mdio, marvell_tbl);
3056