GNU Linux-libre 4.19.268-gnu1
[releases.git] / drivers / net / dsa / mv88e6xxx / serdes.c
1 /*
2  * Marvell 88E6xxx SERDES manipulation, via SMI bus
3  *
4  * Copyright (c) 2008 Marvell Semiconductor
5  *
6  * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13
14 #include <linux/interrupt.h>
15 #include <linux/irqdomain.h>
16 #include <linux/mii.h>
17
18 #include "chip.h"
19 #include "global2.h"
20 #include "phy.h"
21 #include "port.h"
22 #include "serdes.h"
23
24 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
25                                  u16 *val)
26 {
27         return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
28                                        MV88E6352_SERDES_PAGE_FIBER,
29                                        reg, val);
30 }
31
32 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
33                                   u16 val)
34 {
35         return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
36                                         MV88E6352_SERDES_PAGE_FIBER,
37                                         reg, val);
38 }
39
40 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
41                                  int lane, int device, int reg, u16 *val)
42 {
43         int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
44
45         return mv88e6xxx_phy_read(chip, lane, reg_c45, val);
46 }
47
48 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
49                                   int lane, int device, int reg, u16 val)
50 {
51         int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
52
53         return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
54 }
55
56 static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on)
57 {
58         u16 val, new_val;
59         int err;
60
61         err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
62         if (err)
63                 return err;
64
65         if (on)
66                 new_val = val & ~BMCR_PDOWN;
67         else
68                 new_val = val | BMCR_PDOWN;
69
70         if (val != new_val)
71                 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
72
73         return err;
74 }
75
76 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
77 {
78         u8 cmode = chip->ports[port].cmode;
79
80         if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASE_X) ||
81             (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) ||
82             (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
83                 return true;
84
85         return false;
86 }
87
88 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
89 {
90         int err;
91
92         if (mv88e6352_port_has_serdes(chip, port)) {
93                 err = mv88e6352_serdes_power_set(chip, on);
94                 if (err < 0)
95                         return err;
96         }
97
98         return 0;
99 }
100
101 struct mv88e6352_serdes_hw_stat {
102         char string[ETH_GSTRING_LEN];
103         int sizeof_stat;
104         int reg;
105 };
106
107 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
108         { "serdes_fibre_rx_error", 16, 21 },
109         { "serdes_PRBS_error", 32, 24 },
110 };
111
112 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
113 {
114         if (mv88e6352_port_has_serdes(chip, port))
115                 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
116
117         return 0;
118 }
119
120 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
121                                  int port, uint8_t *data)
122 {
123         struct mv88e6352_serdes_hw_stat *stat;
124         int i;
125
126         if (!mv88e6352_port_has_serdes(chip, port))
127                 return 0;
128
129         for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
130                 stat = &mv88e6352_serdes_hw_stats[i];
131                 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
132                        ETH_GSTRING_LEN);
133         }
134         return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
135 }
136
137 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
138                                           struct mv88e6352_serdes_hw_stat *stat)
139 {
140         u64 val = 0;
141         u16 reg;
142         int err;
143
144         err = mv88e6352_serdes_read(chip, stat->reg, &reg);
145         if (err) {
146                 dev_err(chip->dev, "failed to read statistic\n");
147                 return 0;
148         }
149
150         val = reg;
151
152         if (stat->sizeof_stat == 32) {
153                 err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
154                 if (err) {
155                         dev_err(chip->dev, "failed to read statistic\n");
156                         return 0;
157                 }
158                 val = val << 16 | reg;
159         }
160
161         return val;
162 }
163
164 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
165                                uint64_t *data)
166 {
167         struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
168         struct mv88e6352_serdes_hw_stat *stat;
169         u64 value;
170         int i;
171
172         if (!mv88e6352_port_has_serdes(chip, port))
173                 return 0;
174
175         BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
176                      ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
177
178         for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
179                 stat = &mv88e6352_serdes_hw_stats[i];
180                 value = mv88e6352_serdes_get_stat(chip, stat);
181                 mv88e6xxx_port->serdes_stats[i] += value;
182                 data[i] = mv88e6xxx_port->serdes_stats[i];
183         }
184
185         return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
186 }
187
188 /* Return the SERDES lane address a port is using. Only Ports 9 and 10
189  * have SERDES lanes. Returns -ENODEV if a port does not have a lane.
190  */
191 static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
192 {
193         u8 cmode = chip->ports[port].cmode;
194
195         switch (port) {
196         case 9:
197                 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
198                     cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
199                     cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
200                         return MV88E6390_PORT9_LANE0;
201                 return -ENODEV;
202         case 10:
203                 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
204                     cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
205                     cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
206                         return MV88E6390_PORT10_LANE0;
207                 return -ENODEV;
208         default:
209                 return -ENODEV;
210         }
211 }
212
213 /* Return the SERDES lane address a port is using. Ports 9 and 10 can
214  * use multiple lanes. If so, return the first lane the port uses.
215  * Returns -ENODEV if a port does not have a lane.
216  */
217 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
218 {
219         u8 cmode_port9, cmode_port10, cmode_port;
220
221         cmode_port9 = chip->ports[9].cmode;
222         cmode_port10 = chip->ports[10].cmode;
223         cmode_port = chip->ports[port].cmode;
224
225         switch (port) {
226         case 2:
227                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
228                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
229                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
230                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
231                                 return MV88E6390_PORT9_LANE1;
232                 return -ENODEV;
233         case 3:
234                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
235                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
236                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
237                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
238                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
239                                 return MV88E6390_PORT9_LANE2;
240                 return -ENODEV;
241         case 4:
242                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
243                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
244                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
245                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
246                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
247                                 return MV88E6390_PORT9_LANE3;
248                 return -ENODEV;
249         case 5:
250                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
251                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
252                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
253                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
254                                 return MV88E6390_PORT10_LANE1;
255                 return -ENODEV;
256         case 6:
257                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
258                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
259                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
260                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
261                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
262                                 return MV88E6390_PORT10_LANE2;
263                 return -ENODEV;
264         case 7:
265                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
266                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
267                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
268                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
269                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
270                                 return MV88E6390_PORT10_LANE3;
271                 return -ENODEV;
272         case 9:
273                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
274                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
275                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
276                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
277                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
278                         return MV88E6390_PORT9_LANE0;
279                 return -ENODEV;
280         case 10:
281                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
282                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
283                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
284                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
285                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
286                         return MV88E6390_PORT10_LANE0;
287                 return -ENODEV;
288         default:
289                 return -ENODEV;
290         }
291 }
292
293 /* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
294 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
295                                       bool on)
296 {
297         u16 val, new_val;
298         int err;
299
300         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
301                                     MV88E6390_PCS_CONTROL_1, &val);
302
303         if (err)
304                 return err;
305
306         if (on)
307                 new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET |
308                                   MV88E6390_PCS_CONTROL_1_LOOPBACK |
309                                   MV88E6390_PCS_CONTROL_1_PDOWN);
310         else
311                 new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN;
312
313         if (val != new_val)
314                 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
315                                              MV88E6390_PCS_CONTROL_1, new_val);
316
317         return err;
318 }
319
320 /* Set the power on/off for SGMII and 1000Base-X */
321 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
322                                         bool on)
323 {
324         u16 val, new_val;
325         int err;
326
327         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
328                                     MV88E6390_SGMII_CONTROL, &val);
329         if (err)
330                 return err;
331
332         if (on)
333                 new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET |
334                                   MV88E6390_SGMII_CONTROL_LOOPBACK |
335                                   MV88E6390_SGMII_CONTROL_PDOWN);
336         else
337                 new_val = val | MV88E6390_SGMII_CONTROL_PDOWN;
338
339         if (val != new_val)
340                 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
341                                              MV88E6390_SGMII_CONTROL, new_val);
342
343         return err;
344 }
345
346 static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port,
347                                        int lane, bool on)
348 {
349         u8 cmode = chip->ports[port].cmode;
350
351         switch (cmode) {
352         case MV88E6XXX_PORT_STS_CMODE_SGMII:
353         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
354         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
355                 return mv88e6390_serdes_power_sgmii(chip, lane, on);
356         case MV88E6XXX_PORT_STS_CMODE_XAUI:
357         case MV88E6XXX_PORT_STS_CMODE_RXAUI:
358                 return mv88e6390_serdes_power_10g(chip, lane, on);
359         }
360
361         return 0;
362 }
363
364 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
365 {
366         int lane;
367
368         lane = mv88e6390_serdes_get_lane(chip, port);
369         if (lane == -ENODEV)
370                 return 0;
371
372         if (lane < 0)
373                 return lane;
374
375         switch (port) {
376         case 9 ... 10:
377                 return mv88e6390_serdes_power_lane(chip, port, lane, on);
378         }
379
380         return 0;
381 }
382
383 int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
384 {
385         int lane;
386
387         lane = mv88e6390x_serdes_get_lane(chip, port);
388         if (lane == -ENODEV)
389                 return 0;
390
391         if (lane < 0)
392                 return lane;
393
394         switch (port) {
395         case 2 ... 4:
396         case 5 ... 7:
397         case 9 ... 10:
398                 return mv88e6390_serdes_power_lane(chip, port, lane, on);
399         }
400
401         return 0;
402 }
403
404 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
405                                             int port, int lane)
406 {
407         struct dsa_switch *ds = chip->ds;
408         u16 status;
409         bool up;
410
411         mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
412                               MV88E6390_SGMII_STATUS, &status);
413
414         /* Status must be read twice in order to give the current link
415          * status. Otherwise the change in link status since the last
416          * read of the register is returned.
417          */
418         mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
419                               MV88E6390_SGMII_STATUS, &status);
420         up = status & MV88E6390_SGMII_STATUS_LINK;
421
422         dsa_port_phylink_mac_change(ds, port, up);
423 }
424
425 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
426                                              int lane)
427 {
428         return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
429                                       MV88E6390_SGMII_INT_ENABLE,
430                                       MV88E6390_SGMII_INT_LINK_DOWN |
431                                       MV88E6390_SGMII_INT_LINK_UP);
432 }
433
434 static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip *chip,
435                                               int lane)
436 {
437         return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
438                                       MV88E6390_SGMII_INT_ENABLE, 0);
439 }
440
441 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
442                                 int lane)
443 {
444         u8 cmode = chip->ports[port].cmode;
445         int err = 0;
446
447         switch (cmode) {
448         case MV88E6XXX_PORT_STS_CMODE_SGMII:
449         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
450         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
451                 err = mv88e6390_serdes_irq_enable_sgmii(chip, lane);
452         }
453
454         return err;
455 }
456
457 int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port,
458                                  int lane)
459 {
460         u8 cmode = chip->ports[port].cmode;
461         int err = 0;
462
463         switch (cmode) {
464         case MV88E6XXX_PORT_STS_CMODE_SGMII:
465         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
466         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
467                 err = mv88e6390_serdes_irq_disable_sgmii(chip, lane);
468         }
469
470         return err;
471 }
472
473 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
474                                              int lane, u16 *status)
475 {
476         int err;
477
478         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
479                                     MV88E6390_SGMII_INT_STATUS, status);
480
481         return err;
482 }
483
484 static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
485 {
486         struct mv88e6xxx_port *port = dev_id;
487         struct mv88e6xxx_chip *chip = port->chip;
488         irqreturn_t ret = IRQ_NONE;
489         u8 cmode = port->cmode;
490         u16 status;
491         int lane;
492         int err;
493
494         lane = mv88e6390x_serdes_get_lane(chip, port->port);
495
496         mutex_lock(&chip->reg_lock);
497
498         switch (cmode) {
499         case MV88E6XXX_PORT_STS_CMODE_SGMII:
500         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
501         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
502                 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
503                 if (err)
504                         goto out;
505                 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
506                               MV88E6390_SGMII_INT_LINK_UP)) {
507                         ret = IRQ_HANDLED;
508                         mv88e6390_serdes_irq_link_sgmii(chip, port->port, lane);
509                 }
510         }
511 out:
512         mutex_unlock(&chip->reg_lock);
513
514         return ret;
515 }
516
517 int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
518 {
519         int lane;
520         int err;
521
522         /* Only support ports 9 and 10 at the moment */
523         if (port < 9)
524                 return 0;
525
526         lane = mv88e6390x_serdes_get_lane(chip, port);
527
528         if (lane == -ENODEV)
529                 return 0;
530
531         if (lane < 0)
532                 return lane;
533
534         chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain,
535                                                         port);
536         if (chip->ports[port].serdes_irq < 0) {
537                 dev_err(chip->dev, "Unable to map SERDES irq: %d\n",
538                         chip->ports[port].serdes_irq);
539                 return chip->ports[port].serdes_irq;
540         }
541
542         /* Requesting the IRQ will trigger irq callbacks. So we cannot
543          * hold the reg_lock.
544          */
545         mutex_unlock(&chip->reg_lock);
546         err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
547                                    mv88e6390_serdes_thread_fn,
548                                    IRQF_ONESHOT, "mv88e6xxx-serdes",
549                                    &chip->ports[port]);
550         mutex_lock(&chip->reg_lock);
551
552         if (err) {
553                 dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
554                         err);
555                 return err;
556         }
557
558         return mv88e6390_serdes_irq_enable(chip, port, lane);
559 }
560
561 void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
562 {
563         int lane = mv88e6390x_serdes_get_lane(chip, port);
564
565         if (port < 9)
566                 return;
567
568         if (lane < 0)
569                 return;
570
571         mv88e6390_serdes_irq_disable(chip, port, lane);
572
573         /* Freeing the IRQ will trigger irq callbacks. So we cannot
574          * hold the reg_lock.
575          */
576         mutex_unlock(&chip->reg_lock);
577         free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
578         mutex_lock(&chip->reg_lock);
579
580         chip->ports[port].serdes_irq = 0;
581 }
582
583 int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
584 {
585         u8 cmode = chip->ports[port].cmode;
586
587         if (port != 5)
588                 return 0;
589
590         if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
591             cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
592             cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
593                 return mv88e6390_serdes_power_sgmii(chip, MV88E6341_ADDR_SERDES,
594                                                     on);
595
596         return 0;
597 }