1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
5 #include <rte_ethdev_driver.h>
7 #include "otx2_ethdev.h"
9 #define PTP_FREQ_ADJUST (1 << 9)
12 nix_start_timecounters(struct rte_eth_dev *eth_dev)
14 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
16 memset(&dev->systime_tc, 0, sizeof(struct rte_timecounter));
17 memset(&dev->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
18 memset(&dev->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
20 dev->systime_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
21 dev->rx_tstamp_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
22 dev->tx_tstamp_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
26 nix_ptp_config(struct rte_eth_dev *eth_dev, int en)
28 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
29 struct otx2_mbox *mbox = dev->mbox;
32 if (otx2_dev_is_vf(dev))
36 /* Enable time stamping of sent PTP packets. */
37 otx2_mbox_alloc_msg_nix_lf_ptp_tx_enable(mbox);
38 rc = otx2_mbox_process(mbox);
40 otx2_err("MBOX ptp tx conf enable failed: err %d", rc);
43 /* Enable time stamping of received PTP packets. */
44 otx2_mbox_alloc_msg_cgx_ptp_rx_enable(mbox);
46 /* Disable time stamping of sent PTP packets. */
47 otx2_mbox_alloc_msg_nix_lf_ptp_tx_disable(mbox);
48 rc = otx2_mbox_process(mbox);
50 otx2_err("MBOX ptp tx conf disable failed: err %d", rc);
53 /* Disable time stamping of received PTP packets. */
54 otx2_mbox_alloc_msg_cgx_ptp_rx_disable(mbox);
57 return otx2_mbox_process(mbox);
61 otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en)
63 struct otx2_eth_dev *otx2_dev = (struct otx2_eth_dev *)dev;
64 struct rte_eth_dev *eth_dev = otx2_dev->eth_dev;
67 otx2_dev->ptp_en = ptp_en;
68 for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
69 struct otx2_eth_rxq *rxq = eth_dev->data->rx_queues[i];
70 rxq->mbuf_initializer =
71 otx2_nix_rxq_mbuf_setup(otx2_dev,
72 eth_dev->data->port_id);
78 otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev)
80 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
83 if (otx2_ethdev_is_ptp_en(dev)) {
84 otx2_info("PTP mode is already enabled ");
88 /* If we are VF, no further action can be taken */
89 if (otx2_dev_is_vf(dev))
92 if (!(dev->rx_offload_flags & NIX_RX_OFFLOAD_PTYPE_F)) {
93 otx2_err("Ptype offload is disabled, it should be enabled");
97 /* Allocating a iova address for tx tstamp */
98 const struct rte_memzone *ts;
99 ts = rte_eth_dma_zone_reserve(eth_dev, "otx2_ts",
100 0, OTX2_ALIGN, OTX2_ALIGN,
103 otx2_err("Failed to allocate mem for tx tstamp addr");
105 dev->tstamp.tx_tstamp_iova = ts->iova;
106 dev->tstamp.tx_tstamp = ts->addr;
108 /* System time should be already on by default */
109 nix_start_timecounters(eth_dev);
111 dev->rx_offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
112 dev->rx_offload_flags |= NIX_RX_OFFLOAD_TSTAMP_F;
113 dev->tx_offload_flags |= NIX_TX_OFFLOAD_TSTAMP_F;
115 rc = nix_ptp_config(eth_dev, 1);
117 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
118 struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
119 otx2_nix_form_default_desc(txq);
122 /* Setting up the function pointers as per new offload flags */
123 otx2_eth_set_rx_function(eth_dev);
124 otx2_eth_set_tx_function(eth_dev);
130 otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev)
132 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
135 if (!otx2_ethdev_is_ptp_en(dev)) {
136 otx2_nix_dbg("PTP mode is disabled");
140 /* If we are VF, nothing else can be done */
141 if (otx2_dev_is_vf(dev))
144 dev->rx_offloads &= ~DEV_RX_OFFLOAD_TIMESTAMP;
145 dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_TSTAMP_F;
146 dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_TSTAMP_F;
148 rc = nix_ptp_config(eth_dev, 0);
150 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
151 struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
152 otx2_nix_form_default_desc(txq);
155 /* Setting up the function pointers as per new offload flags */
156 otx2_eth_set_rx_function(eth_dev);
157 otx2_eth_set_tx_function(eth_dev);
163 otx2_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
164 struct timespec *timestamp,
165 uint32_t __rte_unused flags)
167 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
168 struct otx2_timesync_info *tstamp = &dev->tstamp;
171 if (!tstamp->rx_ready)
174 ns = rte_timecounter_update(&dev->rx_tstamp_tc, tstamp->rx_tstamp);
175 *timestamp = rte_ns_to_timespec(ns);
176 tstamp->rx_ready = 0;
178 otx2_nix_dbg("rx timestamp: %llu sec: %lu nsec %lu",
179 (unsigned long long)tstamp->rx_tstamp, timestamp->tv_sec,
186 otx2_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
187 struct timespec *timestamp)
189 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
190 struct otx2_timesync_info *tstamp = &dev->tstamp;
193 if (*tstamp->tx_tstamp == 0)
196 ns = rte_timecounter_update(&dev->tx_tstamp_tc, *tstamp->tx_tstamp);
197 *timestamp = rte_ns_to_timespec(ns);
199 otx2_nix_dbg("tx timestamp: %llu sec: %lu nsec %lu",
200 *(unsigned long long *)tstamp->tx_tstamp,
201 timestamp->tv_sec, timestamp->tv_nsec);
203 *tstamp->tx_tstamp = 0;
210 otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
212 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
213 struct otx2_mbox *mbox = dev->mbox;
218 /* Adjust the frequent to make tics increments in 10^9 tics per sec */
219 if (delta < PTP_FREQ_ADJUST && delta > -PTP_FREQ_ADJUST) {
220 req = otx2_mbox_alloc_msg_ptp_op(mbox);
221 req->op = PTP_OP_ADJFINE;
222 req->scaled_ppm = delta;
224 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
228 dev->systime_tc.nsec += delta;
229 dev->rx_tstamp_tc.nsec += delta;
230 dev->tx_tstamp_tc.nsec += delta;
236 otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
237 const struct timespec *ts)
239 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
242 ns = rte_timespec_to_ns(ts);
243 /* Set the time counters to a new value. */
244 dev->systime_tc.nsec = ns;
245 dev->rx_tstamp_tc.nsec = ns;
246 dev->tx_tstamp_tc.nsec = ns;
252 otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
254 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
255 struct otx2_mbox *mbox = dev->mbox;
261 req = otx2_mbox_alloc_msg_ptp_op(mbox);
262 req->op = PTP_OP_GET_CLOCK;
263 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
267 ns = rte_timecounter_update(&dev->systime_tc, rsp->clk);
268 *ts = rte_ns_to_timespec(ns);
270 otx2_nix_dbg("PTP time read: %ld.%09ld", ts->tv_sec, ts->tv_nsec);