net/octeontx2: support base PTP
[dpdk.git] / drivers / net / octeontx2 / otx2_ptp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_ethdev_driver.h>
6
7 #include "otx2_ethdev.h"
8
9 #define PTP_FREQ_ADJUST (1 << 9)
10
11 static void
12 nix_start_timecounters(struct rte_eth_dev *eth_dev)
13 {
14         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
15
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));
19
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;
23 }
24
25 static int
26 nix_ptp_config(struct rte_eth_dev *eth_dev, int en)
27 {
28         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
29         struct otx2_mbox *mbox = dev->mbox;
30         uint8_t rc = 0;
31
32         if (otx2_dev_is_vf(dev))
33                 return rc;
34
35         if (en) {
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);
39                 if (rc) {
40                         otx2_err("MBOX ptp tx conf enable failed: err %d", rc);
41                         return rc;
42                 }
43                 /* Enable time stamping of received PTP packets. */
44                 otx2_mbox_alloc_msg_cgx_ptp_rx_enable(mbox);
45         } else {
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);
49                 if (rc) {
50                         otx2_err("MBOX ptp tx conf disable failed: err %d", rc);
51                         return rc;
52                 }
53                 /* Disable time stamping of received PTP packets. */
54                 otx2_mbox_alloc_msg_cgx_ptp_rx_disable(mbox);
55         }
56
57         return otx2_mbox_process(mbox);
58 }
59
60 int
61 otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev)
62 {
63         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
64         int i, rc = 0;
65
66         if (otx2_ethdev_is_ptp_en(dev)) {
67                 otx2_info("PTP mode is already enabled ");
68                 return -EINVAL;
69         }
70
71         /* If we are VF, no further action can be taken */
72         if (otx2_dev_is_vf(dev))
73                 return -EINVAL;
74
75         if (!(dev->rx_offload_flags & NIX_RX_OFFLOAD_PTYPE_F)) {
76                 otx2_err("Ptype offload is disabled, it should be enabled");
77                 return -EINVAL;
78         }
79
80         /* Allocating a iova address for tx tstamp */
81         const struct rte_memzone *ts;
82         ts = rte_eth_dma_zone_reserve(eth_dev, "otx2_ts",
83                                       0, OTX2_ALIGN, OTX2_ALIGN,
84                                       dev->node);
85         if (ts == NULL)
86                 otx2_err("Failed to allocate mem for tx tstamp addr");
87
88         dev->tstamp.tx_tstamp_iova = ts->iova;
89         dev->tstamp.tx_tstamp = ts->addr;
90
91         /* System time should be already on by default */
92         nix_start_timecounters(eth_dev);
93
94         dev->rx_offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
95         dev->rx_offload_flags |= NIX_RX_OFFLOAD_TSTAMP_F;
96         dev->tx_offload_flags |= NIX_TX_OFFLOAD_TSTAMP_F;
97
98         rc = nix_ptp_config(eth_dev, 1);
99         if (!rc) {
100                 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
101                         struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
102                         otx2_nix_form_default_desc(txq);
103                 }
104         }
105         return rc;
106 }
107
108 int
109 otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev)
110 {
111         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
112         int i, rc = 0;
113
114         if (!otx2_ethdev_is_ptp_en(dev)) {
115                 otx2_nix_dbg("PTP mode is disabled");
116                 return -EINVAL;
117         }
118
119         /* If we are VF, nothing else can be done */
120         if (otx2_dev_is_vf(dev))
121                 return -EINVAL;
122
123         dev->rx_offloads &= ~DEV_RX_OFFLOAD_TIMESTAMP;
124         dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_TSTAMP_F;
125         dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_TSTAMP_F;
126
127         rc = nix_ptp_config(eth_dev, 0);
128         if (!rc) {
129                 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
130                         struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
131                         otx2_nix_form_default_desc(txq);
132                 }
133         }
134         return rc;
135 }