| .. | .. |
|---|
| 2310 | 2310 | |
|---|
| 2311 | 2311 | /* If there is a GPIO connected to the reset pin, toggle it */ |
|---|
| 2312 | 2312 | if (gpiod) { |
|---|
| 2313 | + /* If the switch has just been reset and not yet completed |
|---|
| 2314 | + * loading EEPROM, the reset may interrupt the I2C transaction |
|---|
| 2315 | + * mid-byte, causing the first EEPROM read after the reset |
|---|
| 2316 | + * from the wrong location resulting in the switch booting |
|---|
| 2317 | + * to wrong mode and inoperable. |
|---|
| 2318 | + */ |
|---|
| 2319 | + if (chip->info->ops->get_eeprom) |
|---|
| 2320 | + mv88e6xxx_g2_eeprom_wait(chip); |
|---|
| 2321 | + |
|---|
| 2313 | 2322 | gpiod_set_value_cansleep(gpiod, 1); |
|---|
| 2314 | 2323 | usleep_range(10000, 20000); |
|---|
| 2315 | 2324 | gpiod_set_value_cansleep(gpiod, 0); |
|---|
| 2316 | 2325 | usleep_range(10000, 20000); |
|---|
| 2317 | 2326 | |
|---|
| 2318 | | - mv88e6xxx_g1_wait_eeprom_done(chip); |
|---|
| 2327 | + if (chip->info->ops->get_eeprom) |
|---|
| 2328 | + mv88e6xxx_g2_eeprom_wait(chip); |
|---|
| 2319 | 2329 | } |
|---|
| 2320 | 2330 | } |
|---|
| 2321 | 2331 | |
|---|
| .. | .. |
|---|
| 2611 | 2621 | * If this is the upstream port for this switch, enable |
|---|
| 2612 | 2622 | * forwarding of unknown unicasts and multicasts. |
|---|
| 2613 | 2623 | */ |
|---|
| 2614 | | - reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP | |
|---|
| 2615 | | - MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP | |
|---|
| 2624 | + reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP | |
|---|
| 2616 | 2625 | MV88E6XXX_PORT_CTL0_STATE_FORWARDING; |
|---|
| 2626 | + /* Forward any IPv4 IGMP or IPv6 MLD frames received |
|---|
| 2627 | + * by a USER port to the CPU port to allow snooping. |
|---|
| 2628 | + */ |
|---|
| 2629 | + if (dsa_is_user_port(ds, port)) |
|---|
| 2630 | + reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP; |
|---|
| 2631 | + |
|---|
| 2617 | 2632 | err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); |
|---|
| 2618 | 2633 | if (err) |
|---|
| 2619 | 2634 | return err; |
|---|
| .. | .. |
|---|
| 2734 | 2749 | return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; |
|---|
| 2735 | 2750 | else if (chip->info->ops->set_max_frame_size) |
|---|
| 2736 | 2751 | return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; |
|---|
| 2737 | | - return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; |
|---|
| 2752 | + return ETH_DATA_LEN; |
|---|
| 2738 | 2753 | } |
|---|
| 2739 | 2754 | |
|---|
| 2740 | 2755 | static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) |
|---|
| 2741 | 2756 | { |
|---|
| 2742 | 2757 | struct mv88e6xxx_chip *chip = ds->priv; |
|---|
| 2743 | 2758 | int ret = 0; |
|---|
| 2759 | + |
|---|
| 2760 | + /* For families where we don't know how to alter the MTU, |
|---|
| 2761 | + * just accept any value up to ETH_DATA_LEN |
|---|
| 2762 | + */ |
|---|
| 2763 | + if (!chip->info->ops->port_set_jumbo_size && |
|---|
| 2764 | + !chip->info->ops->set_max_frame_size) { |
|---|
| 2765 | + if (new_mtu > ETH_DATA_LEN) |
|---|
| 2766 | + return -EINVAL; |
|---|
| 2767 | + |
|---|
| 2768 | + return 0; |
|---|
| 2769 | + } |
|---|
| 2744 | 2770 | |
|---|
| 2745 | 2771 | if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) |
|---|
| 2746 | 2772 | new_mtu += EDSA_HLEN; |
|---|
| .. | .. |
|---|
| 2750 | 2776 | ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu); |
|---|
| 2751 | 2777 | else if (chip->info->ops->set_max_frame_size) |
|---|
| 2752 | 2778 | ret = chip->info->ops->set_max_frame_size(chip, new_mtu); |
|---|
| 2753 | | - else |
|---|
| 2754 | | - if (new_mtu > 1522) |
|---|
| 2755 | | - ret = -EINVAL; |
|---|
| 2756 | 2779 | mv88e6xxx_reg_unlock(chip); |
|---|
| 2757 | 2780 | |
|---|
| 2758 | 2781 | return ret; |
|---|
| .. | .. |
|---|
| 4169 | 4192 | .set_cpu_port = mv88e6095_g1_set_cpu_port, |
|---|
| 4170 | 4193 | .set_egress_port = mv88e6095_g1_set_egress_port, |
|---|
| 4171 | 4194 | .watchdog_ops = &mv88e6390_watchdog_ops, |
|---|
| 4195 | + .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, |
|---|
| 4172 | 4196 | .reset = mv88e6352_g1_reset, |
|---|
| 4173 | 4197 | .vtu_getnext = mv88e6185_g1_vtu_getnext, |
|---|
| 4174 | 4198 | .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, |
|---|
| .. | .. |
|---|
| 5533 | 5557 | goto out; |
|---|
| 5534 | 5558 | } |
|---|
| 5535 | 5559 | if (chip->reset) |
|---|
| 5536 | | - usleep_range(1000, 2000); |
|---|
| 5560 | + usleep_range(10000, 20000); |
|---|
| 5537 | 5561 | |
|---|
| 5538 | 5562 | err = mv88e6xxx_detect(chip); |
|---|
| 5539 | 5563 | if (err) |
|---|