xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/serdes.c (revision 3db55767)
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 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
49 					  u16 bmsr, u16 lpa, u16 status,
50 					  struct phylink_link_state *state)
51 {
52 	state->link = false;
53 
54 	/* If the BMSR reports that the link had failed, report this to
55 	 * phylink.
56 	 */
57 	if (!(bmsr & BMSR_LSTATUS))
58 		return 0;
59 
60 	state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
61 	state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
62 
63 	if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
64 		/* The Spped and Duplex Resolved register is 1 if AN is enabled
65 		 * and complete, or if AN is disabled. So with disabled AN we
66 		 * still get here on link up.
67 		 */
68 		state->duplex = status &
69 				MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
70 			                         DUPLEX_FULL : DUPLEX_HALF;
71 
72 		if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
73 			state->pause |= MLO_PAUSE_TX;
74 		if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
75 			state->pause |= MLO_PAUSE_RX;
76 
77 		switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
78 		case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
79 			if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
80 				state->speed = SPEED_2500;
81 			else
82 				state->speed = SPEED_1000;
83 			break;
84 		case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
85 			state->speed = SPEED_100;
86 			break;
87 		case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
88 			state->speed = SPEED_10;
89 			break;
90 		default:
91 			dev_err(chip->dev, "invalid PHY speed\n");
92 			return -EINVAL;
93 		}
94 	} else if (state->link &&
95 		   state->interface != PHY_INTERFACE_MODE_SGMII) {
96 		/* If Speed and Duplex Resolved register is 0 and link is up, it
97 		 * means that AN was enabled, but link partner had it disabled
98 		 * and the PHY invoked the Auto-Negotiation Bypass feature and
99 		 * linked anyway.
100 		 */
101 		state->duplex = DUPLEX_FULL;
102 		if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
103 			state->speed = SPEED_2500;
104 		else
105 			state->speed = SPEED_1000;
106 	} else {
107 		state->link = false;
108 	}
109 
110 	if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
111 		mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
112 				       ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
113 	else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
114 		mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
115 				       ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
116 
117 	return 0;
118 }
119 
120 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
121 			   bool up)
122 {
123 	u16 val, new_val;
124 	int err;
125 
126 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
127 	if (err)
128 		return err;
129 
130 	if (up)
131 		new_val = val & ~BMCR_PDOWN;
132 	else
133 		new_val = val | BMCR_PDOWN;
134 
135 	if (val != new_val)
136 		err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
137 
138 	return err;
139 }
140 
141 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
142 				int lane, unsigned int mode,
143 				phy_interface_t interface,
144 				const unsigned long *advertise)
145 {
146 	u16 adv, bmcr, val;
147 	bool changed;
148 	int err;
149 
150 	switch (interface) {
151 	case PHY_INTERFACE_MODE_SGMII:
152 		adv = 0x0001;
153 		break;
154 
155 	case PHY_INTERFACE_MODE_1000BASEX:
156 		adv = linkmode_adv_to_mii_adv_x(advertise,
157 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
158 		break;
159 
160 	default:
161 		return 0;
162 	}
163 
164 	err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
165 	if (err)
166 		return err;
167 
168 	changed = val != adv;
169 	if (changed) {
170 		err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
171 		if (err)
172 			return err;
173 	}
174 
175 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
176 	if (err)
177 		return err;
178 
179 	if (phylink_autoneg_inband(mode))
180 		bmcr = val | BMCR_ANENABLE;
181 	else
182 		bmcr = val & ~BMCR_ANENABLE;
183 
184 	if (bmcr == val)
185 		return changed;
186 
187 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
188 }
189 
190 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
191 				   int lane, struct phylink_link_state *state)
192 {
193 	u16 bmsr, lpa, status;
194 	int err;
195 
196 	err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
197 	if (err) {
198 		dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
199 		return err;
200 	}
201 
202 	err = mv88e6352_serdes_read(chip, 0x11, &status);
203 	if (err) {
204 		dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
205 		return err;
206 	}
207 
208 	err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
209 	if (err) {
210 		dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
211 		return err;
212 	}
213 
214 	return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
215 }
216 
217 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
218 				    int lane)
219 {
220 	u16 bmcr;
221 	int err;
222 
223 	err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
224 	if (err)
225 		return err;
226 
227 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
228 }
229 
230 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
231 				 int lane, int speed, int duplex)
232 {
233 	u16 val, bmcr;
234 	int err;
235 
236 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
237 	if (err)
238 		return err;
239 
240 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
241 	switch (speed) {
242 	case SPEED_1000:
243 		bmcr |= BMCR_SPEED1000;
244 		break;
245 	case SPEED_100:
246 		bmcr |= BMCR_SPEED100;
247 		break;
248 	case SPEED_10:
249 		break;
250 	}
251 
252 	if (duplex == DUPLEX_FULL)
253 		bmcr |= BMCR_FULLDPLX;
254 
255 	if (bmcr == val)
256 		return 0;
257 
258 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
259 }
260 
261 int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
262 {
263 	u8 cmode = chip->ports[port].cmode;
264 	int lane = -ENODEV;
265 
266 	if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
267 	    (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
268 	    (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
269 		lane = 0xff; /* Unused */
270 
271 	return lane;
272 }
273 
274 struct mv88e6352_serdes_hw_stat {
275 	char string[ETH_GSTRING_LEN];
276 	int sizeof_stat;
277 	int reg;
278 };
279 
280 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
281 	{ "serdes_fibre_rx_error", 16, 21 },
282 	{ "serdes_PRBS_error", 32, 24 },
283 };
284 
285 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
286 {
287 	int err;
288 
289 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
290 	if (err <= 0)
291 		return err;
292 
293 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
294 }
295 
296 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
297 				 int port, uint8_t *data)
298 {
299 	struct mv88e6352_serdes_hw_stat *stat;
300 	int err, i;
301 
302 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
303 	if (err <= 0)
304 		return err;
305 
306 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
307 		stat = &mv88e6352_serdes_hw_stats[i];
308 		memcpy(data + i * ETH_GSTRING_LEN, stat->string,
309 		       ETH_GSTRING_LEN);
310 	}
311 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
312 }
313 
314 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
315 					  struct mv88e6352_serdes_hw_stat *stat)
316 {
317 	u64 val = 0;
318 	u16 reg;
319 	int err;
320 
321 	err = mv88e6352_serdes_read(chip, stat->reg, &reg);
322 	if (err) {
323 		dev_err(chip->dev, "failed to read statistic\n");
324 		return 0;
325 	}
326 
327 	val = reg;
328 
329 	if (stat->sizeof_stat == 32) {
330 		err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
331 		if (err) {
332 			dev_err(chip->dev, "failed to read statistic\n");
333 			return 0;
334 		}
335 		val = val << 16 | reg;
336 	}
337 
338 	return val;
339 }
340 
341 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
342 			       uint64_t *data)
343 {
344 	struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
345 	struct mv88e6352_serdes_hw_stat *stat;
346 	int i, err;
347 	u64 value;
348 
349 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
350 	if (err <= 0)
351 		return err;
352 
353 	BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
354 		     ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
355 
356 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
357 		stat = &mv88e6352_serdes_hw_stats[i];
358 		value = mv88e6352_serdes_get_stat(chip, stat);
359 		mv88e6xxx_port->serdes_stats[i] += value;
360 		data[i] = mv88e6xxx_port->serdes_stats[i];
361 	}
362 
363 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
364 }
365 
366 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
367 {
368 	u16 bmsr;
369 	int err;
370 
371 	/* If the link has dropped, we want to know about it. */
372 	err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
373 	if (err) {
374 		dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
375 		return;
376 	}
377 
378 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
379 }
380 
381 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
382 					int lane)
383 {
384 	irqreturn_t ret = IRQ_NONE;
385 	u16 status;
386 	int err;
387 
388 	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
389 	if (err)
390 		return ret;
391 
392 	if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
393 		ret = IRQ_HANDLED;
394 		mv88e6352_serdes_irq_link(chip, port);
395 	}
396 
397 	return ret;
398 }
399 
400 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
401 				bool enable)
402 {
403 	u16 val = 0;
404 
405 	if (enable)
406 		val |= MV88E6352_SERDES_INT_LINK_CHANGE;
407 
408 	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
409 }
410 
411 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
412 {
413 	return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
414 }
415 
416 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
417 {
418 	int err;
419 
420 	mv88e6xxx_reg_lock(chip);
421 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
422 	mv88e6xxx_reg_unlock(chip);
423 	if (err <= 0)
424 		return err;
425 
426 	return 32 * sizeof(u16);
427 }
428 
429 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
430 {
431 	u16 *p = _p;
432 	u16 reg;
433 	int err;
434 	int i;
435 
436 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
437 	if (err <= 0)
438 		return;
439 
440 	for (i = 0 ; i < 32; i++) {
441 		err = mv88e6352_serdes_read(chip, i, &reg);
442 		if (!err)
443 			p[i] = reg;
444 	}
445 }
446 
447 int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
448 {
449 	u8 cmode = chip->ports[port].cmode;
450 	int lane = -ENODEV;
451 
452 	switch (port) {
453 	case 5:
454 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
455 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
456 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
457 			lane = MV88E6341_PORT5_LANE;
458 		break;
459 	}
460 
461 	return lane;
462 }
463 
464 int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
465 			   bool up)
466 {
467 	/* The serdes power can't be controlled on this switch chip but we need
468 	 * to supply this function to avoid returning -EOPNOTSUPP in
469 	 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
470 	 */
471 	return 0;
472 }
473 
474 int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
475 {
476 	/* There are no configurable serdes lanes on this switch chip but we
477 	 * need to return a non-negative lane number so that callers of
478 	 * mv88e6xxx_serdes_get_lane() know this is a serdes port.
479 	 */
480 	switch (chip->ports[port].cmode) {
481 	case MV88E6185_PORT_STS_CMODE_SERDES:
482 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
483 		return 0;
484 	default:
485 		return -ENODEV;
486 	}
487 }
488 
489 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
490 				   int lane, struct phylink_link_state *state)
491 {
492 	int err;
493 	u16 status;
494 
495 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
496 	if (err)
497 		return err;
498 
499 	state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
500 
501 	if (state->link) {
502 		state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
503 
504 		switch (status &  MV88E6XXX_PORT_STS_SPEED_MASK) {
505 		case MV88E6XXX_PORT_STS_SPEED_1000:
506 			state->speed = SPEED_1000;
507 			break;
508 		case MV88E6XXX_PORT_STS_SPEED_100:
509 			state->speed = SPEED_100;
510 			break;
511 		case MV88E6XXX_PORT_STS_SPEED_10:
512 			state->speed = SPEED_10;
513 			break;
514 		default:
515 			dev_err(chip->dev, "invalid PHY speed\n");
516 			return -EINVAL;
517 		}
518 	} else {
519 		state->duplex = DUPLEX_UNKNOWN;
520 		state->speed = SPEED_UNKNOWN;
521 	}
522 
523 	return 0;
524 }
525 
526 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
527 				bool enable)
528 {
529 	u8 cmode = chip->ports[port].cmode;
530 
531 	/* The serdes interrupts are enabled in the G2_INT_MASK register. We
532 	 * need to return 0 to avoid returning -EOPNOTSUPP in
533 	 * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
534 	 */
535 	switch (cmode) {
536 	case MV88E6185_PORT_STS_CMODE_SERDES:
537 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
538 		return 0;
539 	}
540 
541 	return -EOPNOTSUPP;
542 }
543 
544 static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
545 {
546 	u16 status;
547 	int err;
548 
549 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
550 	if (err) {
551 		dev_err(chip->dev, "can't read port status: %d\n", err);
552 		return;
553 	}
554 
555 	dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
556 }
557 
558 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
559 					int lane)
560 {
561 	u8 cmode = chip->ports[port].cmode;
562 
563 	switch (cmode) {
564 	case MV88E6185_PORT_STS_CMODE_SERDES:
565 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
566 		mv88e6097_serdes_irq_link(chip, port);
567 		return IRQ_HANDLED;
568 	}
569 
570 	return IRQ_NONE;
571 }
572 
573 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
574 {
575 	u8 cmode = chip->ports[port].cmode;
576 	int lane = -ENODEV;
577 
578 	switch (port) {
579 	case 9:
580 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
581 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
582 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
583 			lane = MV88E6390_PORT9_LANE0;
584 		break;
585 	case 10:
586 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
587 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
588 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
589 			lane = MV88E6390_PORT10_LANE0;
590 		break;
591 	}
592 
593 	return lane;
594 }
595 
596 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
597 {
598 	u8 cmode_port = chip->ports[port].cmode;
599 	u8 cmode_port10 = chip->ports[10].cmode;
600 	u8 cmode_port9 = chip->ports[9].cmode;
601 	int lane = -ENODEV;
602 
603 	switch (port) {
604 	case 2:
605 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
606 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
607 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
608 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
609 				lane = MV88E6390_PORT9_LANE1;
610 		break;
611 	case 3:
612 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
613 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
614 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
615 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
616 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
617 				lane = MV88E6390_PORT9_LANE2;
618 		break;
619 	case 4:
620 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
621 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
622 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
623 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
624 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
625 				lane = MV88E6390_PORT9_LANE3;
626 		break;
627 	case 5:
628 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
629 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
630 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
631 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
632 				lane = MV88E6390_PORT10_LANE1;
633 		break;
634 	case 6:
635 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
636 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
637 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
638 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
639 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
640 				lane = MV88E6390_PORT10_LANE2;
641 		break;
642 	case 7:
643 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
644 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
645 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
646 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
647 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
648 				lane = MV88E6390_PORT10_LANE3;
649 		break;
650 	case 9:
651 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
652 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
653 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
654 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
655 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
656 			lane = MV88E6390_PORT9_LANE0;
657 		break;
658 	case 10:
659 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
660 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
661 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
662 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
663 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
664 			lane = MV88E6390_PORT10_LANE0;
665 		break;
666 	}
667 
668 	return lane;
669 }
670 
671 /* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address
672  * a port is using else Returns -ENODEV.
673  */
674 int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
675 {
676 	u8 cmode = chip->ports[port].cmode;
677 	int lane = -ENODEV;
678 
679 	if (port != 0 && port != 9 && port != 10)
680 		return -EOPNOTSUPP;
681 
682 	if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
683 	    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
684 	    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
685 	    cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
686 	    cmode == MV88E6393X_PORT_STS_CMODE_10GBASER)
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_serdes_pcs_get_state(chip, 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 
988 	return 0;
989 }
990 
991 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
992 				   int lane, struct phylink_link_state *state)
993 {
994 	switch (state->interface) {
995 	case PHY_INTERFACE_MODE_SGMII:
996 	case PHY_INTERFACE_MODE_1000BASEX:
997 	case PHY_INTERFACE_MODE_2500BASEX:
998 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
999 							    state);
1000 	case PHY_INTERFACE_MODE_XAUI:
1001 	case PHY_INTERFACE_MODE_RXAUI:
1002 		return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
1003 							  state);
1004 
1005 	default:
1006 		return -EOPNOTSUPP;
1007 	}
1008 }
1009 
1010 int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
1011 				    int lane, struct phylink_link_state *state)
1012 {
1013 	switch (state->interface) {
1014 	case PHY_INTERFACE_MODE_SGMII:
1015 	case PHY_INTERFACE_MODE_1000BASEX:
1016 	case PHY_INTERFACE_MODE_2500BASEX:
1017 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
1018 							    state);
1019 	case PHY_INTERFACE_MODE_5GBASER:
1020 	case PHY_INTERFACE_MODE_10GBASER:
1021 		return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane,
1022 							   state);
1023 
1024 	default:
1025 		return -EOPNOTSUPP;
1026 	}
1027 }
1028 
1029 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
1030 				    int lane)
1031 {
1032 	u16 bmcr;
1033 	int err;
1034 
1035 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1036 				    MV88E6390_SGMII_BMCR, &bmcr);
1037 	if (err)
1038 		return err;
1039 
1040 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1041 				      MV88E6390_SGMII_BMCR,
1042 				      bmcr | BMCR_ANRESTART);
1043 }
1044 
1045 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
1046 				 int lane, int speed, int duplex)
1047 {
1048 	u16 val, bmcr;
1049 	int err;
1050 
1051 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1052 				    MV88E6390_SGMII_BMCR, &val);
1053 	if (err)
1054 		return err;
1055 
1056 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
1057 	switch (speed) {
1058 	case SPEED_2500:
1059 	case SPEED_1000:
1060 		bmcr |= BMCR_SPEED1000;
1061 		break;
1062 	case SPEED_100:
1063 		bmcr |= BMCR_SPEED100;
1064 		break;
1065 	case SPEED_10:
1066 		break;
1067 	}
1068 
1069 	if (duplex == DUPLEX_FULL)
1070 		bmcr |= BMCR_FULLDPLX;
1071 
1072 	if (bmcr == val)
1073 		return 0;
1074 
1075 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1076 				      MV88E6390_SGMII_BMCR, bmcr);
1077 }
1078 
1079 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
1080 					    int port, int lane)
1081 {
1082 	u16 bmsr;
1083 	int err;
1084 
1085 	/* If the link has dropped, we want to know about it. */
1086 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1087 				    MV88E6390_SGMII_BMSR, &bmsr);
1088 	if (err) {
1089 		dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
1090 		return;
1091 	}
1092 
1093 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
1094 }
1095 
1096 static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip,
1097 					   int port, u8 lane)
1098 {
1099 	u16 status;
1100 	int err;
1101 
1102 	/* If the link has dropped, we want to know about it. */
1103 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1104 				    MV88E6390_10G_STAT1, &status);
1105 	if (err) {
1106 		dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err);
1107 		return;
1108 	}
1109 
1110 	dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS));
1111 }
1112 
1113 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
1114 					     int lane, bool enable)
1115 {
1116 	u16 val = 0;
1117 
1118 	if (enable)
1119 		val |= MV88E6390_SGMII_INT_LINK_DOWN |
1120 			MV88E6390_SGMII_INT_LINK_UP;
1121 
1122 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1123 				      MV88E6390_SGMII_INT_ENABLE, val);
1124 }
1125 
1126 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1127 				bool enable)
1128 {
1129 	u8 cmode = chip->ports[port].cmode;
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 		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1136 	}
1137 
1138 	return 0;
1139 }
1140 
1141 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1142 					     int lane, u16 *status)
1143 {
1144 	int err;
1145 
1146 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1147 				    MV88E6390_SGMII_INT_STATUS, status);
1148 
1149 	return err;
1150 }
1151 
1152 static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip,
1153 					    u8 lane, bool enable)
1154 {
1155 	u16 val = 0;
1156 
1157 	if (enable)
1158 		val |= MV88E6393X_10G_INT_LINK_CHANGE;
1159 
1160 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1161 				      MV88E6393X_10G_INT_ENABLE, val);
1162 }
1163 
1164 int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
1165 				 int lane, 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 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1175 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1176 		return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
1177 	}
1178 
1179 	return 0;
1180 }
1181 
1182 static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip,
1183 					    u8 lane, u16 *status)
1184 {
1185 	int err;
1186 
1187 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1188 				    MV88E6393X_10G_INT_STATUS, status);
1189 
1190 	return err;
1191 }
1192 
1193 irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1194 					 int lane)
1195 {
1196 	u8 cmode = chip->ports[port].cmode;
1197 	irqreturn_t ret = IRQ_NONE;
1198 	u16 status;
1199 	int err;
1200 
1201 	switch (cmode) {
1202 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1203 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1204 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1205 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1206 		if (err)
1207 			return ret;
1208 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1209 			      MV88E6390_SGMII_INT_LINK_UP)) {
1210 			ret = IRQ_HANDLED;
1211 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1212 		}
1213 		break;
1214 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1215 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1216 		err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
1217 		if (err)
1218 			return err;
1219 		if (status & MV88E6393X_10G_INT_LINK_CHANGE) {
1220 			ret = IRQ_HANDLED;
1221 			mv88e6393x_serdes_irq_link_10g(chip, port, lane);
1222 		}
1223 		break;
1224 	}
1225 
1226 	return ret;
1227 }
1228 
1229 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1230 					int lane)
1231 {
1232 	u8 cmode = chip->ports[port].cmode;
1233 	irqreturn_t ret = IRQ_NONE;
1234 	u16 status;
1235 	int err;
1236 
1237 	switch (cmode) {
1238 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1239 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1240 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1241 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1242 		if (err)
1243 			return ret;
1244 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1245 			      MV88E6390_SGMII_INT_LINK_UP)) {
1246 			ret = IRQ_HANDLED;
1247 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1248 		}
1249 	}
1250 
1251 	return ret;
1252 }
1253 
1254 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1255 {
1256 	return irq_find_mapping(chip->g2_irq.domain, port);
1257 }
1258 
1259 static const u16 mv88e6390_serdes_regs[] = {
1260 	/* SERDES common registers */
1261 	0xf00a, 0xf00b, 0xf00c,
1262 	0xf010, 0xf011, 0xf012, 0xf013,
1263 	0xf016, 0xf017, 0xf018,
1264 	0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1265 	0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1266 	0xf028, 0xf029,
1267 	0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1268 	0xf038, 0xf039,
1269 	/* SGMII */
1270 	0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1271 	0x2008,
1272 	0x200f,
1273 	0xa000, 0xa001, 0xa002, 0xa003,
1274 	/* 10Gbase-X */
1275 	0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1276 	0x1008,
1277 	0x100e, 0x100f,
1278 	0x1018, 0x1019,
1279 	0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1280 	0x9006,
1281 	0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1282 	/* 10Gbase-R */
1283 	0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1284 	0x1028, 0x1029, 0x102a, 0x102b,
1285 };
1286 
1287 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1288 {
1289 	if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
1290 		return 0;
1291 
1292 	return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1293 }
1294 
1295 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1296 {
1297 	u16 *p = _p;
1298 	int lane;
1299 	u16 reg;
1300 	int err;
1301 	int i;
1302 
1303 	lane = mv88e6xxx_serdes_get_lane(chip, port);
1304 	if (lane < 0)
1305 		return;
1306 
1307 	for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1308 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1309 					    mv88e6390_serdes_regs[i], &reg);
1310 		if (!err)
1311 			p[i] = reg;
1312 	}
1313 }
1314 
1315 static const int mv88e6352_serdes_p2p_to_reg[] = {
1316 	/* Index of value in microvolts corresponds to the register value */
1317 	14000, 112000, 210000, 308000, 406000, 504000, 602000, 700000,
1318 };
1319 
1320 int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port,
1321 				      int val)
1322 {
1323 	bool found = false;
1324 	u16 ctrl, reg;
1325 	int err;
1326 	int i;
1327 
1328 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
1329 	if (err <= 0)
1330 		return err;
1331 
1332 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_p2p_to_reg); ++i) {
1333 		if (mv88e6352_serdes_p2p_to_reg[i] == val) {
1334 			reg = i;
1335 			found = true;
1336 			break;
1337 		}
1338 	}
1339 
1340 	if (!found)
1341 		return -EINVAL;
1342 
1343 	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_SPEC_CTRL2, &ctrl);
1344 	if (err)
1345 		return err;
1346 
1347 	ctrl &= ~MV88E6352_SERDES_OUT_AMP_MASK;
1348 	ctrl |= reg;
1349 
1350 	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_SPEC_CTRL2, ctrl);
1351 }
1352 
1353 static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane,
1354 					bool on)
1355 {
1356 	u16 reg;
1357 	int err;
1358 
1359 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1360 				    MV88E6393X_SERDES_CTRL1, &reg);
1361 	if (err)
1362 		return err;
1363 
1364 	if (on)
1365 		reg &= ~(MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1366 			 MV88E6393X_SERDES_CTRL1_RX_PDOWN);
1367 	else
1368 		reg |= MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1369 		       MV88E6393X_SERDES_CTRL1_RX_PDOWN;
1370 
1371 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1372 				      MV88E6393X_SERDES_CTRL1, reg);
1373 }
1374 
1375 static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane)
1376 {
1377 	u16 reg;
1378 	int err;
1379 
1380 	/* mv88e6393x family errata 4.6:
1381 	 * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD
1382 	 * mode or P0_mode is configured for [x]MII.
1383 	 * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
1384 	 *
1385 	 * It seems that after this workaround the SERDES is automatically
1386 	 * powered up (the bit is cleared), so power it down.
1387 	 */
1388 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1389 				    MV88E6393X_SERDES_POC, &reg);
1390 	if (err)
1391 		return err;
1392 
1393 	reg &= ~MV88E6393X_SERDES_POC_PDOWN;
1394 	reg |= MV88E6393X_SERDES_POC_RESET;
1395 
1396 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1397 				     MV88E6393X_SERDES_POC, reg);
1398 	if (err)
1399 		return err;
1400 
1401 	err = mv88e6390_serdes_power_sgmii(chip, lane, false);
1402 	if (err)
1403 		return err;
1404 
1405 	return mv88e6393x_serdes_power_lane(chip, lane, false);
1406 }
1407 
1408 int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip)
1409 {
1410 	int err;
1411 
1412 	err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT0_LANE);
1413 	if (err)
1414 		return err;
1415 
1416 	err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT9_LANE);
1417 	if (err)
1418 		return err;
1419 
1420 	return mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT10_LANE);
1421 }
1422 
1423 static int mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip *chip, int lane)
1424 {
1425 	u16 reg, pcs;
1426 	int err;
1427 
1428 	/* mv88e6393x family errata 4.8:
1429 	 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may
1430 	 * not come up after hardware reset or software reset of SERDES core.
1431 	 * Workaround is to write SERDES register 4.F074.14=1 for only those
1432 	 * modes and 0 in all other modes.
1433 	 */
1434 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1435 				    MV88E6393X_SERDES_POC, &pcs);
1436 	if (err)
1437 		return err;
1438 
1439 	pcs &= MV88E6393X_SERDES_POC_PCS_MASK;
1440 
1441 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1442 				    MV88E6393X_ERRATA_4_8_REG, &reg);
1443 	if (err)
1444 		return err;
1445 
1446 	if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX ||
1447 	    pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY ||
1448 	    pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC)
1449 		reg |= MV88E6393X_ERRATA_4_8_BIT;
1450 	else
1451 		reg &= ~MV88E6393X_ERRATA_4_8_BIT;
1452 
1453 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1454 				      MV88E6393X_ERRATA_4_8_REG, reg);
1455 }
1456 
1457 static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane,
1458 					 u8 cmode)
1459 {
1460 	static const struct {
1461 		u16 dev, reg, val, mask;
1462 	} fixes[] = {
1463 		{ MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff },
1464 		{ MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff },
1465 		{ MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff },
1466 		{ MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f },
1467 		{ MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 },
1468 		{ MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff },
1469 		{ MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC,
1470 		  MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET },
1471 	};
1472 	int err, i;
1473 	u16 reg;
1474 
1475 	/* mv88e6393x family errata 5.2:
1476 	 * For optimal signal integrity the following sequence should be applied
1477 	 * to SERDES operating in 10G mode. These registers only apply to 10G
1478 	 * operation and have no effect on other speeds.
1479 	 */
1480 	if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER)
1481 		return 0;
1482 
1483 	for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
1484 		err = mv88e6390_serdes_read(chip, lane, fixes[i].dev,
1485 					    fixes[i].reg, &reg);
1486 		if (err)
1487 			return err;
1488 
1489 		reg &= ~fixes[i].mask;
1490 		reg |= fixes[i].val;
1491 
1492 		err = mv88e6390_serdes_write(chip, lane, fixes[i].dev,
1493 					     fixes[i].reg, reg);
1494 		if (err)
1495 			return err;
1496 	}
1497 
1498 	return 0;
1499 }
1500 
1501 static int mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip *chip,
1502 					      int lane, u8 cmode, bool on)
1503 {
1504 	u16 reg;
1505 	int err;
1506 
1507 	if (cmode != MV88E6XXX_PORT_STS_CMODE_2500BASEX)
1508 		return 0;
1509 
1510 	/* Inband AN is broken on Amethyst in 2500base-x mode when set by
1511 	 * standard mechanism (via cmode).
1512 	 * We can get around this by configuring the PCS mode to 1000base-x
1513 	 * and then writing value 0x58 to register 1e.8000. (This must be done
1514 	 * while SerDes receiver and transmitter are disabled, which is, when
1515 	 * this function is called.)
1516 	 * It seem that when we do this configuration to 2500base-x mode (by
1517 	 * changing PCS mode to 1000base-x and frequency to 3.125 GHz from
1518 	 * 1.25 GHz) and then configure to sgmii or 1000base-x, the device
1519 	 * thinks that it already has SerDes at 1.25 GHz and does not change
1520 	 * the 1e.8000 register, leaving SerDes at 3.125 GHz.
1521 	 * To avoid this, change PCS mode back to 2500base-x when disabling
1522 	 * SerDes from 2500base-x mode.
1523 	 */
1524 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1525 				    MV88E6393X_SERDES_POC, &reg);
1526 	if (err)
1527 		return err;
1528 
1529 	reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN);
1530 	if (on)
1531 		reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX |
1532 		       MV88E6393X_SERDES_POC_AN;
1533 	else
1534 		reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX;
1535 	reg |= MV88E6393X_SERDES_POC_RESET;
1536 
1537 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1538 				     MV88E6393X_SERDES_POC, reg);
1539 	if (err)
1540 		return err;
1541 
1542 	err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58);
1543 	if (err)
1544 		return err;
1545 
1546 	return 0;
1547 }
1548 
1549 int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
1550 			    bool on)
1551 {
1552 	u8 cmode = chip->ports[port].cmode;
1553 	int err;
1554 
1555 	if (port != 0 && port != 9 && port != 10)
1556 		return -EOPNOTSUPP;
1557 
1558 	if (on) {
1559 		err = mv88e6393x_serdes_erratum_4_8(chip, lane);
1560 		if (err)
1561 			return err;
1562 
1563 		err = mv88e6393x_serdes_erratum_5_2(chip, lane, cmode);
1564 		if (err)
1565 			return err;
1566 
1567 		err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1568 							 true);
1569 		if (err)
1570 			return err;
1571 
1572 		err = mv88e6393x_serdes_power_lane(chip, lane, true);
1573 		if (err)
1574 			return err;
1575 	}
1576 
1577 	switch (cmode) {
1578 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1579 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1580 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1581 		err = mv88e6390_serdes_power_sgmii(chip, lane, on);
1582 		break;
1583 	case MV88E6393X_PORT_STS_CMODE_5GBASER:
1584 	case MV88E6393X_PORT_STS_CMODE_10GBASER:
1585 		err = mv88e6390_serdes_power_10g(chip, lane, on);
1586 		break;
1587 	default:
1588 		err = -EINVAL;
1589 		break;
1590 	}
1591 
1592 	if (err)
1593 		return err;
1594 
1595 	if (!on) {
1596 		err = mv88e6393x_serdes_power_lane(chip, lane, false);
1597 		if (err)
1598 			return err;
1599 
1600 		err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1601 							 false);
1602 	}
1603 
1604 	return err;
1605 }
1606