diff options
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 84 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.h | 6 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1.c | 89 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1.h | 2 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global2.h | 4 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global2_scratch.c | 35 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/pcs-6185.c | 3 |
7 files changed, 66 insertions, 157 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 2ad9e4cd7b..0918bd6fa8 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -637,12 +637,12 @@ static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, MAC_1000FD; } -static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip) +static int mv88e63xx_get_port_serdes_cmode(struct mv88e6xxx_chip *chip, int port) { u16 reg, val; int err; - err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, ®); + err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); if (err) return err; @@ -651,16 +651,16 @@ static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip) return 0xf; val = reg & ~MV88E6XXX_PORT_STS_PHY_DETECT; - err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, val); + err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, val); if (err) return err; - err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &val); + err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val); if (err) return err; /* Restore PHY_DETECT value */ - err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, reg); + err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); if (err) return err; @@ -688,7 +688,7 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, if (err <= 0) return; - cmode = mv88e6352_get_port4_serdes_cmode(chip); + cmode = mv88e63xx_get_port_serdes_cmode(chip, port); if (cmode < 0) dev_err(chip->dev, "p%d: failed to read serdes cmode\n", port); @@ -701,12 +701,23 @@ static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, struct phylink_config *config) { unsigned long *supported = config->supported_interfaces; + int cmode; /* Translate the default cmode */ mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; + + /* Port 0/1 are serdes only ports */ + if (port == 0 || port == 1) { + cmode = mv88e63xx_get_port_serdes_cmode(chip, port); + if (cmode < 0) + dev_err(chip->dev, "p%d: failed to read serdes cmode\n", + port); + else + mv88e6xxx_translate_cmode(cmode, supported); + } } static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, @@ -1511,14 +1522,14 @@ static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, } static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_eee *e) + struct ethtool_keee *e) { /* Nothing to do on the port's MAC */ return 0; } static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_eee *e) + struct ethtool_keee *e) { /* Nothing to do on the port's MAC */ return 0; @@ -3135,7 +3146,6 @@ static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip) static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) { struct gpio_desc *gpiod = chip->reset; - int err; /* If there is a GPIO connected to the reset pin, toggle it */ if (gpiod) { @@ -3144,26 +3154,17 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) * mid-byte, causing the first EEPROM read after the reset * from the wrong location resulting in the switch booting * to wrong mode and inoperable. - * For this reason, switch families with EEPROM support - * generally wait for EEPROM loads to complete as their pre- - * and post-reset handlers. */ - if (chip->info->ops->hardware_reset_pre) { - err = chip->info->ops->hardware_reset_pre(chip); - if (err) - dev_err(chip->dev, "pre-reset error: %d\n", err); - } + if (chip->info->ops->get_eeprom) + mv88e6xxx_g2_eeprom_wait(chip); gpiod_set_value_cansleep(gpiod, 1); usleep_range(10000, 20000); gpiod_set_value_cansleep(gpiod, 0); usleep_range(10000, 20000); - if (chip->info->ops->hardware_reset_post) { - err = chip->info->ops->hardware_reset_post(chip); - if (err) - dev_err(chip->dev, "post-reset error: %d\n", err); - } + if (chip->info->ops->get_eeprom) + mv88e6xxx_g2_eeprom_wait(chip); } } @@ -3729,7 +3730,7 @@ static int mv88e6xxx_mdio_read_c45(struct mii_bus *bus, int phy, int devad, int err; if (!chip->info->ops->phy_read_c45) - return 0xffff; + return -ENODEV; mv88e6xxx_reg_lock(chip); err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val); @@ -3782,7 +3783,10 @@ static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip, if (external) { mv88e6xxx_reg_lock(chip); - err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true); + if (chip->info->family == MV88E6XXX_FAMILY_6393) + err = mv88e6393x_g2_scratch_gpio_set_smi(chip, true); + else + err = mv88e6390_g2_scratch_gpio_set_smi(chip, true); mv88e6xxx_reg_unlock(chip); if (err) @@ -4390,8 +4394,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -4582,8 +4584,6 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { .watchdog_ops = &mv88e6097_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6352_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -4684,8 +4684,6 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .watchdog_ops = &mv88e6097_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6352_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -4780,8 +4778,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -4840,8 +4836,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -4898,8 +4892,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -4959,8 +4951,6 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .watchdog_ops = &mv88e6097_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6352_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -5014,8 +5004,6 @@ static const struct mv88e6xxx_ops mv88e6250_ops = { .watchdog_ops = &mv88e6250_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6250_g1_wait_eeprom_done_prereset, - .hardware_reset_post = mv88e6xxx_g1_wait_eeprom_done, .reset = mv88e6250_g1_reset, .vtu_getnext = mv88e6185_g1_vtu_getnext, .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, @@ -5063,8 +5051,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -5124,8 +5110,6 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6185_g1_vtu_getnext, .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, @@ -5172,8 +5156,6 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .set_egress_port = mv88e6095_g1_set_egress_port, .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6185_g1_vtu_getnext, .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, @@ -5224,8 +5206,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -5381,8 +5361,6 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .watchdog_ops = &mv88e6097_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6352_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -5445,8 +5423,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -5509,8 +5485,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, @@ -5576,8 +5550,6 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = { .watchdog_ops = &mv88e6393x_watchdog_ops, .mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, - .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, - .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, .rmu_disable = mv88e6390_g1_rmu_disable, .atu_get_hash = mv88e6165_g1_atu_get_hash, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index c34caf9815..85eb293381 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -487,12 +487,6 @@ struct mv88e6xxx_ops { int (*ppu_enable)(struct mv88e6xxx_chip *chip); int (*ppu_disable)(struct mv88e6xxx_chip *chip); - /* Additional handlers to run before and after hard reset, to make sure - * that the switch and EEPROM are in a good state. - */ - int (*hardware_reset_pre)(struct mv88e6xxx_chip *chip); - int (*hardware_reset_post)(struct mv88e6xxx_chip *chip); - /* Switch Software Reset */ int (*reset)(struct mv88e6xxx_chip *chip); diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c index 9820cd5967..49444a72ff 100644 --- a/drivers/net/dsa/mv88e6xxx/global1.c +++ b/drivers/net/dsa/mv88e6xxx/global1.c @@ -75,95 +75,6 @@ static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip) return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); } -static int mv88e6250_g1_eeprom_reload(struct mv88e6xxx_chip *chip) -{ - /* MV88E6185_G1_CTL1_RELOAD_EEPROM is also valid for 88E6250 */ - int bit = __bf_shf(MV88E6185_G1_CTL1_RELOAD_EEPROM); - u16 val; - int err; - - err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); - if (err) - return err; - - val |= MV88E6185_G1_CTL1_RELOAD_EEPROM; - - err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); - if (err) - return err; - - return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_CTL1, bit, 0); -} - -/* Returns 0 when done, -EBUSY when waiting, other negative codes on error */ -static int mv88e6xxx_g1_is_eeprom_done(struct mv88e6xxx_chip *chip) -{ - u16 val; - int err; - - err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val); - if (err < 0) { - dev_err(chip->dev, "Error reading status"); - return err; - } - - /* If the switch is still resetting, it may not - * respond on the bus, and so MDIO read returns - * 0xffff. Differentiate between that, and waiting for - * the EEPROM to be done by bit 0 being set. - */ - if (val == 0xffff || !(val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE))) - return -EBUSY; - - return 0; -} - -/* As the EEInt (EEPROM done) flag clears on read if the status register, this - * function must be called directly after a hard reset or EEPROM ReLoad request, - * or the done condition may have been missed - */ -int mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip) -{ - const unsigned long timeout = jiffies + 1 * HZ; - int ret; - - /* Wait up to 1 second for the switch to finish reading the - * EEPROM. - */ - while (time_before(jiffies, timeout)) { - ret = mv88e6xxx_g1_is_eeprom_done(chip); - if (ret != -EBUSY) - return ret; - } - - dev_err(chip->dev, "Timeout waiting for EEPROM done"); - return -ETIMEDOUT; -} - -int mv88e6250_g1_wait_eeprom_done_prereset(struct mv88e6xxx_chip *chip) -{ - int ret; - - ret = mv88e6xxx_g1_is_eeprom_done(chip); - if (ret != -EBUSY) - return ret; - - /* Pre-reset, we don't know the state of the switch - when - * mv88e6xxx_g1_is_eeprom_done() returns -EBUSY, that may be because - * the switch is actually busy reading the EEPROM, or because - * MV88E6XXX_G1_STS_IRQ_EEPROM_DONE has been cleared by an unrelated - * status register read already. - * - * To account for the latter case, trigger another EEPROM reload for - * another chance at seeing the done flag. - */ - ret = mv88e6250_g1_eeprom_reload(chip); - if (ret) - return ret; - - return mv88e6xxx_g1_wait_eeprom_done(chip); -} - /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 * Offset 0x03: Switch MAC Address Register Bytes 4 & 5 diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h index 3dbb7a1b8f..1095261f5b 100644 --- a/drivers/net/dsa/mv88e6xxx/global1.h +++ b/drivers/net/dsa/mv88e6xxx/global1.h @@ -282,8 +282,6 @@ int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr); int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip); int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip); int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip); -int mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip); -int mv88e6250_g1_wait_eeprom_done_prereset(struct mv88e6xxx_chip *chip); int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip); int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip); diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h index d9434f7cae..82f9b410de 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.h +++ b/drivers/net/dsa/mv88e6xxx/global2.h @@ -378,8 +378,10 @@ extern const struct mv88e6xxx_avb_ops mv88e6390_avb_ops; extern const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops; -int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, +int mv88e6390_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, bool external); +int mv88e6393x_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, + bool external); int mv88e6352_g2_scratch_port_has_serdes(struct mv88e6xxx_chip *chip, int port); int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin); int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats); diff --git a/drivers/net/dsa/mv88e6xxx/global2_scratch.c b/drivers/net/dsa/mv88e6xxx/global2_scratch.c index a9d6e40321..61ab6cc4fb 100644 --- a/drivers/net/dsa/mv88e6xxx/global2_scratch.c +++ b/drivers/net/dsa/mv88e6xxx/global2_scratch.c @@ -240,7 +240,7 @@ const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = { }; /** - * mv88e6xxx_g2_scratch_gpio_set_smi - set gpio muxing for external smi + * mv88e6390_g2_scratch_gpio_set_smi - set gpio muxing for external smi * @chip: chip private data * @external: set mux for external smi, or free for gpio usage * @@ -248,7 +248,7 @@ const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = { * an external SMI interface, or they may be made free for other * GPIO uses. */ -int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, +int mv88e6390_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, bool external) { int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG; @@ -291,6 +291,37 @@ int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, } /** + * mv88e6393x_g2_scratch_gpio_set_smi - set gpio muxing for external smi + * @chip: chip private data + * @external: set mux for external smi, or free for gpio usage + * + * MV88E6191X/6193X/6393X GPIO pins 9 and 10 can be configured as an + * external SMI interface or as regular GPIO-s. + * + * They however have a different register layout then the existing + * function. + */ + +int mv88e6393x_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, + bool external) +{ + int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG; + int err; + u8 val; + + err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val); + if (err) + return err; + + if (external) + val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI; + else + val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI; + + return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val); +} + +/** * mv88e6352_g2_scratch_port_has_serdes - indicate if a port can have a serdes * @chip: chip private data * @port: port number to check for serdes diff --git a/drivers/net/dsa/mv88e6xxx/pcs-6185.c b/drivers/net/dsa/mv88e6xxx/pcs-6185.c index 4d677f8368..5a27d047a3 100644 --- a/drivers/net/dsa/mv88e6xxx/pcs-6185.c +++ b/drivers/net/dsa/mv88e6xxx/pcs-6185.c @@ -95,7 +95,7 @@ static void mv88e6185_pcs_get_state(struct phylink_pcs *pcs, } } -static int mv88e6185_pcs_config(struct phylink_pcs *pcs, unsigned int mode, +static int mv88e6185_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, const unsigned long *advertising, bool permit_pause_to_mac) @@ -137,6 +137,7 @@ static int mv88e6185_pcs_init(struct mv88e6xxx_chip *chip, int port) mpcs->chip = chip; mpcs->port = port; mpcs->phylink_pcs.ops = &mv88e6185_phylink_pcs_ops; + mpcs->phylink_pcs.neg_mode = true; irq = mv88e6xxx_serdes_irq_mapping(chip, port); if (irq) { |