xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/serdes.c (revision d9fd5a71)
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 status, u16 lpa,
54 					  struct phylink_link_state *state)
55 {
56 	if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
57 		state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
58 		state->duplex = status &
59 				MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
60 			                         DUPLEX_FULL : DUPLEX_HALF;
61 
62 		if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
63 			state->pause |= MLO_PAUSE_TX;
64 		if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
65 			state->pause |= MLO_PAUSE_RX;
66 
67 		switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
68 		case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
69 			if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
70 				state->speed = SPEED_2500;
71 			else
72 				state->speed = SPEED_1000;
73 			break;
74 		case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
75 			state->speed = SPEED_100;
76 			break;
77 		case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
78 			state->speed = SPEED_10;
79 			break;
80 		default:
81 			dev_err(chip->dev, "invalid PHY speed\n");
82 			return -EINVAL;
83 		}
84 	} else {
85 		state->link = false;
86 	}
87 
88 	if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
89 		mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
90 				       ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
91 	else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
92 		mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
93 				       ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
94 
95 	return 0;
96 }
97 
98 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
99 			   bool up)
100 {
101 	u16 val, new_val;
102 	int err;
103 
104 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
105 	if (err)
106 		return err;
107 
108 	if (up)
109 		new_val = val & ~BMCR_PDOWN;
110 	else
111 		new_val = val | BMCR_PDOWN;
112 
113 	if (val != new_val)
114 		err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
115 
116 	return err;
117 }
118 
119 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
120 				u8 lane, unsigned int mode,
121 				phy_interface_t interface,
122 				const unsigned long *advertise)
123 {
124 	u16 adv, bmcr, val;
125 	bool changed;
126 	int err;
127 
128 	switch (interface) {
129 	case PHY_INTERFACE_MODE_SGMII:
130 		adv = 0x0001;
131 		break;
132 
133 	case PHY_INTERFACE_MODE_1000BASEX:
134 		adv = linkmode_adv_to_mii_adv_x(advertise,
135 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
136 		break;
137 
138 	default:
139 		return 0;
140 	}
141 
142 	err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
143 	if (err)
144 		return err;
145 
146 	changed = val != adv;
147 	if (changed) {
148 		err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
149 		if (err)
150 			return err;
151 	}
152 
153 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
154 	if (err)
155 		return err;
156 
157 	if (phylink_autoneg_inband(mode))
158 		bmcr = val | BMCR_ANENABLE;
159 	else
160 		bmcr = val & ~BMCR_ANENABLE;
161 
162 	if (bmcr == val)
163 		return changed;
164 
165 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
166 }
167 
168 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
169 				   u8 lane, struct phylink_link_state *state)
170 {
171 	u16 lpa, status;
172 	int err;
173 
174 	err = mv88e6352_serdes_read(chip, 0x11, &status);
175 	if (err) {
176 		dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
177 		return err;
178 	}
179 
180 	err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
181 	if (err) {
182 		dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
183 		return err;
184 	}
185 
186 	return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
187 }
188 
189 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
190 				    u8 lane)
191 {
192 	u16 bmcr;
193 	int err;
194 
195 	err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
196 	if (err)
197 		return err;
198 
199 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
200 }
201 
202 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
203 				 u8 lane, int speed, int duplex)
204 {
205 	u16 val, bmcr;
206 	int err;
207 
208 	err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
209 	if (err)
210 		return err;
211 
212 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
213 	switch (speed) {
214 	case SPEED_1000:
215 		bmcr |= BMCR_SPEED1000;
216 		break;
217 	case SPEED_100:
218 		bmcr |= BMCR_SPEED100;
219 		break;
220 	case SPEED_10:
221 		break;
222 	}
223 
224 	if (duplex == DUPLEX_FULL)
225 		bmcr |= BMCR_FULLDPLX;
226 
227 	if (bmcr == val)
228 		return 0;
229 
230 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
231 }
232 
233 u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
234 {
235 	u8 cmode = chip->ports[port].cmode;
236 	u8 lane = 0;
237 
238 	if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
239 	    (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
240 	    (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
241 		lane = 0xff; /* Unused */
242 
243 	return lane;
244 }
245 
246 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
247 {
248 	if (mv88e6xxx_serdes_get_lane(chip, port))
249 		return true;
250 
251 	return false;
252 }
253 
254 struct mv88e6352_serdes_hw_stat {
255 	char string[ETH_GSTRING_LEN];
256 	int sizeof_stat;
257 	int reg;
258 };
259 
260 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
261 	{ "serdes_fibre_rx_error", 16, 21 },
262 	{ "serdes_PRBS_error", 32, 24 },
263 };
264 
265 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
266 {
267 	if (mv88e6352_port_has_serdes(chip, port))
268 		return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
269 
270 	return 0;
271 }
272 
273 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
274 				 int port, uint8_t *data)
275 {
276 	struct mv88e6352_serdes_hw_stat *stat;
277 	int i;
278 
279 	if (!mv88e6352_port_has_serdes(chip, port))
280 		return 0;
281 
282 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
283 		stat = &mv88e6352_serdes_hw_stats[i];
284 		memcpy(data + i * ETH_GSTRING_LEN, stat->string,
285 		       ETH_GSTRING_LEN);
286 	}
287 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
288 }
289 
290 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
291 					  struct mv88e6352_serdes_hw_stat *stat)
292 {
293 	u64 val = 0;
294 	u16 reg;
295 	int err;
296 
297 	err = mv88e6352_serdes_read(chip, stat->reg, &reg);
298 	if (err) {
299 		dev_err(chip->dev, "failed to read statistic\n");
300 		return 0;
301 	}
302 
303 	val = reg;
304 
305 	if (stat->sizeof_stat == 32) {
306 		err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
307 		if (err) {
308 			dev_err(chip->dev, "failed to read statistic\n");
309 			return 0;
310 		}
311 		val = val << 16 | reg;
312 	}
313 
314 	return val;
315 }
316 
317 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
318 			       uint64_t *data)
319 {
320 	struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
321 	struct mv88e6352_serdes_hw_stat *stat;
322 	u64 value;
323 	int i;
324 
325 	if (!mv88e6352_port_has_serdes(chip, port))
326 		return 0;
327 
328 	BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
329 		     ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
330 
331 	for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
332 		stat = &mv88e6352_serdes_hw_stats[i];
333 		value = mv88e6352_serdes_get_stat(chip, stat);
334 		mv88e6xxx_port->serdes_stats[i] += value;
335 		data[i] = mv88e6xxx_port->serdes_stats[i];
336 	}
337 
338 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
339 }
340 
341 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
342 {
343 	u16 bmsr;
344 	int err;
345 
346 	/* If the link has dropped, we want to know about it. */
347 	err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
348 	if (err) {
349 		dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
350 		return;
351 	}
352 
353 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
354 }
355 
356 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
357 					u8 lane)
358 {
359 	irqreturn_t ret = IRQ_NONE;
360 	u16 status;
361 	int err;
362 
363 	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
364 	if (err)
365 		return ret;
366 
367 	if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
368 		ret = IRQ_HANDLED;
369 		mv88e6352_serdes_irq_link(chip, port);
370 	}
371 
372 	return ret;
373 }
374 
375 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
376 				bool enable)
377 {
378 	u16 val = 0;
379 
380 	if (enable)
381 		val |= MV88E6352_SERDES_INT_LINK_CHANGE;
382 
383 	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
384 }
385 
386 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
387 {
388 	return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
389 }
390 
391 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
392 {
393 	if (!mv88e6352_port_has_serdes(chip, port))
394 		return 0;
395 
396 	return 32 * sizeof(u16);
397 }
398 
399 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
400 {
401 	u16 *p = _p;
402 	u16 reg;
403 	int err;
404 	int i;
405 
406 	if (!mv88e6352_port_has_serdes(chip, port))
407 		return;
408 
409 	for (i = 0 ; i < 32; i++) {
410 		err = mv88e6352_serdes_read(chip, i, &reg);
411 		if (!err)
412 			p[i] = reg;
413 	}
414 }
415 
416 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
417 {
418 	u8 cmode = chip->ports[port].cmode;
419 	u8 lane = 0;
420 
421 	switch (port) {
422 	case 5:
423 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
424 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
425 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
426 			lane = MV88E6341_PORT5_LANE;
427 		break;
428 	}
429 
430 	return lane;
431 }
432 
433 int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
434 			   bool up)
435 {
436 	/* The serdes power can't be controlled on this switch chip but we need
437 	 * to supply this function to avoid returning -EOPNOTSUPP in
438 	 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
439 	 */
440 	return 0;
441 }
442 
443 u8 mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
444 {
445 	/* There are no configurable serdes lanes on this switch chip but we
446 	 * need to return non-zero so that callers of
447 	 * mv88e6xxx_serdes_get_lane() know this is a serdes port.
448 	 */
449 	switch (chip->ports[port].cmode) {
450 	case MV88E6185_PORT_STS_CMODE_SERDES:
451 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
452 		return 0xff;
453 	default:
454 		return 0;
455 	}
456 }
457 
458 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
459 				   u8 lane, struct phylink_link_state *state)
460 {
461 	int err;
462 	u16 status;
463 
464 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
465 	if (err)
466 		return err;
467 
468 	state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
469 
470 	if (state->link) {
471 		state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
472 
473 		switch (status &  MV88E6XXX_PORT_STS_SPEED_MASK) {
474 		case MV88E6XXX_PORT_STS_SPEED_1000:
475 			state->speed = SPEED_1000;
476 			break;
477 		case MV88E6XXX_PORT_STS_SPEED_100:
478 			state->speed = SPEED_100;
479 			break;
480 		case MV88E6XXX_PORT_STS_SPEED_10:
481 			state->speed = SPEED_10;
482 			break;
483 		default:
484 			dev_err(chip->dev, "invalid PHY speed\n");
485 			return -EINVAL;
486 		}
487 	} else {
488 		state->duplex = DUPLEX_UNKNOWN;
489 		state->speed = SPEED_UNKNOWN;
490 	}
491 
492 	return 0;
493 }
494 
495 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
496 				bool enable)
497 {
498 	u8 cmode = chip->ports[port].cmode;
499 
500 	/* The serdes interrupts are enabled in the G2_INT_MASK register. We
501 	 * need to return 0 to avoid returning -EOPNOTSUPP in
502 	 * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
503 	 */
504 	switch (cmode) {
505 	case MV88E6185_PORT_STS_CMODE_SERDES:
506 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
507 		return 0;
508 	}
509 
510 	return -EOPNOTSUPP;
511 }
512 
513 static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
514 {
515 	u16 status;
516 	int err;
517 
518 	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
519 	if (err) {
520 		dev_err(chip->dev, "can't read port status: %d\n", err);
521 		return;
522 	}
523 
524 	dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
525 }
526 
527 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
528 					u8 lane)
529 {
530 	u8 cmode = chip->ports[port].cmode;
531 
532 	switch (cmode) {
533 	case MV88E6185_PORT_STS_CMODE_SERDES:
534 	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
535 		mv88e6097_serdes_irq_link(chip, port);
536 		return IRQ_HANDLED;
537 	}
538 
539 	return IRQ_NONE;
540 }
541 
542 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
543 {
544 	u8 cmode = chip->ports[port].cmode;
545 	u8 lane = 0;
546 
547 	switch (port) {
548 	case 9:
549 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
550 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
551 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
552 			lane = MV88E6390_PORT9_LANE0;
553 		break;
554 	case 10:
555 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
556 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
557 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
558 			lane = MV88E6390_PORT10_LANE0;
559 		break;
560 	}
561 
562 	return lane;
563 }
564 
565 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
566 {
567 	u8 cmode_port = chip->ports[port].cmode;
568 	u8 cmode_port10 = chip->ports[10].cmode;
569 	u8 cmode_port9 = chip->ports[9].cmode;
570 	u8 lane = 0;
571 
572 	switch (port) {
573 	case 2:
574 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
575 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
576 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
577 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
578 				lane = MV88E6390_PORT9_LANE1;
579 		break;
580 	case 3:
581 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
582 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
583 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
584 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
585 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
586 				lane = MV88E6390_PORT9_LANE2;
587 		break;
588 	case 4:
589 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
590 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
591 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
592 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
593 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
594 				lane = MV88E6390_PORT9_LANE3;
595 		break;
596 	case 5:
597 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
598 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
599 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
600 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
601 				lane = MV88E6390_PORT10_LANE1;
602 		break;
603 	case 6:
604 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
605 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
606 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
607 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
608 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
609 				lane = MV88E6390_PORT10_LANE2;
610 		break;
611 	case 7:
612 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
613 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
614 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
615 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
616 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
617 				lane = MV88E6390_PORT10_LANE3;
618 		break;
619 	case 9:
620 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
621 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
622 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
623 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
624 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
625 			lane = MV88E6390_PORT9_LANE0;
626 		break;
627 	case 10:
628 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
629 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
630 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
631 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
632 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
633 			lane = MV88E6390_PORT10_LANE0;
634 		break;
635 	}
636 
637 	return lane;
638 }
639 
640 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
641 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
642 				      bool up)
643 {
644 	u16 val, new_val;
645 	int err;
646 
647 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
648 				    MV88E6390_10G_CTRL1, &val);
649 
650 	if (err)
651 		return err;
652 
653 	if (up)
654 		new_val = val & ~(MDIO_CTRL1_RESET |
655 				  MDIO_PCS_CTRL1_LOOPBACK |
656 				  MDIO_CTRL1_LPOWER);
657 	else
658 		new_val = val | MDIO_CTRL1_LPOWER;
659 
660 	if (val != new_val)
661 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
662 					     MV88E6390_10G_CTRL1, new_val);
663 
664 	return err;
665 }
666 
667 /* Set power up/down for SGMII and 1000Base-X */
668 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
669 					bool up)
670 {
671 	u16 val, new_val;
672 	int err;
673 
674 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
675 				    MV88E6390_SGMII_BMCR, &val);
676 	if (err)
677 		return err;
678 
679 	if (up)
680 		new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
681 	else
682 		new_val = val | BMCR_PDOWN;
683 
684 	if (val != new_val)
685 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
686 					     MV88E6390_SGMII_BMCR, new_val);
687 
688 	return err;
689 }
690 
691 struct mv88e6390_serdes_hw_stat {
692 	char string[ETH_GSTRING_LEN];
693 	int reg;
694 };
695 
696 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
697 	{ "serdes_rx_pkts", 0xf021 },
698 	{ "serdes_rx_bytes", 0xf024 },
699 	{ "serdes_rx_pkts_error", 0xf027 },
700 };
701 
702 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
703 {
704 	if (mv88e6390_serdes_get_lane(chip, port) == 0)
705 		return 0;
706 
707 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
708 }
709 
710 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
711 				 int port, uint8_t *data)
712 {
713 	struct mv88e6390_serdes_hw_stat *stat;
714 	int i;
715 
716 	if (mv88e6390_serdes_get_lane(chip, port) == 0)
717 		return 0;
718 
719 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
720 		stat = &mv88e6390_serdes_hw_stats[i];
721 		memcpy(data + i * ETH_GSTRING_LEN, stat->string,
722 		       ETH_GSTRING_LEN);
723 	}
724 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
725 }
726 
727 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
728 					  struct mv88e6390_serdes_hw_stat *stat)
729 {
730 	u16 reg[3];
731 	int err, i;
732 
733 	for (i = 0; i < 3; i++) {
734 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
735 					    stat->reg + i, &reg[i]);
736 		if (err) {
737 			dev_err(chip->dev, "failed to read statistic\n");
738 			return 0;
739 		}
740 	}
741 
742 	return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
743 }
744 
745 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
746 			       uint64_t *data)
747 {
748 	struct mv88e6390_serdes_hw_stat *stat;
749 	int lane;
750 	int i;
751 
752 	lane = mv88e6390_serdes_get_lane(chip, port);
753 	if (lane == 0)
754 		return 0;
755 
756 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
757 		stat = &mv88e6390_serdes_hw_stats[i];
758 		data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
759 	}
760 
761 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
762 }
763 
764 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane)
765 {
766 	u16 reg;
767 	int err;
768 
769 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
770 				    MV88E6390_PG_CONTROL, &reg);
771 	if (err)
772 		return err;
773 
774 	reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
775 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
776 				      MV88E6390_PG_CONTROL, reg);
777 }
778 
779 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
780 			   bool up)
781 {
782 	u8 cmode = chip->ports[port].cmode;
783 	int err = 0;
784 
785 	switch (cmode) {
786 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
787 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
788 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
789 		err = mv88e6390_serdes_power_sgmii(chip, lane, up);
790 		break;
791 	case MV88E6XXX_PORT_STS_CMODE_XAUI:
792 	case MV88E6XXX_PORT_STS_CMODE_RXAUI:
793 		err = mv88e6390_serdes_power_10g(chip, lane, up);
794 		break;
795 	}
796 
797 	if (!err && up)
798 		err = mv88e6390_serdes_enable_checker(chip, lane);
799 
800 	return err;
801 }
802 
803 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
804 				u8 lane, unsigned int mode,
805 				phy_interface_t interface,
806 				const unsigned long *advertise)
807 {
808 	u16 val, bmcr, adv;
809 	bool changed;
810 	int err;
811 
812 	switch (interface) {
813 	case PHY_INTERFACE_MODE_SGMII:
814 		adv = 0x0001;
815 		break;
816 
817 	case PHY_INTERFACE_MODE_1000BASEX:
818 		adv = linkmode_adv_to_mii_adv_x(advertise,
819 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
820 		break;
821 
822 	case PHY_INTERFACE_MODE_2500BASEX:
823 		adv = linkmode_adv_to_mii_adv_x(advertise,
824 					ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
825 		break;
826 
827 	default:
828 		return 0;
829 	}
830 
831 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
832 				    MV88E6390_SGMII_ADVERTISE, &val);
833 	if (err)
834 		return err;
835 
836 	changed = val != adv;
837 	if (changed) {
838 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
839 					     MV88E6390_SGMII_ADVERTISE, adv);
840 		if (err)
841 			return err;
842 	}
843 
844 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
845 				    MV88E6390_SGMII_BMCR, &val);
846 	if (err)
847 		return err;
848 
849 	if (phylink_autoneg_inband(mode))
850 		bmcr = val | BMCR_ANENABLE;
851 	else
852 		bmcr = val & ~BMCR_ANENABLE;
853 
854 	/* setting ANENABLE triggers a restart of negotiation */
855 	if (bmcr == val)
856 		return changed;
857 
858 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
859 				      MV88E6390_SGMII_BMCR, bmcr);
860 }
861 
862 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
863 	int port, u8 lane, struct phylink_link_state *state)
864 {
865 	u16 lpa, status;
866 	int err;
867 
868 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
869 				    MV88E6390_SGMII_PHY_STATUS, &status);
870 	if (err) {
871 		dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
872 		return err;
873 	}
874 
875 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
876 				    MV88E6390_SGMII_LPA, &lpa);
877 	if (err) {
878 		dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
879 		return err;
880 	}
881 
882 	return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
883 }
884 
885 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
886 	int port, u8 lane, struct phylink_link_state *state)
887 {
888 	u16 status;
889 	int err;
890 
891 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
892 				    MV88E6390_10G_STAT1, &status);
893 	if (err)
894 		return err;
895 
896 	state->link = !!(status & MDIO_STAT1_LSTATUS);
897 	if (state->link) {
898 		state->speed = SPEED_10000;
899 		state->duplex = DUPLEX_FULL;
900 	}
901 
902 	return 0;
903 }
904 
905 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
906 				   u8 lane, struct phylink_link_state *state)
907 {
908 	switch (state->interface) {
909 	case PHY_INTERFACE_MODE_SGMII:
910 	case PHY_INTERFACE_MODE_1000BASEX:
911 	case PHY_INTERFACE_MODE_2500BASEX:
912 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
913 							    state);
914 	case PHY_INTERFACE_MODE_XAUI:
915 	case PHY_INTERFACE_MODE_RXAUI:
916 		return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
917 							  state);
918 
919 	default:
920 		return -EOPNOTSUPP;
921 	}
922 }
923 
924 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
925 				    u8 lane)
926 {
927 	u16 bmcr;
928 	int err;
929 
930 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
931 				    MV88E6390_SGMII_BMCR, &bmcr);
932 	if (err)
933 		return err;
934 
935 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
936 				      MV88E6390_SGMII_BMCR,
937 				      bmcr | BMCR_ANRESTART);
938 }
939 
940 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
941 				 u8 lane, int speed, int duplex)
942 {
943 	u16 val, bmcr;
944 	int err;
945 
946 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
947 				    MV88E6390_SGMII_BMCR, &val);
948 	if (err)
949 		return err;
950 
951 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
952 	switch (speed) {
953 	case SPEED_2500:
954 	case SPEED_1000:
955 		bmcr |= BMCR_SPEED1000;
956 		break;
957 	case SPEED_100:
958 		bmcr |= BMCR_SPEED100;
959 		break;
960 	case SPEED_10:
961 		break;
962 	}
963 
964 	if (duplex == DUPLEX_FULL)
965 		bmcr |= BMCR_FULLDPLX;
966 
967 	if (bmcr == val)
968 		return 0;
969 
970 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
971 				      MV88E6390_SGMII_BMCR, bmcr);
972 }
973 
974 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
975 					    int port, u8 lane)
976 {
977 	u16 bmsr;
978 	int err;
979 
980 	/* If the link has dropped, we want to know about it. */
981 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
982 				    MV88E6390_SGMII_BMSR, &bmsr);
983 	if (err) {
984 		dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
985 		return;
986 	}
987 
988 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
989 }
990 
991 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
992 					     u8 lane, bool enable)
993 {
994 	u16 val = 0;
995 
996 	if (enable)
997 		val |= MV88E6390_SGMII_INT_LINK_DOWN |
998 			MV88E6390_SGMII_INT_LINK_UP;
999 
1000 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1001 				      MV88E6390_SGMII_INT_ENABLE, val);
1002 }
1003 
1004 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
1005 				bool enable)
1006 {
1007 	u8 cmode = chip->ports[port].cmode;
1008 
1009 	switch (cmode) {
1010 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1011 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1012 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1013 		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1014 	}
1015 
1016 	return 0;
1017 }
1018 
1019 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1020 					     u8 lane, u16 *status)
1021 {
1022 	int err;
1023 
1024 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1025 				    MV88E6390_SGMII_INT_STATUS, status);
1026 
1027 	return err;
1028 }
1029 
1030 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1031 					u8 lane)
1032 {
1033 	u8 cmode = chip->ports[port].cmode;
1034 	irqreturn_t ret = IRQ_NONE;
1035 	u16 status;
1036 	int err;
1037 
1038 	switch (cmode) {
1039 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
1040 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1041 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1042 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1043 		if (err)
1044 			return ret;
1045 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1046 			      MV88E6390_SGMII_INT_LINK_UP)) {
1047 			ret = IRQ_HANDLED;
1048 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1049 		}
1050 	}
1051 
1052 	return ret;
1053 }
1054 
1055 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1056 {
1057 	return irq_find_mapping(chip->g2_irq.domain, port);
1058 }
1059 
1060 static const u16 mv88e6390_serdes_regs[] = {
1061 	/* SERDES common registers */
1062 	0xf00a, 0xf00b, 0xf00c,
1063 	0xf010, 0xf011, 0xf012, 0xf013,
1064 	0xf016, 0xf017, 0xf018,
1065 	0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1066 	0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1067 	0xf028, 0xf029,
1068 	0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1069 	0xf038, 0xf039,
1070 	/* SGMII */
1071 	0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1072 	0x2008,
1073 	0x200f,
1074 	0xa000, 0xa001, 0xa002, 0xa003,
1075 	/* 10Gbase-X */
1076 	0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1077 	0x1008,
1078 	0x100e, 0x100f,
1079 	0x1018, 0x1019,
1080 	0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1081 	0x9006,
1082 	0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1083 	/* 10Gbase-R */
1084 	0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1085 	0x1028, 0x1029, 0x102a, 0x102b,
1086 };
1087 
1088 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1089 {
1090 	if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
1091 		return 0;
1092 
1093 	return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1094 }
1095 
1096 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1097 {
1098 	u16 *p = _p;
1099 	int lane;
1100 	u16 reg;
1101 	int err;
1102 	int i;
1103 
1104 	lane = mv88e6xxx_serdes_get_lane(chip, port);
1105 	if (lane == 0)
1106 		return;
1107 
1108 	for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1109 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1110 					    mv88e6390_serdes_regs[i], &reg);
1111 		if (!err)
1112 			p[i] = reg;
1113 	}
1114 }
1115