cd3e6b2e97ab53b9d52ee7034129f4bdb0e505c1
[dpdk.git] / drivers / raw / cnxk_bphy / cnxk_bphy_cgx_test.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 #include <stdint.h>
5
6 #include <rte_cycles.h>
7 #include <rte_log.h>
8 #include <rte_malloc.h>
9 #include <rte_rawdev.h>
10
11 #include "cnxk_bphy_cgx.h"
12 #include "rte_pmd_bphy.h"
13
14 static int
15 cnxk_bphy_cgx_enq_msg(uint16_t dev_id, unsigned int queue, void *msg)
16 {
17         struct rte_rawdev_buf *bufs[1];
18         struct rte_rawdev_buf buf;
19         void *q;
20         int ret;
21
22         q = (void *)(size_t)queue;
23         buf.buf_addr = msg;
24         bufs[0] = &buf;
25
26         ret = rte_rawdev_enqueue_buffers(dev_id, bufs, 1, q);
27         if (ret < 0)
28                 return ret;
29         if (ret != 1)
30                 return -EIO;
31
32         return 0;
33 }
34
35 static int
36 cnxk_bphy_cgx_deq_msg(uint16_t dev_id, unsigned int queue, void **msg)
37 {
38         struct rte_rawdev_buf *bufs[1];
39         struct rte_rawdev_buf buf;
40         void *q;
41         int ret;
42
43         q = (void *)(size_t)queue;
44         bufs[0] = &buf;
45
46         ret = rte_rawdev_dequeue_buffers(dev_id, bufs, 1, q);
47         if (ret < 0)
48                 return ret;
49         if (ret != 1)
50                 return -EIO;
51
52         *msg = buf.buf_addr;
53
54         return 0;
55 }
56
57 static int
58 cnxk_bphy_cgx_link_cond(uint16_t dev_id, unsigned int queue, int cond)
59 {
60         int tries = 10, ret;
61
62         do {
63                 struct cnxk_bphy_cgx_msg_link_info *link_info = NULL;
64                 struct cnxk_bphy_cgx_msg msg;
65
66                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_GET_LINKINFO;
67                 ret = cnxk_bphy_cgx_enq_msg(dev_id, queue, &msg);
68                 if (ret)
69                         return ret;
70
71                 ret = cnxk_bphy_cgx_deq_msg(dev_id, queue, (void **)&link_info);
72                 if (ret)
73                         return ret;
74
75                 if (link_info->link_up == cond) {
76                         rte_free(link_info);
77                         break;
78                 }
79
80                 rte_free(link_info);
81                 rte_delay_ms(500);
82         } while (--tries);
83
84         if (tries)
85                 return !!cond;
86
87         return -ETIMEDOUT;
88 }
89
90 static int
91 cnxk_bphy_cgx_get_supported_fec(uint16_t dev_id, unsigned int queue,
92                                 enum cnxk_bphy_cgx_eth_link_fec *fec)
93 {
94         struct cnxk_bphy_cgx_msg msg = {
95                 .type = CNXK_BPHY_CGX_MSG_TYPE_GET_SUPPORTED_FEC,
96         };
97         int ret;
98
99         ret = cnxk_bphy_cgx_enq_msg(dev_id, queue, &msg);
100         if (ret)
101                 return ret;
102
103         return cnxk_bphy_cgx_deq_msg(dev_id, queue, (void **)&fec);
104 }
105
106 int
107 cnxk_bphy_cgx_dev_selftest(uint16_t dev_id)
108 {
109         unsigned int queues, i;
110         int ret;
111
112         queues = rte_rawdev_queue_count(dev_id);
113         if (queues == 0)
114                 return -ENODEV;
115
116         ret = rte_rawdev_start(dev_id);
117         if (ret)
118                 return ret;
119
120         for (i = 0; i < queues; i++) {
121                 struct cnxk_bphy_cgx_msg_set_link_state link_state;
122                 enum cnxk_bphy_cgx_eth_link_fec fec;
123                 struct cnxk_bphy_cgx_msg msg;
124                 unsigned int descs;
125
126                 ret = rte_rawdev_queue_conf_get(dev_id, i, &descs,
127                                                 sizeof(descs));
128                 if (ret)
129                         break;
130                 if (descs != 1) {
131                         RTE_LOG(ERR, PMD, "Wrong number of descs reported\n");
132                         ret = -ENODEV;
133                         break;
134                 }
135
136                 RTE_LOG(INFO, PMD, "Testing queue %d\n", i);
137
138                 /* stop rx/tx */
139                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_STOP_RXTX;
140                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
141                 if (ret) {
142                         RTE_LOG(ERR, PMD, "Failed to stop rx/tx\n");
143                         break;
144                 }
145
146                 /* start rx/tx */
147                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_START_RXTX;
148                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
149                 if (ret) {
150                         RTE_LOG(ERR, PMD, "Failed to start rx/tx\n");
151                         break;
152                 }
153
154                 /* set link down */
155                 link_state.state = false;
156                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_SET_LINK_STATE;
157                 msg.data = &link_state;
158                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
159                 if (ret) {
160                         RTE_LOG(ERR, PMD, "Failed to set link down\n");
161                         break;
162                 }
163
164                 ret = cnxk_bphy_cgx_link_cond(dev_id, i, 0);
165                 if (ret != 0)
166                         RTE_LOG(ERR, PMD,
167                                 "Timed out waiting for a link down\n");
168
169                 /* set link up */
170                 link_state.state = true;
171                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_SET_LINK_STATE;
172                 msg.data = &link_state;
173                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
174                 if (ret) {
175                         RTE_LOG(ERR, PMD, "Failed to set link up\n");
176                         break;
177                 }
178
179                 ret = cnxk_bphy_cgx_link_cond(dev_id, i, 1);
180                 if (ret != 1)
181                         RTE_LOG(ERR, PMD, "Timed out waiting for a link up\n");
182
183                 /* enable internal loopback */
184                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_INTLBK_ENABLE;
185                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
186                 if (ret) {
187                         RTE_LOG(ERR, PMD, "Failed to enable internal lbk\n");
188                         break;
189                 }
190
191                 /* disable internal loopback */
192                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_INTLBK_DISABLE;
193                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
194                 if (ret) {
195                         RTE_LOG(ERR, PMD, "Failed to disable internal lbk\n");
196                         break;
197                 }
198
199                 /* enable ptp */
200                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_PTP_RX_ENABLE;
201                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
202                 /* ptp not available on RPM */
203                 if (ret < 0 && ret != -ENOTSUP) {
204                         RTE_LOG(ERR, PMD, "Failed to enable ptp\n");
205                         break;
206                 }
207                 ret = 0;
208
209                 /* disable ptp */
210                 msg.type = CNXK_BPHY_CGX_MSG_TYPE_PTP_RX_DISABLE;
211                 ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
212                 /* ptp not available on RPM */
213                 if (ret < 0 && ret != -ENOTSUP) {
214                         RTE_LOG(ERR, PMD, "Failed to disable ptp\n");
215                         break;
216                 }
217                 ret = 0;
218
219                 ret = cnxk_bphy_cgx_get_supported_fec(dev_id, i, &fec);
220                 if (ret) {
221                         RTE_LOG(ERR, PMD, "Failed to get supported FEC\n");
222                         break;
223                 }
224         }
225
226         rte_rawdev_stop(dev_id);
227
228         return ret;
229 }