Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()

New timestamping API was introduced in commit 66f7223039c0 ("net: add
NDOs for configuring hardware timestamping") from kernel v6.6. It is
time to convert DSA to the new API, so that the ndo_eth_ioctl() path can
be removed completely.

Move the ds->ops->port_hwtstamp_get() and ds->ops->port_hwtstamp_set()
calls from dsa_user_ioctl() to dsa_user_hwtstamp_get() and
dsa_user_hwtstamp_set().

Due to the fact that the underlying ifreq type changes to
kernel_hwtstamp_config, the drivers and the Ocelot switchdev front-end,
all hooked up directly or indirectly, must also be converted all at once.

The conversion also updates the comment from dsa_port_supports_hwtstamp(),
which is no longer true because kernel_hwtstamp_config is kernel memory
and does not need copy_to_user(). I've deliberated whether it is
necessary to also update "err != -EOPNOTSUPP" to a more general "!err",
but all drivers now either return 0 or -EOPNOTSUPP.

The existing logic from the ocelot_ioctl() function, to avoid
configuring timestamping if the PHY supports the operation, is obsoleted
by more advanced core logic in dev_set_hwtstamp_phylib().

This is only a partial preparation for proper PHY timestamping support.
None of these switch driver currently sets up PTP traps for PHY
timestamping, so setting dev->see_all_hwtstamp_requests is not yet
necessary and the conversion is relatively trivial.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> # felix, sja1105, mv88e6xxx
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Link: https://patch.msgid.link/20250508095236.887789-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Vladimir Oltean and committed by
Jakub Kicinski
6c14058e 0df69324

+147 -150
+1 -1
drivers/net/dsa/hirschmann/hellcreek.h
··· 244 244 struct sk_buff *tx_skb; 245 245 246 246 /* Current timestamp configuration */ 247 - struct hwtstamp_config tstamp_config; 247 + struct kernel_hwtstamp_config tstamp_config; 248 248 }; 249 249 250 250 struct hellcreek_port {
+9 -15
drivers/net/dsa/hirschmann/hellcreek_hwtstamp.c
··· 40 40 * the user requested what is actually available or not 41 41 */ 42 42 static int hellcreek_set_hwtstamp_config(struct hellcreek *hellcreek, int port, 43 - struct hwtstamp_config *config) 43 + struct kernel_hwtstamp_config *config) 44 44 { 45 45 struct hellcreek_port_hwtstamp *ps = 46 46 &hellcreek->ports[port].port_hwtstamp; ··· 110 110 } 111 111 112 112 int hellcreek_port_hwtstamp_set(struct dsa_switch *ds, int port, 113 - struct ifreq *ifr) 113 + struct kernel_hwtstamp_config *config, 114 + struct netlink_ext_ack *extack) 114 115 { 115 116 struct hellcreek *hellcreek = ds->priv; 116 117 struct hellcreek_port_hwtstamp *ps; 117 - struct hwtstamp_config config; 118 118 int err; 119 119 120 120 ps = &hellcreek->ports[port].port_hwtstamp; 121 121 122 - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 123 - return -EFAULT; 124 - 125 - err = hellcreek_set_hwtstamp_config(hellcreek, port, &config); 122 + err = hellcreek_set_hwtstamp_config(hellcreek, port, config); 126 123 if (err) 127 124 return err; 128 125 129 126 /* Save the chosen configuration to be returned later */ 130 - memcpy(&ps->tstamp_config, &config, sizeof(config)); 127 + ps->tstamp_config = *config; 131 128 132 - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? 133 - -EFAULT : 0; 129 + return 0; 134 130 } 135 131 136 132 int hellcreek_port_hwtstamp_get(struct dsa_switch *ds, int port, 137 - struct ifreq *ifr) 133 + struct kernel_hwtstamp_config *config) 138 134 { 139 135 struct hellcreek *hellcreek = ds->priv; 140 136 struct hellcreek_port_hwtstamp *ps; 141 - struct hwtstamp_config *config; 142 137 143 138 ps = &hellcreek->ports[port].port_hwtstamp; 144 - config = &ps->tstamp_config; 139 + *config = ps->tstamp_config; 145 140 146 - return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ? 147 - -EFAULT : 0; 141 + return 0; 148 142 } 149 143 150 144 /* Returns a pointer to the PTP header if the caller should time stamp, or NULL
+3 -2
drivers/net/dsa/hirschmann/hellcreek_hwtstamp.h
··· 38 38 #define TX_TSTAMP_TIMEOUT msecs_to_jiffies(40) 39 39 40 40 int hellcreek_port_hwtstamp_set(struct dsa_switch *ds, int port, 41 - struct ifreq *ifr); 41 + struct kernel_hwtstamp_config *config, 42 + struct netlink_ext_ack *extack); 42 43 int hellcreek_port_hwtstamp_get(struct dsa_switch *ds, int port, 43 - struct ifreq *ifr); 44 + struct kernel_hwtstamp_config *config); 44 45 45 46 bool hellcreek_port_rxtstamp(struct dsa_switch *ds, int port, 46 47 struct sk_buff *clone, unsigned int type);
+1 -1
drivers/net/dsa/microchip/ksz_common.h
··· 142 142 struct ksz_irq pirq; 143 143 u8 num; 144 144 #if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) 145 - struct hwtstamp_config tstamp_config; 145 + struct kernel_hwtstamp_config tstamp_config; 146 146 bool hwts_tx_en; 147 147 bool hwts_rx_en; 148 148 struct ksz_irq ptpirq;
+10 -16
drivers/net/dsa/microchip/ksz_ptp.c
··· 319 319 return 0; 320 320 } 321 321 322 - int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) 322 + int ksz_hwtstamp_get(struct dsa_switch *ds, int port, 323 + struct kernel_hwtstamp_config *config) 323 324 { 324 325 struct ksz_device *dev = ds->priv; 325 - struct hwtstamp_config *config; 326 326 struct ksz_port *prt; 327 327 328 328 prt = &dev->ports[port]; 329 - config = &prt->tstamp_config; 329 + *config = prt->tstamp_config; 330 330 331 - return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ? 332 - -EFAULT : 0; 331 + return 0; 333 332 } 334 333 335 334 static int ksz_set_hwtstamp_config(struct ksz_device *dev, 336 335 struct ksz_port *prt, 337 - struct hwtstamp_config *config) 336 + struct kernel_hwtstamp_config *config) 338 337 { 339 338 int ret; 340 339 ··· 403 404 return ksz_ptp_enable_mode(dev); 404 405 } 405 406 406 - int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) 407 + int ksz_hwtstamp_set(struct dsa_switch *ds, int port, 408 + struct kernel_hwtstamp_config *config, 409 + struct netlink_ext_ack *extack) 407 410 { 408 411 struct ksz_device *dev = ds->priv; 409 - struct hwtstamp_config config; 410 412 struct ksz_port *prt; 411 413 int ret; 412 414 413 415 prt = &dev->ports[port]; 414 416 415 - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 416 - return -EFAULT; 417 - 418 - ret = ksz_set_hwtstamp_config(dev, prt, &config); 417 + ret = ksz_set_hwtstamp_config(dev, prt, config); 419 418 if (ret) 420 419 return ret; 421 420 422 - memcpy(&prt->tstamp_config, &config, sizeof(config)); 423 - 424 - if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) 425 - return -EFAULT; 421 + prt->tstamp_config = *config; 426 422 427 423 return 0; 428 424 }
+5 -2
drivers/net/dsa/microchip/ksz_ptp.h
··· 39 39 40 40 int ksz_get_ts_info(struct dsa_switch *ds, int port, 41 41 struct kernel_ethtool_ts_info *ts); 42 - int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); 43 - int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); 42 + int ksz_hwtstamp_get(struct dsa_switch *ds, int port, 43 + struct kernel_hwtstamp_config *config); 44 + int ksz_hwtstamp_set(struct dsa_switch *ds, int port, 45 + struct kernel_hwtstamp_config *config, 46 + struct netlink_ext_ack *extack); 44 47 void ksz_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); 45 48 void ksz_port_deferred_xmit(struct kthread_work *work); 46 49 bool ksz_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb,
+1 -1
drivers/net/dsa/mv88e6xxx/chip.h
··· 241 241 u16 tx_seq_id; 242 242 243 243 /* Current timestamp configuration */ 244 - struct hwtstamp_config tstamp_config; 244 + struct kernel_hwtstamp_config tstamp_config; 245 245 }; 246 246 247 247 enum mv88e6xxx_policy_mapping {
+10 -14
drivers/net/dsa/mv88e6xxx/hwtstamp.c
··· 89 89 } 90 90 91 91 static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port, 92 - struct hwtstamp_config *config) 92 + struct kernel_hwtstamp_config *config) 93 93 { 94 94 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; 95 95 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; ··· 169 169 } 170 170 171 171 int mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds, int port, 172 - struct ifreq *ifr) 172 + struct kernel_hwtstamp_config *config, 173 + struct netlink_ext_ack *extack) 173 174 { 174 175 struct mv88e6xxx_chip *chip = ds->priv; 175 176 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; 176 - struct hwtstamp_config config; 177 177 int err; 178 178 179 179 if (!chip->info->ptp_support) 180 180 return -EOPNOTSUPP; 181 181 182 - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 183 - return -EFAULT; 184 - 185 - err = mv88e6xxx_set_hwtstamp_config(chip, port, &config); 182 + err = mv88e6xxx_set_hwtstamp_config(chip, port, config); 186 183 if (err) 187 184 return err; 188 185 189 186 /* Save the chosen configuration to be returned later. */ 190 - memcpy(&ps->tstamp_config, &config, sizeof(config)); 187 + ps->tstamp_config = *config; 191 188 192 - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? 193 - -EFAULT : 0; 189 + return 0; 194 190 } 195 191 196 192 int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port, 197 - struct ifreq *ifr) 193 + struct kernel_hwtstamp_config *config) 198 194 { 199 195 struct mv88e6xxx_chip *chip = ds->priv; 200 196 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; 201 - struct hwtstamp_config *config = &ps->tstamp_config; 202 197 203 198 if (!chip->info->ptp_support) 204 199 return -EOPNOTSUPP; 205 200 206 - return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ? 207 - -EFAULT : 0; 201 + *config = ps->tstamp_config; 202 + 203 + return 0; 208 204 } 209 205 210 206 /* Returns a pointer to the PTP header if the caller should time stamp,
+10 -6
drivers/net/dsa/mv88e6xxx/hwtstamp.h
··· 111 111 #ifdef CONFIG_NET_DSA_MV88E6XXX_PTP 112 112 113 113 int mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds, int port, 114 - struct ifreq *ifr); 114 + struct kernel_hwtstamp_config *cfg, 115 + struct netlink_ext_ack *extack); 115 116 int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port, 116 - struct ifreq *ifr); 117 + struct kernel_hwtstamp_config *cfg); 117 118 118 119 bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port, 119 120 struct sk_buff *clone, unsigned int type); ··· 133 132 134 133 #else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */ 135 134 136 - static inline int mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds, 137 - int port, struct ifreq *ifr) 135 + static inline int 136 + mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds, int port, 137 + struct kernel_hwtstamp_config *config, 138 + struct netlink_ext_ack *extack) 138 139 { 139 140 return -EOPNOTSUPP; 140 141 } 141 142 142 - static inline int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, 143 - int port, struct ifreq *ifr) 143 + static inline int 144 + mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port, 145 + struct kernel_hwtstamp_config *config) 144 146 { 145 147 return -EOPNOTSUPP; 146 148 }
+7 -4
drivers/net/dsa/ocelot/felix.c
··· 1774 1774 } 1775 1775 1776 1776 static int felix_hwtstamp_get(struct dsa_switch *ds, int port, 1777 - struct ifreq *ifr) 1777 + struct kernel_hwtstamp_config *config) 1778 1778 { 1779 1779 struct ocelot *ocelot = ds->priv; 1780 1780 1781 - return ocelot_hwstamp_get(ocelot, port, ifr); 1781 + ocelot_hwstamp_get(ocelot, port, config); 1782 + 1783 + return 0; 1782 1784 } 1783 1785 1784 1786 static int felix_hwtstamp_set(struct dsa_switch *ds, int port, 1785 - struct ifreq *ifr) 1787 + struct kernel_hwtstamp_config *config, 1788 + struct netlink_ext_ack *extack) 1786 1789 { 1787 1790 struct ocelot *ocelot = ds->priv; 1788 1791 struct felix *felix = ocelot_to_felix(ocelot); 1789 1792 bool using_tag_8021q; 1790 1793 int err; 1791 1794 1792 - err = ocelot_hwstamp_set(ocelot, port, ifr); 1795 + err = ocelot_hwstamp_set(ocelot, port, config, extack); 1793 1796 if (err) 1794 1797 return err; 1795 1798
+13 -19
drivers/net/dsa/sja1105/sja1105_ptp.c
··· 58 58 #define ptp_data_to_sja1105(d) \ 59 59 container_of((d), struct sja1105_private, ptp_data) 60 60 61 - int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) 61 + int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, 62 + struct kernel_hwtstamp_config *config, 63 + struct netlink_ext_ack *extack) 62 64 { 63 65 struct sja1105_private *priv = ds->priv; 64 66 unsigned long hwts_tx_en, hwts_rx_en; 65 - struct hwtstamp_config config; 66 - 67 - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 68 - return -EFAULT; 69 67 70 68 hwts_tx_en = priv->hwts_tx_en; 71 69 hwts_rx_en = priv->hwts_rx_en; 72 70 73 - switch (config.tx_type) { 71 + switch (config->tx_type) { 74 72 case HWTSTAMP_TX_OFF: 75 73 hwts_tx_en &= ~BIT(port); 76 74 break; ··· 79 81 return -ERANGE; 80 82 } 81 83 82 - switch (config.rx_filter) { 84 + switch (config->rx_filter) { 83 85 case HWTSTAMP_FILTER_NONE: 84 86 hwts_rx_en &= ~BIT(port); 85 87 break; ··· 90 92 return -ERANGE; 91 93 } 92 94 93 - if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) 94 - return -EFAULT; 95 - 96 95 priv->hwts_tx_en = hwts_tx_en; 97 96 priv->hwts_rx_en = hwts_rx_en; 98 97 99 98 return 0; 100 99 } 101 100 102 - int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) 101 + int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, 102 + struct kernel_hwtstamp_config *config) 103 103 { 104 104 struct sja1105_private *priv = ds->priv; 105 - struct hwtstamp_config config; 106 105 107 - config.flags = 0; 106 + config->flags = 0; 108 107 if (priv->hwts_tx_en & BIT(port)) 109 - config.tx_type = HWTSTAMP_TX_ON; 108 + config->tx_type = HWTSTAMP_TX_ON; 110 109 else 111 - config.tx_type = HWTSTAMP_TX_OFF; 110 + config->tx_type = HWTSTAMP_TX_OFF; 112 111 if (priv->hwts_rx_en & BIT(port)) 113 - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 112 + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 114 113 else 115 - config.rx_filter = HWTSTAMP_FILTER_NONE; 114 + config->rx_filter = HWTSTAMP_FILTER_NONE; 116 115 117 - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? 118 - -EFAULT : 0; 116 + return 0; 119 117 } 120 118 121 119 int sja1105_get_ts_info(struct dsa_switch *ds, int port,
+5 -2
drivers/net/dsa/sja1105/sja1105_ptp.h
··· 112 112 void sja1105_port_txtstamp(struct dsa_switch *ds, int port, 113 113 struct sk_buff *skb); 114 114 115 - int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); 115 + int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, 116 + struct kernel_hwtstamp_config *config); 116 117 117 - int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); 118 + int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, 119 + struct kernel_hwtstamp_config *config, 120 + struct netlink_ext_ack *extack); 118 121 119 122 int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns, 120 123 struct ptp_system_timestamp *sts);
+21 -12
drivers/net/ethernet/mscc/ocelot_net.c
··· 870 870 871 871 static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 872 872 { 873 + return phy_mii_ioctl(dev->phydev, ifr, cmd); 874 + } 875 + 876 + static int ocelot_port_hwtstamp_get(struct net_device *dev, 877 + struct kernel_hwtstamp_config *cfg) 878 + { 873 879 struct ocelot_port_private *priv = netdev_priv(dev); 874 880 struct ocelot *ocelot = priv->port.ocelot; 875 881 int port = priv->port.index; 876 882 877 - /* If the attached PHY device isn't capable of timestamping operations, 878 - * use our own (when possible). 879 - */ 880 - if (!phy_has_hwtstamp(dev->phydev) && ocelot->ptp) { 881 - switch (cmd) { 882 - case SIOCSHWTSTAMP: 883 - return ocelot_hwstamp_set(ocelot, port, ifr); 884 - case SIOCGHWTSTAMP: 885 - return ocelot_hwstamp_get(ocelot, port, ifr); 886 - } 887 - } 883 + ocelot_hwstamp_get(ocelot, port, cfg); 888 884 889 - return phy_mii_ioctl(dev->phydev, ifr, cmd); 885 + return 0; 886 + } 887 + 888 + static int ocelot_port_hwtstamp_set(struct net_device *dev, 889 + struct kernel_hwtstamp_config *cfg, 890 + struct netlink_ext_ack *extack) 891 + { 892 + struct ocelot_port_private *priv = netdev_priv(dev); 893 + struct ocelot *ocelot = priv->port.ocelot; 894 + int port = priv->port.index; 895 + 896 + return ocelot_hwstamp_set(ocelot, port, cfg, extack); 890 897 } 891 898 892 899 static int ocelot_change_mtu(struct net_device *dev, int new_mtu) ··· 924 917 .ndo_set_features = ocelot_set_features, 925 918 .ndo_setup_tc = ocelot_setup_tc, 926 919 .ndo_eth_ioctl = ocelot_ioctl, 920 + .ndo_hwtstamp_get = ocelot_port_hwtstamp_get, 921 + .ndo_hwtstamp_set = ocelot_port_hwtstamp_set, 927 922 }; 928 923 929 924 struct net_device *ocelot_port_to_netdev(struct ocelot *ocelot, int port)
+13 -30
drivers/net/ethernet/mscc/ocelot_ptp.c
··· 514 514 return 0; 515 515 } 516 516 517 - int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) 517 + void ocelot_hwstamp_get(struct ocelot *ocelot, int port, 518 + struct kernel_hwtstamp_config *cfg) 518 519 { 519 520 struct ocelot_port *ocelot_port = ocelot->ports[port]; 520 - struct hwtstamp_config cfg = {}; 521 521 522 522 switch (ocelot_port->ptp_cmd) { 523 523 case IFH_REW_OP_TWO_STEP_PTP: 524 - cfg.tx_type = HWTSTAMP_TX_ON; 524 + cfg->tx_type = HWTSTAMP_TX_ON; 525 525 break; 526 526 case IFH_REW_OP_ORIGIN_PTP: 527 - cfg.tx_type = HWTSTAMP_TX_ONESTEP_SYNC; 527 + cfg->tx_type = HWTSTAMP_TX_ONESTEP_SYNC; 528 528 break; 529 529 default: 530 - cfg.tx_type = HWTSTAMP_TX_OFF; 530 + cfg->tx_type = HWTSTAMP_TX_OFF; 531 531 break; 532 532 } 533 533 534 - cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto); 535 - 536 - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 534 + cfg->rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto); 537 535 } 538 536 EXPORT_SYMBOL(ocelot_hwstamp_get); 539 537 540 - int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) 538 + int ocelot_hwstamp_set(struct ocelot *ocelot, int port, 539 + struct kernel_hwtstamp_config *cfg, 540 + struct netlink_ext_ack *extack) 541 541 { 542 542 struct ocelot_port *ocelot_port = ocelot->ports[port]; 543 - int ptp_cmd, old_ptp_cmd = ocelot_port->ptp_cmd; 544 543 bool l2 = false, l4 = false; 545 - struct hwtstamp_config cfg; 546 - bool old_l2, old_l4; 544 + int ptp_cmd; 547 545 int err; 548 546 549 - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 550 - return -EFAULT; 551 - 552 547 /* Tx type sanity check */ 553 - err = ocelot_ptp_tx_type_to_cmd(cfg.tx_type, &ptp_cmd); 548 + err = ocelot_ptp_tx_type_to_cmd(cfg->tx_type, &ptp_cmd); 554 549 if (err) 555 550 return err; 556 551 557 - switch (cfg.rx_filter) { 552 + switch (cfg->rx_filter) { 558 553 case HWTSTAMP_FILTER_NONE: 559 554 break; 560 555 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: ··· 572 577 return -ERANGE; 573 578 } 574 579 575 - old_l2 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L2; 576 - old_l4 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L4; 577 - 578 580 err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); 579 581 if (err) 580 582 return err; 581 583 582 584 ocelot_port->ptp_cmd = ptp_cmd; 583 585 584 - cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto); 585 - 586 - if (copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg))) { 587 - err = -EFAULT; 588 - goto out_restore_ptp_traps; 589 - } 586 + cfg->rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto); 590 587 591 588 return 0; 592 - out_restore_ptp_traps: 593 - ocelot_setup_ptp_traps(ocelot, port, old_l2, old_l4); 594 - ocelot_port->ptp_cmd = old_ptp_cmd; 595 - return err; 596 589 } 597 590 EXPORT_SYMBOL(ocelot_hwstamp_set); 598 591
+3 -2
include/net/dsa.h
··· 1131 1131 * PTP functionality 1132 1132 */ 1133 1133 int (*port_hwtstamp_get)(struct dsa_switch *ds, int port, 1134 - struct ifreq *ifr); 1134 + struct kernel_hwtstamp_config *config); 1135 1135 int (*port_hwtstamp_set)(struct dsa_switch *ds, int port, 1136 - struct ifreq *ifr); 1136 + struct kernel_hwtstamp_config *config, 1137 + struct netlink_ext_ack *extack); 1137 1138 void (*port_txtstamp)(struct dsa_switch *ds, int port, 1138 1139 struct sk_buff *skb); 1139 1140 bool (*port_rxtstamp)(struct dsa_switch *ds, int port,
+5 -2
include/soc/mscc/ocelot.h
··· 1073 1073 int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, 1074 1074 bool untagged); 1075 1075 int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid); 1076 - int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr); 1077 - int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr); 1076 + void ocelot_hwstamp_get(struct ocelot *ocelot, int port, 1077 + struct kernel_hwtstamp_config *cfg); 1078 + int ocelot_hwstamp_set(struct ocelot *ocelot, int port, 1079 + struct kernel_hwtstamp_config *cfg, 1080 + struct netlink_ext_ack *extack); 1078 1081 int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port, 1079 1082 struct sk_buff *skb, 1080 1083 struct sk_buff **clone);
+3 -7
net/dsa/port.c
··· 116 116 117 117 bool dsa_port_supports_hwtstamp(struct dsa_port *dp) 118 118 { 119 + struct kernel_hwtstamp_config config = {}; 119 120 struct dsa_switch *ds = dp->ds; 120 - struct ifreq ifr = {}; 121 121 int err; 122 122 123 123 if (!ds->ops->port_hwtstamp_get || !ds->ops->port_hwtstamp_set) 124 124 return false; 125 125 126 - /* "See through" shim implementations of the "get" method. 127 - * Since we can't cook up a complete ioctl request structure, this will 128 - * fail in copy_to_user() with -EFAULT, which hopefully is enough to 129 - * detect a valid implementation. 130 - */ 131 - err = ds->ops->port_hwtstamp_get(ds, dp->index, &ifr); 126 + /* "See through" shim implementations of the "get" method. */ 127 + err = ds->ops->port_hwtstamp_get(ds, dp->index, &config); 132 128 return err != -EOPNOTSUPP; 133 129 } 134 130
+27 -14
net/dsa/user.c
··· 578 578 static int dsa_user_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 579 579 { 580 580 struct dsa_user_priv *p = netdev_priv(dev); 581 - struct dsa_switch *ds = p->dp->ds; 582 - int port = p->dp->index; 583 - 584 - /* Pass through to switch driver if it supports timestamping */ 585 - switch (cmd) { 586 - case SIOCGHWTSTAMP: 587 - if (ds->ops->port_hwtstamp_get) 588 - return ds->ops->port_hwtstamp_get(ds, port, ifr); 589 - break; 590 - case SIOCSHWTSTAMP: 591 - if (ds->ops->port_hwtstamp_set) 592 - return ds->ops->port_hwtstamp_set(ds, port, ifr); 593 - break; 594 - } 595 581 596 582 return phylink_mii_ioctl(p->dp->pl, ifr, cmd); 597 583 } ··· 2560 2574 return 0; 2561 2575 } 2562 2576 2577 + static int dsa_user_hwtstamp_get(struct net_device *dev, 2578 + struct kernel_hwtstamp_config *cfg) 2579 + { 2580 + struct dsa_port *dp = dsa_user_to_port(dev); 2581 + struct dsa_switch *ds = dp->ds; 2582 + 2583 + if (!ds->ops->port_hwtstamp_get) 2584 + return -EOPNOTSUPP; 2585 + 2586 + return ds->ops->port_hwtstamp_get(ds, dp->index, cfg); 2587 + } 2588 + 2589 + static int dsa_user_hwtstamp_set(struct net_device *dev, 2590 + struct kernel_hwtstamp_config *cfg, 2591 + struct netlink_ext_ack *extack) 2592 + { 2593 + struct dsa_port *dp = dsa_user_to_port(dev); 2594 + struct dsa_switch *ds = dp->ds; 2595 + 2596 + if (!ds->ops->port_hwtstamp_set) 2597 + return -EOPNOTSUPP; 2598 + 2599 + return ds->ops->port_hwtstamp_set(ds, dp->index, cfg, extack); 2600 + } 2601 + 2563 2602 static const struct net_device_ops dsa_user_netdev_ops = { 2564 2603 .ndo_open = dsa_user_open, 2565 2604 .ndo_stop = dsa_user_close, ··· 2606 2595 .ndo_vlan_rx_kill_vid = dsa_user_vlan_rx_kill_vid, 2607 2596 .ndo_change_mtu = dsa_user_change_mtu, 2608 2597 .ndo_fill_forward_path = dsa_user_fill_forward_path, 2598 + .ndo_hwtstamp_get = dsa_user_hwtstamp_get, 2599 + .ndo_hwtstamp_set = dsa_user_hwtstamp_set, 2609 2600 }; 2610 2601 2611 2602 static const struct device_type dsa_type = {