LCOV - code coverage report
Current view: top level - drivers/net/hns3 - hns3_ptp.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 112 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 54 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2021-2021 Hisilicon Limited.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <ethdev_pci.h>
       6                 :            : #include <rte_io.h>
       7                 :            : #include <rte_time.h>
       8                 :            : 
       9                 :            : #include "hns3_ethdev.h"
      10                 :            : #include "hns3_ptp.h"
      11                 :            : #include "hns3_logs.h"
      12                 :            : 
      13                 :            : uint64_t hns3_timestamp_rx_dynflag;
      14                 :            : int hns3_timestamp_dynfield_offset = -1;
      15                 :            : 
      16                 :            : int
      17                 :          0 : hns3_mbuf_dyn_rx_timestamp_register(struct rte_eth_dev *dev,
      18                 :            :                                     struct rte_eth_conf *conf)
      19                 :            : {
      20                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
      21                 :            :         struct hns3_hw *hw = &hns->hw;
      22                 :            :         int ret;
      23                 :            : 
      24         [ #  # ]:          0 :         if (!(conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP))
      25                 :            :                 return 0;
      26                 :            : 
      27                 :          0 :         ret = rte_mbuf_dyn_rx_timestamp_register
      28                 :            :                         (&hns3_timestamp_dynfield_offset,
      29                 :            :                          &hns3_timestamp_rx_dynflag);
      30         [ #  # ]:          0 :         if (ret) {
      31                 :          0 :                 hns3_err(hw,
      32                 :            :                         "failed to register Rx timestamp field/flag");
      33                 :          0 :                 return ret;
      34                 :            :         }
      35                 :            : 
      36                 :            :         return 0;
      37                 :            : }
      38                 :            : 
      39                 :            : static int
      40                 :          0 : hns3_ptp_int_en(struct hns3_hw *hw, bool en)
      41                 :            : {
      42                 :            :         struct hns3_ptp_int_cmd *req;
      43                 :            :         struct hns3_cmd_desc desc;
      44                 :            :         int ret;
      45                 :            : 
      46                 :            :         req = (struct hns3_ptp_int_cmd *)desc.data;
      47                 :          0 :         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_PTP_INT_EN, false);
      48                 :          0 :         req->int_en = en ? 1 : 0;
      49                 :            : 
      50                 :          0 :         ret = hns3_cmd_send(hw, &desc, 1);
      51         [ #  # ]:          0 :         if (ret)
      52         [ #  # ]:          0 :                 hns3_err(hw,
      53                 :            :                         "failed to %s ptp interrupt, ret = %d",
      54                 :            :                         en ? "enable" : "disable", ret);
      55                 :            : 
      56                 :          0 :         return ret;
      57                 :            : }
      58                 :            : 
      59                 :            : static void
      60                 :            : hns3_ptp_timesync_write_time(struct hns3_hw *hw, const struct timespec *ts)
      61                 :            : {
      62                 :          0 :         uint64_t sec = ts->tv_sec;
      63                 :          0 :         uint64_t ns = ts->tv_nsec;
      64                 :            : 
      65                 :            :         /* Set the timecounters to a new value. */
      66                 :          0 :         hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_H, upper_32_bits(sec));
      67                 :          0 :         hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_M, lower_32_bits(sec));
      68                 :          0 :         hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_L, lower_32_bits(ns));
      69                 :          0 :         hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_RDY, 1);
      70                 :            : }
      71                 :            : 
      72                 :            : int
      73                 :          0 : hns3_ptp_init(struct hns3_hw *hw)
      74                 :            : {
      75                 :            :         struct timespec sys_time;
      76                 :            :         int ret;
      77                 :            : 
      78         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
      79                 :            :                 return 0;
      80                 :            : 
      81                 :          0 :         ret = hns3_ptp_int_en(hw, true);
      82         [ #  # ]:          0 :         if (ret)
      83                 :            :                 return ret;
      84                 :            : 
      85                 :            :         /* Start PTP timer */
      86                 :          0 :         hns3_write_dev(hw, HNS3_CFG_TIME_CYC_EN, 1);
      87                 :            : 
      88                 :            :         /* Initializing the RTC. */
      89                 :          0 :         clock_gettime(CLOCK_REALTIME, &sys_time);
      90                 :            :         hns3_ptp_timesync_write_time(hw, &sys_time);
      91                 :            : 
      92                 :          0 :         return 0;
      93                 :            : }
      94                 :            : 
      95                 :            : static int
      96                 :          0 : hns3_timesync_configure(struct hns3_adapter *hns, bool en)
      97                 :            : {
      98                 :            :         struct hns3_ptp_mode_cfg_cmd *req;
      99                 :          0 :         struct hns3_hw *hw = &hns->hw;
     100                 :            :         struct hns3_pf *pf = &hns->pf;
     101                 :            :         struct hns3_cmd_desc desc;
     102                 :            :         uint32_t val;
     103                 :            :         int ret;
     104                 :            : 
     105                 :          0 :         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CFG_PTP_MODE, false);
     106                 :            : 
     107                 :            :         req = (struct hns3_ptp_mode_cfg_cmd *)desc.data;
     108                 :            : 
     109                 :            :         val = en ? 1 : 0;
     110                 :          0 :         hns3_set_bit(req->enable, HNS3_PTP_ENABLE_B, val);
     111                 :          0 :         hns3_set_bit(req->enable, HNS3_PTP_TX_ENABLE_B, val);
     112                 :          0 :         hns3_set_bit(req->enable, HNS3_PTP_RX_ENABLE_B, val);
     113                 :            : 
     114         [ #  # ]:          0 :         if (en) {
     115                 :          0 :                 hns3_set_field(req->ptp_type, HNS3_PTP_TYPE_M, HNS3_PTP_TYPE_S,
     116                 :            :                                PTP_TYPE_L2_V2_TYPE);
     117                 :          0 :                 hns3_set_field(req->v2_message_type_1, HNS3_PTP_MESSAGE_TYPE_M,
     118                 :            :                                HNS3_PTP_MESSAGE_TYPE_S, ALL_PTP_V2_TYPE);
     119                 :            :         }
     120                 :            : 
     121                 :          0 :         ret = hns3_cmd_send(hw, &desc, 1);
     122         [ #  # ]:          0 :         if (ret) {
     123                 :          0 :                 hns3_err(hw, "configure PTP time failed, en = %d, ret = %d",
     124                 :            :                          en, ret);
     125                 :          0 :                 return ret;
     126                 :            :         }
     127                 :            : 
     128                 :          0 :         pf->ptp_enable = en;
     129                 :            : 
     130                 :          0 :         return 0;
     131                 :            : }
     132                 :            : 
     133                 :            : int
     134                 :          0 : hns3_timesync_enable(struct rte_eth_dev *dev)
     135                 :            : {
     136                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     137                 :            :         struct hns3_hw *hw = &hns->hw;
     138                 :            :         struct hns3_pf *pf = &hns->pf;
     139                 :            :         int ret;
     140                 :            : 
     141         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     142                 :            :                 return -ENOTSUP;
     143                 :            : 
     144         [ #  # ]:          0 :         if (pf->ptp_enable)
     145                 :            :                 return 0;
     146                 :            : 
     147                 :          0 :         rte_spinlock_lock(&hw->lock);
     148                 :          0 :         ret = hns3_timesync_configure(hns, true);
     149                 :            :         rte_spinlock_unlock(&hw->lock);
     150                 :          0 :         return ret;
     151                 :            : }
     152                 :            : 
     153                 :            : int
     154                 :          0 : hns3_timesync_disable(struct rte_eth_dev *dev)
     155                 :            : {
     156                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     157                 :            :         struct hns3_hw *hw = &hns->hw;
     158                 :            :         struct hns3_pf *pf = &hns->pf;
     159                 :            :         int ret;
     160                 :            : 
     161         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     162                 :            :                 return -ENOTSUP;
     163                 :            : 
     164         [ #  # ]:          0 :         if (!pf->ptp_enable)
     165                 :            :                 return 0;
     166                 :            : 
     167                 :          0 :         rte_spinlock_lock(&hw->lock);
     168                 :          0 :         ret = hns3_timesync_configure(hns, false);
     169                 :            :         rte_spinlock_unlock(&hw->lock);
     170                 :            : 
     171                 :          0 :         return ret;
     172                 :            : }
     173                 :            : 
     174                 :            : int
     175                 :          0 : hns3_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
     176                 :            :                                 struct timespec *timestamp,
     177                 :            :                                 uint32_t flags __rte_unused)
     178                 :            : {
     179                 :            : #define TIME_RX_STAMP_NS_MASK 0x3FFFFFFF
     180                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     181                 :            :         struct hns3_hw *hw = &hns->hw;
     182                 :            :         struct hns3_pf *pf = &hns->pf;
     183                 :            :         uint64_t ns, sec;
     184                 :            : 
     185         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     186                 :            :                 return -ENOTSUP;
     187                 :            : 
     188                 :          0 :         ns = pf->rx_timestamp & TIME_RX_STAMP_NS_MASK;
     189                 :          0 :         sec = upper_32_bits(pf->rx_timestamp);
     190                 :            : 
     191         [ #  # ]:          0 :         ns += sec * NSEC_PER_SEC;
     192                 :          0 :         *timestamp = rte_ns_to_timespec(ns);
     193                 :            : 
     194                 :          0 :         return 0;
     195                 :            : }
     196                 :            : 
     197                 :            : int
     198                 :          0 : hns3_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
     199                 :            :                                 struct timespec *timestamp)
     200                 :            : {
     201                 :            : #define TIME_TX_STAMP_NS_MASK 0x3FFFFFFF
     202                 :            : #define TIME_TX_STAMP_VALID   24
     203                 :            : #define TIME_TX_STAMP_CNT_MASK 0x7
     204                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     205                 :            :         struct hns3_hw *hw = &hns->hw;
     206                 :            :         uint64_t sec;
     207                 :            :         uint64_t tmp;
     208                 :            :         uint64_t ns;
     209                 :            :         int ts_cnt;
     210                 :            : 
     211         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     212                 :            :                 return -ENOTSUP;
     213                 :            : 
     214                 :          0 :         ts_cnt = hns3_read_dev(hw, HNS3_TX_1588_BACK_TSP_CNT) &
     215                 :            :                         TIME_TX_STAMP_CNT_MASK;
     216         [ #  # ]:          0 :         if (ts_cnt == 0)
     217                 :            :                 return -EINVAL;
     218                 :            : 
     219                 :          0 :         ns = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_0) & TIME_TX_STAMP_NS_MASK;
     220                 :          0 :         sec = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_1);
     221                 :          0 :         tmp = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_2) & 0xFFFF;
     222                 :          0 :         sec = (tmp << 32) | sec;
     223                 :            : 
     224         [ #  # ]:          0 :         ns += sec * NSEC_PER_SEC;
     225                 :            : 
     226                 :          0 :         *timestamp = rte_ns_to_timespec(ns);
     227                 :            : 
     228                 :            :         /* Clear current timestamp hardware stores */
     229                 :          0 :         hns3_read_dev(hw, HNS3_TX_1588_SEQID_BACK);
     230                 :            : 
     231                 :          0 :         return 0;
     232                 :            : }
     233                 :            : 
     234                 :            : int
     235                 :          0 : hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
     236                 :            : {
     237                 :            : #define HNS3_PTP_SEC_H_OFFSET   32
     238                 :            : #define HNS3_PTP_SEC_H_MASK     0xFFFF
     239                 :            : 
     240                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     241                 :            :         uint32_t sec_hi, sec_lo;
     242                 :            :         uint64_t ns, sec;
     243                 :            : 
     244         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     245                 :            :                 return -ENOTSUP;
     246                 :            : 
     247                 :          0 :         ns = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_NS);
     248                 :          0 :         sec_hi = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_H) & HNS3_PTP_SEC_H_MASK;
     249                 :          0 :         sec_lo = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_L);
     250                 :          0 :         sec = ((uint64_t)sec_hi << HNS3_PTP_SEC_H_OFFSET) | sec_lo;
     251                 :            : 
     252         [ #  # ]:          0 :         ns += sec * NSEC_PER_SEC;
     253                 :          0 :         *ts = rte_ns_to_timespec(ns);
     254                 :            : 
     255                 :          0 :         return 0;
     256                 :            : }
     257                 :            : 
     258                 :            : int
     259                 :          0 : hns3_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
     260                 :            : {
     261                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     262                 :            : 
     263         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     264                 :            :                 return -ENOTSUP;
     265                 :            : 
     266                 :            :         hns3_ptp_timesync_write_time(hw, ts);
     267                 :            : 
     268                 :          0 :         return 0;
     269                 :            : }
     270                 :            : 
     271                 :            : int
     272                 :          0 : hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
     273                 :            : {
     274                 :            : #define TIME_SYNC_L_MASK 0x7FFFFFFF
     275                 :            : #define SYMBOL_BIT_OFFSET 31
     276                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     277                 :            :         struct timespec cur_time;
     278                 :            :         uint64_t ns;
     279                 :            : 
     280         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     281                 :            :                 return -ENOTSUP;
     282                 :            : 
     283                 :          0 :         (void)hns3_timesync_read_time(dev, &cur_time);
     284                 :            :         ns = rte_timespec_to_ns((const struct timespec *)&cur_time);
     285         [ #  # ]:          0 :         cur_time = rte_ns_to_timespec(ns + delta);
     286                 :          0 :         (void)hns3_timesync_write_time(dev, (const struct timespec *)&cur_time);
     287                 :            : 
     288                 :          0 :         return 0;
     289                 :            : }
     290                 :            : 
     291                 :            : int
     292                 :          0 : hns3_restore_ptp(struct hns3_adapter *hns)
     293                 :            : {
     294                 :            :         struct hns3_pf *pf = &hns->pf;
     295                 :            :         struct hns3_hw *hw = &hns->hw;
     296                 :          0 :         bool en = pf->ptp_enable;
     297                 :            :         int ret;
     298                 :            : 
     299         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     300                 :            :                 return 0;
     301                 :            : 
     302                 :          0 :         ret = hns3_timesync_configure(hns, en);
     303         [ #  # ]:          0 :         if (ret)
     304                 :          0 :                 hns3_err(hw, "restore PTP enable state(%d) failed, ret = %d",
     305                 :            :                          en, ret);
     306                 :            : 
     307                 :            :         return ret;
     308                 :            : }
     309                 :            : 
     310                 :            : void
     311                 :          0 : hns3_ptp_uninit(struct hns3_hw *hw)
     312                 :            : {
     313                 :            :         struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
     314                 :            :         int ret;
     315                 :            : 
     316         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, PTP))
     317                 :            :                 return;
     318                 :            : 
     319                 :          0 :         ret = hns3_ptp_int_en(hw, false);
     320         [ #  # ]:          0 :         if (ret != 0)
     321                 :          0 :                 hns3_err(hw, "disable PTP interrupt failed, ret = %d.", ret);
     322                 :            : 
     323                 :          0 :         ret = hns3_timesync_configure(hns, false);
     324         [ #  # ]:          0 :         if (ret != 0)
     325                 :          0 :                 hns3_err(hw, "disable timesync failed, ret = %d.", ret);
     326                 :            : }

Generated by: LCOV version 1.14