diff options
author | Andrew Lunn <andrew@lunn.ch> | 2018-08-09 09:38:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-09 14:08:20 -0400 |
commit | efd1ba6af93ff63d40f92515a83405133145c028 (patch) | |
tree | 46e5072b99ad19c2987c57815224674aecc50d1d | |
parent | 7b898469b91ea08e42dbed52acf8dfcb4f5914d0 (diff) |
net: dsa: mv88e6xxx: Add SERDES phydev_mac_change up for 6390
phylink wants to know when the MAC layers notices a change in the
link. For the 6390 family, this is a change in the SERDES state.
Add interrupt support for the SERDES interface used to implement
SGMII/1000Base-X/2500Base-X. This is currently limited to ports 9 and
10. Support for the 10G SERDES and other ports will be added later,
building on this basic framework.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 22 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.h | 5 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/serdes.c | 179 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/serdes.h | 16 |
4 files changed, 222 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 5845cbf7f096..17752316ab10 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c | |||
@@ -2337,7 +2337,12 @@ static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port, | |||
2337 | int err; | 2337 | int err; |
2338 | 2338 | ||
2339 | mutex_lock(&chip->reg_lock); | 2339 | mutex_lock(&chip->reg_lock); |
2340 | |||
2340 | err = mv88e6xxx_serdes_power(chip, port, true); | 2341 | err = mv88e6xxx_serdes_power(chip, port, true); |
2342 | |||
2343 | if (!err && chip->info->ops->serdes_irq_setup) | ||
2344 | err = chip->info->ops->serdes_irq_setup(chip, port); | ||
2345 | |||
2341 | mutex_unlock(&chip->reg_lock); | 2346 | mutex_unlock(&chip->reg_lock); |
2342 | 2347 | ||
2343 | return err; | 2348 | return err; |
@@ -2349,8 +2354,13 @@ static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port, | |||
2349 | struct mv88e6xxx_chip *chip = ds->priv; | 2354 | struct mv88e6xxx_chip *chip = ds->priv; |
2350 | 2355 | ||
2351 | mutex_lock(&chip->reg_lock); | 2356 | mutex_lock(&chip->reg_lock); |
2357 | |||
2358 | if (chip->info->ops->serdes_irq_free) | ||
2359 | chip->info->ops->serdes_irq_free(chip, port); | ||
2360 | |||
2352 | if (mv88e6xxx_serdes_power(chip, port, false)) | 2361 | if (mv88e6xxx_serdes_power(chip, port, false)) |
2353 | dev_err(chip->dev, "failed to power off SERDES\n"); | 2362 | dev_err(chip->dev, "failed to power off SERDES\n"); |
2363 | |||
2354 | mutex_unlock(&chip->reg_lock); | 2364 | mutex_unlock(&chip->reg_lock); |
2355 | } | 2365 | } |
2356 | 2366 | ||
@@ -3225,6 +3235,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { | |||
3225 | .vtu_getnext = mv88e6390_g1_vtu_getnext, | 3235 | .vtu_getnext = mv88e6390_g1_vtu_getnext, |
3226 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, | 3236 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, |
3227 | .serdes_power = mv88e6390_serdes_power, | 3237 | .serdes_power = mv88e6390_serdes_power, |
3238 | .serdes_irq_setup = mv88e6390_serdes_irq_setup, | ||
3239 | .serdes_irq_free = mv88e6390_serdes_irq_free, | ||
3228 | .gpio_ops = &mv88e6352_gpio_ops, | 3240 | .gpio_ops = &mv88e6352_gpio_ops, |
3229 | .phylink_validate = mv88e6390_phylink_validate, | 3241 | .phylink_validate = mv88e6390_phylink_validate, |
3230 | }; | 3242 | }; |
@@ -3265,6 +3277,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { | |||
3265 | .vtu_getnext = mv88e6390_g1_vtu_getnext, | 3277 | .vtu_getnext = mv88e6390_g1_vtu_getnext, |
3266 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, | 3278 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, |
3267 | .serdes_power = mv88e6390x_serdes_power, | 3279 | .serdes_power = mv88e6390x_serdes_power, |
3280 | .serdes_irq_setup = mv88e6390_serdes_irq_setup, | ||
3281 | .serdes_irq_free = mv88e6390_serdes_irq_free, | ||
3268 | .gpio_ops = &mv88e6352_gpio_ops, | 3282 | .gpio_ops = &mv88e6352_gpio_ops, |
3269 | .phylink_validate = mv88e6390x_phylink_validate, | 3283 | .phylink_validate = mv88e6390x_phylink_validate, |
3270 | }; | 3284 | }; |
@@ -3305,6 +3319,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { | |||
3305 | .vtu_getnext = mv88e6390_g1_vtu_getnext, | 3319 | .vtu_getnext = mv88e6390_g1_vtu_getnext, |
3306 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, | 3320 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, |
3307 | .serdes_power = mv88e6390_serdes_power, | 3321 | .serdes_power = mv88e6390_serdes_power, |
3322 | .serdes_irq_setup = mv88e6390_serdes_irq_setup, | ||
3323 | .serdes_irq_free = mv88e6390_serdes_irq_free, | ||
3308 | .avb_ops = &mv88e6390_avb_ops, | 3324 | .avb_ops = &mv88e6390_avb_ops, |
3309 | .ptp_ops = &mv88e6352_ptp_ops, | 3325 | .ptp_ops = &mv88e6352_ptp_ops, |
3310 | .phylink_validate = mv88e6390_phylink_validate, | 3326 | .phylink_validate = mv88e6390_phylink_validate, |
@@ -3393,6 +3409,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { | |||
3393 | .vtu_getnext = mv88e6390_g1_vtu_getnext, | 3409 | .vtu_getnext = mv88e6390_g1_vtu_getnext, |
3394 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, | 3410 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, |
3395 | .serdes_power = mv88e6390_serdes_power, | 3411 | .serdes_power = mv88e6390_serdes_power, |
3412 | .serdes_irq_setup = mv88e6390_serdes_irq_setup, | ||
3413 | .serdes_irq_free = mv88e6390_serdes_irq_free, | ||
3396 | .gpio_ops = &mv88e6352_gpio_ops, | 3414 | .gpio_ops = &mv88e6352_gpio_ops, |
3397 | .avb_ops = &mv88e6390_avb_ops, | 3415 | .avb_ops = &mv88e6390_avb_ops, |
3398 | .ptp_ops = &mv88e6352_ptp_ops, | 3416 | .ptp_ops = &mv88e6352_ptp_ops, |
@@ -3694,6 +3712,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { | |||
3694 | .vtu_getnext = mv88e6390_g1_vtu_getnext, | 3712 | .vtu_getnext = mv88e6390_g1_vtu_getnext, |
3695 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, | 3713 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, |
3696 | .serdes_power = mv88e6390_serdes_power, | 3714 | .serdes_power = mv88e6390_serdes_power, |
3715 | .serdes_irq_setup = mv88e6390_serdes_irq_setup, | ||
3716 | .serdes_irq_free = mv88e6390_serdes_irq_free, | ||
3697 | .gpio_ops = &mv88e6352_gpio_ops, | 3717 | .gpio_ops = &mv88e6352_gpio_ops, |
3698 | .avb_ops = &mv88e6390_avb_ops, | 3718 | .avb_ops = &mv88e6390_avb_ops, |
3699 | .ptp_ops = &mv88e6352_ptp_ops, | 3719 | .ptp_ops = &mv88e6352_ptp_ops, |
@@ -3739,6 +3759,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { | |||
3739 | .vtu_getnext = mv88e6390_g1_vtu_getnext, | 3759 | .vtu_getnext = mv88e6390_g1_vtu_getnext, |
3740 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, | 3760 | .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, |
3741 | .serdes_power = mv88e6390x_serdes_power, | 3761 | .serdes_power = mv88e6390x_serdes_power, |
3762 | .serdes_irq_setup = mv88e6390_serdes_irq_setup, | ||
3763 | .serdes_irq_free = mv88e6390_serdes_irq_free, | ||
3742 | .gpio_ops = &mv88e6352_gpio_ops, | 3764 | .gpio_ops = &mv88e6352_gpio_ops, |
3743 | .avb_ops = &mv88e6390_avb_ops, | 3765 | .avb_ops = &mv88e6390_avb_ops, |
3744 | .ptp_ops = &mv88e6352_ptp_ops, | 3766 | .ptp_ops = &mv88e6352_ptp_ops, |
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 577398fe36df..f9ecb7872d32 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h | |||
@@ -200,6 +200,7 @@ struct mv88e6xxx_port { | |||
200 | u64 vtu_member_violation; | 200 | u64 vtu_member_violation; |
201 | u64 vtu_miss_violation; | 201 | u64 vtu_miss_violation; |
202 | u8 cmode; | 202 | u8 cmode; |
203 | int serdes_irq; | ||
203 | }; | 204 | }; |
204 | 205 | ||
205 | struct mv88e6xxx_chip { | 206 | struct mv88e6xxx_chip { |
@@ -434,6 +435,10 @@ struct mv88e6xxx_ops { | |||
434 | /* Power on/off a SERDES interface */ | 435 | /* Power on/off a SERDES interface */ |
435 | int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); | 436 | int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); |
436 | 437 | ||
438 | /* SERDES interrupt handling */ | ||
439 | int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port); | ||
440 | void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port); | ||
441 | |||
437 | /* Statistics from the SERDES interface */ | 442 | /* Statistics from the SERDES interface */ |
438 | int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); | 443 | int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); |
439 | int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, | 444 | int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, |
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 064d0bb8fe02..519346b81b87 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irqdomain.h> | ||
14 | #include <linux/mii.h> | 16 | #include <linux/mii.h> |
15 | 17 | ||
16 | #include "chip.h" | 18 | #include "chip.h" |
@@ -399,6 +401,183 @@ int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) | |||
399 | return 0; | 401 | return 0; |
400 | } | 402 | } |
401 | 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 | |||
402 | int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) | 581 | int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) |
403 | { | 582 | { |
404 | u8 cmode = chip->ports[port].cmode; | 583 | u8 cmode = chip->ports[port].cmode; |
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index a64ca1974988..09da08cb5261 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h | |||
@@ -42,11 +42,27 @@ | |||
42 | #define MV88E6390_SGMII_CONTROL_RESET BIT(15) | 42 | #define MV88E6390_SGMII_CONTROL_RESET BIT(15) |
43 | #define MV88E6390_SGMII_CONTROL_LOOPBACK BIT(14) | 43 | #define MV88E6390_SGMII_CONTROL_LOOPBACK BIT(14) |
44 | #define MV88E6390_SGMII_CONTROL_PDOWN BIT(11) | 44 | #define MV88E6390_SGMII_CONTROL_PDOWN BIT(11) |
45 | #define MV88E6390_SGMII_STATUS 0x2001 | ||
46 | #define MV88E6390_SGMII_STATUS_AN_DONE BIT(5) | ||
47 | #define MV88E6390_SGMII_STATUS_REMOTE_FAULT BIT(4) | ||
48 | #define MV88E6390_SGMII_STATUS_LINK BIT(2) | ||
49 | #define MV88E6390_SGMII_INT_ENABLE 0xa001 | ||
50 | #define MV88E6390_SGMII_INT_SPEED_CHANGE BIT(14) | ||
51 | #define MV88E6390_SGMII_INT_DUPLEX_CHANGE BIT(13) | ||
52 | #define MV88E6390_SGMII_INT_PAGE_RX BIT(12) | ||
53 | #define MV88E6390_SGMII_INT_AN_COMPLETE BIT(11) | ||
54 | #define MV88E6390_SGMII_INT_LINK_DOWN BIT(10) | ||
55 | #define MV88E6390_SGMII_INT_LINK_UP BIT(9) | ||
56 | #define MV88E6390_SGMII_INT_SYMBOL_ERROR BIT(8) | ||
57 | #define MV88E6390_SGMII_INT_FALSE_CARRIER BIT(7) | ||
58 | #define MV88E6390_SGMII_INT_STATUS 0xa002 | ||
45 | 59 | ||
46 | int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); | 60 | int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); |
47 | int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); | 61 | int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); |
48 | int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); | 62 | int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); |
49 | int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); | 63 | int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); |
64 | int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); | ||
65 | void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); | ||
50 | int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); | 66 | int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); |
51 | int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, | 67 | int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, |
52 | int port, uint8_t *data); | 68 | int port, uint8_t *data); |