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