diff options
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 3 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/serdes.c | 47 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/serdes.h | 4 |
3 files changed, 54 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 545eb9c6c3fc..e7f68ac0c7e3 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3308,6 +3308,9 @@ static const struct mv88e6xxx_ops mv88e6097_ops = { .serdes_power = mv88e6185_serdes_power, .serdes_get_lane = mv88e6185_serdes_get_lane, .serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6097_serdes_irq_enable, + .serdes_irq_status = mv88e6097_serdes_irq_status, .pot_clear = mv88e6xxx_g2_pot_clear, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6085_g1_rmu_disable, diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index d4f40a739b17..e60e8f0d0225 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -490,6 +490,53 @@ int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, return 0; } +int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool enable) +{ + u8 cmode = chip->ports[port].cmode; + + /* The serdes interrupts are enabled in the G2_INT_MASK register. We + * need to return 0 to avoid returning -EOPNOTSUPP in + * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable + */ + switch (cmode) { + case MV88E6185_PORT_STS_CMODE_SERDES: + case MV88E6185_PORT_STS_CMODE_1000BASE_X: + return 0; + } + + return -EOPNOTSUPP; +} + +static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port) +{ + u16 status; + int err; + + err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status); + if (err) { + dev_err(chip->dev, "can't read port status: %d\n", err); + return; + } + + dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK)); +} + +irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, + u8 lane) +{ + u8 cmode = chip->ports[port].cmode; + + switch (cmode) { + case MV88E6185_PORT_STS_CMODE_SERDES: + case MV88E6185_PORT_STS_CMODE_1000BASE_X: + mv88e6097_serdes_irq_link(chip, port); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) { u8 cmode = chip->ports[port].cmode; diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index c24ec4122c9e..93822ef9bab8 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -110,10 +110,14 @@ int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, bool on); int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, bool on); +int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool enable); int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable); int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable); +irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, + u8 lane); irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, u8 lane); irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, |