diff options
Diffstat (limited to 'drivers/net/dsa/lantiq_gswip.c')
-rw-r--r-- | drivers/net/dsa/lantiq_gswip.c | 164 |
1 files changed, 79 insertions, 85 deletions
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index de48b194048f..6eb3140d4044 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -236,7 +236,9 @@ #define GSWIP_TABLE_ACTIVE_VLAN 0x01 #define GSWIP_TABLE_VLAN_MAPPING 0x02 #define GSWIP_TABLE_MAC_BRIDGE 0x0b -#define GSWIP_TABLE_MAC_BRIDGE_STATIC 0x01 /* Static not, aging entry */ +#define GSWIP_TABLE_MAC_BRIDGE_KEY3_FID GENMASK(5, 0) /* Filtering identifier */ +#define GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT GENMASK(7, 4) /* Port on learned entries */ +#define GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC BIT(0) /* Static, non-aging entry */ #define XRX200_GPHY_FW_ALIGN (16 * 1024) @@ -653,14 +655,8 @@ static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add) struct gswip_pce_table_entry vlan_active = {0,}; struct gswip_pce_table_entry vlan_mapping = {0,}; unsigned int cpu_port = priv->hw_info->cpu_port; - unsigned int max_ports = priv->hw_info->max_ports; int err; - if (port >= max_ports) { - dev_err(priv->dev, "single port for %i supported\n", port); - return -EIO; - } - vlan_active.index = port + 1; vlan_active.table = GSWIP_TABLE_ACTIVE_VLAN; vlan_active.key[0] = 0; /* vid */ @@ -695,13 +691,18 @@ static int gswip_port_enable(struct dsa_switch *ds, int port, struct gswip_priv *priv = ds->priv; int err; - if (!dsa_is_user_port(ds, port)) - return 0; - if (!dsa_is_cpu_port(ds, port)) { + u32 mdio_phy = 0; + err = gswip_add_single_port_br(priv, port, true); if (err) return err; + + if (phydev) + mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK; + + gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy, + GSWIP_MDIO_PHYp(port)); } /* RMON Counter Enable for port */ @@ -714,16 +715,6 @@ static int gswip_port_enable(struct dsa_switch *ds, int port, gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN, GSWIP_SDMA_PCTRLp(port)); - if (!dsa_is_cpu_port(ds, port)) { - u32 mdio_phy = 0; - - if (phydev) - mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK; - - gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy, - GSWIP_MDIO_PHYp(port)); - } - return 0; } @@ -731,9 +722,6 @@ static void gswip_port_disable(struct dsa_switch *ds, int port) { struct gswip_priv *priv = ds->priv; - if (!dsa_is_user_port(ds, port)) - return; - gswip_switch_mask(priv, GSWIP_FDMA_PCTRL_EN, 0, GSWIP_FDMA_PCTRLp(port)); gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0, @@ -792,7 +780,7 @@ static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port, } if (vlan_filtering) { - /* Use port based VLAN tag */ + /* Use tag based VLAN */ gswip_switch_mask(priv, GSWIP_PCE_VCTRL_VSR, GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR | @@ -801,7 +789,7 @@ static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port, gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0, GSWIP_PCE_PCTRL_0p(port)); } else { - /* Use port based VLAN tag */ + /* Use port based VLAN */ gswip_switch_mask(priv, GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR | GSWIP_PCE_VCTRL_VEMR, @@ -836,7 +824,7 @@ static int gswip_setup(struct dsa_switch *ds) err = gswip_pce_load_microcode(priv); if (err) { - dev_err(priv->dev, "writing PCE microcode failed, %i", err); + dev_err(priv->dev, "writing PCE microcode failed, %i\n", err); return err; } @@ -898,8 +886,6 @@ static int gswip_setup(struct dsa_switch *ds) ds->mtu_enforcement_ingress = true; - gswip_port_enable(ds, cpu_port, NULL); - ds->configure_vlan_while_not_filtering = false; return 0; @@ -1314,10 +1300,11 @@ static void gswip_port_fast_age(struct dsa_switch *ds, int port) if (!mac_bridge.valid) continue; - if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC) + if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC) continue; - if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port) + if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT, + mac_bridge.val[0])) continue; mac_bridge.valid = false; @@ -1383,7 +1370,8 @@ static int gswip_port_fdb(struct dsa_switch *ds, int port, } if (fid == -1) { - dev_err(priv->dev, "Port not part of a bridge\n"); + dev_err(priv->dev, "no FID found for bridge %s\n", + bridge->name); return -EINVAL; } @@ -1392,9 +1380,9 @@ static int gswip_port_fdb(struct dsa_switch *ds, int port, mac_bridge.key[0] = addr[5] | (addr[4] << 8); mac_bridge.key[1] = addr[3] | (addr[2] << 8); mac_bridge.key[2] = addr[1] | (addr[0] << 8); - mac_bridge.key[3] = fid; + mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_KEY3_FID, fid); mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */ - mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_STATIC; + mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC; mac_bridge.valid = add; err = gswip_pce_table_entry_write(priv, &mac_bridge); @@ -1423,7 +1411,7 @@ static int gswip_port_fdb_dump(struct dsa_switch *ds, int port, { struct gswip_priv *priv = ds->priv; struct gswip_pce_table_entry mac_bridge = {0,}; - unsigned char addr[6]; + unsigned char addr[ETH_ALEN]; int i; int err; @@ -1448,14 +1436,15 @@ static int gswip_port_fdb_dump(struct dsa_switch *ds, int port, addr[2] = (mac_bridge.key[1] >> 8) & 0xff; addr[1] = mac_bridge.key[2] & 0xff; addr[0] = (mac_bridge.key[2] >> 8) & 0xff; - if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC) { + if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC) { if (mac_bridge.val[0] & BIT(port)) { err = cb(addr, 0, true, data); if (err) return err; } } else { - if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) { + if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT, + mac_bridge.val[0])) { err = cb(addr, 0, false, data); if (err) return err; @@ -1474,12 +1463,11 @@ static int gswip_port_max_mtu(struct dsa_switch *ds, int port) static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) { struct gswip_priv *priv = ds->priv; - int cpu_port = priv->hw_info->cpu_port; /* CPU port always has maximum mtu of user ports, so use it to set * switch frame size, including 8 byte special header. */ - if (port == cpu_port) { + if (dsa_is_cpu_port(ds, port)) { new_mtu += 8; gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN, GSWIP_MAC_FLEN); @@ -1516,6 +1504,7 @@ static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port, case 2: case 3: case 4: + case 6: __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces); break; @@ -1547,6 +1536,7 @@ static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port, case 2: case 3: case 4: + case 6: __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces); break; @@ -1670,11 +1660,13 @@ static void gswip_port_set_pause(struct gswip_priv *priv, int port, mdio_phy, GSWIP_MDIO_PHYp(port)); } -static void gswip_phylink_mac_config(struct dsa_switch *ds, int port, +static void gswip_phylink_mac_config(struct phylink_config *config, unsigned int mode, const struct phylink_link_state *state) { - struct gswip_priv *priv = ds->priv; + struct dsa_port *dp = dsa_phylink_to_port(config); + struct gswip_priv *priv = dp->ds->priv; + int port = dp->index; u32 miicfg = 0; miicfg |= GSWIP_MII_CFG_LDCLKDIS; @@ -1700,7 +1692,7 @@ static void gswip_phylink_mac_config(struct dsa_switch *ds, int port, miicfg |= GSWIP_MII_CFG_MODE_GMII; break; default: - dev_err(ds->dev, + dev_err(dp->ds->dev, "Unsupported interface: %d\n", state->interface); return; } @@ -1726,28 +1718,32 @@ static void gswip_phylink_mac_config(struct dsa_switch *ds, int port, } } -static void gswip_phylink_mac_link_down(struct dsa_switch *ds, int port, +static void gswip_phylink_mac_link_down(struct phylink_config *config, unsigned int mode, phy_interface_t interface) { - struct gswip_priv *priv = ds->priv; + struct dsa_port *dp = dsa_phylink_to_port(config); + struct gswip_priv *priv = dp->ds->priv; + int port = dp->index; gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, port); - if (!dsa_is_cpu_port(ds, port)) + if (!dsa_port_is_cpu(dp)) gswip_port_set_link(priv, port, false); } -static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, +static void gswip_phylink_mac_link_up(struct phylink_config *config, + struct phy_device *phydev, unsigned int mode, phy_interface_t interface, - struct phy_device *phydev, int speed, int duplex, bool tx_pause, bool rx_pause) { - struct gswip_priv *priv = ds->priv; + struct dsa_port *dp = dsa_phylink_to_port(config); + struct gswip_priv *priv = dp->ds->priv; + int port = dp->index; - if (!dsa_is_cpu_port(ds, port)) { + if (!dsa_port_is_cpu(dp)) { gswip_port_set_link(priv, port, true); gswip_port_set_speed(priv, port, speed, interface); gswip_port_set_duplex(priv, port, duplex); @@ -1784,7 +1780,7 @@ static u32 gswip_bcm_ram_entry_read(struct gswip_priv *priv, u32 table, err = gswip_switch_r_timeout(priv, GSWIP_BM_RAM_CTRL, GSWIP_BM_RAM_CTRL_BAS); if (err) { - dev_err(priv->dev, "timeout while reading table: %u, index: %u", + dev_err(priv->dev, "timeout while reading table: %u, index: %u\n", table, index); return 0; } @@ -1824,6 +1820,12 @@ static int gswip_get_sset_count(struct dsa_switch *ds, int port, int sset) return ARRAY_SIZE(gswip_rmon_cnt); } +static const struct phylink_mac_ops gswip_phylink_mac_ops = { + .mac_config = gswip_phylink_mac_config, + .mac_link_down = gswip_phylink_mac_link_down, + .mac_link_up = gswip_phylink_mac_link_up, +}; + static const struct dsa_switch_ops gswip_xrx200_switch_ops = { .get_tag_protocol = gswip_get_tag_protocol, .setup = gswip_setup, @@ -1842,9 +1844,6 @@ static const struct dsa_switch_ops gswip_xrx200_switch_ops = { .port_change_mtu = gswip_port_change_mtu, .port_max_mtu = gswip_port_max_mtu, .phylink_get_caps = gswip_xrx200_phylink_get_caps, - .phylink_mac_config = gswip_phylink_mac_config, - .phylink_mac_link_down = gswip_phylink_mac_link_down, - .phylink_mac_link_up = gswip_phylink_mac_link_up, .get_strings = gswip_get_strings, .get_ethtool_stats = gswip_get_ethtool_stats, .get_sset_count = gswip_get_sset_count, @@ -1868,9 +1867,6 @@ static const struct dsa_switch_ops gswip_xrx300_switch_ops = { .port_change_mtu = gswip_port_change_mtu, .port_max_mtu = gswip_port_max_mtu, .phylink_get_caps = gswip_xrx300_phylink_get_caps, - .phylink_mac_config = gswip_phylink_mac_config, - .phylink_mac_link_down = gswip_phylink_mac_link_down, - .phylink_mac_link_up = gswip_phylink_mac_link_up, .get_strings = gswip_get_strings, .get_ethtool_stats = gswip_get_ethtool_stats, .get_sset_count = gswip_get_sset_count, @@ -1923,11 +1919,9 @@ static int gswip_gphy_fw_load(struct gswip_priv *priv, struct gswip_gphy_fw *gph msleep(200); ret = request_firmware(&fw, gphy_fw->fw_name, dev); - if (ret) { - dev_err(dev, "failed to load firmware: %s, error: %i\n", - gphy_fw->fw_name, ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to load firmware: %s\n", + gphy_fw->fw_name); /* GPHY cores need the firmware code in a persistent and contiguous * memory area with a 16 kB boundary aligned start address. @@ -1940,9 +1934,9 @@ static int gswip_gphy_fw_load(struct gswip_priv *priv, struct gswip_gphy_fw *gph dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN); memcpy(fw_addr, fw->data, fw->size); } else { - dev_err(dev, "failed to alloc firmware memory\n"); release_firmware(fw); - return -ENOMEM; + return dev_err_probe(dev, -ENOMEM, + "failed to alloc firmware memory\n"); } release_firmware(fw); @@ -1969,8 +1963,8 @@ static int gswip_gphy_fw_probe(struct gswip_priv *priv, gphy_fw->clk_gate = devm_clk_get(dev, gphyname); if (IS_ERR(gphy_fw->clk_gate)) { - dev_err(dev, "Failed to lookup gate clock\n"); - return PTR_ERR(gphy_fw->clk_gate); + return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate), + "Failed to lookup gate clock\n"); } ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset); @@ -1990,8 +1984,8 @@ static int gswip_gphy_fw_probe(struct gswip_priv *priv, gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name; break; default: - dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode); - return -EINVAL; + return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n", + gphy_mode); } gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np); @@ -2013,7 +2007,7 @@ static void gswip_gphy_fw_remove(struct gswip_priv *priv, ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, 0); if (ret) - dev_err(priv->dev, "can not reset GPHY FW pointer"); + dev_err(priv->dev, "can not reset GPHY FW pointer\n"); clk_disable_unprepare(gphy_fw->clk_gate); @@ -2042,8 +2036,9 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv, priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data; break; default: - dev_err(dev, "unknown GSWIP version: 0x%x", version); - return -ENOENT; + return dev_err_probe(dev, -ENOENT, + "unknown GSWIP version: 0x%x\n", + version); } } @@ -2051,10 +2046,9 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv, if (match && match->data) priv->gphy_fw_name_cfg = match->data; - if (!priv->gphy_fw_name_cfg) { - dev_err(dev, "GPHY compatible type not supported"); - return -ENOENT; - } + if (!priv->gphy_fw_name_cfg) + return dev_err_probe(dev, -ENOENT, + "GPHY compatible type not supported\n"); priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np); if (!priv->num_gphy_fw) @@ -2136,6 +2130,7 @@ static int gswip_probe(struct platform_device *pdev) priv->ds->num_ports = priv->hw_info->max_ports; priv->ds->priv = priv; priv->ds->ops = priv->hw_info->ops; + priv->ds->phylink_mac_ops = &gswip_phylink_mac_ops; priv->dev = dev; mutex_init(&priv->pce_table_lock); version = gswip_switch_r(priv, GSWIP_VERSION); @@ -2154,8 +2149,8 @@ static int gswip_probe(struct platform_device *pdev) return -EINVAL; break; default: - dev_err(dev, "unknown GSWIP version: 0x%x", version); - return -ENOENT; + return dev_err_probe(dev, -ENOENT, + "unknown GSWIP version: 0x%x\n", version); } /* bring up the mdio bus */ @@ -2163,28 +2158,27 @@ static int gswip_probe(struct platform_device *pdev) if (gphy_fw_np) { err = gswip_gphy_fw_list(priv, gphy_fw_np, version); of_node_put(gphy_fw_np); - if (err) { - dev_err(dev, "gphy fw probe failed\n"); - return err; - } + if (err) + return dev_err_probe(dev, err, + "gphy fw probe failed\n"); } /* bring up the mdio bus */ err = gswip_mdio(priv); if (err) { - dev_err(dev, "mdio probe failed\n"); + dev_err_probe(dev, err, "mdio probe failed\n"); goto gphy_fw_remove; } err = dsa_register_switch(priv->ds); if (err) { - dev_err(dev, "dsa switch register failed: %i\n", err); + dev_err_probe(dev, err, "dsa switch registration failed\n"); goto gphy_fw_remove; } if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) { - dev_err(dev, "wrong CPU port defined, HW only supports port: %i", - priv->hw_info->cpu_port); - err = -EINVAL; + err = dev_err_probe(dev, -EINVAL, + "wrong CPU port defined, HW only supports port: %i\n", + priv->hw_info->cpu_port); goto disable_switch; } @@ -2255,7 +2249,7 @@ MODULE_DEVICE_TABLE(of, gswip_of_match); static struct platform_driver gswip_driver = { .probe = gswip_probe, - .remove_new = gswip_remove, + .remove = gswip_remove, .shutdown = gswip_shutdown, .driver = { .name = "gswip", |