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

net: Convert PHYs hwtstamp callback to use kernel_hwtstamp_config

The PHYs hwtstamp callback are still getting the timestamp config from
ifreq and using copy_from/to_user.
Get rid of these functions by using timestamp configuration in parameter.
This also allow to move on to kernel_hwtstamp_config and be similar to
net devices using the new ndo_hwstamp_get/set.

This adds the possibility to manipulate the timestamp configuration
from the kernel which was not possible with the copy_from/to_user.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Kory Maincent and committed by
David S. Miller
446e2305 18de1e51

+82 -77
+6 -9
drivers/net/phy/bcm-phy-ptp.c
··· 782 782 } 783 783 784 784 static int bcm_ptp_hwtstamp(struct mii_timestamper *mii_ts, 785 - struct ifreq *ifr) 785 + struct kernel_hwtstamp_config *cfg, 786 + struct netlink_ext_ack *extack) 786 787 { 787 788 struct bcm_ptp_private *priv = mii2priv(mii_ts); 788 - struct hwtstamp_config cfg; 789 789 u16 mode, ctrl; 790 790 791 - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 792 - return -EFAULT; 793 - 794 - switch (cfg.rx_filter) { 791 + switch (cfg->rx_filter) { 795 792 case HWTSTAMP_FILTER_NONE: 796 793 priv->hwts_rx = false; 797 794 break; ··· 801 804 case HWTSTAMP_FILTER_PTP_V2_EVENT: 802 805 case HWTSTAMP_FILTER_PTP_V2_SYNC: 803 806 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 804 - cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 807 + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 805 808 priv->hwts_rx = true; 806 809 break; 807 810 default: 808 811 return -ERANGE; 809 812 } 810 813 811 - priv->tx_type = cfg.tx_type; 814 + priv->tx_type = cfg->tx_type; 812 815 813 816 ctrl = priv->hwts_rx ? SLICE_RX_EN : 0; 814 817 ctrl |= priv->tx_type != HWTSTAMP_TX_OFF ? SLICE_TX_EN : 0; ··· 837 840 /* purge existing data */ 838 841 skb_queue_purge(&priv->tx_queue); 839 842 840 - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 843 + return 0; 841 844 } 842 845 843 846 static int bcm_ptp_ts_info(struct mii_timestamper *mii_ts,
+11 -13
drivers/net/phy/dp83640.c
··· 1207 1207 return IRQ_HANDLED; 1208 1208 } 1209 1209 1210 - static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) 1210 + static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, 1211 + struct kernel_hwtstamp_config *cfg, 1212 + struct netlink_ext_ack *extack) 1211 1213 { 1212 1214 struct dp83640_private *dp83640 = 1213 1215 container_of(mii_ts, struct dp83640_private, mii_ts); 1214 - struct hwtstamp_config cfg; 1215 1216 u16 txcfg0, rxcfg0; 1216 1217 1217 - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 1218 - return -EFAULT; 1219 - 1220 - if (cfg.tx_type < 0 || cfg.tx_type > HWTSTAMP_TX_ONESTEP_SYNC) 1218 + if (cfg->tx_type < 0 || cfg->tx_type > HWTSTAMP_TX_ONESTEP_SYNC) 1221 1219 return -ERANGE; 1222 1220 1223 - dp83640->hwts_tx_en = cfg.tx_type; 1221 + dp83640->hwts_tx_en = cfg->tx_type; 1224 1222 1225 - switch (cfg.rx_filter) { 1223 + switch (cfg->rx_filter) { 1226 1224 case HWTSTAMP_FILTER_NONE: 1227 1225 dp83640->hwts_rx_en = 0; 1228 1226 dp83640->layer = 0; ··· 1232 1234 dp83640->hwts_rx_en = 1; 1233 1235 dp83640->layer = PTP_CLASS_L4; 1234 1236 dp83640->version = PTP_CLASS_V1; 1235 - cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 1237 + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 1236 1238 break; 1237 1239 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 1238 1240 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: ··· 1240 1242 dp83640->hwts_rx_en = 1; 1241 1243 dp83640->layer = PTP_CLASS_L4; 1242 1244 dp83640->version = PTP_CLASS_V2; 1243 - cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 1245 + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 1244 1246 break; 1245 1247 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 1246 1248 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: ··· 1248 1250 dp83640->hwts_rx_en = 1; 1249 1251 dp83640->layer = PTP_CLASS_L2; 1250 1252 dp83640->version = PTP_CLASS_V2; 1251 - cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 1253 + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 1252 1254 break; 1253 1255 case HWTSTAMP_FILTER_PTP_V2_EVENT: 1254 1256 case HWTSTAMP_FILTER_PTP_V2_SYNC: ··· 1256 1258 dp83640->hwts_rx_en = 1; 1257 1259 dp83640->layer = PTP_CLASS_L4 | PTP_CLASS_L2; 1258 1260 dp83640->version = PTP_CLASS_V2; 1259 - cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 1261 + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 1260 1262 break; 1261 1263 default: 1262 1264 return -ERANGE; ··· 1290 1292 1291 1293 mutex_unlock(&dp83640->clock->extreg_lock); 1292 1294 1293 - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1295 + return 0; 1294 1296 } 1295 1297 1296 1298 static void rx_timestamp_work(struct work_struct *work)
+17 -21
drivers/net/phy/micrel.c
··· 2395 2395 lanphy_read_page_reg(phydev, 5, PTP_TSU_INT_STS); 2396 2396 } 2397 2397 2398 - static int lan8814_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) 2398 + static int lan8814_hwtstamp(struct mii_timestamper *mii_ts, 2399 + struct kernel_hwtstamp_config *config, 2400 + struct netlink_ext_ack *extack) 2399 2401 { 2400 2402 struct kszphy_ptp_priv *ptp_priv = 2401 2403 container_of(mii_ts, struct kszphy_ptp_priv, mii_ts); 2402 2404 struct phy_device *phydev = ptp_priv->phydev; 2403 2405 struct lan8814_shared_priv *shared = phydev->shared->priv; 2404 2406 struct lan8814_ptp_rx_ts *rx_ts, *tmp; 2405 - struct hwtstamp_config config; 2406 2407 int txcfg = 0, rxcfg = 0; 2407 2408 int pkt_ts_enable; 2408 2409 2409 - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 2410 - return -EFAULT; 2410 + ptp_priv->hwts_tx_type = config->tx_type; 2411 + ptp_priv->rx_filter = config->rx_filter; 2411 2412 2412 - ptp_priv->hwts_tx_type = config.tx_type; 2413 - ptp_priv->rx_filter = config.rx_filter; 2414 - 2415 - switch (config.rx_filter) { 2413 + switch (config->rx_filter) { 2416 2414 case HWTSTAMP_FILTER_NONE: 2417 2415 ptp_priv->layer = 0; 2418 2416 ptp_priv->version = 0; ··· 2456 2458 lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD, 2457 2459 PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_); 2458 2460 2459 - if (config.rx_filter != HWTSTAMP_FILTER_NONE) 2461 + if (config->rx_filter != HWTSTAMP_FILTER_NONE) 2460 2462 lan8814_config_ts_intr(ptp_priv->phydev, true); 2461 2463 else 2462 2464 lan8814_config_ts_intr(ptp_priv->phydev, false); 2463 2465 2464 2466 mutex_lock(&shared->shared_lock); 2465 - if (config.rx_filter != HWTSTAMP_FILTER_NONE) 2467 + if (config->rx_filter != HWTSTAMP_FILTER_NONE) 2466 2468 shared->ref++; 2467 2469 else 2468 2470 shared->ref--; ··· 2486 2488 lan8814_flush_fifo(ptp_priv->phydev, false); 2487 2489 lan8814_flush_fifo(ptp_priv->phydev, true); 2488 2490 2489 - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; 2491 + return 0; 2490 2492 } 2491 2493 2492 2494 static void lan8814_txtstamp(struct mii_timestamper *mii_ts, ··· 3701 3703 #define LAN8841_PTP_TX_TIMESTAMP_EN 443 3702 3704 #define LAN8841_PTP_TX_MOD 445 3703 3705 3704 - static int lan8841_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) 3706 + static int lan8841_hwtstamp(struct mii_timestamper *mii_ts, 3707 + struct kernel_hwtstamp_config *config, 3708 + struct netlink_ext_ack *extack) 3705 3709 { 3706 3710 struct kszphy_ptp_priv *ptp_priv = container_of(mii_ts, struct kszphy_ptp_priv, mii_ts); 3707 3711 struct phy_device *phydev = ptp_priv->phydev; 3708 - struct hwtstamp_config config; 3709 3712 int txcfg = 0, rxcfg = 0; 3710 3713 int pkt_ts_enable; 3711 3714 3712 - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 3713 - return -EFAULT; 3715 + ptp_priv->hwts_tx_type = config->tx_type; 3716 + ptp_priv->rx_filter = config->rx_filter; 3714 3717 3715 - ptp_priv->hwts_tx_type = config.tx_type; 3716 - ptp_priv->rx_filter = config.rx_filter; 3717 - 3718 - switch (config.rx_filter) { 3718 + switch (config->rx_filter) { 3719 3719 case HWTSTAMP_FILTER_NONE: 3720 3720 ptp_priv->layer = 0; 3721 3721 ptp_priv->version = 0; ··· 3767 3771 3768 3772 /* Now enable/disable the timestamping */ 3769 3773 lan8841_ptp_enable_processing(ptp_priv, 3770 - config.rx_filter != HWTSTAMP_FILTER_NONE); 3774 + config->rx_filter != HWTSTAMP_FILTER_NONE); 3771 3775 3772 3776 skb_queue_purge(&ptp_priv->tx_queue); 3773 3777 3774 3778 lan8841_ptp_flush_fifo(ptp_priv); 3775 3779 3776 - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; 3780 + return 0; 3777 3781 } 3778 3782 3779 3783 static bool lan8841_rxtstamp(struct mii_timestamper *mii_ts,
+8 -10
drivers/net/phy/mscc/mscc_ptp.c
··· 1045 1045 val); 1046 1046 } 1047 1047 1048 - static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) 1048 + static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts, 1049 + struct kernel_hwtstamp_config *cfg, 1050 + struct netlink_ext_ack *extack) 1049 1051 { 1050 1052 struct vsc8531_private *vsc8531 = 1051 1053 container_of(mii_ts, struct vsc8531_private, mii_ts); 1052 1054 struct phy_device *phydev = vsc8531->ptp->phydev; 1053 - struct hwtstamp_config cfg; 1054 1055 bool one_step = false; 1055 1056 u32 val; 1056 1057 1057 - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 1058 - return -EFAULT; 1059 - 1060 - switch (cfg.tx_type) { 1058 + switch (cfg->tx_type) { 1061 1059 case HWTSTAMP_TX_ONESTEP_SYNC: 1062 1060 one_step = true; 1063 1061 break; ··· 1067 1069 return -ERANGE; 1068 1070 } 1069 1071 1070 - vsc8531->ptp->tx_type = cfg.tx_type; 1072 + vsc8531->ptp->tx_type = cfg->tx_type; 1071 1073 1072 - switch (cfg.rx_filter) { 1074 + switch (cfg->rx_filter) { 1073 1075 case HWTSTAMP_FILTER_NONE: 1074 1076 break; 1075 1077 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: ··· 1082 1084 return -ERANGE; 1083 1085 } 1084 1086 1085 - vsc8531->ptp->rx_filter = cfg.rx_filter; 1087 + vsc8531->ptp->rx_filter = cfg->rx_filter; 1086 1088 1087 1089 mutex_lock(&vsc8531->ts_lock); 1088 1090 ··· 1130 1132 vsc8531->ptp->configured = 1; 1131 1133 mutex_unlock(&vsc8531->ts_lock); 1132 1134 1133 - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1135 + return 0; 1134 1136 } 1135 1137 1136 1138 static int vsc85xx_ts_info(struct mii_timestamper *mii_ts,
+7 -10
drivers/net/phy/nxp-c45-tja11xx.c
··· 1022 1022 } 1023 1023 1024 1024 static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts, 1025 - struct ifreq *ifreq) 1025 + struct kernel_hwtstamp_config *cfg, 1026 + struct netlink_ext_ack *extack) 1026 1027 { 1027 1028 struct nxp_c45_phy *priv = container_of(mii_ts, struct nxp_c45_phy, 1028 1029 mii_ts); 1029 1030 struct phy_device *phydev = priv->phydev; 1030 1031 const struct nxp_c45_phy_data *data; 1031 - struct hwtstamp_config cfg; 1032 1032 1033 - if (copy_from_user(&cfg, ifreq->ifr_data, sizeof(cfg))) 1034 - return -EFAULT; 1035 - 1036 - if (cfg.tx_type < 0 || cfg.tx_type > HWTSTAMP_TX_ON) 1033 + if (cfg->tx_type < 0 || cfg->tx_type > HWTSTAMP_TX_ON) 1037 1034 return -ERANGE; 1038 1035 1039 1036 data = nxp_c45_get_data(phydev); 1040 - priv->hwts_tx = cfg.tx_type; 1037 + priv->hwts_tx = cfg->tx_type; 1041 1038 1042 - switch (cfg.rx_filter) { 1039 + switch (cfg->rx_filter) { 1043 1040 case HWTSTAMP_FILTER_NONE: 1044 1041 priv->hwts_rx = 0; 1045 1042 break; ··· 1044 1047 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 1045 1048 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 1046 1049 priv->hwts_rx = 1; 1047 - cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 1050 + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 1048 1051 break; 1049 1052 default: 1050 1053 return -ERANGE; ··· 1071 1074 nxp_c45_clear_reg_field(phydev, &data->regmap->irq_egr_ts_en); 1072 1075 1073 1076 nxp_c45_no_ptp_irq: 1074 - return copy_to_user(ifreq->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1077 + return 0; 1075 1078 } 1076 1079 1077 1080 static int nxp_c45_ts_info(struct mii_timestamper *mii_ts,
+19 -2
drivers/net/phy/phy.c
··· 325 325 int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) 326 326 { 327 327 struct mii_ioctl_data *mii_data = if_mii(ifr); 328 + struct kernel_hwtstamp_config kernel_cfg; 329 + struct netlink_ext_ack extack = {}; 328 330 u16 val = mii_data->val_in; 329 331 bool change_autoneg = false; 332 + struct hwtstamp_config cfg; 330 333 int prtad, devad; 334 + int ret; 331 335 332 336 switch (cmd) { 333 337 case SIOCGMIIPHY: ··· 415 411 return 0; 416 412 417 413 case SIOCSHWTSTAMP: 418 - if (phydev->mii_ts && phydev->mii_ts->hwtstamp) 419 - return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr); 414 + if (phydev->mii_ts && phydev->mii_ts->hwtstamp) { 415 + if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 416 + return -EFAULT; 417 + 418 + hwtstamp_config_to_kernel(&kernel_cfg, &cfg); 419 + ret = phydev->mii_ts->hwtstamp(phydev->mii_ts, &kernel_cfg, &extack); 420 + if (ret) 421 + return ret; 422 + 423 + hwtstamp_config_from_kernel(&cfg, &kernel_cfg); 424 + if (copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg))) 425 + return -EFAULT; 426 + 427 + return 0; 428 + } 420 429 fallthrough; 421 430 422 431 default:
+7 -9
drivers/ptp/ptp_ines.c
··· 328 328 return ns; 329 329 } 330 330 331 - static int ines_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) 331 + static int ines_hwtstamp(struct mii_timestamper *mii_ts, 332 + struct kernel_hwtstamp_config *cfg, 333 + struct netlink_ext_ack *extack) 332 334 { 333 335 struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts); 334 336 u32 cm_one_step = 0, port_conf, ts_stat_rx, ts_stat_tx; 335 - struct hwtstamp_config cfg; 336 337 unsigned long flags; 337 338 338 - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 339 - return -EFAULT; 340 - 341 - switch (cfg.tx_type) { 339 + switch (cfg->tx_type) { 342 340 case HWTSTAMP_TX_OFF: 343 341 ts_stat_tx = 0; 344 342 break; ··· 351 353 return -ERANGE; 352 354 } 353 355 354 - switch (cfg.rx_filter) { 356 + switch (cfg->rx_filter) { 355 357 case HWTSTAMP_FILTER_NONE: 356 358 ts_stat_rx = 0; 357 359 break; ··· 370 372 case HWTSTAMP_FILTER_PTP_V2_SYNC: 371 373 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 372 374 ts_stat_rx = TS_ENABLE; 373 - cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 375 + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 374 376 break; 375 377 default: 376 378 return -ERANGE; ··· 391 393 392 394 spin_unlock_irqrestore(&port->lock, flags); 393 395 394 - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 396 + return 0; 395 397 } 396 398 397 399 static void ines_link_state(struct mii_timestamper *mii_ts,
+3 -1
include/linux/mii_timestamper.h
··· 9 9 #include <linux/device.h> 10 10 #include <linux/ethtool.h> 11 11 #include <linux/skbuff.h> 12 + #include <linux/net_tstamp.h> 12 13 13 14 struct phy_device; 14 15 ··· 52 51 struct sk_buff *skb, int type); 53 52 54 53 int (*hwtstamp)(struct mii_timestamper *mii_ts, 55 - struct ifreq *ifreq); 54 + struct kernel_hwtstamp_config *kernel_config, 55 + struct netlink_ext_ack *extack); 56 56 57 57 void (*link_state)(struct mii_timestamper *mii_ts, 58 58 struct phy_device *phydev);
+4 -2
include/linux/phy.h
··· 1560 1560 return phydev && phydev->mii_ts && phydev->mii_ts->txtstamp; 1561 1561 } 1562 1562 1563 - static inline int phy_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) 1563 + static inline int phy_hwtstamp(struct phy_device *phydev, 1564 + struct kernel_hwtstamp_config *cfg, 1565 + struct netlink_ext_ack *extack) 1564 1566 { 1565 - return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr); 1567 + return phydev->mii_ts->hwtstamp(phydev->mii_ts, cfg, extack); 1566 1568 } 1567 1569 1568 1570 static inline bool phy_rxtstamp(struct phy_device *phydev, struct sk_buff *skb,