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