GNU Linux-libre 5.10.153-gnu1
[releases.git] / drivers / net / dsa / mv88e6xxx / serdes.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Marvell 88E6xxx SERDES manipulation, via SMI bus
4  *
5  * Copyright (c) 2008 Marvell Semiconductor
6  *
7  * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
8  */
9
10 #include <linux/interrupt.h>
11 #include <linux/irqdomain.h>
12 #include <linux/mii.h>
13
14 #include "chip.h"
15 #include "global2.h"
16 #include "phy.h"
17 #include "port.h"
18 #include "serdes.h"
19
20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
21                                  u16 *val)
22 {
23         return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
24                                        MV88E6352_SERDES_PAGE_FIBER,
25                                        reg, val);
26 }
27
28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
29                                   u16 val)
30 {
31         return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
32                                         MV88E6352_SERDES_PAGE_FIBER,
33                                         reg, val);
34 }
35
36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
37                                  int lane, int device, int reg, u16 *val)
38 {
39         int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
40
41         return mv88e6xxx_phy_read(chip, lane, reg_c45, val);
42 }
43
44 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
45                                   int lane, int device, int reg, u16 val)
46 {
47         int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
48
49         return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
50 }
51
52 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
53                                           u16 status, u16 lpa,
54                                           struct phylink_link_state *state)
55 {
56         if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
57                 state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
58                 state->duplex = status &
59                                 MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
60                                                  DUPLEX_FULL : DUPLEX_HALF;
61
62                 if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
63                         state->pause |= MLO_PAUSE_TX;
64                 if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
65                         state->pause |= MLO_PAUSE_RX;
66
67                 switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
68                 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
69                         if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
70                                 state->speed = SPEED_2500;
71                         else
72                                 state->speed = SPEED_1000;
73                         break;
74                 case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
75                         state->speed = SPEED_100;
76                         break;
77                 case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
78                         state->speed = SPEED_10;
79                         break;
80                 default:
81                         dev_err(chip->dev, "invalid PHY speed\n");
82                         return -EINVAL;
83                 }
84         } else {
85                 state->link = false;
86         }
87
88         if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
89                 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
90                                        ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
91         else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
92                 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
93                                        ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
94
95         return 0;
96 }
97
98 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
99                            bool up)
100 {
101         u16 val, new_val;
102         int err;
103
104         err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
105         if (err)
106                 return err;
107
108         if (up)
109                 new_val = val & ~BMCR_PDOWN;
110         else
111                 new_val = val | BMCR_PDOWN;
112
113         if (val != new_val)
114                 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
115
116         return err;
117 }
118
119 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
120                                 u8 lane, unsigned int mode,
121                                 phy_interface_t interface,
122                                 const unsigned long *advertise)
123 {
124         u16 adv, bmcr, val;
125         bool changed;
126         int err;
127
128         switch (interface) {
129         case PHY_INTERFACE_MODE_SGMII:
130                 adv = 0x0001;
131                 break;
132
133         case PHY_INTERFACE_MODE_1000BASEX:
134                 adv = linkmode_adv_to_mii_adv_x(advertise,
135                                         ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
136                 break;
137
138         default:
139                 return 0;
140         }
141
142         err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
143         if (err)
144                 return err;
145
146         changed = val != adv;
147         if (changed) {
148                 err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
149                 if (err)
150                         return err;
151         }
152
153         err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
154         if (err)
155                 return err;
156
157         if (phylink_autoneg_inband(mode))
158                 bmcr = val | BMCR_ANENABLE;
159         else
160                 bmcr = val & ~BMCR_ANENABLE;
161
162         if (bmcr == val)
163                 return changed;
164
165         return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
166 }
167
168 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
169                                    u8 lane, struct phylink_link_state *state)
170 {
171         u16 lpa, status;
172         int err;
173
174         err = mv88e6352_serdes_read(chip, 0x11, &status);
175         if (err) {
176                 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
177                 return err;
178         }
179
180         err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
181         if (err) {
182                 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
183                 return err;
184         }
185
186         return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
187 }
188
189 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
190                                     u8 lane)
191 {
192         u16 bmcr;
193         int err;
194
195         err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
196         if (err)
197                 return err;
198
199         return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
200 }
201
202 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
203                                  u8 lane, int speed, int duplex)
204 {
205         u16 val, bmcr;
206         int err;
207
208         err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
209         if (err)
210                 return err;
211
212         bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
213         switch (speed) {
214         case SPEED_1000:
215                 bmcr |= BMCR_SPEED1000;
216                 break;
217         case SPEED_100:
218                 bmcr |= BMCR_SPEED100;
219                 break;
220         case SPEED_10:
221                 break;
222         }
223
224         if (duplex == DUPLEX_FULL)
225                 bmcr |= BMCR_FULLDPLX;
226
227         if (bmcr == val)
228                 return 0;
229
230         return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
231 }
232
233 u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
234 {
235         u8 cmode = chip->ports[port].cmode;
236         u8 lane = 0;
237
238         if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
239             (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
240             (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
241                 lane = 0xff; /* Unused */
242
243         return lane;
244 }
245
246 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
247 {
248         if (mv88e6xxx_serdes_get_lane(chip, port))
249                 return true;
250
251         return false;
252 }
253
254 struct mv88e6352_serdes_hw_stat {
255         char string[ETH_GSTRING_LEN];
256         int sizeof_stat;
257         int reg;
258 };
259
260 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
261         { "serdes_fibre_rx_error", 16, 21 },
262         { "serdes_PRBS_error", 32, 24 },
263 };
264
265 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
266 {
267         if (mv88e6352_port_has_serdes(chip, port))
268                 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
269
270         return 0;
271 }
272
273 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
274                                  int port, uint8_t *data)
275 {
276         struct mv88e6352_serdes_hw_stat *stat;
277         int i;
278
279         if (!mv88e6352_port_has_serdes(chip, port))
280                 return 0;
281
282         for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
283                 stat = &mv88e6352_serdes_hw_stats[i];
284                 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
285                        ETH_GSTRING_LEN);
286         }
287         return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
288 }
289
290 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
291                                           struct mv88e6352_serdes_hw_stat *stat)
292 {
293         u64 val = 0;
294         u16 reg;
295         int err;
296
297         err = mv88e6352_serdes_read(chip, stat->reg, &reg);
298         if (err) {
299                 dev_err(chip->dev, "failed to read statistic\n");
300                 return 0;
301         }
302
303         val = reg;
304
305         if (stat->sizeof_stat == 32) {
306                 err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
307                 if (err) {
308                         dev_err(chip->dev, "failed to read statistic\n");
309                         return 0;
310                 }
311                 val = val << 16 | reg;
312         }
313
314         return val;
315 }
316
317 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
318                                uint64_t *data)
319 {
320         struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
321         struct mv88e6352_serdes_hw_stat *stat;
322         u64 value;
323         int i;
324
325         if (!mv88e6352_port_has_serdes(chip, port))
326                 return 0;
327
328         BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
329                      ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
330
331         for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
332                 stat = &mv88e6352_serdes_hw_stats[i];
333                 value = mv88e6352_serdes_get_stat(chip, stat);
334                 mv88e6xxx_port->serdes_stats[i] += value;
335                 data[i] = mv88e6xxx_port->serdes_stats[i];
336         }
337
338         return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
339 }
340
341 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
342 {
343         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
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
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
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
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
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, &reg);
410                 p[i] = reg;
411         }
412 }
413
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
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
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 */
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 */
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
591 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
592 {
593         if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
594                 return 0;
595
596         return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
597 }
598
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 (mv88e6xxx_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
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, &reg[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
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 = mv88e6xxx_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
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, &reg);
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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], &reg);
999                 p[i] = reg;
1000         }
1001 }