xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/serdes.c (revision 4aabe35c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Marvell 88E6xxx SERDES manipulation, via SMI bus
4  *
5  * Copyright (c) 2008 Marvell Semiconductor
6  *
7  * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
8  */
9 
10 #include <linux/interrupt.h>
11 #include <linux/irqdomain.h>
12 #include <linux/mii.h>
13 
14 #include "chip.h"
15 #include "global2.h"
16 #include "phy.h"
17 #include "port.h"
18 #include "serdes.h"
19 
20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
21 				 u16 *val)
22 {
23 	return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
24 				       MV88E6352_SERDES_PAGE_FIBER,
25 				       reg, val);
26 }
27 
28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
29 				  u16 val)
30 {
31 	return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
32 					MV88E6352_SERDES_PAGE_FIBER,
33 					reg, val);
34 }
35 
36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
37 				 int lane, int device, int reg, u16 *val)
38 {
39 	return mv88e6xxx_phy_read_c45(chip, lane, device, reg, val);
40 }
41 
42 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
43 				  int lane, int device, int reg, u16 val)
44 {
45 	return mv88e6xxx_phy_write_c45(chip, lane, device, reg, val);
46 }
47 
48 int mv88e6xxx_pcs_decode_state(struct device *dev, u16 bmsr, u16 lpa,
49 			       u16 status, struct phylink_link_state *state)
50 {
51 	state->link = false;
52 
53 	/* If the BMSR reports that the link had failed, report this to
54 	 * phylink.
55 	 */
56 	if (!(bmsr & BMSR_LSTATUS))
57 		return 0;
58 
59 	state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
60 	state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
61 
62 	if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
63 		/* The Spped and Duplex Resolved register is 1 if AN is enabled
64 		 * and complete, or if AN is disabled. So with disabled AN we
65 		 * still get here on link up.
66 		 */
67 		state->duplex = status &
68 				MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
69 			                         DUPLEX_FULL : DUPLEX_HALF;
70 
71 		if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
72 			state->pause |= MLO_PAUSE_TX;
73 		if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
74 			state->pause |= MLO_PAUSE_RX;
75 
76 		switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
77 		case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
78 			if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
79 				state->speed = SPEED_2500;
80 			else
81 				state->speed = SPEED_1000;
82 			break;
83 		case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
84 			state->speed = SPEED_100;
85 			break;
86 		case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
87 			state->speed = SPEED_10;
88 			break;
89 		default:
90 			dev_err(dev, "invalid PHY speed\n");
91 			return -EINVAL;
92 		}
93 	} else if (state->link &&
94 		   state->interface != PHY_INTERFACE_MODE_SGMII) {
95 		/* If Speed and Duplex Resolved register is 0 and link is up, it
96 		 * means that AN was enabled, but link partner had it disabled
97 		 * and the PHY invoked the Auto-Negotiation Bypass feature and
98 		 * linked anyway.
99 		 */
100 		state->duplex = DUPLEX_FULL;
101 		if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
102 			state->speed = SPEED_2500;
103 		else
104 			state->speed = SPEED_1000;
105 	} else {
106 		state->link = false;
107 	}
108 
109 	if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
110 		mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
111 				       ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
112 	else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
113 		mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
114 				       ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
115 
116 	return 0;
117 }
118 
119 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
120 			   bool up)
121 {
122 	u16 val, new_val;
123 	int err;
124 
125 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
126 	if (err)
127 		return err;
128 
129 	if (up)
130 		new_val = val & ~BMCR_PDOWN;
131 	else
132 		new_val = val | BMCR_PDOWN;
133 
134 	if (val != new_val)
135 		err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
136 
137 	return err;
138 }
139 
140 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
141 				int lane, unsigned int mode,
142 				phy_interface_t interface,
143 				const unsigned long *advertise)
144 {
145 	u16 adv, bmcr, val;
146 	bool changed;
147 	int err;
148 
149 	switch (interface) {
150 	case PHY_INTERFACE_MODE_SGMII:
151 		adv = 0x0001;
152 		break;
153 
154 	case PHY_INTERFACE_MODE_1000BASEX:
155 		adv = linkmode_adv_to_mii_adv_x(advertise,
156 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
157 		break;
158 
159 	default:
160 		return 0;
161 	}
162 
163 	err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
164 	if (err)
165 		return err;
166 
167 	changed = val != adv;
168 	if (changed) {
169 		err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
170 		if (err)
171 			return err;
172 	}
173 
174 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
175 	if (err)
176 		return err;
177 
178 	if (phylink_autoneg_inband(mode))
179 		bmcr = val | BMCR_ANENABLE;
180 	else
181 		bmcr = val & ~BMCR_ANENABLE;
182 
183 	if (bmcr == val)
184 		return changed;
185 
186 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
187 }
188 
189 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
190 				   int lane, struct phylink_link_state *state)
191 {
192 	u16 bmsr, lpa, status;
193 	int err;
194 
195 	err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
196 	if (err) {
197 		dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
198 		return err;
199 	}
200 
201 	err = mv88e6352_serdes_read(chip, 0x11, &status);
202 	if (err) {
203 		dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
204 		return err;
205 	}
206 
207 	err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
208 	if (err) {
209 		dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
210 		return err;
211 	}
212 
213 	return mv88e6xxx_pcs_decode_state(chip->dev, bmsr, lpa, status, state);
214 }
215 
216 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
217 				    int lane)
218 {
219 	u16 bmcr;
220 	int err;
221 
222 	err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
223 	if (err)
224 		return err;
225 
226 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
227 }
228 
229 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
230 				 int lane, int speed, int duplex)
231 {
232 	u16 val, bmcr;
233 	int err;
234 
235 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
236 	if (err)
237 		return err;
238 
239 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
240 	switch (speed) {
241 	case SPEED_1000:
242 		bmcr |= BMCR_SPEED1000;
243 		break;
244 	case SPEED_100:
245 		bmcr |= BMCR_SPEED100;
246 		break;
247 	case SPEED_10:
248 		break;
249 	}
250 
251 	if (duplex == DUPLEX_FULL)
252 		bmcr |= BMCR_FULLDPLX;
253 
254 	if (bmcr == val)
255 		return 0;
256 
257 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
258 }
259 
260 int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
261 {
262 	u8 cmode = chip->ports[port].cmode;
263 	int lane = -ENODEV;
264 
265 	if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
266 	    (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
267 	    (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
268 		lane = 0xff; /* Unused */
269 
270 	return lane;
271 }
272 
273 struct mv88e6352_serdes_hw_stat {
274 	char string[ETH_GSTRING_LEN];
275 	int sizeof_stat;
276 	int reg;
277 };
278 
279 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
280 	{ "serdes_fibre_rx_error", 16, 21 },
281 	{ "serdes_PRBS_error", 32, 24 },
282 };
283 
284 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
285 {
286 	int err;
287 
288 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
289 	if (err <= 0)
290 		return err;
291 
292 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
293 }
294 
295 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
296 				 int port, uint8_t *data)
297 {
298 	struct mv88e6352_serdes_hw_stat *stat;
299 	int err, i;
300 
301 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
302 	if (err <= 0)
303 		return err;
304 
305 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
306 		stat = &mv88e6352_serdes_hw_stats[i];
307 		memcpy(data + i * ETH_GSTRING_LEN, stat->string,
308 		       ETH_GSTRING_LEN);
309 	}
310 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
311 }
312 
313 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
314 					  struct mv88e6352_serdes_hw_stat *stat)
315 {
316 	u64 val = 0;
317 	u16 reg;
318 	int err;
319 
320 	err = mv88e6352_serdes_read(chip, stat->reg, &reg);
321 	if (err) {
322 		dev_err(chip->dev, "failed to read statistic\n");
323 		return 0;
324 	}
325 
326 	val = reg;
327 
328 	if (stat->sizeof_stat == 32) {
329 		err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
330 		if (err) {
331 			dev_err(chip->dev, "failed to read statistic\n");
332 			return 0;
333 		}
334 		val = val << 16 | reg;
335 	}
336 
337 	return val;
338 }
339 
340 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
341 			       uint64_t *data)
342 {
343 	struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
344 	struct mv88e6352_serdes_hw_stat *stat;
345 	int i, err;
346 	u64 value;
347 
348 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
349 	if (err <= 0)
350 		return err;
351 
352 	BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
353 		     ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
354 
355 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
356 		stat = &mv88e6352_serdes_hw_stats[i];
357 		value = mv88e6352_serdes_get_stat(chip, stat);
358 		mv88e6xxx_port->serdes_stats[i] += value;
359 		data[i] = mv88e6xxx_port->serdes_stats[i];
360 	}
361 
362 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
363 }
364 
365 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
366 {
367 	u16 bmsr;
368 	int err;
369 
370 	/* If the link has dropped, we want to know about it. */
371 	err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
372 	if (err) {
373 		dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
374 		return;
375 	}
376 
377 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
378 }
379 
380 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
381 					int lane)
382 {
383 	irqreturn_t ret = IRQ_NONE;
384 	u16 status;
385 	int err;
386 
387 	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
388 	if (err)
389 		return ret;
390 
391 	if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
392 		ret = IRQ_HANDLED;
393 		mv88e6352_serdes_irq_link(chip, port);
394 	}
395 
396 	return ret;
397 }
398 
399 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
400 				bool enable)
401 {
402 	u16 val = 0;
403 
404 	if (enable)
405 		val |= MV88E6352_SERDES_INT_LINK_CHANGE;
406 
407 	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
408 }
409 
410 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
411 {
412 	return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
413 }
414 
415 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
416 {
417 	int err;
418 
419 	mv88e6xxx_reg_lock(chip);
420 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
421 	mv88e6xxx_reg_unlock(chip);
422 	if (err <= 0)
423 		return err;
424 
425 	return 32 * sizeof(u16);
426 }
427 
428 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
429 {
430 	u16 *p = _p;
431 	u16 reg;
432 	int err;
433 	int i;
434 
435 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
436 	if (err <= 0)
437 		return;
438 
439 	for (i = 0 ; i < 32; i++) {
440 		err = mv88e6352_serdes_read(chip, i, &reg);
441 		if (!err)
442 			p[i] = reg;
443 	}
444 }
445 
446 int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
447 {
448 	u8 cmode = chip->ports[port].cmode;
449 	int lane = -ENODEV;
450 
451 	switch (port) {
452 	case 5:
453 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
454 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
455 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
456 			lane = MV88E6341_PORT5_LANE;
457 		break;
458 	}
459 
460 	return lane;
461 }
462 
463 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
464 {
465 	u8 cmode = chip->ports[port].cmode;
466 	int lane = -ENODEV;
467 
468 	switch (port) {
469 	case 9:
470 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
471 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
472 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
473 			lane = MV88E6390_PORT9_LANE0;
474 		break;
475 	case 10:
476 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
477 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
478 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
479 			lane = MV88E6390_PORT10_LANE0;
480 		break;
481 	}
482 
483 	return lane;
484 }
485 
486 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
487 {
488 	u8 cmode_port = chip->ports[port].cmode;
489 	u8 cmode_port10 = chip->ports[10].cmode;
490 	u8 cmode_port9 = chip->ports[9].cmode;
491 	int lane = -ENODEV;
492 
493 	switch (port) {
494 	case 2:
495 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
496 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
497 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
498 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
499 				lane = MV88E6390_PORT9_LANE1;
500 		break;
501 	case 3:
502 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
503 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
504 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
505 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
506 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
507 				lane = MV88E6390_PORT9_LANE2;
508 		break;
509 	case 4:
510 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
511 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
512 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
513 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
514 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
515 				lane = MV88E6390_PORT9_LANE3;
516 		break;
517 	case 5:
518 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
519 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
520 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
521 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
522 				lane = MV88E6390_PORT10_LANE1;
523 		break;
524 	case 6:
525 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
526 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
527 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
528 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
529 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
530 				lane = MV88E6390_PORT10_LANE2;
531 		break;
532 	case 7:
533 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
534 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
535 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
536 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
537 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
538 				lane = MV88E6390_PORT10_LANE3;
539 		break;
540 	case 9:
541 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
542 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
543 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
544 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
545 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
546 			lane = MV88E6390_PORT9_LANE0;
547 		break;
548 	case 10:
549 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
550 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
551 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
552 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
553 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
554 			lane = MV88E6390_PORT10_LANE0;
555 		break;
556 	}
557 
558 	return lane;
559 }
560 
561 /* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address
562  * a port is using else Returns -ENODEV.
563  */
564 int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
565 {
566 	u8 cmode = chip->ports[port].cmode;
567 	int lane = -ENODEV;
568 
569 	if (port != 0 && port != 9 && port != 10)
570 		return -EOPNOTSUPP;
571 
572 	if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
573 	    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
574 	    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
575 	    cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
576 	    cmode == MV88E6393X_PORT_STS_CMODE_10GBASER ||
577 	    cmode == MV88E6393X_PORT_STS_CMODE_USXGMII)
578 		lane = port;
579 
580 	return lane;
581 }
582 
583 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
584 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
585 				      bool up)
586 {
587 	u16 val, new_val;
588 	int err;
589 
590 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
591 				    MV88E6390_10G_CTRL1, &val);
592 
593 	if (err)
594 		return err;
595 
596 	if (up)
597 		new_val = val & ~(MDIO_CTRL1_RESET |
598 				  MDIO_PCS_CTRL1_LOOPBACK |
599 				  MDIO_CTRL1_LPOWER);
600 	else
601 		new_val = val | MDIO_CTRL1_LPOWER;
602 
603 	if (val != new_val)
604 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
605 					     MV88E6390_10G_CTRL1, new_val);
606 
607 	return err;
608 }
609 
610 /* Set power up/down for SGMII and 1000Base-X */
611 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
612 					bool up)
613 {
614 	u16 val, new_val;
615 	int err;
616 
617 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
618 				    MV88E6390_SGMII_BMCR, &val);
619 	if (err)
620 		return err;
621 
622 	if (up)
623 		new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
624 	else
625 		new_val = val | BMCR_PDOWN;
626 
627 	if (val != new_val)
628 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
629 					     MV88E6390_SGMII_BMCR, new_val);
630 
631 	return err;
632 }
633 
634 struct mv88e6390_serdes_hw_stat {
635 	char string[ETH_GSTRING_LEN];
636 	int reg;
637 };
638 
639 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
640 	{ "serdes_rx_pkts", 0xf021 },
641 	{ "serdes_rx_bytes", 0xf024 },
642 	{ "serdes_rx_pkts_error", 0xf027 },
643 };
644 
645 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
646 {
647 	if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
648 		return 0;
649 
650 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
651 }
652 
653 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
654 				 int port, uint8_t *data)
655 {
656 	struct mv88e6390_serdes_hw_stat *stat;
657 	int i;
658 
659 	if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
660 		return 0;
661 
662 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
663 		stat = &mv88e6390_serdes_hw_stats[i];
664 		memcpy(data + i * ETH_GSTRING_LEN, stat->string,
665 		       ETH_GSTRING_LEN);
666 	}
667 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
668 }
669 
670 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
671 					  struct mv88e6390_serdes_hw_stat *stat)
672 {
673 	u16 reg[3];
674 	int err, i;
675 
676 	for (i = 0; i < 3; i++) {
677 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
678 					    stat->reg + i, &reg[i]);
679 		if (err) {
680 			dev_err(chip->dev, "failed to read statistic\n");
681 			return 0;
682 		}
683 	}
684 
685 	return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
686 }
687 
688 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
689 			       uint64_t *data)
690 {
691 	struct mv88e6390_serdes_hw_stat *stat;
692 	int lane;
693 	int i;
694 
695 	lane = mv88e6xxx_serdes_get_lane(chip, port);
696 	if (lane < 0)
697 		return 0;
698 
699 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
700 		stat = &mv88e6390_serdes_hw_stats[i];
701 		data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
702 	}
703 
704 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
705 }
706 
707 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, int lane)
708 {
709 	u16 reg;
710 	int err;
711 
712 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
713 				    MV88E6390_PG_CONTROL, &reg);
714 	if (err)
715 		return err;
716 
717 	reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
718 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
719 				      MV88E6390_PG_CONTROL, reg);
720 }
721 
722 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
723 			   bool up)
724 {
725 	u8 cmode = chip->ports[port].cmode;
726 	int err;
727 
728 	switch (cmode) {
729 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
730 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
731 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
732 		err = mv88e6390_serdes_power_sgmii(chip, lane, up);
733 		break;
734 	case MV88E6XXX_PORT_STS_CMODE_XAUI:
735 	case MV88E6XXX_PORT_STS_CMODE_RXAUI:
736 		err = mv88e6390_serdes_power_10g(chip, lane, up);
737 		break;
738 	default:
739 		err = -EINVAL;
740 		break;
741 	}
742 
743 	if (!err && up)
744 		err = mv88e6390_serdes_enable_checker(chip, lane);
745 
746 	return err;
747 }
748 
749 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
750 				int lane, unsigned int mode,
751 				phy_interface_t interface,
752 				const unsigned long *advertise)
753 {
754 	u16 val, bmcr, adv;
755 	bool changed;
756 	int err;
757 
758 	switch (interface) {
759 	case PHY_INTERFACE_MODE_SGMII:
760 		adv = 0x0001;
761 		break;
762 
763 	case PHY_INTERFACE_MODE_1000BASEX:
764 		adv = linkmode_adv_to_mii_adv_x(advertise,
765 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
766 		break;
767 
768 	case PHY_INTERFACE_MODE_2500BASEX:
769 		adv = linkmode_adv_to_mii_adv_x(advertise,
770 					ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
771 		break;
772 
773 	default:
774 		return 0;
775 	}
776 
777 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
778 				    MV88E6390_SGMII_ADVERTISE, &val);
779 	if (err)
780 		return err;
781 
782 	changed = val != adv;
783 	if (changed) {
784 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
785 					     MV88E6390_SGMII_ADVERTISE, adv);
786 		if (err)
787 			return err;
788 	}
789 
790 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
791 				    MV88E6390_SGMII_BMCR, &val);
792 	if (err)
793 		return err;
794 
795 	if (phylink_autoneg_inband(mode))
796 		bmcr = val | BMCR_ANENABLE;
797 	else
798 		bmcr = val & ~BMCR_ANENABLE;
799 
800 	/* setting ANENABLE triggers a restart of negotiation */
801 	if (bmcr == val)
802 		return changed;
803 
804 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
805 				      MV88E6390_SGMII_BMCR, bmcr);
806 }
807 
808 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
809 	int port, int lane, struct phylink_link_state *state)
810 {
811 	u16 bmsr, lpa, status;
812 	int err;
813 
814 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
815 				    MV88E6390_SGMII_BMSR, &bmsr);
816 	if (err) {
817 		dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
818 		return err;
819 	}
820 
821 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
822 				    MV88E6390_SGMII_PHY_STATUS, &status);
823 	if (err) {
824 		dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
825 		return err;
826 	}
827 
828 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
829 				    MV88E6390_SGMII_LPA, &lpa);
830 	if (err) {
831 		dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
832 		return err;
833 	}
834 
835 	return mv88e6xxx_pcs_decode_state(chip->dev, bmsr, lpa, status, state);
836 }
837 
838 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
839 	int port, int lane, struct phylink_link_state *state)
840 {
841 	u16 status;
842 	int err;
843 
844 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
845 				    MV88E6390_10G_STAT1, &status);
846 	if (err)
847 		return err;
848 
849 	state->link = !!(status & MDIO_STAT1_LSTATUS);
850 	if (state->link) {
851 		state->speed = SPEED_10000;
852 		state->duplex = DUPLEX_FULL;
853 	}
854 
855 	return 0;
856 }
857 
858 static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
859 					       int port, int lane,
860 					       struct phylink_link_state *state)
861 {
862 	u16 status;
863 	int err;
864 
865 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
866 				    MV88E6390_10G_STAT1, &status);
867 	if (err)
868 		return err;
869 
870 	state->link = !!(status & MDIO_STAT1_LSTATUS);
871 	if (state->link) {
872 		if (state->interface == PHY_INTERFACE_MODE_5GBASER)
873 			state->speed = SPEED_5000;
874 		else
875 			state->speed = SPEED_10000;
876 		state->duplex = DUPLEX_FULL;
877 	}
878 	return 0;
879 }
880 
881 /* USXGMII registers for Marvell switch 88e639x are undocumented and this function is based
882  * on some educated guesses. It appears that there are no status bits related to
883  * autonegotiation complete or flow control.
884  */
885 static int mv88e639x_serdes_pcs_get_state_usxgmii(struct mv88e6xxx_chip *chip,
886 						  int port, int lane,
887 						  struct phylink_link_state *state)
888 {
889 	u16 status, lp_status;
890 	int err;
891 
892 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
893 				    MV88E6390_USXGMII_PHY_STATUS, &status);
894 	if (err) {
895 		dev_err(chip->dev, "can't read Serdes USXGMII PHY status: %d\n", err);
896 		return err;
897 	}
898 	dev_dbg(chip->dev, "USXGMII PHY status: 0x%x\n", status);
899 
900 	state->link = !!(status & MDIO_USXGMII_LINK);
901 	state->an_complete = state->link;
902 
903 	if (state->link) {
904 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
905 					    MV88E6390_USXGMII_LP_STATUS, &lp_status);
906 		if (err) {
907 			dev_err(chip->dev, "can't read Serdes USXGMII LP status: %d\n", err);
908 			return err;
909 		}
910 		dev_dbg(chip->dev, "USXGMII LP status: 0x%x\n", lp_status);
911 		/* lp_status appears to include the "link" bit as per USXGMII spec. */
912 		phylink_decode_usxgmii_word(state, lp_status);
913 	}
914 	return 0;
915 }
916 
917 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
918 				   int lane, struct phylink_link_state *state)
919 {
920 	switch (state->interface) {
921 	case PHY_INTERFACE_MODE_SGMII:
922 	case PHY_INTERFACE_MODE_1000BASEX:
923 	case PHY_INTERFACE_MODE_2500BASEX:
924 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
925 							    state);
926 	case PHY_INTERFACE_MODE_XAUI:
927 	case PHY_INTERFACE_MODE_RXAUI:
928 		return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
929 							  state);
930 
931 	default:
932 		return -EOPNOTSUPP;
933 	}
934 }
935 
936 int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
937 				    int lane, struct phylink_link_state *state)
938 {
939 	switch (state->interface) {
940 	case PHY_INTERFACE_MODE_SGMII:
941 	case PHY_INTERFACE_MODE_1000BASEX:
942 	case PHY_INTERFACE_MODE_2500BASEX:
943 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
944 							    state);
945 	case PHY_INTERFACE_MODE_5GBASER:
946 	case PHY_INTERFACE_MODE_10GBASER:
947 		return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane,
948 							   state);
949 	case PHY_INTERFACE_MODE_USXGMII:
950 		return mv88e639x_serdes_pcs_get_state_usxgmii(chip, port, lane,
951 							   state);
952 
953 	default:
954 		return -EOPNOTSUPP;
955 	}
956 }
957 
958 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
959 				    int lane)
960 {
961 	u16 bmcr;
962 	int err;
963 
964 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
965 				    MV88E6390_SGMII_BMCR, &bmcr);
966 	if (err)
967 		return err;
968 
969 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
970 				      MV88E6390_SGMII_BMCR,
971 				      bmcr | BMCR_ANRESTART);
972 }
973 
974 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
975 				 int lane, int speed, int duplex)
976 {
977 	u16 val, bmcr;
978 	int err;
979 
980 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
981 				    MV88E6390_SGMII_BMCR, &val);
982 	if (err)
983 		return err;
984 
985 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
986 	switch (speed) {
987 	case SPEED_2500:
988 	case SPEED_1000:
989 		bmcr |= BMCR_SPEED1000;
990 		break;
991 	case SPEED_100:
992 		bmcr |= BMCR_SPEED100;
993 		break;
994 	case SPEED_10:
995 		break;
996 	}
997 
998 	if (duplex == DUPLEX_FULL)
999 		bmcr |= BMCR_FULLDPLX;
1000 
1001 	if (bmcr == val)
1002 		return 0;
1003 
1004 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1005 				      MV88E6390_SGMII_BMCR, bmcr);
1006 }
1007 
1008 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
1009 					    int port, int lane)
1010 {
1011 	u16 bmsr;
1012 	int err;
1013 
1014 	/* If the link has dropped, we want to know about it. */
1015 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1016 				    MV88E6390_SGMII_BMSR, &bmsr);
1017 	if (err) {
1018 		dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
1019 		return;
1020 	}
1021 
1022 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
1023 }
1024 
1025 static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip,
1026 					   int port, u8 lane)
1027 {
1028 	u16 status;
1029 	int err;
1030 
1031 	/* If the link has dropped, we want to know about it. */
1032 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1033 				    MV88E6390_10G_STAT1, &status);
1034 	if (err) {
1035 		dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err);
1036 		return;
1037 	}
1038 
1039 	dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS));
1040 }
1041 
1042 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
1043 					     int lane, bool enable)
1044 {
1045 	u16 val = 0;
1046 
1047 	if (enable)
1048 		val |= MV88E6390_SGMII_INT_LINK_DOWN |
1049 			MV88E6390_SGMII_INT_LINK_UP;
1050 
1051 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1052 				      MV88E6390_SGMII_INT_ENABLE, val);
1053 }
1054 
1055 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1056 				bool enable)
1057 {
1058 	u8 cmode = chip->ports[port].cmode;
1059 
1060 	switch (cmode) {
1061 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1062 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1063 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1064 		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1065 	}
1066 
1067 	return 0;
1068 }
1069 
1070 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1071 					     int lane, u16 *status)
1072 {
1073 	int err;
1074 
1075 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1076 				    MV88E6390_SGMII_INT_STATUS, status);
1077 
1078 	return err;
1079 }
1080 
1081 static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip,
1082 					    u8 lane, bool enable)
1083 {
1084 	u16 val = 0;
1085 
1086 	if (enable)
1087 		val |= MV88E6393X_10G_INT_LINK_CHANGE;
1088 
1089 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1090 				      MV88E6393X_10G_INT_ENABLE, val);
1091 }
1092 
1093 int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
1094 				 int lane, bool enable)
1095 {
1096 	u8 cmode = chip->ports[port].cmode;
1097 
1098 	switch (cmode) {
1099 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1100 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1101 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1102 		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1103 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1104 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1105 	case MV88E6393X_PORT_STS_CMODE_USXGMII:
1106 		return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
1107 	}
1108 
1109 	return 0;
1110 }
1111 
1112 static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip,
1113 					    u8 lane, u16 *status)
1114 {
1115 	int err;
1116 
1117 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1118 				    MV88E6393X_10G_INT_STATUS, status);
1119 
1120 	return err;
1121 }
1122 
1123 irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1124 					 int lane)
1125 {
1126 	u8 cmode = chip->ports[port].cmode;
1127 	irqreturn_t ret = IRQ_NONE;
1128 	u16 status;
1129 	int err;
1130 
1131 	switch (cmode) {
1132 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1133 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1134 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1135 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1136 		if (err)
1137 			return ret;
1138 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1139 			      MV88E6390_SGMII_INT_LINK_UP)) {
1140 			ret = IRQ_HANDLED;
1141 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1142 		}
1143 		break;
1144 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1145 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1146 	case MV88E6393X_PORT_STS_CMODE_USXGMII:
1147 		err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
1148 		if (err)
1149 			return err;
1150 		if (status & MV88E6393X_10G_INT_LINK_CHANGE) {
1151 			ret = IRQ_HANDLED;
1152 			mv88e6393x_serdes_irq_link_10g(chip, port, lane);
1153 		}
1154 		break;
1155 	}
1156 
1157 	return ret;
1158 }
1159 
1160 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1161 					int lane)
1162 {
1163 	u8 cmode = chip->ports[port].cmode;
1164 	irqreturn_t ret = IRQ_NONE;
1165 	u16 status;
1166 	int err;
1167 
1168 	switch (cmode) {
1169 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1170 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1171 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1172 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1173 		if (err)
1174 			return ret;
1175 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1176 			      MV88E6390_SGMII_INT_LINK_UP)) {
1177 			ret = IRQ_HANDLED;
1178 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1179 		}
1180 	}
1181 
1182 	return ret;
1183 }
1184 
1185 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1186 {
1187 	return irq_find_mapping(chip->g2_irq.domain, port);
1188 }
1189 
1190 static const u16 mv88e6390_serdes_regs[] = {
1191 	/* SERDES common registers */
1192 	0xf00a, 0xf00b, 0xf00c,
1193 	0xf010, 0xf011, 0xf012, 0xf013,
1194 	0xf016, 0xf017, 0xf018,
1195 	0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1196 	0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1197 	0xf028, 0xf029,
1198 	0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1199 	0xf038, 0xf039,
1200 	/* SGMII */
1201 	0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1202 	0x2008,
1203 	0x200f,
1204 	0xa000, 0xa001, 0xa002, 0xa003,
1205 	/* 10Gbase-X */
1206 	0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1207 	0x1008,
1208 	0x100e, 0x100f,
1209 	0x1018, 0x1019,
1210 	0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1211 	0x9006,
1212 	0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1213 	/* 10Gbase-R */
1214 	0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1215 	0x1028, 0x1029, 0x102a, 0x102b,
1216 };
1217 
1218 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1219 {
1220 	if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
1221 		return 0;
1222 
1223 	return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1224 }
1225 
1226 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1227 {
1228 	u16 *p = _p;
1229 	int lane;
1230 	u16 reg;
1231 	int err;
1232 	int i;
1233 
1234 	lane = mv88e6xxx_serdes_get_lane(chip, port);
1235 	if (lane < 0)
1236 		return;
1237 
1238 	for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1239 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1240 					    mv88e6390_serdes_regs[i], &reg);
1241 		if (!err)
1242 			p[i] = reg;
1243 	}
1244 }
1245 
1246 static const int mv88e6352_serdes_p2p_to_reg[] = {
1247 	/* Index of value in microvolts corresponds to the register value */
1248 	14000, 112000, 210000, 308000, 406000, 504000, 602000, 700000,
1249 };
1250 
1251 int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port,
1252 				      int val)
1253 {
1254 	bool found = false;
1255 	u16 ctrl, reg;
1256 	int err;
1257 	int i;
1258 
1259 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
1260 	if (err <= 0)
1261 		return err;
1262 
1263 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_p2p_to_reg); ++i) {
1264 		if (mv88e6352_serdes_p2p_to_reg[i] == val) {
1265 			reg = i;
1266 			found = true;
1267 			break;
1268 		}
1269 	}
1270 
1271 	if (!found)
1272 		return -EINVAL;
1273 
1274 	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_SPEC_CTRL2, &ctrl);
1275 	if (err)
1276 		return err;
1277 
1278 	ctrl &= ~MV88E6352_SERDES_OUT_AMP_MASK;
1279 	ctrl |= reg;
1280 
1281 	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_SPEC_CTRL2, ctrl);
1282 }
1283 
1284 static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane,
1285 					bool on)
1286 {
1287 	u16 reg;
1288 	int err;
1289 
1290 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1291 				    MV88E6393X_SERDES_CTRL1, &reg);
1292 	if (err)
1293 		return err;
1294 
1295 	if (on)
1296 		reg &= ~(MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1297 			 MV88E6393X_SERDES_CTRL1_RX_PDOWN);
1298 	else
1299 		reg |= MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1300 		       MV88E6393X_SERDES_CTRL1_RX_PDOWN;
1301 
1302 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1303 				      MV88E6393X_SERDES_CTRL1, reg);
1304 }
1305 
1306 static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane)
1307 {
1308 	u16 reg;
1309 	int err;
1310 
1311 	/* mv88e6393x family errata 4.6:
1312 	 * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD
1313 	 * mode or P0_mode is configured for [x]MII.
1314 	 * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
1315 	 *
1316 	 * It seems that after this workaround the SERDES is automatically
1317 	 * powered up (the bit is cleared), so power it down.
1318 	 */
1319 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1320 				    MV88E6393X_SERDES_POC, &reg);
1321 	if (err)
1322 		return err;
1323 
1324 	reg &= ~MV88E6393X_SERDES_POC_PDOWN;
1325 	reg |= MV88E6393X_SERDES_POC_RESET;
1326 
1327 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1328 				     MV88E6393X_SERDES_POC, reg);
1329 	if (err)
1330 		return err;
1331 
1332 	err = mv88e6390_serdes_power_sgmii(chip, lane, false);
1333 	if (err)
1334 		return err;
1335 
1336 	return mv88e6393x_serdes_power_lane(chip, lane, false);
1337 }
1338 
1339 int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip)
1340 {
1341 	int err;
1342 
1343 	err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT0_LANE);
1344 	if (err)
1345 		return err;
1346 
1347 	err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT9_LANE);
1348 	if (err)
1349 		return err;
1350 
1351 	return mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT10_LANE);
1352 }
1353 
1354 static int mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip *chip, int lane)
1355 {
1356 	u16 reg, pcs;
1357 	int err;
1358 
1359 	/* mv88e6393x family errata 4.8:
1360 	 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may
1361 	 * not come up after hardware reset or software reset of SERDES core.
1362 	 * Workaround is to write SERDES register 4.F074.14=1 for only those
1363 	 * modes and 0 in all other modes.
1364 	 */
1365 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1366 				    MV88E6393X_SERDES_POC, &pcs);
1367 	if (err)
1368 		return err;
1369 
1370 	pcs &= MV88E6393X_SERDES_POC_PCS_MASK;
1371 
1372 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1373 				    MV88E6393X_ERRATA_4_8_REG, &reg);
1374 	if (err)
1375 		return err;
1376 
1377 	if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX ||
1378 	    pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY ||
1379 	    pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC)
1380 		reg |= MV88E6393X_ERRATA_4_8_BIT;
1381 	else
1382 		reg &= ~MV88E6393X_ERRATA_4_8_BIT;
1383 
1384 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1385 				      MV88E6393X_ERRATA_4_8_REG, reg);
1386 }
1387 
1388 static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane,
1389 					 u8 cmode)
1390 {
1391 	static const struct {
1392 		u16 dev, reg, val, mask;
1393 	} fixes[] = {
1394 		{ MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff },
1395 		{ MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff },
1396 		{ MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff },
1397 		{ MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f },
1398 		{ MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 },
1399 		{ MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff },
1400 		{ MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC,
1401 		  MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET },
1402 	};
1403 	int err, i;
1404 	u16 reg;
1405 
1406 	/* mv88e6393x family errata 5.2:
1407 	 * For optimal signal integrity the following sequence should be applied
1408 	 * to SERDES operating in 10G mode. These registers only apply to 10G
1409 	 * operation and have no effect on other speeds.
1410 	 */
1411 	if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER &&
1412 	    cmode != MV88E6393X_PORT_STS_CMODE_USXGMII)
1413 		return 0;
1414 
1415 	for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
1416 		err = mv88e6390_serdes_read(chip, lane, fixes[i].dev,
1417 					    fixes[i].reg, &reg);
1418 		if (err)
1419 			return err;
1420 
1421 		reg &= ~fixes[i].mask;
1422 		reg |= fixes[i].val;
1423 
1424 		err = mv88e6390_serdes_write(chip, lane, fixes[i].dev,
1425 					     fixes[i].reg, reg);
1426 		if (err)
1427 			return err;
1428 	}
1429 
1430 	return 0;
1431 }
1432 
1433 static int mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip *chip,
1434 					      int lane, u8 cmode, bool on)
1435 {
1436 	u16 reg;
1437 	int err;
1438 
1439 	if (cmode != MV88E6XXX_PORT_STS_CMODE_2500BASEX)
1440 		return 0;
1441 
1442 	/* Inband AN is broken on Amethyst in 2500base-x mode when set by
1443 	 * standard mechanism (via cmode).
1444 	 * We can get around this by configuring the PCS mode to 1000base-x
1445 	 * and then writing value 0x58 to register 1e.8000. (This must be done
1446 	 * while SerDes receiver and transmitter are disabled, which is, when
1447 	 * this function is called.)
1448 	 * It seem that when we do this configuration to 2500base-x mode (by
1449 	 * changing PCS mode to 1000base-x and frequency to 3.125 GHz from
1450 	 * 1.25 GHz) and then configure to sgmii or 1000base-x, the device
1451 	 * thinks that it already has SerDes at 1.25 GHz and does not change
1452 	 * the 1e.8000 register, leaving SerDes at 3.125 GHz.
1453 	 * To avoid this, change PCS mode back to 2500base-x when disabling
1454 	 * SerDes from 2500base-x mode.
1455 	 */
1456 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1457 				    MV88E6393X_SERDES_POC, &reg);
1458 	if (err)
1459 		return err;
1460 
1461 	reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN);
1462 	if (on)
1463 		reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX |
1464 		       MV88E6393X_SERDES_POC_AN;
1465 	else
1466 		reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX;
1467 	reg |= MV88E6393X_SERDES_POC_RESET;
1468 
1469 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1470 				     MV88E6393X_SERDES_POC, reg);
1471 	if (err)
1472 		return err;
1473 
1474 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58);
1475 	if (err)
1476 		return err;
1477 
1478 	return 0;
1479 }
1480 
1481 int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
1482 			    bool on)
1483 {
1484 	u8 cmode = chip->ports[port].cmode;
1485 	int err;
1486 
1487 	if (port != 0 && port != 9 && port != 10)
1488 		return -EOPNOTSUPP;
1489 
1490 	if (on) {
1491 		err = mv88e6393x_serdes_erratum_4_8(chip, lane);
1492 		if (err)
1493 			return err;
1494 
1495 		err = mv88e6393x_serdes_erratum_5_2(chip, lane, cmode);
1496 		if (err)
1497 			return err;
1498 
1499 		err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1500 							 true);
1501 		if (err)
1502 			return err;
1503 
1504 		err = mv88e6393x_serdes_power_lane(chip, lane, true);
1505 		if (err)
1506 			return err;
1507 	}
1508 
1509 	switch (cmode) {
1510 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1511 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1512 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1513 		err = mv88e6390_serdes_power_sgmii(chip, lane, on);
1514 		break;
1515 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1516 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1517 	case MV88E6393X_PORT_STS_CMODE_USXGMII:
1518 		err = mv88e6390_serdes_power_10g(chip, lane, on);
1519 		break;
1520 	default:
1521 		err = -EINVAL;
1522 		break;
1523 	}
1524 
1525 	if (err)
1526 		return err;
1527 
1528 	if (!on) {
1529 		err = mv88e6393x_serdes_power_lane(chip, lane, false);
1530 		if (err)
1531 			return err;
1532 
1533 		err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1534 							 false);
1535 	}
1536 
1537 	return err;
1538 }
1539