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

Configure Feed

Select the types of activity you want to include in your feed.

net: stmmac: 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 the stmmac driver to the new API, so that
timestamping configuration can be removed from the ndo_eth_ioctl()
path completely.

The existing timestamping calls are guarded by netif_running(). For
stmmac_hwtstamp_get() that is probably unnecessary, since no hardware
access is performed. But for stmmac_hwtstamp_set() I've preserved it,
since at least some IPs probably need pm_runtime_resume_and_get() to
access registers, which is otherwise called by __stmmac_open().

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

authored by

Vladimir Oltean and committed by
Jakub Kicinski
894fbb55 abb258eb

+42 -44
+1 -1
drivers/net/ethernet/stmicro/stmmac/stmmac.h
··· 301 301 unsigned int mode; 302 302 unsigned int chain_mode; 303 303 int extend_desc; 304 - struct hwtstamp_config tstamp_config; 304 + struct kernel_hwtstamp_config tstamp_config; 305 305 struct ptp_clock *ptp_clock; 306 306 struct ptp_clock_info ptp_clock_ops; 307 307 unsigned int default_addend;
+41 -43
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 568 568 /** 569 569 * stmmac_hwtstamp_set - control hardware timestamping. 570 570 * @dev: device pointer. 571 - * @ifr: An IOCTL specific structure, that can contain a pointer to 572 - * a proprietary structure used to pass information to the driver. 571 + * @config: the timestamping configuration. 572 + * @extack: netlink extended ack structure for error reporting. 573 573 * Description: 574 574 * This function configures the MAC to enable/disable both outgoing(TX) 575 575 * and incoming(RX) packets time stamping based on user input. 576 576 * Return Value: 577 577 * 0 on success and an appropriate -ve integer on failure. 578 578 */ 579 - static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) 579 + static int stmmac_hwtstamp_set(struct net_device *dev, 580 + struct kernel_hwtstamp_config *config, 581 + struct netlink_ext_ack *extack) 580 582 { 581 583 struct stmmac_priv *priv = netdev_priv(dev); 582 - struct hwtstamp_config config; 583 584 u32 ptp_v2 = 0; 584 585 u32 tstamp_all = 0; 585 586 u32 ptp_over_ipv4_udp = 0; ··· 591 590 u32 ts_event_en = 0; 592 591 593 592 if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { 594 - netdev_alert(priv->dev, "No support for HW time stamping\n"); 593 + NL_SET_ERR_MSG_MOD(extack, "No support for HW time stamping"); 595 594 priv->hwts_tx_en = 0; 596 595 priv->hwts_rx_en = 0; 597 596 598 597 return -EOPNOTSUPP; 599 598 } 600 599 601 - if (copy_from_user(&config, ifr->ifr_data, 602 - sizeof(config))) 603 - return -EFAULT; 600 + if (!netif_running(dev)) { 601 + NL_SET_ERR_MSG_MOD(extack, 602 + "Cannot change timestamping configuration while down"); 603 + return -ENODEV; 604 + } 604 605 605 606 netdev_dbg(priv->dev, "%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n", 606 - __func__, config.flags, config.tx_type, config.rx_filter); 607 + __func__, config->flags, config->tx_type, config->rx_filter); 607 608 608 - if (config.tx_type != HWTSTAMP_TX_OFF && 609 - config.tx_type != HWTSTAMP_TX_ON) 609 + if (config->tx_type != HWTSTAMP_TX_OFF && 610 + config->tx_type != HWTSTAMP_TX_ON) 610 611 return -ERANGE; 611 612 612 613 if (priv->adv_ts) { 613 - switch (config.rx_filter) { 614 + switch (config->rx_filter) { 614 615 case HWTSTAMP_FILTER_NONE: 615 616 /* time stamp no incoming packet at all */ 616 - config.rx_filter = HWTSTAMP_FILTER_NONE; 617 + config->rx_filter = HWTSTAMP_FILTER_NONE; 617 618 break; 618 619 619 620 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 620 621 /* PTP v1, UDP, any kind of event packet */ 621 - config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 622 + config->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 622 623 /* 'xmac' hardware can support Sync, Pdelay_Req and 623 624 * Pdelay_resp by setting bit14 and bits17/16 to 01 624 625 * This leaves Delay_Req timestamps out. ··· 634 631 635 632 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 636 633 /* PTP v1, UDP, Sync packet */ 637 - config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC; 634 + config->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC; 638 635 /* take time stamp for SYNC messages only */ 639 636 ts_event_en = PTP_TCR_TSEVNTENA; 640 637 ··· 644 641 645 642 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 646 643 /* PTP v1, UDP, Delay_req packet */ 647 - config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ; 644 + config->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ; 648 645 /* take time stamp for Delay_Req messages only */ 649 646 ts_master_en = PTP_TCR_TSMSTRENA; 650 647 ts_event_en = PTP_TCR_TSEVNTENA; ··· 655 652 656 653 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 657 654 /* PTP v2, UDP, any kind of event packet */ 658 - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 655 + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 659 656 ptp_v2 = PTP_TCR_TSVER2ENA; 660 657 /* take time stamp for all event messages */ 661 658 snap_type_sel = PTP_TCR_SNAPTYPSEL_1; ··· 666 663 667 664 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 668 665 /* PTP v2, UDP, Sync packet */ 669 - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC; 666 + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC; 670 667 ptp_v2 = PTP_TCR_TSVER2ENA; 671 668 /* take time stamp for SYNC messages only */ 672 669 ts_event_en = PTP_TCR_TSEVNTENA; ··· 677 674 678 675 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 679 676 /* PTP v2, UDP, Delay_req packet */ 680 - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ; 677 + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ; 681 678 ptp_v2 = PTP_TCR_TSVER2ENA; 682 679 /* take time stamp for Delay_Req messages only */ 683 680 ts_master_en = PTP_TCR_TSMSTRENA; ··· 689 686 690 687 case HWTSTAMP_FILTER_PTP_V2_EVENT: 691 688 /* PTP v2/802.AS1 any layer, any kind of event packet */ 692 - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 689 + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 693 690 ptp_v2 = PTP_TCR_TSVER2ENA; 694 691 snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 695 692 if (priv->synopsys_id < DWMAC_CORE_4_10) ··· 701 698 702 699 case HWTSTAMP_FILTER_PTP_V2_SYNC: 703 700 /* PTP v2/802.AS1, any layer, Sync packet */ 704 - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 701 + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 705 702 ptp_v2 = PTP_TCR_TSVER2ENA; 706 703 /* take time stamp for SYNC messages only */ 707 704 ts_event_en = PTP_TCR_TSEVNTENA; ··· 713 710 714 711 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 715 712 /* PTP v2/802.AS1, any layer, Delay_req packet */ 716 - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 713 + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 717 714 ptp_v2 = PTP_TCR_TSVER2ENA; 718 715 /* take time stamp for Delay_Req messages only */ 719 716 ts_master_en = PTP_TCR_TSMSTRENA; ··· 727 724 case HWTSTAMP_FILTER_NTP_ALL: 728 725 case HWTSTAMP_FILTER_ALL: 729 726 /* time stamp any incoming packet */ 730 - config.rx_filter = HWTSTAMP_FILTER_ALL; 727 + config->rx_filter = HWTSTAMP_FILTER_ALL; 731 728 tstamp_all = PTP_TCR_TSENALL; 732 729 break; 733 730 ··· 735 732 return -ERANGE; 736 733 } 737 734 } else { 738 - switch (config.rx_filter) { 735 + switch (config->rx_filter) { 739 736 case HWTSTAMP_FILTER_NONE: 740 - config.rx_filter = HWTSTAMP_FILTER_NONE; 737 + config->rx_filter = HWTSTAMP_FILTER_NONE; 741 738 break; 742 739 default: 743 740 /* PTP v1, UDP, any kind of event packet */ 744 - config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 741 + config->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 745 742 break; 746 743 } 747 744 } 748 - priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1); 749 - priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON; 745 + priv->hwts_rx_en = config->rx_filter != HWTSTAMP_FILTER_NONE; 746 + priv->hwts_tx_en = config->tx_type == HWTSTAMP_TX_ON; 750 747 751 748 priv->systime_flags = STMMAC_HWTS_ACTIVE; 752 749 ··· 759 756 760 757 stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags); 761 758 762 - memcpy(&priv->tstamp_config, &config, sizeof(config)); 759 + priv->tstamp_config = *config; 763 760 764 - return copy_to_user(ifr->ifr_data, &config, 765 - sizeof(config)) ? -EFAULT : 0; 761 + return 0; 766 762 } 767 763 768 764 /** 769 765 * stmmac_hwtstamp_get - read hardware timestamping. 770 766 * @dev: device pointer. 771 - * @ifr: An IOCTL specific structure, that can contain a pointer to 772 - * a proprietary structure used to pass information to the driver. 767 + * @config: the timestamping configuration. 773 768 * Description: 774 769 * This function obtain the current hardware timestamping settings 775 770 * as requested. 776 771 */ 777 - static int stmmac_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) 772 + static int stmmac_hwtstamp_get(struct net_device *dev, 773 + struct kernel_hwtstamp_config *config) 778 774 { 779 775 struct stmmac_priv *priv = netdev_priv(dev); 780 - struct hwtstamp_config *config = &priv->tstamp_config; 781 776 782 777 if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) 783 778 return -EOPNOTSUPP; 784 779 785 - return copy_to_user(ifr->ifr_data, config, 786 - sizeof(*config)) ? -EFAULT : 0; 780 + *config = priv->tstamp_config; 781 + 782 + return 0; 787 783 } 788 784 789 785 /** ··· 6227 6225 case SIOCSMIIREG: 6228 6226 ret = phylink_mii_ioctl(priv->phylink, rq, cmd); 6229 6227 break; 6230 - case SIOCSHWTSTAMP: 6231 - ret = stmmac_hwtstamp_set(dev, rq); 6232 - break; 6233 - case SIOCGHWTSTAMP: 6234 - ret = stmmac_hwtstamp_get(dev, rq); 6235 - break; 6236 6228 default: 6237 6229 break; 6238 6230 } ··· 7165 7169 .ndo_bpf = stmmac_bpf, 7166 7170 .ndo_xdp_xmit = stmmac_xdp_xmit, 7167 7171 .ndo_xsk_wakeup = stmmac_xsk_wakeup, 7172 + .ndo_hwtstamp_get = stmmac_hwtstamp_get, 7173 + .ndo_hwtstamp_set = stmmac_hwtstamp_set, 7168 7174 }; 7169 7175 7170 7176 static void stmmac_reset_subtask(struct stmmac_priv *priv)