xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/serdes.c (revision 05407b0e)
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 mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
464 			   bool up)
465 {
466 	/* The serdes power can't be controlled on this switch chip but we need
467 	 * to supply this function to avoid returning -EOPNOTSUPP in
468 	 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
469 	 */
470 	return 0;
471 }
472 
473 int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
474 {
475 	/* There are no configurable serdes lanes on this switch chip but we
476 	 * need to return a non-negative lane number so that callers of
477 	 * mv88e6xxx_serdes_get_lane() know this is a serdes port.
478 	 */
479 	switch (chip->ports[port].cmode) {
480 	case MV88E6185_PORT_STS_CMODE_SERDES:
481 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
482 		return 0;
483 	default:
484 		return -ENODEV;
485 	}
486 }
487 
488 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
489 				   int lane, struct phylink_link_state *state)
490 {
491 	int err;
492 	u16 status;
493 
494 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
495 	if (err)
496 		return err;
497 
498 	state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
499 
500 	if (state->link) {
501 		state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
502 
503 		switch (status &  MV88E6XXX_PORT_STS_SPEED_MASK) {
504 		case MV88E6XXX_PORT_STS_SPEED_1000:
505 			state->speed = SPEED_1000;
506 			break;
507 		case MV88E6XXX_PORT_STS_SPEED_100:
508 			state->speed = SPEED_100;
509 			break;
510 		case MV88E6XXX_PORT_STS_SPEED_10:
511 			state->speed = SPEED_10;
512 			break;
513 		default:
514 			dev_err(chip->dev, "invalid PHY speed\n");
515 			return -EINVAL;
516 		}
517 	} else {
518 		state->duplex = DUPLEX_UNKNOWN;
519 		state->speed = SPEED_UNKNOWN;
520 	}
521 
522 	return 0;
523 }
524 
525 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
526 				bool enable)
527 {
528 	u8 cmode = chip->ports[port].cmode;
529 
530 	/* The serdes interrupts are enabled in the G2_INT_MASK register. We
531 	 * need to return 0 to avoid returning -EOPNOTSUPP in
532 	 * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
533 	 */
534 	switch (cmode) {
535 	case MV88E6185_PORT_STS_CMODE_SERDES:
536 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
537 		return 0;
538 	}
539 
540 	return -EOPNOTSUPP;
541 }
542 
543 static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
544 {
545 	u16 status;
546 	int err;
547 
548 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
549 	if (err) {
550 		dev_err(chip->dev, "can't read port status: %d\n", err);
551 		return;
552 	}
553 
554 	dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
555 }
556 
557 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
558 					int lane)
559 {
560 	u8 cmode = chip->ports[port].cmode;
561 
562 	switch (cmode) {
563 	case MV88E6185_PORT_STS_CMODE_SERDES:
564 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
565 		mv88e6097_serdes_irq_link(chip, port);
566 		return IRQ_HANDLED;
567 	}
568 
569 	return IRQ_NONE;
570 }
571 
572 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
573 {
574 	u8 cmode = chip->ports[port].cmode;
575 	int lane = -ENODEV;
576 
577 	switch (port) {
578 	case 9:
579 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
580 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
581 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
582 			lane = MV88E6390_PORT9_LANE0;
583 		break;
584 	case 10:
585 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
586 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
587 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
588 			lane = MV88E6390_PORT10_LANE0;
589 		break;
590 	}
591 
592 	return lane;
593 }
594 
595 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
596 {
597 	u8 cmode_port = chip->ports[port].cmode;
598 	u8 cmode_port10 = chip->ports[10].cmode;
599 	u8 cmode_port9 = chip->ports[9].cmode;
600 	int lane = -ENODEV;
601 
602 	switch (port) {
603 	case 2:
604 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
605 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
606 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
607 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
608 				lane = MV88E6390_PORT9_LANE1;
609 		break;
610 	case 3:
611 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
612 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
613 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
614 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
615 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
616 				lane = MV88E6390_PORT9_LANE2;
617 		break;
618 	case 4:
619 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
620 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
621 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
622 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
623 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
624 				lane = MV88E6390_PORT9_LANE3;
625 		break;
626 	case 5:
627 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
628 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
629 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
630 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
631 				lane = MV88E6390_PORT10_LANE1;
632 		break;
633 	case 6:
634 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
635 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
636 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
637 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
638 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
639 				lane = MV88E6390_PORT10_LANE2;
640 		break;
641 	case 7:
642 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
643 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
644 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
645 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
646 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
647 				lane = MV88E6390_PORT10_LANE3;
648 		break;
649 	case 9:
650 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
651 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
652 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
653 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
654 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
655 			lane = MV88E6390_PORT9_LANE0;
656 		break;
657 	case 10:
658 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
659 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
660 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
661 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
662 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
663 			lane = MV88E6390_PORT10_LANE0;
664 		break;
665 	}
666 
667 	return lane;
668 }
669 
670 /* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address
671  * a port is using else Returns -ENODEV.
672  */
673 int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
674 {
675 	u8 cmode = chip->ports[port].cmode;
676 	int lane = -ENODEV;
677 
678 	if (port != 0 && port != 9 && port != 10)
679 		return -EOPNOTSUPP;
680 
681 	if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
682 	    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
683 	    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
684 	    cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
685 	    cmode == MV88E6393X_PORT_STS_CMODE_10GBASER ||
686 	    cmode == MV88E6393X_PORT_STS_CMODE_USXGMII)
687 		lane = port;
688 
689 	return lane;
690 }
691 
692 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
693 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
694 				      bool up)
695 {
696 	u16 val, new_val;
697 	int err;
698 
699 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
700 				    MV88E6390_10G_CTRL1, &val);
701 
702 	if (err)
703 		return err;
704 
705 	if (up)
706 		new_val = val & ~(MDIO_CTRL1_RESET |
707 				  MDIO_PCS_CTRL1_LOOPBACK |
708 				  MDIO_CTRL1_LPOWER);
709 	else
710 		new_val = val | MDIO_CTRL1_LPOWER;
711 
712 	if (val != new_val)
713 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
714 					     MV88E6390_10G_CTRL1, new_val);
715 
716 	return err;
717 }
718 
719 /* Set power up/down for SGMII and 1000Base-X */
720 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
721 					bool up)
722 {
723 	u16 val, new_val;
724 	int err;
725 
726 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
727 				    MV88E6390_SGMII_BMCR, &val);
728 	if (err)
729 		return err;
730 
731 	if (up)
732 		new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
733 	else
734 		new_val = val | BMCR_PDOWN;
735 
736 	if (val != new_val)
737 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
738 					     MV88E6390_SGMII_BMCR, new_val);
739 
740 	return err;
741 }
742 
743 struct mv88e6390_serdes_hw_stat {
744 	char string[ETH_GSTRING_LEN];
745 	int reg;
746 };
747 
748 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
749 	{ "serdes_rx_pkts", 0xf021 },
750 	{ "serdes_rx_bytes", 0xf024 },
751 	{ "serdes_rx_pkts_error", 0xf027 },
752 };
753 
754 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
755 {
756 	if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
757 		return 0;
758 
759 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
760 }
761 
762 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
763 				 int port, uint8_t *data)
764 {
765 	struct mv88e6390_serdes_hw_stat *stat;
766 	int i;
767 
768 	if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
769 		return 0;
770 
771 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
772 		stat = &mv88e6390_serdes_hw_stats[i];
773 		memcpy(data + i * ETH_GSTRING_LEN, stat->string,
774 		       ETH_GSTRING_LEN);
775 	}
776 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
777 }
778 
779 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
780 					  struct mv88e6390_serdes_hw_stat *stat)
781 {
782 	u16 reg[3];
783 	int err, i;
784 
785 	for (i = 0; i < 3; i++) {
786 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
787 					    stat->reg + i, &reg[i]);
788 		if (err) {
789 			dev_err(chip->dev, "failed to read statistic\n");
790 			return 0;
791 		}
792 	}
793 
794 	return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
795 }
796 
797 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
798 			       uint64_t *data)
799 {
800 	struct mv88e6390_serdes_hw_stat *stat;
801 	int lane;
802 	int i;
803 
804 	lane = mv88e6xxx_serdes_get_lane(chip, port);
805 	if (lane < 0)
806 		return 0;
807 
808 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
809 		stat = &mv88e6390_serdes_hw_stats[i];
810 		data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
811 	}
812 
813 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
814 }
815 
816 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, int lane)
817 {
818 	u16 reg;
819 	int err;
820 
821 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
822 				    MV88E6390_PG_CONTROL, &reg);
823 	if (err)
824 		return err;
825 
826 	reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
827 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
828 				      MV88E6390_PG_CONTROL, reg);
829 }
830 
831 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
832 			   bool up)
833 {
834 	u8 cmode = chip->ports[port].cmode;
835 	int err;
836 
837 	switch (cmode) {
838 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
839 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
840 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
841 		err = mv88e6390_serdes_power_sgmii(chip, lane, up);
842 		break;
843 	case MV88E6XXX_PORT_STS_CMODE_XAUI:
844 	case MV88E6XXX_PORT_STS_CMODE_RXAUI:
845 		err = mv88e6390_serdes_power_10g(chip, lane, up);
846 		break;
847 	default:
848 		err = -EINVAL;
849 		break;
850 	}
851 
852 	if (!err && up)
853 		err = mv88e6390_serdes_enable_checker(chip, lane);
854 
855 	return err;
856 }
857 
858 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
859 				int lane, unsigned int mode,
860 				phy_interface_t interface,
861 				const unsigned long *advertise)
862 {
863 	u16 val, bmcr, adv;
864 	bool changed;
865 	int err;
866 
867 	switch (interface) {
868 	case PHY_INTERFACE_MODE_SGMII:
869 		adv = 0x0001;
870 		break;
871 
872 	case PHY_INTERFACE_MODE_1000BASEX:
873 		adv = linkmode_adv_to_mii_adv_x(advertise,
874 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
875 		break;
876 
877 	case PHY_INTERFACE_MODE_2500BASEX:
878 		adv = linkmode_adv_to_mii_adv_x(advertise,
879 					ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
880 		break;
881 
882 	default:
883 		return 0;
884 	}
885 
886 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
887 				    MV88E6390_SGMII_ADVERTISE, &val);
888 	if (err)
889 		return err;
890 
891 	changed = val != adv;
892 	if (changed) {
893 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
894 					     MV88E6390_SGMII_ADVERTISE, adv);
895 		if (err)
896 			return err;
897 	}
898 
899 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
900 				    MV88E6390_SGMII_BMCR, &val);
901 	if (err)
902 		return err;
903 
904 	if (phylink_autoneg_inband(mode))
905 		bmcr = val | BMCR_ANENABLE;
906 	else
907 		bmcr = val & ~BMCR_ANENABLE;
908 
909 	/* setting ANENABLE triggers a restart of negotiation */
910 	if (bmcr == val)
911 		return changed;
912 
913 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
914 				      MV88E6390_SGMII_BMCR, bmcr);
915 }
916 
917 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
918 	int port, int lane, struct phylink_link_state *state)
919 {
920 	u16 bmsr, lpa, status;
921 	int err;
922 
923 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
924 				    MV88E6390_SGMII_BMSR, &bmsr);
925 	if (err) {
926 		dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
927 		return err;
928 	}
929 
930 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
931 				    MV88E6390_SGMII_PHY_STATUS, &status);
932 	if (err) {
933 		dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
934 		return err;
935 	}
936 
937 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
938 				    MV88E6390_SGMII_LPA, &lpa);
939 	if (err) {
940 		dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
941 		return err;
942 	}
943 
944 	return mv88e6xxx_pcs_decode_state(chip->dev, bmsr, lpa, status, state);
945 }
946 
947 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
948 	int port, int lane, struct phylink_link_state *state)
949 {
950 	u16 status;
951 	int err;
952 
953 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
954 				    MV88E6390_10G_STAT1, &status);
955 	if (err)
956 		return err;
957 
958 	state->link = !!(status & MDIO_STAT1_LSTATUS);
959 	if (state->link) {
960 		state->speed = SPEED_10000;
961 		state->duplex = DUPLEX_FULL;
962 	}
963 
964 	return 0;
965 }
966 
967 static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
968 					       int port, int lane,
969 					       struct phylink_link_state *state)
970 {
971 	u16 status;
972 	int err;
973 
974 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
975 				    MV88E6390_10G_STAT1, &status);
976 	if (err)
977 		return err;
978 
979 	state->link = !!(status & MDIO_STAT1_LSTATUS);
980 	if (state->link) {
981 		if (state->interface == PHY_INTERFACE_MODE_5GBASER)
982 			state->speed = SPEED_5000;
983 		else
984 			state->speed = SPEED_10000;
985 		state->duplex = DUPLEX_FULL;
986 	}
987 	return 0;
988 }
989 
990 /* USXGMII registers for Marvell switch 88e639x are undocumented and this function is based
991  * on some educated guesses. It appears that there are no status bits related to
992  * autonegotiation complete or flow control.
993  */
994 static int mv88e639x_serdes_pcs_get_state_usxgmii(struct mv88e6xxx_chip *chip,
995 						  int port, int lane,
996 						  struct phylink_link_state *state)
997 {
998 	u16 status, lp_status;
999 	int err;
1000 
1001 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1002 				    MV88E6390_USXGMII_PHY_STATUS, &status);
1003 	if (err) {
1004 		dev_err(chip->dev, "can't read Serdes USXGMII PHY status: %d\n", err);
1005 		return err;
1006 	}
1007 	dev_dbg(chip->dev, "USXGMII PHY status: 0x%x\n", status);
1008 
1009 	state->link = !!(status & MDIO_USXGMII_LINK);
1010 	state->an_complete = state->link;
1011 
1012 	if (state->link) {
1013 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1014 					    MV88E6390_USXGMII_LP_STATUS, &lp_status);
1015 		if (err) {
1016 			dev_err(chip->dev, "can't read Serdes USXGMII LP status: %d\n", err);
1017 			return err;
1018 		}
1019 		dev_dbg(chip->dev, "USXGMII LP status: 0x%x\n", lp_status);
1020 		/* lp_status appears to include the "link" bit as per USXGMII spec. */
1021 		phylink_decode_usxgmii_word(state, lp_status);
1022 	}
1023 	return 0;
1024 }
1025 
1026 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
1027 				   int lane, struct phylink_link_state *state)
1028 {
1029 	switch (state->interface) {
1030 	case PHY_INTERFACE_MODE_SGMII:
1031 	case PHY_INTERFACE_MODE_1000BASEX:
1032 	case PHY_INTERFACE_MODE_2500BASEX:
1033 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
1034 							    state);
1035 	case PHY_INTERFACE_MODE_XAUI:
1036 	case PHY_INTERFACE_MODE_RXAUI:
1037 		return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
1038 							  state);
1039 
1040 	default:
1041 		return -EOPNOTSUPP;
1042 	}
1043 }
1044 
1045 int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
1046 				    int lane, struct phylink_link_state *state)
1047 {
1048 	switch (state->interface) {
1049 	case PHY_INTERFACE_MODE_SGMII:
1050 	case PHY_INTERFACE_MODE_1000BASEX:
1051 	case PHY_INTERFACE_MODE_2500BASEX:
1052 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
1053 							    state);
1054 	case PHY_INTERFACE_MODE_5GBASER:
1055 	case PHY_INTERFACE_MODE_10GBASER:
1056 		return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane,
1057 							   state);
1058 	case PHY_INTERFACE_MODE_USXGMII:
1059 		return mv88e639x_serdes_pcs_get_state_usxgmii(chip, port, lane,
1060 							   state);
1061 
1062 	default:
1063 		return -EOPNOTSUPP;
1064 	}
1065 }
1066 
1067 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
1068 				    int lane)
1069 {
1070 	u16 bmcr;
1071 	int err;
1072 
1073 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1074 				    MV88E6390_SGMII_BMCR, &bmcr);
1075 	if (err)
1076 		return err;
1077 
1078 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1079 				      MV88E6390_SGMII_BMCR,
1080 				      bmcr | BMCR_ANRESTART);
1081 }
1082 
1083 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
1084 				 int lane, int speed, int duplex)
1085 {
1086 	u16 val, bmcr;
1087 	int err;
1088 
1089 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1090 				    MV88E6390_SGMII_BMCR, &val);
1091 	if (err)
1092 		return err;
1093 
1094 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
1095 	switch (speed) {
1096 	case SPEED_2500:
1097 	case SPEED_1000:
1098 		bmcr |= BMCR_SPEED1000;
1099 		break;
1100 	case SPEED_100:
1101 		bmcr |= BMCR_SPEED100;
1102 		break;
1103 	case SPEED_10:
1104 		break;
1105 	}
1106 
1107 	if (duplex == DUPLEX_FULL)
1108 		bmcr |= BMCR_FULLDPLX;
1109 
1110 	if (bmcr == val)
1111 		return 0;
1112 
1113 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1114 				      MV88E6390_SGMII_BMCR, bmcr);
1115 }
1116 
1117 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
1118 					    int port, int lane)
1119 {
1120 	u16 bmsr;
1121 	int err;
1122 
1123 	/* If the link has dropped, we want to know about it. */
1124 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1125 				    MV88E6390_SGMII_BMSR, &bmsr);
1126 	if (err) {
1127 		dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
1128 		return;
1129 	}
1130 
1131 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
1132 }
1133 
1134 static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip,
1135 					   int port, u8 lane)
1136 {
1137 	u16 status;
1138 	int err;
1139 
1140 	/* If the link has dropped, we want to know about it. */
1141 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1142 				    MV88E6390_10G_STAT1, &status);
1143 	if (err) {
1144 		dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err);
1145 		return;
1146 	}
1147 
1148 	dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS));
1149 }
1150 
1151 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
1152 					     int lane, bool enable)
1153 {
1154 	u16 val = 0;
1155 
1156 	if (enable)
1157 		val |= MV88E6390_SGMII_INT_LINK_DOWN |
1158 			MV88E6390_SGMII_INT_LINK_UP;
1159 
1160 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1161 				      MV88E6390_SGMII_INT_ENABLE, val);
1162 }
1163 
1164 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1165 				bool enable)
1166 {
1167 	u8 cmode = chip->ports[port].cmode;
1168 
1169 	switch (cmode) {
1170 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1171 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1172 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1173 		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1174 	}
1175 
1176 	return 0;
1177 }
1178 
1179 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1180 					     int lane, u16 *status)
1181 {
1182 	int err;
1183 
1184 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1185 				    MV88E6390_SGMII_INT_STATUS, status);
1186 
1187 	return err;
1188 }
1189 
1190 static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip,
1191 					    u8 lane, bool enable)
1192 {
1193 	u16 val = 0;
1194 
1195 	if (enable)
1196 		val |= MV88E6393X_10G_INT_LINK_CHANGE;
1197 
1198 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1199 				      MV88E6393X_10G_INT_ENABLE, val);
1200 }
1201 
1202 int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
1203 				 int lane, bool enable)
1204 {
1205 	u8 cmode = chip->ports[port].cmode;
1206 
1207 	switch (cmode) {
1208 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1209 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1210 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1211 		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1212 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1213 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1214 	case MV88E6393X_PORT_STS_CMODE_USXGMII:
1215 		return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
1216 	}
1217 
1218 	return 0;
1219 }
1220 
1221 static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip,
1222 					    u8 lane, u16 *status)
1223 {
1224 	int err;
1225 
1226 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1227 				    MV88E6393X_10G_INT_STATUS, status);
1228 
1229 	return err;
1230 }
1231 
1232 irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1233 					 int lane)
1234 {
1235 	u8 cmode = chip->ports[port].cmode;
1236 	irqreturn_t ret = IRQ_NONE;
1237 	u16 status;
1238 	int err;
1239 
1240 	switch (cmode) {
1241 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1242 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1243 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1244 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1245 		if (err)
1246 			return ret;
1247 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1248 			      MV88E6390_SGMII_INT_LINK_UP)) {
1249 			ret = IRQ_HANDLED;
1250 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1251 		}
1252 		break;
1253 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1254 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1255 	case MV88E6393X_PORT_STS_CMODE_USXGMII:
1256 		err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
1257 		if (err)
1258 			return err;
1259 		if (status & MV88E6393X_10G_INT_LINK_CHANGE) {
1260 			ret = IRQ_HANDLED;
1261 			mv88e6393x_serdes_irq_link_10g(chip, port, lane);
1262 		}
1263 		break;
1264 	}
1265 
1266 	return ret;
1267 }
1268 
1269 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1270 					int lane)
1271 {
1272 	u8 cmode = chip->ports[port].cmode;
1273 	irqreturn_t ret = IRQ_NONE;
1274 	u16 status;
1275 	int err;
1276 
1277 	switch (cmode) {
1278 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1279 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1280 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1281 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1282 		if (err)
1283 			return ret;
1284 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1285 			      MV88E6390_SGMII_INT_LINK_UP)) {
1286 			ret = IRQ_HANDLED;
1287 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1288 		}
1289 	}
1290 
1291 	return ret;
1292 }
1293 
1294 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1295 {
1296 	return irq_find_mapping(chip->g2_irq.domain, port);
1297 }
1298 
1299 static const u16 mv88e6390_serdes_regs[] = {
1300 	/* SERDES common registers */
1301 	0xf00a, 0xf00b, 0xf00c,
1302 	0xf010, 0xf011, 0xf012, 0xf013,
1303 	0xf016, 0xf017, 0xf018,
1304 	0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1305 	0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1306 	0xf028, 0xf029,
1307 	0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1308 	0xf038, 0xf039,
1309 	/* SGMII */
1310 	0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1311 	0x2008,
1312 	0x200f,
1313 	0xa000, 0xa001, 0xa002, 0xa003,
1314 	/* 10Gbase-X */
1315 	0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1316 	0x1008,
1317 	0x100e, 0x100f,
1318 	0x1018, 0x1019,
1319 	0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1320 	0x9006,
1321 	0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1322 	/* 10Gbase-R */
1323 	0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1324 	0x1028, 0x1029, 0x102a, 0x102b,
1325 };
1326 
1327 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1328 {
1329 	if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
1330 		return 0;
1331 
1332 	return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1333 }
1334 
1335 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1336 {
1337 	u16 *p = _p;
1338 	int lane;
1339 	u16 reg;
1340 	int err;
1341 	int i;
1342 
1343 	lane = mv88e6xxx_serdes_get_lane(chip, port);
1344 	if (lane < 0)
1345 		return;
1346 
1347 	for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1348 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1349 					    mv88e6390_serdes_regs[i], &reg);
1350 		if (!err)
1351 			p[i] = reg;
1352 	}
1353 }
1354 
1355 static const int mv88e6352_serdes_p2p_to_reg[] = {
1356 	/* Index of value in microvolts corresponds to the register value */
1357 	14000, 112000, 210000, 308000, 406000, 504000, 602000, 700000,
1358 };
1359 
1360 int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port,
1361 				      int val)
1362 {
1363 	bool found = false;
1364 	u16 ctrl, reg;
1365 	int err;
1366 	int i;
1367 
1368 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
1369 	if (err <= 0)
1370 		return err;
1371 
1372 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_p2p_to_reg); ++i) {
1373 		if (mv88e6352_serdes_p2p_to_reg[i] == val) {
1374 			reg = i;
1375 			found = true;
1376 			break;
1377 		}
1378 	}
1379 
1380 	if (!found)
1381 		return -EINVAL;
1382 
1383 	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_SPEC_CTRL2, &ctrl);
1384 	if (err)
1385 		return err;
1386 
1387 	ctrl &= ~MV88E6352_SERDES_OUT_AMP_MASK;
1388 	ctrl |= reg;
1389 
1390 	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_SPEC_CTRL2, ctrl);
1391 }
1392 
1393 static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane,
1394 					bool on)
1395 {
1396 	u16 reg;
1397 	int err;
1398 
1399 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1400 				    MV88E6393X_SERDES_CTRL1, &reg);
1401 	if (err)
1402 		return err;
1403 
1404 	if (on)
1405 		reg &= ~(MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1406 			 MV88E6393X_SERDES_CTRL1_RX_PDOWN);
1407 	else
1408 		reg |= MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1409 		       MV88E6393X_SERDES_CTRL1_RX_PDOWN;
1410 
1411 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1412 				      MV88E6393X_SERDES_CTRL1, reg);
1413 }
1414 
1415 static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane)
1416 {
1417 	u16 reg;
1418 	int err;
1419 
1420 	/* mv88e6393x family errata 4.6:
1421 	 * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD
1422 	 * mode or P0_mode is configured for [x]MII.
1423 	 * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
1424 	 *
1425 	 * It seems that after this workaround the SERDES is automatically
1426 	 * powered up (the bit is cleared), so power it down.
1427 	 */
1428 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1429 				    MV88E6393X_SERDES_POC, &reg);
1430 	if (err)
1431 		return err;
1432 
1433 	reg &= ~MV88E6393X_SERDES_POC_PDOWN;
1434 	reg |= MV88E6393X_SERDES_POC_RESET;
1435 
1436 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1437 				     MV88E6393X_SERDES_POC, reg);
1438 	if (err)
1439 		return err;
1440 
1441 	err = mv88e6390_serdes_power_sgmii(chip, lane, false);
1442 	if (err)
1443 		return err;
1444 
1445 	return mv88e6393x_serdes_power_lane(chip, lane, false);
1446 }
1447 
1448 int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip)
1449 {
1450 	int err;
1451 
1452 	err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT0_LANE);
1453 	if (err)
1454 		return err;
1455 
1456 	err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT9_LANE);
1457 	if (err)
1458 		return err;
1459 
1460 	return mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT10_LANE);
1461 }
1462 
1463 static int mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip *chip, int lane)
1464 {
1465 	u16 reg, pcs;
1466 	int err;
1467 
1468 	/* mv88e6393x family errata 4.8:
1469 	 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may
1470 	 * not come up after hardware reset or software reset of SERDES core.
1471 	 * Workaround is to write SERDES register 4.F074.14=1 for only those
1472 	 * modes and 0 in all other modes.
1473 	 */
1474 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1475 				    MV88E6393X_SERDES_POC, &pcs);
1476 	if (err)
1477 		return err;
1478 
1479 	pcs &= MV88E6393X_SERDES_POC_PCS_MASK;
1480 
1481 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1482 				    MV88E6393X_ERRATA_4_8_REG, &reg);
1483 	if (err)
1484 		return err;
1485 
1486 	if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX ||
1487 	    pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY ||
1488 	    pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC)
1489 		reg |= MV88E6393X_ERRATA_4_8_BIT;
1490 	else
1491 		reg &= ~MV88E6393X_ERRATA_4_8_BIT;
1492 
1493 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1494 				      MV88E6393X_ERRATA_4_8_REG, reg);
1495 }
1496 
1497 static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane,
1498 					 u8 cmode)
1499 {
1500 	static const struct {
1501 		u16 dev, reg, val, mask;
1502 	} fixes[] = {
1503 		{ MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff },
1504 		{ MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff },
1505 		{ MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff },
1506 		{ MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f },
1507 		{ MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 },
1508 		{ MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff },
1509 		{ MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC,
1510 		  MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET },
1511 	};
1512 	int err, i;
1513 	u16 reg;
1514 
1515 	/* mv88e6393x family errata 5.2:
1516 	 * For optimal signal integrity the following sequence should be applied
1517 	 * to SERDES operating in 10G mode. These registers only apply to 10G
1518 	 * operation and have no effect on other speeds.
1519 	 */
1520 	if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER &&
1521 	    cmode != MV88E6393X_PORT_STS_CMODE_USXGMII)
1522 		return 0;
1523 
1524 	for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
1525 		err = mv88e6390_serdes_read(chip, lane, fixes[i].dev,
1526 					    fixes[i].reg, &reg);
1527 		if (err)
1528 			return err;
1529 
1530 		reg &= ~fixes[i].mask;
1531 		reg |= fixes[i].val;
1532 
1533 		err = mv88e6390_serdes_write(chip, lane, fixes[i].dev,
1534 					     fixes[i].reg, reg);
1535 		if (err)
1536 			return err;
1537 	}
1538 
1539 	return 0;
1540 }
1541 
1542 static int mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip *chip,
1543 					      int lane, u8 cmode, bool on)
1544 {
1545 	u16 reg;
1546 	int err;
1547 
1548 	if (cmode != MV88E6XXX_PORT_STS_CMODE_2500BASEX)
1549 		return 0;
1550 
1551 	/* Inband AN is broken on Amethyst in 2500base-x mode when set by
1552 	 * standard mechanism (via cmode).
1553 	 * We can get around this by configuring the PCS mode to 1000base-x
1554 	 * and then writing value 0x58 to register 1e.8000. (This must be done
1555 	 * while SerDes receiver and transmitter are disabled, which is, when
1556 	 * this function is called.)
1557 	 * It seem that when we do this configuration to 2500base-x mode (by
1558 	 * changing PCS mode to 1000base-x and frequency to 3.125 GHz from
1559 	 * 1.25 GHz) and then configure to sgmii or 1000base-x, the device
1560 	 * thinks that it already has SerDes at 1.25 GHz and does not change
1561 	 * the 1e.8000 register, leaving SerDes at 3.125 GHz.
1562 	 * To avoid this, change PCS mode back to 2500base-x when disabling
1563 	 * SerDes from 2500base-x mode.
1564 	 */
1565 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1566 				    MV88E6393X_SERDES_POC, &reg);
1567 	if (err)
1568 		return err;
1569 
1570 	reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN);
1571 	if (on)
1572 		reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX |
1573 		       MV88E6393X_SERDES_POC_AN;
1574 	else
1575 		reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX;
1576 	reg |= MV88E6393X_SERDES_POC_RESET;
1577 
1578 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1579 				     MV88E6393X_SERDES_POC, reg);
1580 	if (err)
1581 		return err;
1582 
1583 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58);
1584 	if (err)
1585 		return err;
1586 
1587 	return 0;
1588 }
1589 
1590 int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
1591 			    bool on)
1592 {
1593 	u8 cmode = chip->ports[port].cmode;
1594 	int err;
1595 
1596 	if (port != 0 && port != 9 && port != 10)
1597 		return -EOPNOTSUPP;
1598 
1599 	if (on) {
1600 		err = mv88e6393x_serdes_erratum_4_8(chip, lane);
1601 		if (err)
1602 			return err;
1603 
1604 		err = mv88e6393x_serdes_erratum_5_2(chip, lane, cmode);
1605 		if (err)
1606 			return err;
1607 
1608 		err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1609 							 true);
1610 		if (err)
1611 			return err;
1612 
1613 		err = mv88e6393x_serdes_power_lane(chip, lane, true);
1614 		if (err)
1615 			return err;
1616 	}
1617 
1618 	switch (cmode) {
1619 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1620 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1621 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1622 		err = mv88e6390_serdes_power_sgmii(chip, lane, on);
1623 		break;
1624 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1625 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1626 	case MV88E6393X_PORT_STS_CMODE_USXGMII:
1627 		err = mv88e6390_serdes_power_10g(chip, lane, on);
1628 		break;
1629 	default:
1630 		err = -EINVAL;
1631 		break;
1632 	}
1633 
1634 	if (err)
1635 		return err;
1636 
1637 	if (!on) {
1638 		err = mv88e6393x_serdes_power_lane(chip, lane, false);
1639 		if (err)
1640 			return err;
1641 
1642 		err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1643 							 false);
1644 	}
1645 
1646 	return err;
1647 }
1648