diff options
Diffstat (limited to 'drivers/net/dsa/ocelot/felix.c')
-rw-r--r-- | drivers/net/dsa/ocelot/felix.c | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 3b738cb2ae6e..d4cc9e60f369 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -1075,9 +1075,12 @@ static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port, phy_interface_t interface) { struct ocelot *ocelot = ds->priv; + struct felix *felix; + + felix = ocelot_to_felix(ocelot); ocelot_phylink_mac_link_down(ocelot, port, link_an_mode, interface, - FELIX_MAC_QUIRKS); + felix->info->quirks); } static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, @@ -1092,7 +1095,7 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, ocelot_phylink_mac_link_up(ocelot, port, phydev, link_an_mode, interface, speed, duplex, tx_pause, rx_pause, - FELIX_MAC_QUIRKS); + felix->info->quirks); if (felix->info->port_sched_speed_set) felix->info->port_sched_speed_set(ocelot, port, speed); @@ -1270,10 +1273,15 @@ static int felix_parse_ports_node(struct felix *felix, err = felix_validate_phy_mode(felix, port, phy_mode); if (err < 0) { - dev_err(dev, "Unsupported PHY mode %s on port %d\n", - phy_modes(phy_mode), port); + dev_info(dev, "Unsupported PHY mode %s on port %d\n", + phy_modes(phy_mode), port); of_node_put(child); - return err; + + /* Leave port_phy_modes[port] = 0, which is also + * PHY_INTERFACE_MODE_NA. This will perform a + * best-effort to bring up as many ports as possible. + */ + continue; } port_phy_modes[port] = phy_mode; @@ -1312,6 +1320,13 @@ static struct regmap *felix_request_regmap_by_name(struct felix *felix, struct resource res; int i; + /* In an MFD configuration, regmaps are registered directly to the + * parent device before the child devices are probed, so there is no + * need to initialize a new one. + */ + if (!felix->info->resources) + return dev_get_regmap(ocelot->dev->parent, resource_name); + for (i = 0; i < felix->info->num_resources; i++) { if (strcmp(resource_name, felix->info->resources[i].name)) continue; @@ -2024,6 +2039,31 @@ static int felix_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, return ocelot_port_del_dscp_prio(ocelot, port, dscp, prio); } +static int felix_get_mm(struct dsa_switch *ds, int port, + struct ethtool_mm_state *state) +{ + struct ocelot *ocelot = ds->priv; + + return ocelot_port_get_mm(ocelot, port, state); +} + +static int felix_set_mm(struct dsa_switch *ds, int port, + struct ethtool_mm_cfg *cfg, + struct netlink_ext_ack *extack) +{ + struct ocelot *ocelot = ds->priv; + + return ocelot_port_set_mm(ocelot, port, cfg, extack); +} + +static void felix_get_mm_stats(struct dsa_switch *ds, int port, + struct ethtool_mm_stats *stats) +{ + struct ocelot *ocelot = ds->priv; + + ocelot_port_get_mm_stats(ocelot, port, stats); +} + const struct dsa_switch_ops felix_switch_ops = { .get_tag_protocol = felix_get_tag_protocol, .change_tag_protocol = felix_change_tag_protocol, @@ -2031,6 +2071,9 @@ const struct dsa_switch_ops felix_switch_ops = { .setup = felix_setup, .teardown = felix_teardown, .set_ageing_time = felix_set_ageing_time, + .get_mm = felix_get_mm, + .set_mm = felix_set_mm, + .get_mm_stats = felix_get_mm_stats, .get_stats64 = felix_get_stats64, .get_pause_stats = felix_get_pause_stats, .get_rmon_stats = felix_get_rmon_stats, @@ -2103,6 +2146,7 @@ const struct dsa_switch_ops felix_switch_ops = { .port_set_host_flood = felix_port_set_host_flood, .port_change_master = felix_port_change_master, }; +EXPORT_SYMBOL_GPL(felix_switch_ops); struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port) { @@ -2114,6 +2158,7 @@ struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port) return dsa_to_port(ds, port)->slave; } +EXPORT_SYMBOL_GPL(felix_port_to_netdev); int felix_netdev_to_port(struct net_device *dev) { @@ -2125,3 +2170,7 @@ int felix_netdev_to_port(struct net_device *dev) return dp->index; } +EXPORT_SYMBOL_GPL(felix_netdev_to_port); + +MODULE_DESCRIPTION("Felix DSA library"); +MODULE_LICENSE("GPL"); |