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