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.

Merge branch 'net-stmmac-add-support-for-coarse-timestamping'

Maxime Chevallier says:

====================
net: stmmac: Add support for coarse timestamping

This is V2 for coarse timetamping support in stmmac. This version uses a
dedicated devlink param "ts_coarse" to control this mode.

This doesn't conflict with Russell's cleanup of hwif.

Maxime

[1] : https://lore.kernel.org/netdev/20200514102808.31163-1-olivier.dautricourt@orolia.com/

V1: https://lore.kernel.org/netdev/20251015102725.1297985-1-maxime.chevallier@bootlin.com/
====================

Link: https://patch.msgid.link/20251024070720.71174-1-maxime.chevallier@bootlin.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+176 -23
+1
Documentation/networking/devlink/index.rst
··· 99 99 prestera 100 100 qed 101 101 sfc 102 + stmmac 102 103 ti-cpsw-switch 103 104 zl3073x
+31
Documentation/networking/devlink/stmmac.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ======================================= 4 + stmmac (synopsys dwmac) devlink support 5 + ======================================= 6 + 7 + This document describes the devlink features implemented by the ``stmmac`` 8 + device driver. 9 + 10 + Parameters 11 + ========== 12 + 13 + The ``stmmac`` driver implements the following driver-specific parameters. 14 + 15 + .. list-table:: Driver-specific parameters implemented 16 + :widths: 5 5 5 85 17 + 18 + * - Name 19 + - Type 20 + - Mode 21 + - Description 22 + * - ``ts_coarse`` 23 + - Boolean 24 + - runtime 25 + - Enable the Coarse timestamping mode. In Coarse mode, the ptp clock is 26 + expected to be updated through an external PPS input, but the subsecond 27 + increment used for timestamping is set to 1/ptp_clock_rate. In Fine mode 28 + (i.e. Coarse mode == false), the ptp clock frequency is adjusted more 29 + frequently, but the subsecond increment is set to 2/ptp_clock_rate. 30 + Coarse mode is suitable for PTP Grand Master operation. If unsure, leave 31 + the parameter to False.
+1
drivers/net/ethernet/stmicro/stmmac/Kconfig
··· 10 10 select PHYLINK 11 11 select CRC32 12 12 select RESET_CONTROLLER 13 + select NET_DEVLINK 13 14 help 14 15 This is the driver for the Ethernet IPs built around a 15 16 Synopsys IP Core.
+3
drivers/net/ethernet/stmicro/stmmac/stmmac.h
··· 259 259 u32 sarc_type; 260 260 u32 rx_riwt[MTL_MAX_RX_QUEUES]; 261 261 int hwts_rx_en; 262 + bool tsfupdt_coarse; 262 263 263 264 void __iomem *ioaddr; 264 265 struct net_device *dev; ··· 370 369 /* XDP BPF Program */ 371 370 unsigned long *af_xdp_zc_qps; 372 371 struct bpf_prog *xdp_prog; 372 + 373 + struct devlink *devlink; 373 374 }; 374 375 375 376 enum stmmac_state {
+140 -23
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 40 40 #include <linux/phylink.h> 41 41 #include <linux/udp.h> 42 42 #include <linux/bpf_trace.h> 43 + #include <net/devlink.h> 43 44 #include <net/page_pool/helpers.h> 44 45 #include <net/pkt_cls.h> 45 46 #include <net/xdp_sock_drv.h> ··· 59 58 * with fine resolution and binary rollover. This avoid non-monotonic behavior 60 59 * (clock jumps) when changing timestamping settings at runtime. 61 60 */ 62 - #define STMMAC_HWTS_ACTIVE (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | \ 63 - PTP_TCR_TSCTRLSSR) 61 + #define STMMAC_HWTS_ACTIVE (PTP_TCR_TSENA | PTP_TCR_TSCTRLSSR) 64 62 65 63 #define STMMAC_ALIGN(x) ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16) 66 64 #define TSO_MAX_BUFF_SIZE (SZ_16K - 1) ··· 147 147 #endif 148 148 149 149 #define STMMAC_COAL_TIMER(x) (ns_to_ktime((x) * NSEC_PER_USEC)) 150 + 151 + struct stmmac_devlink_priv { 152 + struct stmmac_priv *stmmac_priv; 153 + }; 154 + 155 + enum stmmac_dl_param_id { 156 + STMMAC_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 157 + STMMAC_DEVLINK_PARAM_ID_TS_COARSE, 158 + }; 150 159 151 160 /** 152 161 * stmmac_set_clk_tx_rate() - set the clock rate for the MAC transmit clock ··· 473 464 } 474 465 } 475 466 467 + static void stmmac_update_subsecond_increment(struct stmmac_priv *priv) 468 + { 469 + bool xmac = dwmac_is_xmac(priv->plat->core_type); 470 + u32 sec_inc = 0; 471 + u64 temp = 0; 472 + 473 + stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags); 474 + 475 + /* program Sub Second Increment reg */ 476 + stmmac_config_sub_second_increment(priv, priv->ptpaddr, 477 + priv->plat->clk_ptp_rate, 478 + xmac, &sec_inc); 479 + temp = div_u64(1000000000ULL, sec_inc); 480 + 481 + /* Store sub second increment for later use */ 482 + priv->sub_second_inc = sec_inc; 483 + 484 + /* calculate default added value: 485 + * formula is : 486 + * addend = (2^32)/freq_div_ratio; 487 + * where, freq_div_ratio = 1e9ns/sec_inc 488 + */ 489 + temp = (u64)(temp << 32); 490 + priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); 491 + stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend); 492 + } 493 + 476 494 /** 477 495 * stmmac_hwtstamp_set - control hardware timestamping. 478 496 * @dev: device pointer. ··· 684 648 priv->hwts_tx_en = config->tx_type == HWTSTAMP_TX_ON; 685 649 686 650 priv->systime_flags = STMMAC_HWTS_ACTIVE; 651 + if (!priv->tsfupdt_coarse) 652 + priv->systime_flags |= PTP_TCR_TSCFUPDT; 687 653 688 654 if (priv->hwts_tx_en || priv->hwts_rx_en) { 689 655 priv->systime_flags |= tstamp_all | ptp_v2 | ··· 735 697 static int stmmac_init_tstamp_counter(struct stmmac_priv *priv, 736 698 u32 systime_flags) 737 699 { 738 - bool xmac = dwmac_is_xmac(priv->plat->core_type); 739 700 struct timespec64 now; 740 - u32 sec_inc = 0; 741 - u64 temp = 0; 742 701 743 702 if (!priv->plat->clk_ptp_rate) { 744 703 netdev_err(priv->dev, "Invalid PTP clock rate"); ··· 745 710 stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags); 746 711 priv->systime_flags = systime_flags; 747 712 748 - /* program Sub Second Increment reg */ 749 - stmmac_config_sub_second_increment(priv, priv->ptpaddr, 750 - priv->plat->clk_ptp_rate, 751 - xmac, &sec_inc); 752 - temp = div_u64(1000000000ULL, sec_inc); 753 - 754 - /* Store sub second increment for later use */ 755 - priv->sub_second_inc = sec_inc; 756 - 757 - /* calculate default added value: 758 - * formula is : 759 - * addend = (2^32)/freq_div_ratio; 760 - * where, freq_div_ratio = 1e9ns/sec_inc 761 - */ 762 - temp = (u64)(temp << 32); 763 - priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); 764 - stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend); 713 + stmmac_update_subsecond_increment(priv); 765 714 766 715 /* initialize system time */ 767 716 ktime_get_real_ts64(&now); ··· 776 757 return -EOPNOTSUPP; 777 758 } 778 759 779 - ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE); 760 + ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE | 761 + PTP_TCR_TSCFUPDT); 780 762 if (ret) { 781 763 netdev_warn(priv->dev, "PTP init failed\n"); 782 764 return ret; ··· 7412 7392 .xmo_rx_timestamp = stmmac_xdp_rx_timestamp, 7413 7393 }; 7414 7394 7395 + static int stmmac_dl_ts_coarse_set(struct devlink *dl, u32 id, 7396 + struct devlink_param_gset_ctx *ctx, 7397 + struct netlink_ext_ack *extack) 7398 + { 7399 + struct stmmac_devlink_priv *dl_priv = devlink_priv(dl); 7400 + struct stmmac_priv *priv = dl_priv->stmmac_priv; 7401 + 7402 + priv->tsfupdt_coarse = ctx->val.vbool; 7403 + 7404 + if (priv->tsfupdt_coarse) 7405 + priv->systime_flags &= ~PTP_TCR_TSCFUPDT; 7406 + else 7407 + priv->systime_flags |= PTP_TCR_TSCFUPDT; 7408 + 7409 + /* In Coarse mode, we can use a smaller subsecond increment, let's 7410 + * reconfigure the systime, subsecond increment and addend. 7411 + */ 7412 + stmmac_update_subsecond_increment(priv); 7413 + 7414 + return 0; 7415 + } 7416 + 7417 + static int stmmac_dl_ts_coarse_get(struct devlink *dl, u32 id, 7418 + struct devlink_param_gset_ctx *ctx) 7419 + { 7420 + struct stmmac_devlink_priv *dl_priv = devlink_priv(dl); 7421 + struct stmmac_priv *priv = dl_priv->stmmac_priv; 7422 + 7423 + ctx->val.vbool = priv->tsfupdt_coarse; 7424 + 7425 + return 0; 7426 + } 7427 + 7428 + static const struct devlink_param stmmac_devlink_params[] = { 7429 + DEVLINK_PARAM_DRIVER(STMMAC_DEVLINK_PARAM_ID_TS_COARSE, "ts_coarse", 7430 + DEVLINK_PARAM_TYPE_BOOL, 7431 + BIT(DEVLINK_PARAM_CMODE_RUNTIME), 7432 + stmmac_dl_ts_coarse_get, 7433 + stmmac_dl_ts_coarse_set, NULL), 7434 + }; 7435 + 7436 + /* None of the generic devlink parameters are implemented */ 7437 + static const struct devlink_ops stmmac_devlink_ops = {}; 7438 + 7439 + static int stmmac_register_devlink(struct stmmac_priv *priv) 7440 + { 7441 + struct stmmac_devlink_priv *dl_priv; 7442 + int ret; 7443 + 7444 + /* For now, what is exposed over devlink is only relevant when 7445 + * timestamping is available and we have a valid ptp clock rate 7446 + */ 7447 + if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp) || 7448 + !priv->plat->clk_ptp_rate) 7449 + return 0; 7450 + 7451 + priv->devlink = devlink_alloc(&stmmac_devlink_ops, sizeof(*dl_priv), 7452 + priv->device); 7453 + if (!priv->devlink) 7454 + return -ENOMEM; 7455 + 7456 + dl_priv = devlink_priv(priv->devlink); 7457 + dl_priv->stmmac_priv = priv; 7458 + 7459 + ret = devlink_params_register(priv->devlink, stmmac_devlink_params, 7460 + ARRAY_SIZE(stmmac_devlink_params)); 7461 + if (ret) 7462 + goto dl_free; 7463 + 7464 + devlink_register(priv->devlink); 7465 + return 0; 7466 + 7467 + dl_free: 7468 + devlink_free(priv->devlink); 7469 + 7470 + return ret; 7471 + } 7472 + 7473 + static void stmmac_unregister_devlink(struct stmmac_priv *priv) 7474 + { 7475 + if (!priv->devlink) 7476 + return; 7477 + 7478 + devlink_unregister(priv->devlink); 7479 + devlink_params_unregister(priv->devlink, stmmac_devlink_params, 7480 + ARRAY_SIZE(stmmac_devlink_params)); 7481 + devlink_free(priv->devlink); 7482 + } 7483 + 7415 7484 /** 7416 7485 * stmmac_dvr_probe 7417 7486 * @device: device pointer ··· 7774 7665 goto error_phy_setup; 7775 7666 } 7776 7667 7668 + ret = stmmac_register_devlink(priv); 7669 + if (ret) 7670 + goto error_devlink_setup; 7671 + 7777 7672 ret = register_netdev(ndev); 7778 7673 if (ret) { 7779 7674 dev_err(priv->device, "%s: ERROR %i registering the device\n", ··· 7800 7687 return ret; 7801 7688 7802 7689 error_netdev_register: 7690 + stmmac_unregister_devlink(priv); 7691 + error_devlink_setup: 7803 7692 phylink_destroy(priv->phylink); 7804 7693 error_phy_setup: 7805 7694 stmmac_pcs_clean(ndev); ··· 7838 7723 #ifdef CONFIG_DEBUG_FS 7839 7724 stmmac_exit_fs(ndev); 7840 7725 #endif 7726 + stmmac_unregister_devlink(priv); 7727 + 7841 7728 phylink_destroy(priv->phylink); 7842 7729 if (priv->plat->stmmac_rst) 7843 7730 reset_control_assert(priv->plat->stmmac_rst);