LCOV - code coverage report
Current view: top level - drivers/net/cnxk - cnxk_ptp.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 118 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 9 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 60 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2021 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "cnxk_ethdev.h"
       6                 :            : 
       7                 :            : int
       8                 :          0 : cnxk_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock)
       9                 :            : {
      10                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
      11                 :            : 
      12                 :            :         /* This API returns the raw PTP HI clock value. Since LFs do not
      13                 :            :          * have direct access to PTP registers and it requires mbox msg
      14                 :            :          * to AF for this value. In fastpath reading this value for every
      15                 :            :          * packet (which involves mbox call) becomes very expensive, hence
      16                 :            :          * we should be able to derive PTP HI clock value from tsc by
      17                 :            :          * using freq_mult and clk_delta calculated during configure stage.
      18                 :            :          */
      19                 :          0 :         *clock = (rte_get_tsc_cycles() + dev->clk_delta) * dev->clk_freq_mult;
      20                 :            : 
      21                 :          0 :         return 0;
      22                 :            : }
      23                 :            : 
      24                 :            : /* This function calculates two parameters "clk_freq_mult" and
      25                 :            :  * "clk_delta" which is useful in deriving PTP HI clock from
      26                 :            :  * timestamp counter (tsc) value.
      27                 :            :  */
      28                 :            : int
      29                 :          0 : cnxk_nix_tsc_convert(struct cnxk_eth_dev *dev)
      30                 :            : {
      31                 :          0 :         uint64_t ticks_base = 0, ticks = 0, tsc = 0, t_freq;
      32                 :          0 :         struct roc_nix *nix = &dev->nix;
      33                 :            :         int rc, val;
      34                 :            : 
      35                 :            :         /* Calculating the frequency at which PTP HI clock is running */
      36                 :          0 :         rc = roc_nix_ptp_clock_read(nix, &ticks_base, &tsc, false);
      37         [ #  # ]:          0 :         if (rc) {
      38                 :          0 :                 plt_err("Failed to read the raw clock value: %d", rc);
      39                 :          0 :                 goto fail;
      40                 :            :         }
      41                 :            : 
      42                 :            :         rte_delay_ms(100);
      43                 :            : 
      44                 :          0 :         rc = roc_nix_ptp_clock_read(nix, &ticks, &tsc, false);
      45         [ #  # ]:          0 :         if (rc) {
      46                 :          0 :                 plt_err("Failed to read the raw clock value: %d", rc);
      47                 :          0 :                 goto fail;
      48                 :            :         }
      49                 :            : 
      50                 :          0 :         t_freq = (ticks - ticks_base) * 10;
      51                 :            : 
      52                 :            :         /* Calculating the freq multiplier viz the ratio between the
      53                 :            :          * frequency at which PTP HI clock works and tsc clock runs
      54                 :            :          */
      55                 :          0 :         dev->clk_freq_mult =
      56                 :          0 :                 (double)pow(10, floor(log10(t_freq))) / rte_get_timer_hz();
      57                 :            : 
      58                 :            :         val = false;
      59                 :            : #ifdef RTE_ARM_EAL_RDTSC_USE_PMU
      60                 :            :         val = true;
      61                 :            : #endif
      62                 :          0 :         rc = roc_nix_ptp_clock_read(nix, &ticks, &tsc, val);
      63         [ #  # ]:          0 :         if (rc) {
      64                 :          0 :                 plt_err("Failed to read the raw clock value: %d", rc);
      65                 :          0 :                 goto fail;
      66                 :            :         }
      67                 :            : 
      68                 :            :         /* Calculating delta between PTP HI clock and tsc */
      69                 :          0 :         dev->clk_delta = ((uint64_t)(ticks / dev->clk_freq_mult) - tsc);
      70                 :            : 
      71                 :          0 : fail:
      72                 :          0 :         return rc;
      73                 :            : }
      74                 :            : 
      75                 :            : int
      76                 :          0 : cnxk_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
      77                 :            : {
      78                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
      79                 :          0 :         struct roc_nix *nix = &dev->nix;
      80                 :            :         uint64_t clock, ns;
      81                 :            :         int rc;
      82                 :            : 
      83                 :          0 :         rc = roc_nix_ptp_clock_read(nix, &clock, NULL, false);
      84         [ #  # ]:          0 :         if (rc)
      85                 :            :                 return rc;
      86                 :            : 
      87         [ #  # ]:          0 :         ns = rte_timecounter_update(&dev->systime_tc, clock);
      88                 :          0 :         *ts = rte_ns_to_timespec(ns);
      89                 :          0 :         return 0;
      90                 :            : }
      91                 :            : 
      92                 :            : int
      93                 :          0 : cnxk_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
      94                 :            :                              const struct timespec *ts)
      95                 :            : {
      96                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
      97                 :            :         uint64_t ns;
      98                 :            : 
      99                 :            :         ns = rte_timespec_to_ns(ts);
     100                 :            :         /* Set the time counters to a new value. */
     101                 :          0 :         dev->systime_tc.nsec = ns;
     102                 :          0 :         dev->rx_tstamp_tc.nsec = ns;
     103                 :          0 :         dev->tx_tstamp_tc.nsec = ns;
     104                 :            : 
     105                 :          0 :         return 0;
     106                 :            : }
     107                 :            : 
     108                 :            : int
     109         [ #  # ]:          0 : cnxk_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
     110                 :            : {
     111                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     112                 :          0 :         struct roc_nix *nix = &dev->nix;
     113                 :            :         int rc;
     114                 :            : 
     115                 :            :         /* Adjust the frequent to make tics increments in 10^9 tics per sec */
     116         [ #  # ]:          0 :         if (delta < ROC_NIX_PTP_FREQ_ADJUST &&
     117                 :            :             delta > -ROC_NIX_PTP_FREQ_ADJUST) {
     118                 :          0 :                 rc = roc_nix_ptp_sync_time_adjust(nix, delta);
     119         [ #  # ]:          0 :                 if (rc)
     120                 :            :                         return rc;
     121                 :            : 
     122                 :            :                 /* Since the frequency of PTP comp register is tuned, delta and
     123                 :            :                  * freq mult calculation for deriving PTP_HI from timestamp
     124                 :            :                  * counter should be done again.
     125                 :            :                  */
     126                 :          0 :                 rc = cnxk_nix_tsc_convert(dev);
     127         [ #  # ]:          0 :                 if (rc)
     128                 :          0 :                         plt_err("Failed to calculate delta and freq mult");
     129                 :            :         }
     130                 :            : 
     131                 :          0 :         dev->systime_tc.nsec += delta;
     132                 :          0 :         dev->rx_tstamp_tc.nsec += delta;
     133                 :          0 :         dev->tx_tstamp_tc.nsec += delta;
     134                 :            : 
     135                 :          0 :         return 0;
     136                 :            : }
     137                 :            : 
     138                 :            : int
     139         [ #  # ]:          0 : cnxk_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
     140                 :            :                                     struct timespec *timestamp, uint32_t flags)
     141                 :            : {
     142                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     143                 :            :         struct cnxk_timesync_info *tstamp = &dev->tstamp;
     144                 :            :         uint64_t ns;
     145                 :            : 
     146                 :            :         PLT_SET_USED(flags);
     147                 :            : 
     148         [ #  # ]:          0 :         if (!tstamp->rx_ready)
     149                 :            :                 return -EINVAL;
     150                 :            : 
     151         [ #  # ]:          0 :         ns = rte_timecounter_update(&dev->rx_tstamp_tc, tstamp->rx_tstamp);
     152                 :          0 :         *timestamp = rte_ns_to_timespec(ns);
     153                 :          0 :         tstamp->rx_ready = 0;
     154                 :          0 :         return 0;
     155                 :            : }
     156                 :            : 
     157                 :            : int
     158         [ #  # ]:          0 : cnxk_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
     159                 :            :                                     struct timespec *timestamp)
     160                 :            : {
     161                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     162                 :            :         struct cnxk_timesync_info *tstamp = &dev->tstamp;
     163                 :            :         uint64_t ns;
     164                 :            : 
     165         [ #  # ]:          0 :         if (*tstamp->tx_tstamp == 0)
     166                 :            :                 return -EINVAL;
     167                 :            : 
     168                 :            :         ns = rte_timecounter_update(&dev->tx_tstamp_tc, *tstamp->tx_tstamp);
     169                 :          0 :         *timestamp = rte_ns_to_timespec(ns);
     170                 :          0 :         *tstamp->tx_tstamp = 0;
     171                 :            :         rte_wmb();
     172                 :            : 
     173                 :          0 :         return 0;
     174                 :            : }
     175                 :            : 
     176                 :            : int
     177                 :          0 : cnxk_nix_timesync_enable(struct rte_eth_dev *eth_dev)
     178                 :            : {
     179                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     180                 :            :         struct cnxk_timesync_info *tstamp = &dev->tstamp;
     181                 :          0 :         struct roc_nix *nix = &dev->nix;
     182                 :            :         const struct rte_memzone *ts;
     183                 :            :         int rc = 0;
     184                 :            : 
     185                 :            :         /* If we are VF/SDP/LBK, ptp cannot not be enabled */
     186   [ #  #  #  # ]:          0 :         if (roc_nix_is_vf_or_sdp(nix) || roc_nix_is_lbk(nix)) {
     187                 :          0 :                 plt_err("PTP cannot be enabled for VF/SDP/LBK");
     188                 :          0 :                 return -EINVAL;
     189                 :            :         }
     190                 :            : 
     191         [ #  # ]:          0 :         if (dev->ptp_en)
     192                 :            :                 return rc;
     193                 :            : 
     194         [ #  # ]:          0 :         if (dev->ptype_disable) {
     195                 :          0 :                 plt_err("Ptype offload is disabled, it should be enabled");
     196                 :          0 :                 return -EINVAL;
     197                 :            :         }
     198                 :            : 
     199         [ #  # ]:          0 :         if (dev->npc.switch_header_type == ROC_PRIV_FLAGS_HIGIG) {
     200                 :          0 :                 plt_err("Both PTP and switch header cannot be enabled");
     201                 :          0 :                 return -EINVAL;
     202                 :            :         }
     203                 :            : 
     204                 :            :         /* Allocating a iova address for tx tstamp */
     205                 :          0 :         ts = rte_eth_dma_zone_reserve(eth_dev, "cnxk_ts", 0, 128, 128, 0);
     206         [ #  # ]:          0 :         if (ts == NULL) {
     207                 :          0 :                 plt_err("Failed to allocate mem for tx tstamp addr");
     208                 :          0 :                 return -ENOMEM;
     209                 :            :         }
     210                 :            : 
     211                 :          0 :         tstamp->tx_tstamp_iova = ts->iova;
     212                 :          0 :         tstamp->tx_tstamp = ts->addr;
     213                 :            : 
     214                 :          0 :         rc = rte_mbuf_dyn_rx_timestamp_register(&tstamp->tstamp_dynfield_offset,
     215                 :            :                                                 &tstamp->rx_tstamp_dynflag);
     216         [ #  # ]:          0 :         if (rc) {
     217                 :          0 :                 plt_err("Failed to register Rx timestamp field/flag");
     218                 :          0 :                 goto error;
     219                 :            :         }
     220                 :            : 
     221                 :            :         /* System time should be already on by default */
     222                 :          0 :         memset(&dev->systime_tc, 0, sizeof(struct rte_timecounter));
     223                 :          0 :         memset(&dev->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
     224                 :          0 :         memset(&dev->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
     225                 :            : 
     226                 :          0 :         dev->systime_tc.cc_mask = CNXK_CYCLECOUNTER_MASK;
     227                 :          0 :         dev->rx_tstamp_tc.cc_mask = CNXK_CYCLECOUNTER_MASK;
     228                 :          0 :         dev->tx_tstamp_tc.cc_mask = CNXK_CYCLECOUNTER_MASK;
     229                 :            : 
     230                 :          0 :         dev->rx_offloads |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
     231                 :            : 
     232                 :          0 :         rc = roc_nix_ptp_rx_ena_dis(nix, true);
     233         [ #  # ]:          0 :         if (!rc) {
     234                 :          0 :                 rc = roc_nix_ptp_tx_ena_dis(nix, true);
     235         [ #  # ]:          0 :                 if (rc) {
     236                 :          0 :                         roc_nix_ptp_rx_ena_dis(nix, false);
     237                 :          0 :                         goto error;
     238                 :            :                 }
     239                 :            :         }
     240                 :            : 
     241                 :          0 :         rc = nix_recalc_mtu(eth_dev);
     242         [ #  # ]:          0 :         if (rc) {
     243                 :          0 :                 plt_err("Failed to set MTU size for ptp");
     244                 :          0 :                 goto error;
     245                 :            :         }
     246                 :            : 
     247                 :            :         return rc;
     248                 :            : 
     249                 :          0 : error:
     250                 :          0 :         rte_eth_dma_zone_free(eth_dev, "cnxk_ts", 0);
     251                 :          0 :         dev->tstamp.tx_tstamp_iova = 0;
     252                 :          0 :         dev->tstamp.tx_tstamp = NULL;
     253                 :          0 :         return rc;
     254                 :            : }
     255                 :            : 
     256                 :            : int
     257                 :          0 : cnxk_nix_timesync_disable(struct rte_eth_dev *eth_dev)
     258                 :            : {
     259                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     260                 :            :         uint64_t rx_offloads = RTE_ETH_RX_OFFLOAD_TIMESTAMP;
     261                 :          0 :         struct roc_nix *nix = &dev->nix;
     262                 :            :         int rc = 0;
     263                 :            : 
     264                 :            :         /* If we are VF/SDP/LBK, ptp cannot not be disabled */
     265   [ #  #  #  # ]:          0 :         if (roc_nix_is_vf_or_sdp(nix) || roc_nix_is_lbk(nix))
     266                 :          0 :                 return -EINVAL;
     267                 :            : 
     268         [ #  # ]:          0 :         if (!dev->ptp_en)
     269                 :            :                 return rc;
     270                 :            : 
     271                 :          0 :         dev->rx_offloads &= ~rx_offloads;
     272                 :            : 
     273                 :          0 :         rc = roc_nix_ptp_rx_ena_dis(nix, false);
     274         [ #  # ]:          0 :         if (!rc) {
     275                 :          0 :                 rc = roc_nix_ptp_tx_ena_dis(nix, false);
     276         [ #  # ]:          0 :                 if (rc) {
     277                 :          0 :                         roc_nix_ptp_rx_ena_dis(nix, true);
     278                 :          0 :                         return rc;
     279                 :            :                 }
     280                 :            :         }
     281                 :            : 
     282                 :          0 :         rc = nix_recalc_mtu(eth_dev);
     283         [ #  # ]:          0 :         if (rc)
     284                 :          0 :                 plt_err("Failed to set MTU size for ptp");
     285                 :            : 
     286                 :            :         return rc;
     287                 :            : }

Generated by: LCOV version 1.14