Merge tag 'nfs-for-4.20-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[sfrench/cifs-2.6.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 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
189 {
190         struct dsa_switch *ds = chip->ds;
191         u16 status;
192         bool up;
193
194         mv88e6352_serdes_read(chip, MII_BMSR, &status);
195
196         /* Status must be read twice in order to give the current link
197          * status. Otherwise the change in link status since the last
198          * read of the register is returned.
199          */
200         mv88e6352_serdes_read(chip, MII_BMSR, &status);
201
202         up = status & BMSR_LSTATUS;
203
204         dsa_port_phylink_mac_change(ds, port, up);
205 }
206
207 static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id)
208 {
209         struct mv88e6xxx_port *port = dev_id;
210         struct mv88e6xxx_chip *chip = port->chip;
211         irqreturn_t ret = IRQ_NONE;
212         u16 status;
213         int err;
214
215         mutex_lock(&chip->reg_lock);
216
217         err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
218         if (err)
219                 goto out;
220
221         if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
222                 ret = IRQ_HANDLED;
223                 mv88e6352_serdes_irq_link(chip, port->port);
224         }
225 out:
226         mutex_unlock(&chip->reg_lock);
227
228         return ret;
229 }
230
231 static int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip)
232 {
233         return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE,
234                                       MV88E6352_SERDES_INT_LINK_CHANGE);
235 }
236
237 static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip *chip)
238 {
239         return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, 0);
240 }
241
242 int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
243 {
244         int err;
245
246         if (!mv88e6352_port_has_serdes(chip, port))
247                 return 0;
248
249         chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain,
250                                                         MV88E6352_SERDES_IRQ);
251         if (chip->ports[port].serdes_irq < 0) {
252                 dev_err(chip->dev, "Unable to map SERDES irq: %d\n",
253                         chip->ports[port].serdes_irq);
254                 return chip->ports[port].serdes_irq;
255         }
256
257         /* Requesting the IRQ will trigger irq callbacks. So we cannot
258          * hold the reg_lock.
259          */
260         mutex_unlock(&chip->reg_lock);
261         err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
262                                    mv88e6352_serdes_thread_fn,
263                                    IRQF_ONESHOT, "mv88e6xxx-serdes",
264                                    &chip->ports[port]);
265         mutex_lock(&chip->reg_lock);
266
267         if (err) {
268                 dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
269                         err);
270                 return err;
271         }
272
273         return mv88e6352_serdes_irq_enable(chip);
274 }
275
276 void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
277 {
278         if (!mv88e6352_port_has_serdes(chip, port))
279                 return;
280
281         mv88e6352_serdes_irq_disable(chip);
282
283         /* Freeing the IRQ will trigger irq callbacks. So we cannot
284          * hold the reg_lock.
285          */
286         mutex_unlock(&chip->reg_lock);
287         free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
288         mutex_lock(&chip->reg_lock);
289
290         chip->ports[port].serdes_irq = 0;
291 }
292
293 /* Return the SERDES lane address a port is using. Only Ports 9 and 10
294  * have SERDES lanes. Returns -ENODEV if a port does not have a lane.
295  */
296 static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
297 {
298         u8 cmode = chip->ports[port].cmode;
299
300         switch (port) {
301         case 9:
302                 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
303                     cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
304                     cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
305                         return MV88E6390_PORT9_LANE0;
306                 return -ENODEV;
307         case 10:
308                 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
309                     cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
310                     cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
311                         return MV88E6390_PORT10_LANE0;
312                 return -ENODEV;
313         default:
314                 return -ENODEV;
315         }
316 }
317
318 /* Return the SERDES lane address a port is using. Ports 9 and 10 can
319  * use multiple lanes. If so, return the first lane the port uses.
320  * Returns -ENODEV if a port does not have a lane.
321  */
322 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
323 {
324         u8 cmode_port9, cmode_port10, cmode_port;
325
326         cmode_port9 = chip->ports[9].cmode;
327         cmode_port10 = chip->ports[10].cmode;
328         cmode_port = chip->ports[port].cmode;
329
330         switch (port) {
331         case 2:
332                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
333                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
334                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
335                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
336                                 return MV88E6390_PORT9_LANE1;
337                 return -ENODEV;
338         case 3:
339                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
340                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
341                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
342                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
343                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
344                                 return MV88E6390_PORT9_LANE2;
345                 return -ENODEV;
346         case 4:
347                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
348                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
349                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
350                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
351                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
352                                 return MV88E6390_PORT9_LANE3;
353                 return -ENODEV;
354         case 5:
355                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
356                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
357                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
358                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
359                                 return MV88E6390_PORT10_LANE1;
360                 return -ENODEV;
361         case 6:
362                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
363                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
364                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
365                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
366                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
367                                 return MV88E6390_PORT10_LANE2;
368                 return -ENODEV;
369         case 7:
370                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
371                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
372                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
373                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
374                         if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X)
375                                 return MV88E6390_PORT10_LANE3;
376                 return -ENODEV;
377         case 9:
378                 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
379                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
380                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
381                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
382                     cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
383                         return MV88E6390_PORT9_LANE0;
384                 return -ENODEV;
385         case 10:
386                 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
387                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
388                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
389                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
390                     cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
391                         return MV88E6390_PORT10_LANE0;
392                 return -ENODEV;
393         default:
394                 return -ENODEV;
395         }
396 }
397
398 /* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
399 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
400                                       bool on)
401 {
402         u16 val, new_val;
403         int err;
404
405         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
406                                     MV88E6390_PCS_CONTROL_1, &val);
407
408         if (err)
409                 return err;
410
411         if (on)
412                 new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET |
413                                   MV88E6390_PCS_CONTROL_1_LOOPBACK |
414                                   MV88E6390_PCS_CONTROL_1_PDOWN);
415         else
416                 new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN;
417
418         if (val != new_val)
419                 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
420                                              MV88E6390_PCS_CONTROL_1, new_val);
421
422         return err;
423 }
424
425 /* Set the power on/off for SGMII and 1000Base-X */
426 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
427                                         bool on)
428 {
429         u16 val, new_val;
430         int err;
431
432         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
433                                     MV88E6390_SGMII_CONTROL, &val);
434         if (err)
435                 return err;
436
437         if (on)
438                 new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET |
439                                   MV88E6390_SGMII_CONTROL_LOOPBACK |
440                                   MV88E6390_SGMII_CONTROL_PDOWN);
441         else
442                 new_val = val | MV88E6390_SGMII_CONTROL_PDOWN;
443
444         if (val != new_val)
445                 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
446                                              MV88E6390_SGMII_CONTROL, new_val);
447
448         return err;
449 }
450
451 static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port,
452                                        int lane, bool on)
453 {
454         u8 cmode = chip->ports[port].cmode;
455
456         switch (cmode) {
457         case MV88E6XXX_PORT_STS_CMODE_SGMII:
458         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
459         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
460                 return mv88e6390_serdes_power_sgmii(chip, lane, on);
461         case MV88E6XXX_PORT_STS_CMODE_XAUI:
462         case MV88E6XXX_PORT_STS_CMODE_RXAUI:
463                 return mv88e6390_serdes_power_10g(chip, lane, on);
464         }
465
466         return 0;
467 }
468
469 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
470 {
471         int lane;
472
473         lane = mv88e6390_serdes_get_lane(chip, port);
474         if (lane == -ENODEV)
475                 return 0;
476
477         if (lane < 0)
478                 return lane;
479
480         switch (port) {
481         case 9 ... 10:
482                 return mv88e6390_serdes_power_lane(chip, port, lane, on);
483         }
484
485         return 0;
486 }
487
488 int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
489 {
490         int lane;
491
492         lane = mv88e6390x_serdes_get_lane(chip, port);
493         if (lane == -ENODEV)
494                 return 0;
495
496         if (lane < 0)
497                 return lane;
498
499         switch (port) {
500         case 2 ... 4:
501         case 5 ... 7:
502         case 9 ... 10:
503                 return mv88e6390_serdes_power_lane(chip, port, lane, on);
504         }
505
506         return 0;
507 }
508
509 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
510                                             int port, int lane)
511 {
512         struct dsa_switch *ds = chip->ds;
513         u16 status;
514         bool up;
515
516         mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
517                               MV88E6390_SGMII_STATUS, &status);
518
519         /* Status must be read twice in order to give the current link
520          * status. Otherwise the change in link status since the last
521          * read of the register is returned.
522          */
523         mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
524                               MV88E6390_SGMII_STATUS, &status);
525         up = status & MV88E6390_SGMII_STATUS_LINK;
526
527         dsa_port_phylink_mac_change(ds, port, up);
528 }
529
530 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
531                                              int lane)
532 {
533         return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
534                                       MV88E6390_SGMII_INT_ENABLE,
535                                       MV88E6390_SGMII_INT_LINK_DOWN |
536                                       MV88E6390_SGMII_INT_LINK_UP);
537 }
538
539 static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip *chip,
540                                               int lane)
541 {
542         return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
543                                       MV88E6390_SGMII_INT_ENABLE, 0);
544 }
545
546 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
547                                 int lane)
548 {
549         u8 cmode = chip->ports[port].cmode;
550         int err = 0;
551
552         switch (cmode) {
553         case MV88E6XXX_PORT_STS_CMODE_SGMII:
554         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
555         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
556                 err = mv88e6390_serdes_irq_enable_sgmii(chip, lane);
557         }
558
559         return err;
560 }
561
562 int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port,
563                                  int lane)
564 {
565         u8 cmode = chip->ports[port].cmode;
566         int err = 0;
567
568         switch (cmode) {
569         case MV88E6XXX_PORT_STS_CMODE_SGMII:
570         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
571         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
572                 err = mv88e6390_serdes_irq_disable_sgmii(chip, lane);
573         }
574
575         return err;
576 }
577
578 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
579                                              int lane, u16 *status)
580 {
581         int err;
582
583         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
584                                     MV88E6390_SGMII_INT_STATUS, status);
585
586         return err;
587 }
588
589 static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
590 {
591         struct mv88e6xxx_port *port = dev_id;
592         struct mv88e6xxx_chip *chip = port->chip;
593         irqreturn_t ret = IRQ_NONE;
594         u8 cmode = port->cmode;
595         u16 status;
596         int lane;
597         int err;
598
599         lane = mv88e6390x_serdes_get_lane(chip, port->port);
600
601         mutex_lock(&chip->reg_lock);
602
603         switch (cmode) {
604         case MV88E6XXX_PORT_STS_CMODE_SGMII:
605         case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
606         case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
607                 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
608                 if (err)
609                         goto out;
610                 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
611                               MV88E6390_SGMII_INT_LINK_UP)) {
612                         ret = IRQ_HANDLED;
613                         mv88e6390_serdes_irq_link_sgmii(chip, port->port, lane);
614                 }
615         }
616 out:
617         mutex_unlock(&chip->reg_lock);
618
619         return ret;
620 }
621
622 int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
623 {
624         int lane;
625         int err;
626
627         /* Only support ports 9 and 10 at the moment */
628         if (port < 9)
629                 return 0;
630
631         lane = mv88e6390x_serdes_get_lane(chip, port);
632
633         if (lane == -ENODEV)
634                 return 0;
635
636         if (lane < 0)
637                 return lane;
638
639         chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain,
640                                                         port);
641         if (chip->ports[port].serdes_irq < 0) {
642                 dev_err(chip->dev, "Unable to map SERDES irq: %d\n",
643                         chip->ports[port].serdes_irq);
644                 return chip->ports[port].serdes_irq;
645         }
646
647         /* Requesting the IRQ will trigger irq callbacks. So we cannot
648          * hold the reg_lock.
649          */
650         mutex_unlock(&chip->reg_lock);
651         err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
652                                    mv88e6390_serdes_thread_fn,
653                                    IRQF_ONESHOT, "mv88e6xxx-serdes",
654                                    &chip->ports[port]);
655         mutex_lock(&chip->reg_lock);
656
657         if (err) {
658                 dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
659                         err);
660                 return err;
661         }
662
663         return mv88e6390_serdes_irq_enable(chip, port, lane);
664 }
665
666 void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
667 {
668         int lane = mv88e6390x_serdes_get_lane(chip, port);
669
670         if (port < 9)
671                 return;
672
673         if (lane < 0)
674                 return;
675
676         mv88e6390_serdes_irq_disable(chip, port, lane);
677
678         /* Freeing the IRQ will trigger irq callbacks. So we cannot
679          * hold the reg_lock.
680          */
681         mutex_unlock(&chip->reg_lock);
682         free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
683         mutex_lock(&chip->reg_lock);
684
685         chip->ports[port].serdes_irq = 0;
686 }
687
688 int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
689 {
690         u8 cmode = chip->ports[port].cmode;
691
692         if (port != 5)
693                 return 0;
694
695         if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
696             cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
697             cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
698                 return mv88e6390_serdes_power_sgmii(chip, MV88E6341_ADDR_SERDES,
699                                                     on);
700
701         return 0;
702 }