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 status,u16 lpa,struct phylink_link_state * state)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
mv88e6352_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool up)98 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int 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
mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip * chip,int port,int lane,unsigned int mode,phy_interface_t interface,const unsigned long * advertise)119 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
120 int 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
mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)168 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
169 int 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
mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip * chip,int port,int lane)189 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
190 int 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
mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip * chip,int port,int lane,int speed,int duplex)202 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
203 int 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
mv88e6352_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)233 int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
234 {
235 u8 cmode = chip->ports[port].cmode;
236 int lane = -ENODEV;
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
mv88e6352_port_has_serdes(struct mv88e6xxx_chip * chip,int port)246 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
247 {
248 if (mv88e6xxx_serdes_get_lane(chip, port) >= 0)
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
mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip * chip,int port)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
mv88e6352_serdes_get_strings(struct mv88e6xxx_chip * chip,int port,uint8_t * data)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
mv88e6352_serdes_get_stat(struct mv88e6xxx_chip * chip,struct mv88e6352_serdes_hw_stat * stat)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, ®);
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, ®);
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
mv88e6352_serdes_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)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
mv88e6352_serdes_irq_link(struct mv88e6xxx_chip * chip,int port)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
mv88e6352_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)356 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
357 int 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
mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)375 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int 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
mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip * chip,int port)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
mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip * chip,int port)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
mv88e6352_serdes_get_regs(struct mv88e6xxx_chip * chip,int port,void * _p)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, ®);
411 if (!err)
412 p[i] = reg;
413 }
414 }
415
mv88e6341_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)416 int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
417 {
418 u8 cmode = chip->ports[port].cmode;
419 int lane = -ENODEV;
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
mv88e6185_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool up)433 int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int 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
mv88e6185_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)443 int 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 a non-negative lane number 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 0;
453 default:
454 return -ENODEV;
455 }
456 }
457
mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)458 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
459 int 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
mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)495 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int 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
mv88e6097_serdes_irq_link(struct mv88e6xxx_chip * chip,int port)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
mv88e6097_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)527 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
528 int 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
mv88e6390_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)542 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
543 {
544 u8 cmode = chip->ports[port].cmode;
545 int lane = -ENODEV;
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
mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)565 int 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 int lane = -ENODEV;
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 /* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address
641 * a port is using else Returns -ENODEV.
642 */
mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)643 int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
644 {
645 u8 cmode = chip->ports[port].cmode;
646 int lane = -ENODEV;
647
648 if (port != 0 && port != 9 && port != 10)
649 return -EOPNOTSUPP;
650
651 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
652 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
653 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
654 cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
655 cmode == MV88E6393X_PORT_STS_CMODE_10GBASER)
656 lane = port;
657
658 return lane;
659 }
660
661 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
mv88e6390_serdes_power_10g(struct mv88e6xxx_chip * chip,int lane,bool up)662 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
663 bool up)
664 {
665 u16 val, new_val;
666 int err;
667
668 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
669 MV88E6390_10G_CTRL1, &val);
670
671 if (err)
672 return err;
673
674 if (up)
675 new_val = val & ~(MDIO_CTRL1_RESET |
676 MDIO_PCS_CTRL1_LOOPBACK |
677 MDIO_CTRL1_LPOWER);
678 else
679 new_val = val | MDIO_CTRL1_LPOWER;
680
681 if (val != new_val)
682 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
683 MV88E6390_10G_CTRL1, new_val);
684
685 return err;
686 }
687
688 /* Set power up/down for SGMII and 1000Base-X */
mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip * chip,int lane,bool up)689 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
690 bool up)
691 {
692 u16 val, new_val;
693 int err;
694
695 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
696 MV88E6390_SGMII_BMCR, &val);
697 if (err)
698 return err;
699
700 if (up)
701 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
702 else
703 new_val = val | BMCR_PDOWN;
704
705 if (val != new_val)
706 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
707 MV88E6390_SGMII_BMCR, new_val);
708
709 return err;
710 }
711
712 struct mv88e6390_serdes_hw_stat {
713 char string[ETH_GSTRING_LEN];
714 int reg;
715 };
716
717 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
718 { "serdes_rx_pkts", 0xf021 },
719 { "serdes_rx_bytes", 0xf024 },
720 { "serdes_rx_pkts_error", 0xf027 },
721 };
722
mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip * chip,int port)723 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
724 {
725 if (mv88e6390_serdes_get_lane(chip, port) < 0)
726 return 0;
727
728 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
729 }
730
mv88e6390_serdes_get_strings(struct mv88e6xxx_chip * chip,int port,uint8_t * data)731 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
732 int port, uint8_t *data)
733 {
734 struct mv88e6390_serdes_hw_stat *stat;
735 int i;
736
737 if (mv88e6390_serdes_get_lane(chip, port) < 0)
738 return 0;
739
740 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
741 stat = &mv88e6390_serdes_hw_stats[i];
742 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
743 ETH_GSTRING_LEN);
744 }
745 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
746 }
747
mv88e6390_serdes_get_stat(struct mv88e6xxx_chip * chip,int lane,struct mv88e6390_serdes_hw_stat * stat)748 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
749 struct mv88e6390_serdes_hw_stat *stat)
750 {
751 u16 reg[3];
752 int err, i;
753
754 for (i = 0; i < 3; i++) {
755 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
756 stat->reg + i, ®[i]);
757 if (err) {
758 dev_err(chip->dev, "failed to read statistic\n");
759 return 0;
760 }
761 }
762
763 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
764 }
765
mv88e6390_serdes_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)766 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
767 uint64_t *data)
768 {
769 struct mv88e6390_serdes_hw_stat *stat;
770 int lane;
771 int i;
772
773 lane = mv88e6390_serdes_get_lane(chip, port);
774 if (lane < 0)
775 return 0;
776
777 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
778 stat = &mv88e6390_serdes_hw_stats[i];
779 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
780 }
781
782 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
783 }
784
mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip * chip,int lane)785 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, int lane)
786 {
787 u16 reg;
788 int err;
789
790 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
791 MV88E6390_PG_CONTROL, ®);
792 if (err)
793 return err;
794
795 reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
796 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
797 MV88E6390_PG_CONTROL, reg);
798 }
799
mv88e6390_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool up)800 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
801 bool up)
802 {
803 u8 cmode = chip->ports[port].cmode;
804 int err = 0;
805
806 switch (cmode) {
807 case MV88E6XXX_PORT_STS_CMODE_SGMII:
808 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
809 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
810 err = mv88e6390_serdes_power_sgmii(chip, lane, up);
811 break;
812 case MV88E6XXX_PORT_STS_CMODE_XAUI:
813 case MV88E6XXX_PORT_STS_CMODE_RXAUI:
814 err = mv88e6390_serdes_power_10g(chip, lane, up);
815 break;
816 }
817
818 if (!err && up)
819 err = mv88e6390_serdes_enable_checker(chip, lane);
820
821 return err;
822 }
823
mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip * chip,int port,int lane,unsigned int mode,phy_interface_t interface,const unsigned long * advertise)824 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
825 int lane, unsigned int mode,
826 phy_interface_t interface,
827 const unsigned long *advertise)
828 {
829 u16 val, bmcr, adv;
830 bool changed;
831 int err;
832
833 switch (interface) {
834 case PHY_INTERFACE_MODE_SGMII:
835 adv = 0x0001;
836 break;
837
838 case PHY_INTERFACE_MODE_1000BASEX:
839 adv = linkmode_adv_to_mii_adv_x(advertise,
840 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
841 break;
842
843 case PHY_INTERFACE_MODE_2500BASEX:
844 adv = linkmode_adv_to_mii_adv_x(advertise,
845 ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
846 break;
847
848 default:
849 return 0;
850 }
851
852 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
853 MV88E6390_SGMII_ADVERTISE, &val);
854 if (err)
855 return err;
856
857 changed = val != adv;
858 if (changed) {
859 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
860 MV88E6390_SGMII_ADVERTISE, adv);
861 if (err)
862 return err;
863 }
864
865 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
866 MV88E6390_SGMII_BMCR, &val);
867 if (err)
868 return err;
869
870 if (phylink_autoneg_inband(mode))
871 bmcr = val | BMCR_ANENABLE;
872 else
873 bmcr = val & ~BMCR_ANENABLE;
874
875 /* setting ANENABLE triggers a restart of negotiation */
876 if (bmcr == val)
877 return changed;
878
879 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
880 MV88E6390_SGMII_BMCR, bmcr);
881 }
882
mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)883 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
884 int port, int lane, struct phylink_link_state *state)
885 {
886 u16 lpa, status;
887 int err;
888
889 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
890 MV88E6390_SGMII_PHY_STATUS, &status);
891 if (err) {
892 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
893 return err;
894 }
895
896 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
897 MV88E6390_SGMII_LPA, &lpa);
898 if (err) {
899 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
900 return err;
901 }
902
903 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
904 }
905
mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)906 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
907 int port, int lane, struct phylink_link_state *state)
908 {
909 u16 status;
910 int err;
911
912 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
913 MV88E6390_10G_STAT1, &status);
914 if (err)
915 return err;
916
917 state->link = !!(status & MDIO_STAT1_LSTATUS);
918 if (state->link) {
919 state->speed = SPEED_10000;
920 state->duplex = DUPLEX_FULL;
921 }
922
923 return 0;
924 }
925
mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)926 static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
927 int port, int lane,
928 struct phylink_link_state *state)
929 {
930 u16 status;
931 int err;
932
933 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
934 MV88E6390_10G_STAT1, &status);
935 if (err)
936 return err;
937
938 state->link = !!(status & MDIO_STAT1_LSTATUS);
939 if (state->link) {
940 if (state->interface == PHY_INTERFACE_MODE_5GBASER)
941 state->speed = SPEED_5000;
942 else
943 state->speed = SPEED_10000;
944 state->duplex = DUPLEX_FULL;
945 }
946
947 return 0;
948 }
949
mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)950 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
951 int lane, struct phylink_link_state *state)
952 {
953 switch (state->interface) {
954 case PHY_INTERFACE_MODE_SGMII:
955 case PHY_INTERFACE_MODE_1000BASEX:
956 case PHY_INTERFACE_MODE_2500BASEX:
957 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
958 state);
959 case PHY_INTERFACE_MODE_XAUI:
960 case PHY_INTERFACE_MODE_RXAUI:
961 return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
962 state);
963
964 default:
965 return -EOPNOTSUPP;
966 }
967 }
968
mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,int lane,struct phylink_link_state * state)969 int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
970 int lane, struct phylink_link_state *state)
971 {
972 switch (state->interface) {
973 case PHY_INTERFACE_MODE_SGMII:
974 case PHY_INTERFACE_MODE_1000BASEX:
975 case PHY_INTERFACE_MODE_2500BASEX:
976 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
977 state);
978 case PHY_INTERFACE_MODE_5GBASER:
979 case PHY_INTERFACE_MODE_10GBASER:
980 return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane,
981 state);
982
983 default:
984 return -EOPNOTSUPP;
985 }
986 }
987
mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip * chip,int port,int lane)988 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
989 int lane)
990 {
991 u16 bmcr;
992 int err;
993
994 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
995 MV88E6390_SGMII_BMCR, &bmcr);
996 if (err)
997 return err;
998
999 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1000 MV88E6390_SGMII_BMCR,
1001 bmcr | BMCR_ANRESTART);
1002 }
1003
mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip * chip,int port,int lane,int speed,int duplex)1004 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
1005 int lane, int speed, int duplex)
1006 {
1007 u16 val, bmcr;
1008 int err;
1009
1010 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1011 MV88E6390_SGMII_BMCR, &val);
1012 if (err)
1013 return err;
1014
1015 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
1016 switch (speed) {
1017 case SPEED_2500:
1018 case SPEED_1000:
1019 bmcr |= BMCR_SPEED1000;
1020 break;
1021 case SPEED_100:
1022 bmcr |= BMCR_SPEED100;
1023 break;
1024 case SPEED_10:
1025 break;
1026 }
1027
1028 if (duplex == DUPLEX_FULL)
1029 bmcr |= BMCR_FULLDPLX;
1030
1031 if (bmcr == val)
1032 return 0;
1033
1034 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1035 MV88E6390_SGMII_BMCR, bmcr);
1036 }
1037
mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip * chip,int port,int lane)1038 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
1039 int port, int lane)
1040 {
1041 u16 bmsr;
1042 int err;
1043
1044 /* If the link has dropped, we want to know about it. */
1045 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1046 MV88E6390_SGMII_BMSR, &bmsr);
1047 if (err) {
1048 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
1049 return;
1050 }
1051
1052 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
1053 }
1054
mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip * chip,int port,u8 lane)1055 static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip,
1056 int port, u8 lane)
1057 {
1058 u16 status;
1059 int err;
1060
1061 /* If the link has dropped, we want to know about it. */
1062 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1063 MV88E6390_10G_STAT1, &status);
1064 if (err) {
1065 dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err);
1066 return;
1067 }
1068
1069 dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS));
1070 }
1071
mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip * chip,int lane,bool enable)1072 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
1073 int lane, bool enable)
1074 {
1075 u16 val = 0;
1076
1077 if (enable)
1078 val |= MV88E6390_SGMII_INT_LINK_DOWN |
1079 MV88E6390_SGMII_INT_LINK_UP;
1080
1081 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1082 MV88E6390_SGMII_INT_ENABLE, val);
1083 }
1084
mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)1085 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1086 bool enable)
1087 {
1088 u8 cmode = chip->ports[port].cmode;
1089
1090 switch (cmode) {
1091 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1092 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1093 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1094 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1095 }
1096
1097 return 0;
1098 }
1099
mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip * chip,int lane,u16 * status)1100 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1101 int lane, u16 *status)
1102 {
1103 int err;
1104
1105 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1106 MV88E6390_SGMII_INT_STATUS, status);
1107
1108 return err;
1109 }
1110
mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip * chip,u8 lane,bool enable)1111 static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip,
1112 u8 lane, bool enable)
1113 {
1114 u16 val = 0;
1115
1116 if (enable)
1117 val |= MV88E6393X_10G_INT_LINK_CHANGE;
1118
1119 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1120 MV88E6393X_10G_INT_ENABLE, val);
1121 }
1122
mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,int lane,bool enable)1123 int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
1124 int lane, bool enable)
1125 {
1126 u8 cmode = chip->ports[port].cmode;
1127
1128 switch (cmode) {
1129 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1130 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1131 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1132 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1133 case MV88E6393X_PORT_STS_CMODE_5GBASER:
1134 case MV88E6393X_PORT_STS_CMODE_10GBASER:
1135 return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
1136 }
1137
1138 return 0;
1139 }
1140
mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip * chip,u8 lane,u16 * status)1141 static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip,
1142 u8 lane, u16 *status)
1143 {
1144 int err;
1145
1146 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1147 MV88E6393X_10G_INT_STATUS, status);
1148
1149 return err;
1150 }
1151
mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)1152 irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1153 int lane)
1154 {
1155 u8 cmode = chip->ports[port].cmode;
1156 irqreturn_t ret = IRQ_NONE;
1157 u16 status;
1158 int err;
1159
1160 switch (cmode) {
1161 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1162 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1163 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1164 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1165 if (err)
1166 return ret;
1167 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1168 MV88E6390_SGMII_INT_LINK_UP)) {
1169 ret = IRQ_HANDLED;
1170 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1171 }
1172 break;
1173 case MV88E6393X_PORT_STS_CMODE_5GBASER:
1174 case MV88E6393X_PORT_STS_CMODE_10GBASER:
1175 err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
1176 if (err)
1177 return err;
1178 if (status & MV88E6393X_10G_INT_LINK_CHANGE) {
1179 ret = IRQ_HANDLED;
1180 mv88e6393x_serdes_irq_link_10g(chip, port, lane);
1181 }
1182 break;
1183 }
1184
1185 return ret;
1186 }
1187
mv88e6390_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,int lane)1188 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1189 int lane)
1190 {
1191 u8 cmode = chip->ports[port].cmode;
1192 irqreturn_t ret = IRQ_NONE;
1193 u16 status;
1194 int err;
1195
1196 switch (cmode) {
1197 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1198 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1199 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1200 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1201 if (err)
1202 return ret;
1203 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1204 MV88E6390_SGMII_INT_LINK_UP)) {
1205 ret = IRQ_HANDLED;
1206 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1207 }
1208 }
1209
1210 return ret;
1211 }
1212
mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip * chip,int port)1213 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1214 {
1215 return irq_find_mapping(chip->g2_irq.domain, port);
1216 }
1217
1218 static const u16 mv88e6390_serdes_regs[] = {
1219 /* SERDES common registers */
1220 0xf00a, 0xf00b, 0xf00c,
1221 0xf010, 0xf011, 0xf012, 0xf013,
1222 0xf016, 0xf017, 0xf018,
1223 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1224 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1225 0xf028, 0xf029,
1226 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1227 0xf038, 0xf039,
1228 /* SGMII */
1229 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1230 0x2008,
1231 0x200f,
1232 0xa000, 0xa001, 0xa002, 0xa003,
1233 /* 10Gbase-X */
1234 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1235 0x1008,
1236 0x100e, 0x100f,
1237 0x1018, 0x1019,
1238 0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1239 0x9006,
1240 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1241 /* 10Gbase-R */
1242 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1243 0x1028, 0x1029, 0x102a, 0x102b,
1244 };
1245
mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip * chip,int port)1246 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1247 {
1248 if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
1249 return 0;
1250
1251 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1252 }
1253
mv88e6390_serdes_get_regs(struct mv88e6xxx_chip * chip,int port,void * _p)1254 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1255 {
1256 u16 *p = _p;
1257 int lane;
1258 u16 reg;
1259 int err;
1260 int i;
1261
1262 lane = mv88e6xxx_serdes_get_lane(chip, port);
1263 if (lane < 0)
1264 return;
1265
1266 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1267 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1268 mv88e6390_serdes_regs[i], ®);
1269 if (!err)
1270 p[i] = reg;
1271 }
1272 }
1273
mv88e6393x_serdes_port_errata(struct mv88e6xxx_chip * chip,int lane)1274 static int mv88e6393x_serdes_port_errata(struct mv88e6xxx_chip *chip, int lane)
1275 {
1276 u16 reg, pcs;
1277 int err;
1278
1279 /* mv88e6393x family errata 4.6:
1280 * Cannot clear PwrDn bit on SERDES on port 0 if device is configured
1281 * CPU_MGD mode or P0_mode is configured for [x]MII.
1282 * Workaround: Set Port0 SERDES register 4.F002 bit 5=0 and bit 15=1.
1283 *
1284 * It seems that after this workaround the SERDES is automatically
1285 * powered up (the bit is cleared), so power it down.
1286 */
1287 if (lane == MV88E6393X_PORT0_LANE) {
1288 err = mv88e6390_serdes_read(chip, MV88E6393X_PORT0_LANE,
1289 MDIO_MMD_PHYXS,
1290 MV88E6393X_SERDES_POC, ®);
1291 if (err)
1292 return err;
1293
1294 reg &= ~MV88E6393X_SERDES_POC_PDOWN;
1295 reg |= MV88E6393X_SERDES_POC_RESET;
1296
1297 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1298 MV88E6393X_SERDES_POC, reg);
1299 if (err)
1300 return err;
1301
1302 err = mv88e6390_serdes_power_sgmii(chip, lane, false);
1303 if (err)
1304 return err;
1305 }
1306
1307 /* mv88e6393x family errata 4.8:
1308 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may
1309 * not come up after hardware reset or software reset of SERDES core.
1310 * Workaround is to write SERDES register 4.F074.14=1 for only those
1311 * modes and 0 in all other modes.
1312 */
1313 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1314 MV88E6393X_SERDES_POC, &pcs);
1315 if (err)
1316 return err;
1317
1318 pcs &= MV88E6393X_SERDES_POC_PCS_MASK;
1319
1320 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1321 MV88E6393X_ERRATA_4_8_REG, ®);
1322 if (err)
1323 return err;
1324
1325 if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX ||
1326 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY ||
1327 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC)
1328 reg |= MV88E6393X_ERRATA_4_8_BIT;
1329 else
1330 reg &= ~MV88E6393X_ERRATA_4_8_BIT;
1331
1332 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1333 MV88E6393X_ERRATA_4_8_REG, reg);
1334 }
1335
mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip * chip)1336 int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip)
1337 {
1338 int err;
1339
1340 err = mv88e6393x_serdes_port_errata(chip, MV88E6393X_PORT0_LANE);
1341 if (err)
1342 return err;
1343
1344 err = mv88e6393x_serdes_port_errata(chip, MV88E6393X_PORT9_LANE);
1345 if (err)
1346 return err;
1347
1348 return mv88e6393x_serdes_port_errata(chip, MV88E6393X_PORT10_LANE);
1349 }
1350
mv88e6393x_serdes_power(struct mv88e6xxx_chip * chip,int port,int lane,bool on)1351 int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
1352 bool on)
1353 {
1354 u8 cmode = chip->ports[port].cmode;
1355
1356 if (port != 0 && port != 9 && port != 10)
1357 return -EOPNOTSUPP;
1358
1359 switch (cmode) {
1360 case MV88E6XXX_PORT_STS_CMODE_SGMII:
1361 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1362 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1363 return mv88e6390_serdes_power_sgmii(chip, lane, on);
1364 case MV88E6393X_PORT_STS_CMODE_5GBASER:
1365 case MV88E6393X_PORT_STS_CMODE_10GBASER:
1366 return mv88e6390_serdes_power_10g(chip, lane, on);
1367 }
1368
1369 return 0;
1370 }
1371