xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/serdes.c (revision a5a6858b)
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 	struct dsa_switch *ds = chip->ds;
344 	u16 status;
345 	bool up;
346 	int err;
347 
348 	err = mv88e6352_serdes_read(chip, MII_BMSR, &status);
349 	if (err)
350 		return;
351 
352 	/* Status must be read twice in order to give the current link
353 	 * status. Otherwise the change in link status since the last
354 	 * read of the register is returned.
355 	 */
356 	err = mv88e6352_serdes_read(chip, MII_BMSR, &status);
357 	if (err)
358 		return;
359 
360 	up = status & BMSR_LSTATUS;
361 
362 	dsa_port_phylink_mac_change(ds, port, up);
363 }
364 
365 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
366 					u8 lane)
367 {
368 	irqreturn_t ret = IRQ_NONE;
369 	u16 status;
370 	int err;
371 
372 	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
373 	if (err)
374 		return ret;
375 
376 	if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
377 		ret = IRQ_HANDLED;
378 		mv88e6352_serdes_irq_link(chip, port);
379 	}
380 
381 	return ret;
382 }
383 
384 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
385 				bool enable)
386 {
387 	u16 val = 0;
388 
389 	if (enable)
390 		val |= MV88E6352_SERDES_INT_LINK_CHANGE;
391 
392 	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
393 }
394 
395 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
396 {
397 	return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
398 }
399 
400 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
401 {
402 	if (!mv88e6352_port_has_serdes(chip, port))
403 		return 0;
404 
405 	return 32 * sizeof(u16);
406 }
407 
408 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
409 {
410 	u16 *p = _p;
411 	u16 reg;
412 	int i;
413 
414 	if (!mv88e6352_port_has_serdes(chip, port))
415 		return;
416 
417 	for (i = 0 ; i < 32; i++) {
418 		mv88e6352_serdes_read(chip, i, &reg);
419 		p[i] = reg;
420 	}
421 }
422 
423 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
424 {
425 	u8 cmode = chip->ports[port].cmode;
426 	u8 lane = 0;
427 
428 	switch (port) {
429 	case 5:
430 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
431 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
432 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
433 			lane = MV88E6341_PORT5_LANE;
434 		break;
435 	}
436 
437 	return lane;
438 }
439 
440 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
441 {
442 	u8 cmode = chip->ports[port].cmode;
443 	u8 lane = 0;
444 
445 	switch (port) {
446 	case 9:
447 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
448 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
449 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
450 			lane = MV88E6390_PORT9_LANE0;
451 		break;
452 	case 10:
453 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
454 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
455 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
456 			lane = MV88E6390_PORT10_LANE0;
457 		break;
458 	}
459 
460 	return lane;
461 }
462 
463 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
464 {
465 	u8 cmode_port = chip->ports[port].cmode;
466 	u8 cmode_port10 = chip->ports[10].cmode;
467 	u8 cmode_port9 = chip->ports[9].cmode;
468 	u8 lane = 0;
469 
470 	switch (port) {
471 	case 2:
472 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
473 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
474 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
475 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
476 				lane = MV88E6390_PORT9_LANE1;
477 		break;
478 	case 3:
479 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
480 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
481 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
482 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
483 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
484 				lane = MV88E6390_PORT9_LANE2;
485 		break;
486 	case 4:
487 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
488 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
489 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
490 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
491 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
492 				lane = MV88E6390_PORT9_LANE3;
493 		break;
494 	case 5:
495 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
496 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
497 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
498 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
499 				lane = MV88E6390_PORT10_LANE1;
500 		break;
501 	case 6:
502 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
503 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
504 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
505 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
506 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
507 				lane = MV88E6390_PORT10_LANE2;
508 		break;
509 	case 7:
510 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
511 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
512 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
513 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
514 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
515 				lane = MV88E6390_PORT10_LANE3;
516 		break;
517 	case 9:
518 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
519 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
520 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
521 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
522 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
523 			lane = MV88E6390_PORT9_LANE0;
524 		break;
525 	case 10:
526 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
527 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
528 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
529 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
530 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
531 			lane = MV88E6390_PORT10_LANE0;
532 		break;
533 	}
534 
535 	return lane;
536 }
537 
538 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
539 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
540 				      bool up)
541 {
542 	u16 val, new_val;
543 	int err;
544 
545 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
546 				    MV88E6390_PCS_CONTROL_1, &val);
547 
548 	if (err)
549 		return err;
550 
551 	if (up)
552 		new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET |
553 				  MV88E6390_PCS_CONTROL_1_LOOPBACK |
554 				  MV88E6390_PCS_CONTROL_1_PDOWN);
555 	else
556 		new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN;
557 
558 	if (val != new_val)
559 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
560 					     MV88E6390_PCS_CONTROL_1, new_val);
561 
562 	return err;
563 }
564 
565 /* Set power up/down for SGMII and 1000Base-X */
566 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
567 					bool up)
568 {
569 	u16 val, new_val;
570 	int err;
571 
572 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
573 				    MV88E6390_SGMII_BMCR, &val);
574 	if (err)
575 		return err;
576 
577 	if (up)
578 		new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
579 	else
580 		new_val = val | BMCR_PDOWN;
581 
582 	if (val != new_val)
583 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
584 					     MV88E6390_SGMII_BMCR, new_val);
585 
586 	return err;
587 }
588 
589 struct mv88e6390_serdes_hw_stat {
590 	char string[ETH_GSTRING_LEN];
591 	int reg;
592 };
593 
594 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
595 	{ "serdes_rx_pkts", 0xf021 },
596 	{ "serdes_rx_bytes", 0xf024 },
597 	{ "serdes_rx_pkts_error", 0xf027 },
598 };
599 
600 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
601 {
602 	if (mv88e6390_serdes_get_lane(chip, port) == 0)
603 		return 0;
604 
605 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
606 }
607 
608 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
609 				 int port, uint8_t *data)
610 {
611 	struct mv88e6390_serdes_hw_stat *stat;
612 	int i;
613 
614 	if (mv88e6390_serdes_get_lane(chip, port) == 0)
615 		return 0;
616 
617 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
618 		stat = &mv88e6390_serdes_hw_stats[i];
619 		memcpy(data + i * ETH_GSTRING_LEN, stat->string,
620 		       ETH_GSTRING_LEN);
621 	}
622 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
623 }
624 
625 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
626 					  struct mv88e6390_serdes_hw_stat *stat)
627 {
628 	u16 reg[3];
629 	int err, i;
630 
631 	for (i = 0; i < 3; i++) {
632 		err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
633 					    stat->reg + i, &reg[i]);
634 		if (err) {
635 			dev_err(chip->dev, "failed to read statistic\n");
636 			return 0;
637 		}
638 	}
639 
640 	return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
641 }
642 
643 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
644 			       uint64_t *data)
645 {
646 	struct mv88e6390_serdes_hw_stat *stat;
647 	int lane;
648 	int i;
649 
650 	lane = mv88e6390_serdes_get_lane(chip, port);
651 	if (lane == 0)
652 		return 0;
653 
654 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
655 		stat = &mv88e6390_serdes_hw_stats[i];
656 		data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
657 	}
658 
659 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
660 }
661 
662 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane)
663 {
664 	u16 reg;
665 	int err;
666 
667 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
668 				    MV88E6390_PG_CONTROL, &reg);
669 	if (err)
670 		return err;
671 
672 	reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
673 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
674 				      MV88E6390_PG_CONTROL, reg);
675 }
676 
677 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
678 			   bool up)
679 {
680 	u8 cmode = chip->ports[port].cmode;
681 	int err = 0;
682 
683 	switch (cmode) {
684 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
685 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
686 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
687 		err = mv88e6390_serdes_power_sgmii(chip, lane, up);
688 		break;
689 	case MV88E6XXX_PORT_STS_CMODE_XAUI:
690 	case MV88E6XXX_PORT_STS_CMODE_RXAUI:
691 		err = mv88e6390_serdes_power_10g(chip, lane, up);
692 		break;
693 	}
694 
695 	if (!err && up)
696 		err = mv88e6390_serdes_enable_checker(chip, lane);
697 
698 	return err;
699 }
700 
701 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
702 				u8 lane, unsigned int mode,
703 				phy_interface_t interface,
704 				const unsigned long *advertise)
705 {
706 	u16 val, bmcr, adv;
707 	bool changed;
708 	int err;
709 
710 	switch (interface) {
711 	case PHY_INTERFACE_MODE_SGMII:
712 		adv = 0x0001;
713 		break;
714 
715 	case PHY_INTERFACE_MODE_1000BASEX:
716 		adv = linkmode_adv_to_mii_adv_x(advertise,
717 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
718 		break;
719 
720 	case PHY_INTERFACE_MODE_2500BASEX:
721 		adv = linkmode_adv_to_mii_adv_x(advertise,
722 					ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
723 		break;
724 
725 	default:
726 		return 0;
727 	}
728 
729 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
730 				    MV88E6390_SGMII_ADVERTISE, &val);
731 	if (err)
732 		return err;
733 
734 	changed = val != adv;
735 	if (changed) {
736 		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
737 					     MV88E6390_SGMII_ADVERTISE, adv);
738 		if (err)
739 			return err;
740 	}
741 
742 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
743 				    MV88E6390_SGMII_BMCR, &val);
744 	if (err)
745 		return err;
746 
747 	if (phylink_autoneg_inband(mode))
748 		bmcr = val | BMCR_ANENABLE;
749 	else
750 		bmcr = val & ~BMCR_ANENABLE;
751 
752 	/* setting ANENABLE triggers a restart of negotiation */
753 	if (bmcr == val)
754 		return changed;
755 
756 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
757 				      MV88E6390_SGMII_BMCR, bmcr);
758 }
759 
760 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
761 				   u8 lane, struct phylink_link_state *state)
762 {
763 	u16 lpa, status;
764 	int err;
765 
766 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
767 				    MV88E6390_SGMII_PHY_STATUS, &status);
768 	if (err) {
769 		dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
770 		return err;
771 	}
772 
773 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
774 				    MV88E6390_SGMII_LPA, &lpa);
775 	if (err) {
776 		dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
777 		return err;
778 	}
779 
780 	return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
781 }
782 
783 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
784 				    u8 lane)
785 {
786 	u16 bmcr;
787 	int err;
788 
789 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
790 				    MV88E6390_SGMII_BMCR, &bmcr);
791 	if (err)
792 		return err;
793 
794 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
795 				      MV88E6390_SGMII_BMCR,
796 				      bmcr | BMCR_ANRESTART);
797 }
798 
799 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
800 				 u8 lane, int speed, int duplex)
801 {
802 	u16 val, bmcr;
803 	int err;
804 
805 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
806 				    MV88E6390_SGMII_BMCR, &val);
807 	if (err)
808 		return err;
809 
810 	bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
811 	switch (speed) {
812 	case SPEED_2500:
813 	case SPEED_1000:
814 		bmcr |= BMCR_SPEED1000;
815 		break;
816 	case SPEED_100:
817 		bmcr |= BMCR_SPEED100;
818 		break;
819 	case SPEED_10:
820 		break;
821 	}
822 
823 	if (duplex == DUPLEX_FULL)
824 		bmcr |= BMCR_FULLDPLX;
825 
826 	if (bmcr == val)
827 		return 0;
828 
829 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
830 				      MV88E6390_SGMII_BMCR, bmcr);
831 }
832 
833 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
834 					    int port, u8 lane)
835 {
836 	u16 status;
837 	int err;
838 
839 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
840 				    MV88E6390_SGMII_PHY_STATUS, &status);
841 	if (err) {
842 		dev_err(chip->dev, "can't read SGMII PHY status: %d\n", err);
843 		return;
844 	}
845 
846 	dsa_port_phylink_mac_change(chip->ds, port,
847 				!!(status & MV88E6390_SGMII_PHY_STATUS_LINK));
848 }
849 
850 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
851 					     u8 lane, bool enable)
852 {
853 	u16 val = 0;
854 
855 	if (enable)
856 		val |= MV88E6390_SGMII_INT_LINK_DOWN |
857 			MV88E6390_SGMII_INT_LINK_UP;
858 
859 	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
860 				      MV88E6390_SGMII_INT_ENABLE, val);
861 }
862 
863 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
864 				bool enable)
865 {
866 	u8 cmode = chip->ports[port].cmode;
867 
868 	switch (cmode) {
869 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
870 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
871 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
872 		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
873 	}
874 
875 	return 0;
876 }
877 
878 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
879 					     u8 lane, u16 *status)
880 {
881 	int err;
882 
883 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
884 				    MV88E6390_SGMII_INT_STATUS, status);
885 
886 	return err;
887 }
888 
889 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
890 					u8 lane)
891 {
892 	u8 cmode = chip->ports[port].cmode;
893 	irqreturn_t ret = IRQ_NONE;
894 	u16 status;
895 	int err;
896 
897 	switch (cmode) {
898 	case MV88E6XXX_PORT_STS_CMODE_SGMII:
899 	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
900 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
901 		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
902 		if (err)
903 			return ret;
904 		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
905 			      MV88E6390_SGMII_INT_LINK_UP)) {
906 			ret = IRQ_HANDLED;
907 			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
908 		}
909 	}
910 
911 	return ret;
912 }
913 
914 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
915 {
916 	return irq_find_mapping(chip->g2_irq.domain, port);
917 }
918 
919 static const u16 mv88e6390_serdes_regs[] = {
920 	/* SERDES common registers */
921 	0xf00a, 0xf00b, 0xf00c,
922 	0xf010, 0xf011, 0xf012, 0xf013,
923 	0xf016, 0xf017, 0xf018,
924 	0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
925 	0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
926 	0xf028, 0xf029,
927 	0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
928 	0xf038, 0xf039,
929 	/* SGMII */
930 	0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
931 	0x2008,
932 	0x200f,
933 	0xa000, 0xa001, 0xa002, 0xa003,
934 	/* 10Gbase-X */
935 	0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
936 	0x1008,
937 	0x100e, 0x100f,
938 	0x1018, 0x1019,
939 	0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
940 	0x9006,
941 	0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
942 	/* 10Gbase-R */
943 	0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
944 	0x1028, 0x1029, 0x102a, 0x102b,
945 };
946 
947 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
948 {
949 	if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
950 		return 0;
951 
952 	return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
953 }
954 
955 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
956 {
957 	u16 *p = _p;
958 	int lane;
959 	u16 reg;
960 	int i;
961 
962 	lane = mv88e6xxx_serdes_get_lane(chip, port);
963 	if (lane == 0)
964 		return;
965 
966 	for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
967 		mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
968 				      mv88e6390_serdes_regs[i], &reg);
969 		p[i] = reg;
970 	}
971 }
972