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