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