net/ionic: observe endiannness in ioread/iowrite
[dpdk.git] / drivers / net / ionic / ionic_main.c
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
3  */
4
5 #include <stdbool.h>
6
7 #include <rte_memzone.h>
8
9 #include "ionic.h"
10 #include "ionic_ethdev.h"
11 #include "ionic_lif.h"
12
13 static const char *
14 ionic_error_to_str(enum ionic_status_code code)
15 {
16         switch (code) {
17         case IONIC_RC_SUCCESS:
18                 return "IONIC_RC_SUCCESS";
19         case IONIC_RC_EVERSION:
20                 return "IONIC_RC_EVERSION";
21         case IONIC_RC_EOPCODE:
22                 return "IONIC_RC_EOPCODE";
23         case IONIC_RC_EIO:
24                 return "IONIC_RC_EIO";
25         case IONIC_RC_EPERM:
26                 return "IONIC_RC_EPERM";
27         case IONIC_RC_EQID:
28                 return "IONIC_RC_EQID";
29         case IONIC_RC_EQTYPE:
30                 return "IONIC_RC_EQTYPE";
31         case IONIC_RC_ENOENT:
32                 return "IONIC_RC_ENOENT";
33         case IONIC_RC_EINTR:
34                 return "IONIC_RC_EINTR";
35         case IONIC_RC_EAGAIN:
36                 return "IONIC_RC_EAGAIN";
37         case IONIC_RC_ENOMEM:
38                 return "IONIC_RC_ENOMEM";
39         case IONIC_RC_EFAULT:
40                 return "IONIC_RC_EFAULT";
41         case IONIC_RC_EBUSY:
42                 return "IONIC_RC_EBUSY";
43         case IONIC_RC_EEXIST:
44                 return "IONIC_RC_EEXIST";
45         case IONIC_RC_EINVAL:
46                 return "IONIC_RC_EINVAL";
47         case IONIC_RC_ENOSPC:
48                 return "IONIC_RC_ENOSPC";
49         case IONIC_RC_ERANGE:
50                 return "IONIC_RC_ERANGE";
51         case IONIC_RC_BAD_ADDR:
52                 return "IONIC_RC_BAD_ADDR";
53         case IONIC_RC_DEV_CMD:
54                 return "IONIC_RC_DEV_CMD";
55         case IONIC_RC_ERROR:
56                 return "IONIC_RC_ERROR";
57         case IONIC_RC_ERDMA:
58                 return "IONIC_RC_ERDMA";
59         default:
60                 return "IONIC_RC_UNKNOWN";
61         }
62 }
63
64 const char *
65 ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
66 {
67         switch (opcode) {
68         case IONIC_CMD_NOP:
69                 return "IONIC_CMD_NOP";
70         case IONIC_CMD_INIT:
71                 return "IONIC_CMD_INIT";
72         case IONIC_CMD_RESET:
73                 return "IONIC_CMD_RESET";
74         case IONIC_CMD_IDENTIFY:
75                 return "IONIC_CMD_IDENTIFY";
76         case IONIC_CMD_GETATTR:
77                 return "IONIC_CMD_GETATTR";
78         case IONIC_CMD_SETATTR:
79                 return "IONIC_CMD_SETATTR";
80         case IONIC_CMD_PORT_IDENTIFY:
81                 return "IONIC_CMD_PORT_IDENTIFY";
82         case IONIC_CMD_PORT_INIT:
83                 return "IONIC_CMD_PORT_INIT";
84         case IONIC_CMD_PORT_RESET:
85                 return "IONIC_CMD_PORT_RESET";
86         case IONIC_CMD_PORT_GETATTR:
87                 return "IONIC_CMD_PORT_GETATTR";
88         case IONIC_CMD_PORT_SETATTR:
89                 return "IONIC_CMD_PORT_SETATTR";
90         case IONIC_CMD_LIF_INIT:
91                 return "IONIC_CMD_LIF_INIT";
92         case IONIC_CMD_LIF_RESET:
93                 return "IONIC_CMD_LIF_RESET";
94         case IONIC_CMD_LIF_IDENTIFY:
95                 return "IONIC_CMD_LIF_IDENTIFY";
96         case IONIC_CMD_LIF_SETATTR:
97                 return "IONIC_CMD_LIF_SETATTR";
98         case IONIC_CMD_LIF_GETATTR:
99                 return "IONIC_CMD_LIF_GETATTR";
100         case IONIC_CMD_RX_MODE_SET:
101                 return "IONIC_CMD_RX_MODE_SET";
102         case IONIC_CMD_RX_FILTER_ADD:
103                 return "IONIC_CMD_RX_FILTER_ADD";
104         case IONIC_CMD_RX_FILTER_DEL:
105                 return "IONIC_CMD_RX_FILTER_DEL";
106         case IONIC_CMD_Q_INIT:
107                 return "IONIC_CMD_Q_INIT";
108         case IONIC_CMD_Q_CONTROL:
109                 return "IONIC_CMD_Q_CONTROL";
110         case IONIC_CMD_Q_IDENTIFY:
111                 return "IONIC_CMD_Q_IDENTIFY";
112         case IONIC_CMD_RDMA_RESET_LIF:
113                 return "IONIC_CMD_RDMA_RESET_LIF";
114         case IONIC_CMD_RDMA_CREATE_EQ:
115                 return "IONIC_CMD_RDMA_CREATE_EQ";
116         case IONIC_CMD_RDMA_CREATE_CQ:
117                 return "IONIC_CMD_RDMA_CREATE_CQ";
118         case IONIC_CMD_RDMA_CREATE_ADMINQ:
119                 return "IONIC_CMD_RDMA_CREATE_ADMINQ";
120         default:
121                 return "DEVCMD_UNKNOWN";
122         }
123 }
124
125 int
126 ionic_adminq_check_err(struct ionic_admin_ctx *ctx, bool timeout)
127 {
128         const char *name;
129         const char *status;
130
131         name = ionic_opcode_to_str(ctx->cmd.cmd.opcode);
132
133         if (ctx->comp.comp.status || timeout) {
134                 status = ionic_error_to_str(ctx->comp.comp.status);
135                 IONIC_PRINT(ERR, "%s (%d) failed: %s (%d)",
136                         name,
137                         ctx->cmd.cmd.opcode,
138                         timeout ? "TIMEOUT" : status,
139                         timeout ? -1 : ctx->comp.comp.status);
140                 return -EIO;
141         }
142
143         IONIC_PRINT(DEBUG, "%s (%d) succeeded", name, ctx->cmd.cmd.opcode);
144
145         return 0;
146 }
147
148 static int
149 ionic_wait_ctx_for_completion(struct ionic_lif *lif, struct ionic_qcq *qcq,
150                 struct ionic_admin_ctx *ctx, unsigned long max_wait)
151 {
152         unsigned long step_usec = IONIC_DEVCMD_CHECK_PERIOD_US;
153         unsigned long max_wait_usec = max_wait * 1000000L;
154         unsigned long elapsed_usec = 0;
155         int budget = 8;
156
157         while (ctx->pending_work && elapsed_usec < max_wait_usec) {
158                 /*
159                  * Locking here as adminq is served inline (this could be called
160                  * from multiple places)
161                  */
162                 rte_spinlock_lock(&lif->adminq_service_lock);
163
164                 ionic_qcq_service(qcq, budget, ionic_adminq_service, NULL);
165
166                 rte_spinlock_unlock(&lif->adminq_service_lock);
167
168                 rte_delay_us_block(step_usec);
169                 elapsed_usec += step_usec;
170         }
171
172         return (!ctx->pending_work);
173 }
174
175 int
176 ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
177 {
178         struct ionic_qcq *qcq = lif->adminqcq;
179         bool done;
180         int err;
181
182         IONIC_PRINT(DEBUG, "Sending %s (%d) via the admin queue",
183                 ionic_opcode_to_str(ctx->cmd.cmd.opcode), ctx->cmd.cmd.opcode);
184
185         err = ionic_adminq_post(lif, ctx);
186         if (err) {
187                 IONIC_PRINT(ERR, "Failure posting %d to the admin queue (%d)",
188                         ctx->cmd.cmd.opcode, err);
189                 return err;
190         }
191
192         done = ionic_wait_ctx_for_completion(lif, qcq, ctx,
193                 IONIC_DEVCMD_TIMEOUT);
194
195         return ionic_adminq_check_err(ctx, !done /* timed out */);
196 }
197
198 static int
199 ionic_dev_cmd_wait(struct ionic_dev *idev, unsigned long max_wait)
200 {
201         unsigned long step_usec = IONIC_DEVCMD_CHECK_PERIOD_US;
202         unsigned long max_wait_usec = max_wait * 1000000L;
203         unsigned long elapsed_usec = 0;
204         int done;
205
206         /* Wait for dev cmd to complete.. but no more than max_wait sec */
207
208         do {
209                 done = ionic_dev_cmd_done(idev);
210                 if (done) {
211                         IONIC_PRINT(DEBUG, "DEVCMD %d done took %ld usecs",
212                                 ioread8(&idev->dev_cmd->cmd.cmd.opcode),
213                                 elapsed_usec);
214                         return 0;
215                 }
216
217                 rte_delay_us_block(step_usec);
218
219                 elapsed_usec += step_usec;
220         } while (elapsed_usec < max_wait_usec);
221
222         IONIC_PRINT(ERR, "DEVCMD %d timeout after %ld usecs",
223                 ioread8(&idev->dev_cmd->cmd.cmd.opcode),
224                 elapsed_usec);
225
226         return -ETIMEDOUT;
227 }
228
229 static int
230 ionic_dev_cmd_check_error(struct ionic_dev *idev)
231 {
232         uint8_t status;
233
234         status = ionic_dev_cmd_status(idev);
235         if (status == 0)
236                 return 0;
237
238         return -EIO;
239 }
240
241 int
242 ionic_dev_cmd_wait_check(struct ionic_dev *idev, unsigned long max_wait)
243 {
244         int err;
245
246         err = ionic_dev_cmd_wait(idev, max_wait);
247
248         if (!err)
249                 err = ionic_dev_cmd_check_error(idev);
250
251         IONIC_PRINT(DEBUG, "dev_cmd returned %d", err);
252         return err;
253 }
254
255 int
256 ionic_setup(struct ionic_adapter *adapter)
257 {
258         return ionic_dev_setup(adapter);
259 }
260
261 int
262 ionic_identify(struct ionic_adapter *adapter)
263 {
264         struct ionic_dev *idev = &adapter->idev;
265         struct ionic_identity *ident = &adapter->ident;
266         int err = 0;
267         uint32_t i;
268         unsigned int nwords;
269         uint32_t drv_size = sizeof(ident->drv.words) /
270                 sizeof(ident->drv.words[0]);
271         uint32_t cmd_size = sizeof(idev->dev_cmd->data) /
272                 sizeof(idev->dev_cmd->data[0]);
273         uint32_t dev_size = sizeof(ident->dev.words) /
274                 sizeof(ident->dev.words[0]);
275
276         memset(ident, 0, sizeof(*ident));
277
278         ident->drv.os_type = IONIC_OS_TYPE_LINUX;
279         ident->drv.os_dist = 0;
280         snprintf(ident->drv.os_dist_str,
281                 sizeof(ident->drv.os_dist_str), "Unknown");
282         ident->drv.kernel_ver = 0;
283         snprintf(ident->drv.kernel_ver_str,
284                 sizeof(ident->drv.kernel_ver_str), "DPDK");
285         strncpy(ident->drv.driver_ver_str, IONIC_DRV_VERSION,
286                 sizeof(ident->drv.driver_ver_str) - 1);
287
288         nwords = RTE_MIN(drv_size, cmd_size);
289         for (i = 0; i < nwords; i++)
290                 iowrite32(ident->drv.words[i], &idev->dev_cmd->data[i]);
291
292         ionic_dev_cmd_identify(idev, IONIC_IDENTITY_VERSION_1);
293         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
294         if (!err) {
295                 nwords = RTE_MIN(dev_size, cmd_size);
296                 for (i = 0; i < nwords; i++)
297                         ident->dev.words[i] = ioread32(&idev->dev_cmd->data[i]);
298         }
299
300         return err;
301 }
302
303 int
304 ionic_init(struct ionic_adapter *adapter)
305 {
306         struct ionic_dev *idev = &adapter->idev;
307
308         ionic_dev_cmd_init(idev);
309         return ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
310 }
311
312 int
313 ionic_reset(struct ionic_adapter *adapter)
314 {
315         struct ionic_dev *idev = &adapter->idev;
316
317         ionic_dev_cmd_reset(idev);
318         return ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
319 }
320
321 int
322 ionic_port_identify(struct ionic_adapter *adapter)
323 {
324         struct ionic_dev *idev = &adapter->idev;
325         struct ionic_identity *ident = &adapter->ident;
326         unsigned int port_words = sizeof(ident->port.words) /
327                 sizeof(ident->port.words[0]);
328         unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
329                 sizeof(idev->dev_cmd->data[0]);
330         unsigned int i;
331         unsigned int nwords;
332         int err;
333
334         ionic_dev_cmd_port_identify(idev);
335         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
336         if (!err) {
337                 nwords = RTE_MIN(port_words, cmd_words);
338                 for (i = 0; i < nwords; i++)
339                         ident->port.words[i] =
340                                 ioread32(&idev->dev_cmd->data[i]);
341         }
342
343         IONIC_PRINT(INFO, "speed %d",
344                 rte_le_to_cpu_32(ident->port.config.speed));
345         IONIC_PRINT(INFO, "mtu %d",
346                 rte_le_to_cpu_32(ident->port.config.mtu));
347         IONIC_PRINT(INFO, "state %d", ident->port.config.state);
348         IONIC_PRINT(INFO, "an_enable %d", ident->port.config.an_enable);
349         IONIC_PRINT(INFO, "fec_type %d", ident->port.config.fec_type);
350         IONIC_PRINT(INFO, "pause_type %d", ident->port.config.pause_type);
351         IONIC_PRINT(INFO, "loopback_mode %d",
352                 ident->port.config.loopback_mode);
353
354         return err;
355 }
356
357 static const struct rte_memzone *
358 ionic_memzone_reserve(const char *name, uint32_t len, int socket_id)
359 {
360         const struct rte_memzone *mz;
361
362         mz = rte_memzone_lookup(name);
363         if (mz)
364                 return mz;
365
366         mz = rte_memzone_reserve_aligned(name, len, socket_id,
367                 RTE_MEMZONE_IOVA_CONTIG, IONIC_ALIGN);
368         return mz;
369 }
370
371 int
372 ionic_port_init(struct ionic_adapter *adapter)
373 {
374         struct ionic_dev *idev = &adapter->idev;
375         struct ionic_identity *ident = &adapter->ident;
376         char z_name[RTE_MEMZONE_NAMESIZE];
377         unsigned int config_words = sizeof(ident->port.config.words) /
378                 sizeof(ident->port.config.words[0]);
379         unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
380                 sizeof(idev->dev_cmd->data[0]);
381         unsigned int nwords;
382         unsigned int i;
383         int err;
384
385         if (idev->port_info)
386                 return 0;
387
388         idev->port_info_sz = RTE_ALIGN(sizeof(*idev->port_info), PAGE_SIZE);
389
390         snprintf(z_name, sizeof(z_name), "%s_port_%s_info",
391                 IONIC_DRV_NAME, adapter->name);
392
393         idev->port_info_z = ionic_memzone_reserve(z_name, idev->port_info_sz,
394                 SOCKET_ID_ANY);
395         if (!idev->port_info_z) {
396                 IONIC_PRINT(ERR, "Cannot reserve port info DMA memory");
397                 return -ENOMEM;
398         }
399
400         idev->port_info = idev->port_info_z->addr;
401         idev->port_info_pa = idev->port_info_z->iova;
402
403         nwords = RTE_MIN(config_words, cmd_words);
404
405         for (i = 0; i < nwords; i++)
406                 iowrite32(ident->port.config.words[i], &idev->dev_cmd->data[i]);
407
408         idev->port_info->config.state = IONIC_PORT_ADMIN_STATE_UP;
409         ionic_dev_cmd_port_init(idev);
410         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
411         if (err)
412                 IONIC_PRINT(ERR, "Failed to init port");
413
414         return err;
415 }
416
417 int
418 ionic_port_reset(struct ionic_adapter *adapter)
419 {
420         struct ionic_dev *idev = &adapter->idev;
421         int err;
422
423         if (!idev->port_info)
424                 return 0;
425
426         ionic_dev_cmd_port_reset(idev);
427         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
428         if (err) {
429                 IONIC_PRINT(ERR, "Failed to reset port");
430                 return err;
431         }
432
433         idev->port_info = NULL;
434         idev->port_info_pa = 0;
435
436         return 0;
437 }