diff options
Diffstat (limited to 'drivers/net/dsa/sja1105')
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105.h | 2 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_ethtool.c | 10 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_flower.c | 3 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_main.c | 145 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_mdio.c | 34 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_ptp.c | 68 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_ptp.h | 9 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_static_config.c | 14 |
8 files changed, 142 insertions, 143 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 8c66d3bf61f0..dceb96ae9c83 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -278,7 +278,7 @@ struct sja1105_private { struct mii_bus *mdio_base_t1; struct mii_bus *mdio_base_tx; struct mii_bus *mdio_pcs; - struct dw_xpcs *xpcs[SJA1105_MAX_NUM_PORTS]; + struct phylink_pcs *pcs[SJA1105_MAX_NUM_PORTS]; struct sja1105_ptp_data ptp_data; struct sja1105_tas_data tas_data; }; diff --git a/drivers/net/dsa/sja1105/sja1105_ethtool.c b/drivers/net/dsa/sja1105/sja1105_ethtool.c index decc6c931dc1..84d7d3f66bd0 100644 --- a/drivers/net/dsa/sja1105/sja1105_ethtool.c +++ b/drivers/net/dsa/sja1105/sja1105_ethtool.c @@ -571,6 +571,9 @@ void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data) max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER; for (i = 0; i < max_ctr; i++) { + if (!strlen(sja1105_port_counters[i].name)) + continue; + rc = sja1105_port_counter_read(priv, port, i, &data[k++]); if (rc) { dev_err(ds->dev, @@ -586,7 +589,6 @@ void sja1105_get_strings(struct dsa_switch *ds, int port, { struct sja1105_private *priv = ds->priv; enum sja1105_counter_index max_ctr, i; - char *p = data; if (stringset != ETH_SS_STATS) return; @@ -598,8 +600,10 @@ void sja1105_get_strings(struct dsa_switch *ds, int port, max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER; for (i = 0; i < max_ctr; i++) { - strscpy(p, sja1105_port_counters[i].name, ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; + if (!strlen(sja1105_port_counters[i].name)) + continue; + + ethtool_puts(&data, sja1105_port_counters[i].name); } } diff --git a/drivers/net/dsa/sja1105/sja1105_flower.c b/drivers/net/dsa/sja1105/sja1105_flower.c index 9e8ca182c722..05d8ed3121e7 100644 --- a/drivers/net/dsa/sja1105/sja1105_flower.c +++ b/drivers/net/dsa/sja1105/sja1105_flower.c @@ -214,6 +214,9 @@ static int sja1105_flower_parse_key(struct sja1105_private *priv, return -EOPNOTSUPP; } + if (flow_rule_match_has_control_flags(rule, extack)) + return -EOPNOTSUPP; + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { struct flow_match_basic match; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 6646f7fb0f90..f674c400f05b 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -15,7 +15,6 @@ #include <linux/of.h> #include <linux/of_net.h> #include <linux/of_mdio.h> -#include <linux/pcs/pcs-xpcs.h> #include <linux/netdev_features.h> #include <linux/netdevice.h> #include <linux/if_bridge.h> @@ -1188,9 +1187,8 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv, struct device_node *ports_node) { struct device *dev = &priv->spidev->dev; - struct device_node *child; - for_each_available_child_of_node(ports_node, child) { + for_each_available_child_of_node_scoped(ports_node, child) { struct device_node *phy_node; phy_interface_t phy_mode; u32 index; @@ -1200,7 +1198,6 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv, if (of_property_read_u32(child, "reg", &index) < 0) { dev_err(dev, "Port number not defined in device tree " "(property \"reg\")\n"); - of_node_put(child); return -ENODEV; } @@ -1210,7 +1207,6 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv, dev_err(dev, "Failed to read phy-mode or " "phy-interface-type property for port %d\n", index); - of_node_put(child); return -ENODEV; } @@ -1219,7 +1215,6 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv, if (!of_phy_is_fixed_link(child)) { dev_err(dev, "phy-handle or fixed-link " "properties missing!\n"); - of_node_put(child); return -ENODEV; } /* phy-handle is missing, but fixed-link isn't. @@ -1233,10 +1228,8 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv, priv->phy_mode[index] = phy_mode; err = sja1105_parse_rgmii_delays(priv, index, child); - if (err) { - of_node_put(child); + if (err) return err; - } } return 0; @@ -1263,29 +1256,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv) return rc; } -/* Convert link speed from SJA1105 to ethtool encoding */ -static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv, - u64 speed) -{ - if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) - return SPEED_10; - if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) - return SPEED_100; - if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) - return SPEED_1000; - if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS]) - return SPEED_2500; - return SPEED_UNKNOWN; -} - -/* Set link speed in the MAC configuration for a specific port. */ -static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, - int speed_mbps) +static int sja1105_set_port_speed(struct sja1105_private *priv, int port, + int speed_mbps) { struct sja1105_mac_config_entry *mac; - struct device *dev = priv->ds->dev; u64 speed; - int rc; /* On P/Q/R/S, one can read from the device via the MAC reconfiguration * tables. On E/T, MAC reconfig tables are not readable, only writable. @@ -1319,7 +1294,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; break; default: - dev_err(dev, "Invalid speed %iMbps\n", speed_mbps); + dev_err(priv->ds->dev, "Invalid speed %iMbps\n", speed_mbps); return -EINVAL; } @@ -1331,11 +1306,31 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, * we need to configure the PCS only (if even that). */ if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII) - mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; + speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX) - mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; - else - mac[port].speed = speed; + speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; + + mac[port].speed = speed; + + return 0; +} + +/* Write the MAC Configuration Table entry and, if necessary, the CGU settings, + * after a link speedchange for this port. + */ +static int sja1105_set_port_config(struct sja1105_private *priv, int port) +{ + struct sja1105_mac_config_entry *mac; + struct device *dev = priv->ds->dev; + int rc; + + /* On P/Q/R/S, one can read from the device via the MAC reconfiguration + * tables. On E/T, MAC reconfig tables are not readable, only writable. + * We have to *know* what the MAC looks like. For the sake of keeping + * the code common, we'll use the static configuration tables as a + * reasonable approximation for both E/T and P/Q/R/S. + */ + mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; /* Write to the dynamic reconfiguration tables */ rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port, @@ -1358,34 +1353,42 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, } static struct phylink_pcs * -sja1105_mac_select_pcs(struct dsa_switch *ds, int port, phy_interface_t iface) +sja1105_mac_select_pcs(struct phylink_config *config, phy_interface_t iface) { - struct sja1105_private *priv = ds->priv; - struct dw_xpcs *xpcs = priv->xpcs[port]; + struct dsa_port *dp = dsa_phylink_to_port(config); + struct sja1105_private *priv = dp->ds->priv; - if (xpcs) - return &xpcs->pcs; + return priv->pcs[dp->index]; +} - return NULL; +static void sja1105_mac_config(struct phylink_config *config, + unsigned int mode, + const struct phylink_link_state *state) +{ } -static void sja1105_mac_link_down(struct dsa_switch *ds, int port, +static void sja1105_mac_link_down(struct phylink_config *config, unsigned int mode, phy_interface_t interface) { - sja1105_inhibit_tx(ds->priv, BIT(port), true); + struct dsa_port *dp = dsa_phylink_to_port(config); + + sja1105_inhibit_tx(dp->ds->priv, BIT(dp->index), true); } -static void sja1105_mac_link_up(struct dsa_switch *ds, int port, +static void sja1105_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 sja1105_private *priv = ds->priv; + struct dsa_port *dp = dsa_phylink_to_port(config); + struct sja1105_private *priv = dp->ds->priv; + int port = dp->index; - sja1105_adjust_port_config(priv, port, speed); + if (!sja1105_set_port_speed(priv, port, speed)) + sja1105_set_port_config(priv, port); sja1105_inhibit_tx(priv, BIT(port), false); } @@ -2078,6 +2081,7 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port, switch (state) { case BR_STATE_DISABLED: case BR_STATE_BLOCKING: + case BR_STATE_LISTENING: /* From UM10944 description of DRPDTAG (why put this there?): * "Management traffic flows to the port regardless of the state * of the INGRESS flag". So BPDUs are still be allowed to pass. @@ -2087,11 +2091,6 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port, mac[port].egress = false; mac[port].dyn_learn = false; break; - case BR_STATE_LISTENING: - mac[port].ingress = true; - mac[port].egress = false; - mac[port].dyn_learn = false; - break; case BR_STATE_LEARNING: mac[port].ingress = true; mac[port].egress = false; @@ -2122,14 +2121,13 @@ static int sja1105_bridge_join(struct dsa_switch *ds, int port, if (rc) return rc; - rc = dsa_tag_8021q_bridge_join(ds, port, bridge); + rc = dsa_tag_8021q_bridge_join(ds, port, bridge, tx_fwd_offload, + extack); if (rc) { sja1105_bridge_member(ds, port, bridge, false); return rc; } - *tx_fwd_offload = true; - return 0; } @@ -2289,8 +2287,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv, { struct ptp_system_timestamp ptp_sts_before; struct ptp_system_timestamp ptp_sts_after; - int speed_mbps[SJA1105_MAX_NUM_PORTS]; u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0}; + u64 mac_speed[SJA1105_MAX_NUM_PORTS]; struct sja1105_mac_config_entry *mac; struct dsa_switch *ds = priv->ds; s64 t1, t2, t3, t4; @@ -2303,17 +2301,16 @@ int sja1105_static_config_reload(struct sja1105_private *priv, mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; - /* Back up the dynamic link speed changed by sja1105_adjust_port_config + /* Back up the dynamic link speed changed by sja1105_set_port_speed() * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the * switch wants to see in the static config in order to allow us to * change it through the dynamic interface later. */ for (i = 0; i < ds->num_ports; i++) { - speed_mbps[i] = sja1105_port_speed_to_ethtool(priv, - mac[i].speed); + mac_speed[i] = mac[i].speed; mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; - if (priv->xpcs[i]) + if (priv->pcs[i]) bmcr[i] = mdiobus_c45_read(priv->mdio_pcs, i, MDIO_MMD_VEND2, MDIO_CTRL1); } @@ -2370,14 +2367,15 @@ int sja1105_static_config_reload(struct sja1105_private *priv, } for (i = 0; i < ds->num_ports; i++) { - struct dw_xpcs *xpcs = priv->xpcs[i]; + struct phylink_pcs *pcs = priv->pcs[i]; unsigned int neg_mode; - rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]); + mac[i].speed = mac_speed[i]; + rc = sja1105_set_port_config(priv, i); if (rc < 0) goto out; - if (!xpcs) + if (!pcs) continue; if (bmcr[i] & BMCR_ANENABLE) @@ -2385,7 +2383,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv, else neg_mode = PHYLINK_PCS_NEG_OUTBAND; - rc = xpcs_do_config(xpcs, priv->phy_mode[i], NULL, neg_mode); + rc = pcs->ops->pcs_config(pcs, neg_mode, priv->phy_mode[i], + NULL, true); if (rc < 0) goto out; @@ -2401,8 +2400,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv, else speed = SPEED_10; - xpcs_link_up(&xpcs->pcs, neg_mode, priv->phy_mode[i], - speed, DUPLEX_FULL); + pcs->ops->pcs_link_up(pcs, neg_mode, priv->phy_mode[i], + speed, DUPLEX_FULL); } } @@ -3154,10 +3153,8 @@ static int sja1105_setup(struct dsa_switch *ds) * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid. */ ds->vlan_filtering_is_global = true; - ds->untag_bridge_pvid = true; ds->fdb_isolation = true; - /* tag_8021q has 3 bits for the VBID, and the value 0 is reserved */ - ds->max_num_bridges = 7; + ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; /* Advertise the 8 egress queues */ ds->num_tx_queues = SJA1105_NUM_TC; @@ -3198,6 +3195,13 @@ static void sja1105_teardown(struct dsa_switch *ds) sja1105_static_config_free(&priv->static_config); } +static const struct phylink_mac_ops sja1105_phylink_mac_ops = { + .mac_select_pcs = sja1105_mac_select_pcs, + .mac_config = sja1105_mac_config, + .mac_link_up = sja1105_mac_link_up, + .mac_link_down = sja1105_mac_link_down, +}; + static const struct dsa_switch_ops sja1105_switch_ops = { .get_tag_protocol = sja1105_get_tag_protocol, .connect_tag_protocol = sja1105_connect_tag_protocol, @@ -3207,9 +3211,6 @@ static const struct dsa_switch_ops sja1105_switch_ops = { .port_change_mtu = sja1105_change_mtu, .port_max_mtu = sja1105_get_max_mtu, .phylink_get_caps = sja1105_phylink_get_caps, - .phylink_mac_select_pcs = sja1105_mac_select_pcs, - .phylink_mac_link_up = sja1105_mac_link_up, - .phylink_mac_link_down = sja1105_mac_link_down, .get_strings = sja1105_get_strings, .get_ethtool_stats = sja1105_get_ethtool_stats, .get_sset_count = sja1105_get_sset_count, @@ -3375,6 +3376,7 @@ static int sja1105_probe(struct spi_device *spi) ds->dev = dev; ds->num_ports = priv->info->num_ports; ds->ops = &sja1105_switch_ops; + ds->phylink_mac_ops = &sja1105_phylink_mac_ops; ds->priv = priv; priv->ds = ds; @@ -3456,7 +3458,6 @@ MODULE_DEVICE_TABLE(spi, sja1105_spi_ids); static struct spi_driver sja1105_driver = { .driver = { .name = "sja1105", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(sja1105_dt_ids), }, .id_table = sja1105_spi_ids, diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c index 52ddb4ef259e..8d535c033cef 100644 --- a/drivers/net/dsa/sja1105/sja1105_mdio.c +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c @@ -400,7 +400,7 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv) } for (port = 0; port < ds->num_ports; port++) { - struct dw_xpcs *xpcs; + struct phylink_pcs *pcs; if (dsa_is_unused_port(ds, port)) continue; @@ -409,13 +409,13 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv) priv->phy_mode[port] != PHY_INTERFACE_MODE_2500BASEX) continue; - xpcs = xpcs_create_mdiodev(bus, port, priv->phy_mode[port]); - if (IS_ERR(xpcs)) { - rc = PTR_ERR(xpcs); + pcs = xpcs_create_pcs_mdiodev(bus, port); + if (IS_ERR(pcs)) { + rc = PTR_ERR(pcs); goto out_pcs_free; } - priv->xpcs[port] = xpcs; + priv->pcs[port] = pcs; } priv->mdio_pcs = bus; @@ -424,11 +424,10 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv) out_pcs_free: for (port = 0; port < ds->num_ports; port++) { - if (!priv->xpcs[port]) - continue; - - xpcs_destroy(priv->xpcs[port]); - priv->xpcs[port] = NULL; + if (priv->pcs[port]) { + xpcs_destroy_pcs(priv->pcs[port]); + priv->pcs[port] = NULL; + } } mdiobus_unregister(bus); @@ -446,11 +445,10 @@ static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv) return; for (port = 0; port < ds->num_ports; port++) { - if (!priv->xpcs[port]) - continue; - - xpcs_destroy(priv->xpcs[port]); - priv->xpcs[port] = NULL; + if (priv->pcs[port]) { + xpcs_destroy_pcs(priv->pcs[port]); + priv->pcs[port] = NULL; + } } mdiobus_unregister(priv->mdio_pcs); @@ -470,13 +468,10 @@ int sja1105_mdiobus_register(struct dsa_switch *ds) if (rc) return rc; - mdio_node = of_get_child_by_name(switch_node, "mdios"); + mdio_node = of_get_available_child_by_name(switch_node, "mdios"); if (!mdio_node) return 0; - if (!of_device_is_available(mdio_node)) - goto out_put_mdio_node; - if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) { rc = sja1105_mdiobus_base_tx_register(priv, mdio_node); if (rc) @@ -489,7 +484,6 @@ int sja1105_mdiobus_register(struct dsa_switch *ds) goto err_free_base_tx_mdiobus; } -out_put_mdio_node: of_node_put(mdio_node); return 0; diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c index a7d41e781398..fefe46e2a5e6 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.c +++ b/drivers/net/dsa/sja1105/sja1105_ptp.c @@ -58,60 +58,64 @@ enum sja1105_ptp_clk_mode { #define ptp_data_to_sja1105(d) \ container_of((d), struct sja1105_private, ptp_data) -int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) +int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack) { struct sja1105_private *priv = ds->priv; - struct hwtstamp_config config; + unsigned long hwts_tx_en, hwts_rx_en; - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) - return -EFAULT; + hwts_tx_en = priv->hwts_tx_en; + hwts_rx_en = priv->hwts_rx_en; - switch (config.tx_type) { + switch (config->tx_type) { case HWTSTAMP_TX_OFF: - priv->hwts_tx_en &= ~BIT(port); + hwts_tx_en &= ~BIT(port); break; case HWTSTAMP_TX_ON: - priv->hwts_tx_en |= BIT(port); + hwts_tx_en |= BIT(port); break; default: return -ERANGE; } - switch (config.rx_filter) { + switch (config->rx_filter) { case HWTSTAMP_FILTER_NONE: - priv->hwts_rx_en &= ~BIT(port); + hwts_rx_en &= ~BIT(port); break; - default: - priv->hwts_rx_en |= BIT(port); + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + hwts_rx_en |= BIT(port); break; + default: + return -ERANGE; } - if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) - return -EFAULT; + priv->hwts_tx_en = hwts_tx_en; + priv->hwts_rx_en = hwts_rx_en; + return 0; } -int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) +int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config) { struct sja1105_private *priv = ds->priv; - struct hwtstamp_config config; - config.flags = 0; + config->flags = 0; if (priv->hwts_tx_en & BIT(port)) - config.tx_type = HWTSTAMP_TX_ON; + config->tx_type = HWTSTAMP_TX_ON; else - config.tx_type = HWTSTAMP_TX_OFF; + config->tx_type = HWTSTAMP_TX_OFF; if (priv->hwts_rx_en & BIT(port)) - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; else - config.rx_filter = HWTSTAMP_FILTER_NONE; + config->rx_filter = HWTSTAMP_FILTER_NONE; - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? - -EFAULT : 0; + return 0; } int sja1105_get_ts_info(struct dsa_switch *ds, int port, - struct ethtool_ts_info *info) + struct kernel_ethtool_ts_info *info) { struct sja1105_private *priv = ds->priv; struct sja1105_ptp_data *ptp_data = &priv->ptp_data; @@ -727,10 +731,6 @@ static int sja1105_per_out_enable(struct sja1105_private *priv, if (perout->index != 0) return -EOPNOTSUPP; - /* Reject requests with unsupported flags */ - if (perout->flags) - return -EOPNOTSUPP; - mutex_lock(&ptp_data->lock); rc = sja1105_change_ptp_clk_pin_func(priv, PTP_PF_PEROUT); @@ -810,13 +810,6 @@ static int sja1105_extts_enable(struct sja1105_private *priv, if (extts->index != 0) return -EOPNOTSUPP; - /* Reject requests with unsupported flags */ - if (extts->flags & ~(PTP_ENABLE_FEATURE | - PTP_RISING_EDGE | - PTP_FALLING_EDGE | - PTP_STRICT_FLAGS)) - return -EOPNOTSUPP; - /* We can only enable time stamping on both edges, sadly. */ if ((extts->flags & PTP_STRICT_FLAGS) && (extts->flags & PTP_ENABLE_FEATURE) && @@ -832,7 +825,7 @@ static int sja1105_extts_enable(struct sja1105_private *priv, if (on) sja1105_ptp_extts_setup_timer(&priv->ptp_data); else - del_timer_sync(&priv->ptp_data.extts_timer); + timer_delete_sync(&priv->ptp_data.extts_timer); return 0; } @@ -902,6 +895,9 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds) .n_pins = 1, .n_ext_ts = 1, .n_per_out = 1, + .supported_extts_flags = PTP_RISING_EDGE | + PTP_FALLING_EDGE | + PTP_STRICT_FLAGS, }; /* Only used on SJA1105 */ @@ -929,7 +925,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds) if (IS_ERR_OR_NULL(ptp_data->clock)) return; - del_timer_sync(&ptp_data->extts_timer); + timer_delete_sync(&ptp_data->extts_timer); ptp_cancel_worker_sync(ptp_data->clock); skb_queue_purge(&ptp_data->skb_txtstamp_queue); skb_queue_purge(&ptp_data->skb_rxtstamp_queue); diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h index 416461ee95d2..325e3777ea07 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.h +++ b/drivers/net/dsa/sja1105/sja1105_ptp.h @@ -101,7 +101,7 @@ void sja1105pqrs_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd, enum packing_op op); int sja1105_get_ts_info(struct dsa_switch *ds, int port, - struct ethtool_ts_info *ts); + struct kernel_ethtool_ts_info *ts); void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot, struct sk_buff *clone); @@ -112,9 +112,12 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port, void sja1105_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); -int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); +int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config); -int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); +int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack); int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns, struct ptp_system_timestamp *sts); diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c index baba204ad62f..ffece8a400a6 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.c +++ b/drivers/net/dsa/sja1105/sja1105_static_config.c @@ -26,12 +26,8 @@ void sja1105_pack(void *buf, const u64 *val, int start, int end, size_t len) pr_err("Start bit (%d) expected to be larger than end (%d)\n", start, end); } else if (rc == -ERANGE) { - if ((start - end + 1) > 64) - pr_err("Field %d-%d too large for 64 bits!\n", - start, end); - else - pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n", - *val, start, end); + pr_err("Field %d-%d too large for 64 bits!\n", + start, end); } dump_stack(); } @@ -1921,8 +1917,10 @@ int sja1105_table_delete_entry(struct sja1105_table *table, int i) if (i > table->entry_count) return -ERANGE; - memmove(entries + i * entry_size, entries + (i + 1) * entry_size, - (table->entry_count - i) * entry_size); + if (i + 1 < table->entry_count) { + memmove(entries + i * entry_size, entries + (i + 1) * entry_size, + (table->entry_count - i - 1) * entry_size); + } table->entry_count--; |