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,u8 lane,bool up)98 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
99 bool up)
100 {
101 u16 val, new_val;
102 int err;
103
104 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
105 if (err)
106 return err;
107
108 if (up)
109 new_val = val & ~BMCR_PDOWN;
110 else
111 new_val = val | BMCR_PDOWN;
112
113 if (val != new_val)
114 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
115
116 return err;
117 }
118
mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip * chip,int port,u8 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 u8 lane, unsigned int mode,
121 phy_interface_t interface,
122 const unsigned long *advertise)
123 {
124 u16 adv, bmcr, val;
125 bool changed;
126 int err;
127
128 switch (interface) {
129 case PHY_INTERFACE_MODE_SGMII:
130 adv = 0x0001;
131 break;
132
133 case PHY_INTERFACE_MODE_1000BASEX:
134 adv = linkmode_adv_to_mii_adv_x(advertise,
135 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
136 break;
137
138 default:
139 return 0;
140 }
141
142 err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
143 if (err)
144 return err;
145
146 changed = val != adv;
147 if (changed) {
148 err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
149 if (err)
150 return err;
151 }
152
153 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
154 if (err)
155 return err;
156
157 if (phylink_autoneg_inband(mode))
158 bmcr = val | BMCR_ANENABLE;
159 else
160 bmcr = val & ~BMCR_ANENABLE;
161
162 if (bmcr == val)
163 return changed;
164
165 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
166 }
167
mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,u8 lane,struct phylink_link_state * state)168 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
169 u8 lane, struct phylink_link_state *state)
170 {
171 u16 lpa, status;
172 int err;
173
174 err = mv88e6352_serdes_read(chip, 0x11, &status);
175 if (err) {
176 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
177 return err;
178 }
179
180 err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
181 if (err) {
182 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
183 return err;
184 }
185
186 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
187 }
188
mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip * chip,int port,u8 lane)189 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
190 u8 lane)
191 {
192 u16 bmcr;
193 int err;
194
195 err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
196 if (err)
197 return err;
198
199 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
200 }
201
mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip * chip,int port,u8 lane,int speed,int duplex)202 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
203 u8 lane, int speed, int duplex)
204 {
205 u16 val, bmcr;
206 int err;
207
208 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
209 if (err)
210 return err;
211
212 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
213 switch (speed) {
214 case SPEED_1000:
215 bmcr |= BMCR_SPEED1000;
216 break;
217 case SPEED_100:
218 bmcr |= BMCR_SPEED100;
219 break;
220 case SPEED_10:
221 break;
222 }
223
224 if (duplex == DUPLEX_FULL)
225 bmcr |= BMCR_FULLDPLX;
226
227 if (bmcr == val)
228 return 0;
229
230 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
231 }
232
mv88e6352_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)233 u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
234 {
235 u8 cmode = chip->ports[port].cmode;
236 u8 lane = 0;
237
238 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
239 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
240 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
241 lane = 0xff; /* Unused */
242
243 return lane;
244 }
245
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))
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,u8 lane)356 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
357 u8 lane)
358 {
359 irqreturn_t ret = IRQ_NONE;
360 u16 status;
361 int err;
362
363 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
364 if (err)
365 return ret;
366
367 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
368 ret = IRQ_HANDLED;
369 mv88e6352_serdes_irq_link(chip, port);
370 }
371
372 return ret;
373 }
374
mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,u8 lane,bool enable)375 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
376 bool enable)
377 {
378 u16 val = 0;
379
380 if (enable)
381 val |= MV88E6352_SERDES_INT_LINK_CHANGE;
382
383 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
384 }
385
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 i;
404
405 if (!mv88e6352_port_has_serdes(chip, port))
406 return;
407
408 for (i = 0 ; i < 32; i++) {
409 mv88e6352_serdes_read(chip, i, ®);
410 p[i] = reg;
411 }
412 }
413
mv88e6341_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)414 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
415 {
416 u8 cmode = chip->ports[port].cmode;
417 u8 lane = 0;
418
419 switch (port) {
420 case 5:
421 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
422 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
423 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
424 lane = MV88E6341_PORT5_LANE;
425 break;
426 }
427
428 return lane;
429 }
430
mv88e6390_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)431 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
432 {
433 u8 cmode = chip->ports[port].cmode;
434 u8 lane = 0;
435
436 switch (port) {
437 case 9:
438 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
439 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
440 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
441 lane = MV88E6390_PORT9_LANE0;
442 break;
443 case 10:
444 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
445 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
446 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
447 lane = MV88E6390_PORT10_LANE0;
448 break;
449 }
450
451 return lane;
452 }
453
mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip * chip,int port)454 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
455 {
456 u8 cmode_port = chip->ports[port].cmode;
457 u8 cmode_port10 = chip->ports[10].cmode;
458 u8 cmode_port9 = chip->ports[9].cmode;
459 u8 lane = 0;
460
461 switch (port) {
462 case 2:
463 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
464 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
465 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
466 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
467 lane = MV88E6390_PORT9_LANE1;
468 break;
469 case 3:
470 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
471 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
472 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
473 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
474 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
475 lane = MV88E6390_PORT9_LANE2;
476 break;
477 case 4:
478 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
479 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
480 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
481 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
482 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
483 lane = MV88E6390_PORT9_LANE3;
484 break;
485 case 5:
486 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
487 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
488 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
489 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
490 lane = MV88E6390_PORT10_LANE1;
491 break;
492 case 6:
493 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
494 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
495 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
496 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
497 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
498 lane = MV88E6390_PORT10_LANE2;
499 break;
500 case 7:
501 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
502 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
503 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
504 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
505 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
506 lane = MV88E6390_PORT10_LANE3;
507 break;
508 case 9:
509 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
510 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
511 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
512 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
513 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
514 lane = MV88E6390_PORT9_LANE0;
515 break;
516 case 10:
517 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
518 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
519 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
520 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
521 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
522 lane = MV88E6390_PORT10_LANE0;
523 break;
524 }
525
526 return lane;
527 }
528
529 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
mv88e6390_serdes_power_10g(struct mv88e6xxx_chip * chip,u8 lane,bool up)530 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
531 bool up)
532 {
533 u16 val, new_val;
534 int err;
535
536 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
537 MV88E6390_10G_CTRL1, &val);
538
539 if (err)
540 return err;
541
542 if (up)
543 new_val = val & ~(MDIO_CTRL1_RESET |
544 MDIO_PCS_CTRL1_LOOPBACK |
545 MDIO_CTRL1_LPOWER);
546 else
547 new_val = val | MDIO_CTRL1_LPOWER;
548
549 if (val != new_val)
550 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
551 MV88E6390_10G_CTRL1, new_val);
552
553 return err;
554 }
555
556 /* Set power up/down for SGMII and 1000Base-X */
mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip * chip,u8 lane,bool up)557 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
558 bool up)
559 {
560 u16 val, new_val;
561 int err;
562
563 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
564 MV88E6390_SGMII_BMCR, &val);
565 if (err)
566 return err;
567
568 if (up)
569 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
570 else
571 new_val = val | BMCR_PDOWN;
572
573 if (val != new_val)
574 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
575 MV88E6390_SGMII_BMCR, new_val);
576
577 return err;
578 }
579
580 struct mv88e6390_serdes_hw_stat {
581 char string[ETH_GSTRING_LEN];
582 int reg;
583 };
584
585 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
586 { "serdes_rx_pkts", 0xf021 },
587 { "serdes_rx_bytes", 0xf024 },
588 { "serdes_rx_pkts_error", 0xf027 },
589 };
590
mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip * chip,int port)591 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
592 {
593 if (mv88e6390_serdes_get_lane(chip, port) == 0)
594 return 0;
595
596 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
597 }
598
mv88e6390_serdes_get_strings(struct mv88e6xxx_chip * chip,int port,uint8_t * data)599 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
600 int port, uint8_t *data)
601 {
602 struct mv88e6390_serdes_hw_stat *stat;
603 int i;
604
605 if (mv88e6390_serdes_get_lane(chip, port) == 0)
606 return 0;
607
608 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
609 stat = &mv88e6390_serdes_hw_stats[i];
610 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
611 ETH_GSTRING_LEN);
612 }
613 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
614 }
615
mv88e6390_serdes_get_stat(struct mv88e6xxx_chip * chip,int lane,struct mv88e6390_serdes_hw_stat * stat)616 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
617 struct mv88e6390_serdes_hw_stat *stat)
618 {
619 u16 reg[3];
620 int err, i;
621
622 for (i = 0; i < 3; i++) {
623 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
624 stat->reg + i, ®[i]);
625 if (err) {
626 dev_err(chip->dev, "failed to read statistic\n");
627 return 0;
628 }
629 }
630
631 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
632 }
633
mv88e6390_serdes_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)634 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
635 uint64_t *data)
636 {
637 struct mv88e6390_serdes_hw_stat *stat;
638 int lane;
639 int i;
640
641 lane = mv88e6390_serdes_get_lane(chip, port);
642 if (lane == 0)
643 return 0;
644
645 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
646 stat = &mv88e6390_serdes_hw_stats[i];
647 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
648 }
649
650 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
651 }
652
mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip * chip,u8 lane)653 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane)
654 {
655 u16 reg;
656 int err;
657
658 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
659 MV88E6390_PG_CONTROL, ®);
660 if (err)
661 return err;
662
663 reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
664 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
665 MV88E6390_PG_CONTROL, reg);
666 }
667
mv88e6390_serdes_power(struct mv88e6xxx_chip * chip,int port,u8 lane,bool up)668 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
669 bool up)
670 {
671 u8 cmode = chip->ports[port].cmode;
672 int err = 0;
673
674 switch (cmode) {
675 case MV88E6XXX_PORT_STS_CMODE_SGMII:
676 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
677 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
678 err = mv88e6390_serdes_power_sgmii(chip, lane, up);
679 break;
680 case MV88E6XXX_PORT_STS_CMODE_XAUI:
681 case MV88E6XXX_PORT_STS_CMODE_RXAUI:
682 err = mv88e6390_serdes_power_10g(chip, lane, up);
683 break;
684 }
685
686 if (!err && up)
687 err = mv88e6390_serdes_enable_checker(chip, lane);
688
689 return err;
690 }
691
mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip * chip,int port,u8 lane,unsigned int mode,phy_interface_t interface,const unsigned long * advertise)692 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
693 u8 lane, unsigned int mode,
694 phy_interface_t interface,
695 const unsigned long *advertise)
696 {
697 u16 val, bmcr, adv;
698 bool changed;
699 int err;
700
701 switch (interface) {
702 case PHY_INTERFACE_MODE_SGMII:
703 adv = 0x0001;
704 break;
705
706 case PHY_INTERFACE_MODE_1000BASEX:
707 adv = linkmode_adv_to_mii_adv_x(advertise,
708 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
709 break;
710
711 case PHY_INTERFACE_MODE_2500BASEX:
712 adv = linkmode_adv_to_mii_adv_x(advertise,
713 ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
714 break;
715
716 default:
717 return 0;
718 }
719
720 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
721 MV88E6390_SGMII_ADVERTISE, &val);
722 if (err)
723 return err;
724
725 changed = val != adv;
726 if (changed) {
727 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
728 MV88E6390_SGMII_ADVERTISE, adv);
729 if (err)
730 return err;
731 }
732
733 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
734 MV88E6390_SGMII_BMCR, &val);
735 if (err)
736 return err;
737
738 if (phylink_autoneg_inband(mode))
739 bmcr = val | BMCR_ANENABLE;
740 else
741 bmcr = val & ~BMCR_ANENABLE;
742
743 /* setting ANENABLE triggers a restart of negotiation */
744 if (bmcr == val)
745 return changed;
746
747 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
748 MV88E6390_SGMII_BMCR, bmcr);
749 }
750
mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip * chip,int port,u8 lane,struct phylink_link_state * state)751 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
752 int port, u8 lane, struct phylink_link_state *state)
753 {
754 u16 lpa, status;
755 int err;
756
757 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
758 MV88E6390_SGMII_PHY_STATUS, &status);
759 if (err) {
760 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
761 return err;
762 }
763
764 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
765 MV88E6390_SGMII_LPA, &lpa);
766 if (err) {
767 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
768 return err;
769 }
770
771 return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
772 }
773
mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip * chip,int port,u8 lane,struct phylink_link_state * state)774 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
775 int port, u8 lane, struct phylink_link_state *state)
776 {
777 u16 status;
778 int err;
779
780 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
781 MV88E6390_10G_STAT1, &status);
782 if (err)
783 return err;
784
785 state->link = !!(status & MDIO_STAT1_LSTATUS);
786 if (state->link) {
787 state->speed = SPEED_10000;
788 state->duplex = DUPLEX_FULL;
789 }
790
791 return 0;
792 }
793
mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip * chip,int port,u8 lane,struct phylink_link_state * state)794 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
795 u8 lane, struct phylink_link_state *state)
796 {
797 switch (state->interface) {
798 case PHY_INTERFACE_MODE_SGMII:
799 case PHY_INTERFACE_MODE_1000BASEX:
800 case PHY_INTERFACE_MODE_2500BASEX:
801 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
802 state);
803 case PHY_INTERFACE_MODE_XAUI:
804 case PHY_INTERFACE_MODE_RXAUI:
805 return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
806 state);
807
808 default:
809 return -EOPNOTSUPP;
810 }
811 }
812
mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip * chip,int port,u8 lane)813 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
814 u8 lane)
815 {
816 u16 bmcr;
817 int err;
818
819 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
820 MV88E6390_SGMII_BMCR, &bmcr);
821 if (err)
822 return err;
823
824 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
825 MV88E6390_SGMII_BMCR,
826 bmcr | BMCR_ANRESTART);
827 }
828
mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip * chip,int port,u8 lane,int speed,int duplex)829 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
830 u8 lane, int speed, int duplex)
831 {
832 u16 val, bmcr;
833 int err;
834
835 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
836 MV88E6390_SGMII_BMCR, &val);
837 if (err)
838 return err;
839
840 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
841 switch (speed) {
842 case SPEED_2500:
843 case SPEED_1000:
844 bmcr |= BMCR_SPEED1000;
845 break;
846 case SPEED_100:
847 bmcr |= BMCR_SPEED100;
848 break;
849 case SPEED_10:
850 break;
851 }
852
853 if (duplex == DUPLEX_FULL)
854 bmcr |= BMCR_FULLDPLX;
855
856 if (bmcr == val)
857 return 0;
858
859 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
860 MV88E6390_SGMII_BMCR, bmcr);
861 }
862
mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip * chip,int port,u8 lane)863 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
864 int port, u8 lane)
865 {
866 u16 bmsr;
867 int err;
868
869 /* If the link has dropped, we want to know about it. */
870 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
871 MV88E6390_SGMII_BMSR, &bmsr);
872 if (err) {
873 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
874 return;
875 }
876
877 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
878 }
879
mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip * chip,u8 lane,bool enable)880 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
881 u8 lane, bool enable)
882 {
883 u16 val = 0;
884
885 if (enable)
886 val |= MV88E6390_SGMII_INT_LINK_DOWN |
887 MV88E6390_SGMII_INT_LINK_UP;
888
889 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
890 MV88E6390_SGMII_INT_ENABLE, val);
891 }
892
mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip * chip,int port,u8 lane,bool enable)893 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
894 bool enable)
895 {
896 u8 cmode = chip->ports[port].cmode;
897
898 switch (cmode) {
899 case MV88E6XXX_PORT_STS_CMODE_SGMII:
900 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
901 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
902 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
903 }
904
905 return 0;
906 }
907
mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip * chip,u8 lane,u16 * status)908 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
909 u8 lane, u16 *status)
910 {
911 int err;
912
913 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
914 MV88E6390_SGMII_INT_STATUS, status);
915
916 return err;
917 }
918
mv88e6390_serdes_irq_status(struct mv88e6xxx_chip * chip,int port,u8 lane)919 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
920 u8 lane)
921 {
922 u8 cmode = chip->ports[port].cmode;
923 irqreturn_t ret = IRQ_NONE;
924 u16 status;
925 int err;
926
927 switch (cmode) {
928 case MV88E6XXX_PORT_STS_CMODE_SGMII:
929 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
930 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
931 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
932 if (err)
933 return ret;
934 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
935 MV88E6390_SGMII_INT_LINK_UP)) {
936 ret = IRQ_HANDLED;
937 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
938 }
939 }
940
941 return ret;
942 }
943
mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip * chip,int port)944 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
945 {
946 return irq_find_mapping(chip->g2_irq.domain, port);
947 }
948
949 static const u16 mv88e6390_serdes_regs[] = {
950 /* SERDES common registers */
951 0xf00a, 0xf00b, 0xf00c,
952 0xf010, 0xf011, 0xf012, 0xf013,
953 0xf016, 0xf017, 0xf018,
954 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
955 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
956 0xf028, 0xf029,
957 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
958 0xf038, 0xf039,
959 /* SGMII */
960 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
961 0x2008,
962 0x200f,
963 0xa000, 0xa001, 0xa002, 0xa003,
964 /* 10Gbase-X */
965 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
966 0x1008,
967 0x100e, 0x100f,
968 0x1018, 0x1019,
969 0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
970 0x9006,
971 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
972 /* 10Gbase-R */
973 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
974 0x1028, 0x1029, 0x102a, 0x102b,
975 };
976
mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip * chip,int port)977 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
978 {
979 if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
980 return 0;
981
982 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
983 }
984
mv88e6390_serdes_get_regs(struct mv88e6xxx_chip * chip,int port,void * _p)985 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
986 {
987 u16 *p = _p;
988 int lane;
989 u16 reg;
990 int i;
991
992 lane = mv88e6xxx_serdes_get_lane(chip, port);
993 if (lane == 0)
994 return;
995
996 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
997 mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
998 mv88e6390_serdes_regs[i], ®);
999 p[i] = reg;
1000 }
1001 }
1002