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