1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2021-2021 Hisilicon Limited.
5 #include <ethdev_pci.h>
9 #include "hns3_ethdev.h"
10 #include "hns3_regs.h"
11 #include "hns3_logs.h"
13 uint64_t hns3_timestamp_rx_dynflag;
14 int hns3_timestamp_dynfield_offset = -1;
17 hns3_mbuf_dyn_rx_timestamp_register(struct rte_eth_dev *dev,
18 struct rte_eth_conf *conf)
20 struct hns3_adapter *hns = dev->data->dev_private;
21 struct hns3_hw *hw = &hns->hw;
24 if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_TIMESTAMP))
27 ret = rte_mbuf_dyn_rx_timestamp_register
28 (&hns3_timestamp_dynfield_offset,
29 &hns3_timestamp_rx_dynflag);
32 "failed to register Rx timestamp field/flag");
40 hns3_ptp_int_en(struct hns3_hw *hw, bool en)
42 struct hns3_ptp_int_cmd *req;
43 struct hns3_cmd_desc desc;
46 req = (struct hns3_ptp_int_cmd *)desc.data;
47 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_PTP_INT_EN, false);
48 req->int_en = en ? 1 : 0;
50 ret = hns3_cmd_send(hw, &desc, 1);
53 "failed to %s ptp interrupt, ret = %d\n",
54 en ? "enable" : "disable", ret);
60 hns3_ptp_init(struct hns3_hw *hw)
64 if (!hns3_dev_ptp_supported(hw))
67 ret = hns3_ptp_int_en(hw, true);
72 hns3_write_dev(hw, HNS3_CFG_TIME_CYC_EN, 1);
78 hns3_timesync_configure(struct hns3_adapter *hns, bool en)
80 struct hns3_ptp_mode_cfg_cmd *req;
81 struct hns3_hw *hw = &hns->hw;
82 struct hns3_pf *pf = &hns->pf;
83 struct hns3_cmd_desc desc;
87 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CFG_PTP_MODE, false);
89 req = (struct hns3_ptp_mode_cfg_cmd *)desc.data;
92 hns3_set_bit(req->enable, HNS3_PTP_ENABLE_B, val);
93 hns3_set_bit(req->enable, HNS3_PTP_TX_ENABLE_B, val);
94 hns3_set_bit(req->enable, HNS3_PTP_RX_ENABLE_B, val);
97 hns3_set_field(req->ptp_type, HNS3_PTP_TYPE_M, HNS3_PTP_TYPE_S,
99 hns3_set_field(req->v2_message_type_1, HNS3_PTP_MESSAGE_TYPE_M,
100 HNS3_PTP_MESSAGE_TYPE_S, ALL_PTP_V2_TYPE);
103 ret = hns3_cmd_send(hw, &desc, 1);
105 hns3_err(hw, "configure PTP time failed, en = %d, ret = %d",
116 hns3_timesync_enable(struct rte_eth_dev *dev)
118 struct hns3_adapter *hns = dev->data->dev_private;
119 struct hns3_hw *hw = &hns->hw;
120 struct hns3_pf *pf = &hns->pf;
123 if (!hns3_dev_ptp_supported(hw))
129 rte_spinlock_lock(&hw->lock);
130 ret = hns3_timesync_configure(hns, true);
131 rte_spinlock_unlock(&hw->lock);
136 hns3_timesync_disable(struct rte_eth_dev *dev)
138 struct hns3_adapter *hns = dev->data->dev_private;
139 struct hns3_hw *hw = &hns->hw;
140 struct hns3_pf *pf = &hns->pf;
143 if (!hns3_dev_ptp_supported(hw))
149 rte_spinlock_lock(&hw->lock);
150 ret = hns3_timesync_configure(hns, false);
151 rte_spinlock_unlock(&hw->lock);
157 hns3_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
158 struct timespec *timestamp,
159 uint32_t flags __rte_unused)
161 #define TIME_RX_STAMP_NS_MASK 0x3FFFFFFF
162 struct hns3_adapter *hns = dev->data->dev_private;
163 struct hns3_hw *hw = &hns->hw;
164 struct hns3_pf *pf = &hns->pf;
167 if (!hns3_dev_ptp_supported(hw))
170 ns = pf->rx_timestamp & TIME_RX_STAMP_NS_MASK;
171 sec = upper_32_bits(pf->rx_timestamp);
173 ns += sec * NSEC_PER_SEC;
174 *timestamp = rte_ns_to_timespec(ns);
180 hns3_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
181 struct timespec *timestamp)
183 #define TIME_TX_STAMP_NS_MASK 0x3FFFFFFF
184 #define TIME_TX_STAMP_VALID 24
185 #define TIME_TX_STAMP_CNT_MASK 0x7
186 struct hns3_adapter *hns = dev->data->dev_private;
187 struct hns3_hw *hw = &hns->hw;
193 if (!hns3_dev_ptp_supported(hw))
196 ts_cnt = hns3_read_dev(hw, HNS3_TX_1588_BACK_TSP_CNT) &
197 TIME_TX_STAMP_CNT_MASK;
201 ns = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_0) & TIME_TX_STAMP_NS_MASK;
202 sec = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_1);
203 tmp = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_2) & 0xFFFF;
204 sec = (tmp << 32) | sec;
206 ns += sec * NSEC_PER_SEC;
208 *timestamp = rte_ns_to_timespec(ns);
210 /* Clear current timestamp hardware stores */
211 hns3_read_dev(hw, HNS3_TX_1588_SEQID_BACK);
217 hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
219 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
222 if (!hns3_dev_ptp_supported(hw))
225 sec = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_L);
226 sec |= (uint64_t)(hns3_read_dev(hw, HNS3_CURR_TIME_OUT_H) & 0xFFFF)
229 ns = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_NS);
230 ns += sec * NSEC_PER_SEC;
231 *ts = rte_ns_to_timespec(ns);
237 hns3_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
239 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
240 uint64_t sec = ts->tv_sec;
241 uint64_t ns = ts->tv_nsec;
243 if (!hns3_dev_ptp_supported(hw))
246 /* Set the timecounters to a new value. */
247 hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_H, upper_32_bits(sec));
248 hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_M, lower_32_bits(sec));
249 hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_L, lower_32_bits(ns));
250 hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_RDY, 1);
256 hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
258 #define TIME_SYNC_L_MASK 0x7FFFFFFF
259 #define SYMBOL_BIT_OFFSET 31
260 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
261 struct timespec cur_time;
264 if (!hns3_dev_ptp_supported(hw))
267 (void)hns3_timesync_read_time(dev, &cur_time);
268 ns = rte_timespec_to_ns((const struct timespec *)&cur_time);
269 cur_time = rte_ns_to_timespec(ns + delta);
270 (void)hns3_timesync_write_time(dev, (const struct timespec *)&cur_time);
276 hns3_restore_ptp(struct hns3_adapter *hns)
278 struct hns3_pf *pf = &hns->pf;
279 struct hns3_hw *hw = &hns->hw;
280 bool en = pf->ptp_enable;
283 if (!hns3_dev_ptp_supported(hw))
286 ret = hns3_timesync_configure(hns, en);
288 hns3_err(hw, "restore PTP enable state(%d) failed, ret = %d",