net/bnxt: fix FW version query
[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 static 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_RDMA_RESET_LIF:
111                 return "IONIC_CMD_RDMA_RESET_LIF";
112         case IONIC_CMD_RDMA_CREATE_EQ:
113                 return "IONIC_CMD_RDMA_CREATE_EQ";
114         case IONIC_CMD_RDMA_CREATE_CQ:
115                 return "IONIC_CMD_RDMA_CREATE_CQ";
116         case IONIC_CMD_RDMA_CREATE_ADMINQ:
117                 return "IONIC_CMD_RDMA_CREATE_ADMINQ";
118         default:
119                 return "DEVCMD_UNKNOWN";
120         }
121 }
122
123 int
124 ionic_adminq_check_err(struct ionic_admin_ctx *ctx, bool timeout)
125 {
126         const char *name;
127         const char *status;
128
129         if (ctx->comp.comp.status || timeout) {
130                 name = ionic_opcode_to_str(ctx->cmd.cmd.opcode);
131                 status = ionic_error_to_str(ctx->comp.comp.status);
132                 IONIC_PRINT(ERR, "%s (%d) failed: %s (%d)",
133                         name,
134                         ctx->cmd.cmd.opcode,
135                         timeout ? "TIMEOUT" : status,
136                         timeout ? -1 : ctx->comp.comp.status);
137                 return -EIO;
138         }
139
140         return 0;
141 }
142
143 static int
144 ionic_wait_ctx_for_completion(struct ionic_lif *lif, struct ionic_qcq *qcq,
145                 struct ionic_admin_ctx *ctx, unsigned long max_wait)
146 {
147         unsigned long step_msec = 1;
148         unsigned int max_wait_msec = max_wait * 1000;
149         unsigned long elapsed_msec = 0;
150         int budget = 8;
151
152         while (ctx->pending_work && elapsed_msec < max_wait_msec) {
153                 /*
154                  * Locking here as adminq is served inline (this could be called
155                  * from multiple places)
156                  */
157                 rte_spinlock_lock(&lif->adminq_service_lock);
158
159                 ionic_qcq_service(qcq, budget, ionic_adminq_service, NULL);
160
161                 rte_spinlock_unlock(&lif->adminq_service_lock);
162
163                 msec_delay(step_msec);
164                 elapsed_msec += step_msec;
165         }
166
167         return (!ctx->pending_work);
168 }
169
170 int
171 ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
172 {
173         struct ionic_qcq *qcq = lif->adminqcq;
174         bool done;
175         int err;
176
177         IONIC_PRINT(DEBUG, "Sending %s to the admin queue",
178                 ionic_opcode_to_str(ctx->cmd.cmd.opcode));
179
180         err = ionic_adminq_post(lif, ctx);
181         if (err) {
182                 IONIC_PRINT(ERR, "Failure posting to the admin queue %d (%d)",
183                         ctx->cmd.cmd.opcode, err);
184
185                 return err;
186         }
187
188         done = ionic_wait_ctx_for_completion(lif, qcq, ctx,
189                 IONIC_DEVCMD_TIMEOUT);
190
191         err = ionic_adminq_check_err(ctx, !done /* timed out */);
192         return err;
193 }
194
195 static int
196 ionic_dev_cmd_wait(struct ionic_dev *idev, unsigned long max_wait)
197 {
198         unsigned long step_msec = 100;
199         unsigned int max_wait_msec = max_wait * 1000;
200         unsigned long elapsed_msec = 0;
201         int done;
202
203         /* Wait for dev cmd to complete.. but no more than max_wait sec */
204
205         do {
206                 done = ionic_dev_cmd_done(idev);
207                 if (done) {
208                         IONIC_PRINT(DEBUG, "DEVCMD %d done took %ld msecs",
209                                 idev->dev_cmd->cmd.cmd.opcode,
210                                 elapsed_msec);
211                         return 0;
212                 }
213
214                 msec_delay(step_msec);
215
216                 elapsed_msec += step_msec;
217         } while (elapsed_msec < max_wait_msec);
218
219         IONIC_PRINT(DEBUG, "DEVCMD %d timeout after %ld msecs",
220                 idev->dev_cmd->cmd.cmd.opcode,
221                 elapsed_msec);
222
223         return -ETIMEDOUT;
224 }
225
226 static int
227 ionic_dev_cmd_check_error(struct ionic_dev *idev)
228 {
229         uint8_t status;
230
231         status = ionic_dev_cmd_status(idev);
232         if (status == 0)
233                 return 0;
234
235         return -EIO;
236 }
237
238 int
239 ionic_dev_cmd_wait_check(struct ionic_dev *idev, unsigned long max_wait)
240 {
241         int err;
242
243         err = ionic_dev_cmd_wait(idev, max_wait);
244         if (err)
245                 return err;
246
247         return ionic_dev_cmd_check_error(idev);
248 }
249
250 int
251 ionic_setup(struct ionic_adapter *adapter)
252 {
253         return ionic_dev_setup(adapter);
254 }
255
256 int
257 ionic_identify(struct ionic_adapter *adapter)
258 {
259         struct ionic_dev *idev = &adapter->idev;
260         struct ionic_identity *ident = &adapter->ident;
261         int err = 0;
262         uint32_t i;
263         unsigned int nwords;
264         uint32_t drv_size = sizeof(ident->drv.words) /
265                 sizeof(ident->drv.words[0]);
266         uint32_t cmd_size = sizeof(idev->dev_cmd->data) /
267                 sizeof(idev->dev_cmd->data[0]);
268         uint32_t dev_size = sizeof(ident->dev.words) /
269                 sizeof(ident->dev.words[0]);
270
271         memset(ident, 0, sizeof(*ident));
272
273         ident->drv.os_type = IONIC_OS_TYPE_LINUX;
274         ident->drv.os_dist = 0;
275         snprintf(ident->drv.os_dist_str,
276                 sizeof(ident->drv.os_dist_str), "Unknown");
277         ident->drv.kernel_ver = 0;
278         snprintf(ident->drv.kernel_ver_str,
279                 sizeof(ident->drv.kernel_ver_str), "DPDK");
280         strncpy(ident->drv.driver_ver_str, IONIC_DRV_VERSION,
281                 sizeof(ident->drv.driver_ver_str) - 1);
282
283         nwords = RTE_MIN(drv_size, cmd_size);
284         for (i = 0; i < nwords; i++)
285                 iowrite32(ident->drv.words[i], &idev->dev_cmd->data[i]);
286
287         ionic_dev_cmd_identify(idev, IONIC_IDENTITY_VERSION_1);
288         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
289         if (!err) {
290                 nwords = RTE_MIN(dev_size, cmd_size);
291                 for (i = 0; i < nwords; i++)
292                         ident->dev.words[i] = ioread32(&idev->dev_cmd->data[i]);
293         }
294
295         return err;
296 }
297
298 int
299 ionic_init(struct ionic_adapter *adapter)
300 {
301         struct ionic_dev *idev = &adapter->idev;
302         int err;
303
304         ionic_dev_cmd_init(idev);
305         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
306         return err;
307 }
308
309 int
310 ionic_reset(struct ionic_adapter *adapter)
311 {
312         struct ionic_dev *idev = &adapter->idev;
313         int err;
314
315         ionic_dev_cmd_reset(idev);
316         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
317         return err;
318 }
319
320 int
321 ionic_port_identify(struct ionic_adapter *adapter)
322 {
323         struct ionic_dev *idev = &adapter->idev;
324         struct ionic_identity *ident = &adapter->ident;
325         unsigned int port_words = sizeof(ident->port.words) /
326                 sizeof(ident->port.words[0]);
327         unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
328                 sizeof(idev->dev_cmd->data[0]);
329         unsigned int i;
330         unsigned int nwords;
331         int err;
332
333         ionic_dev_cmd_port_identify(idev);
334         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
335         if (!err) {
336                 nwords = RTE_MIN(port_words, cmd_words);
337                 for (i = 0; i < nwords; i++)
338                         ident->port.words[i] =
339                                 ioread32(&idev->dev_cmd->data[i]);
340         }
341
342         IONIC_PRINT(INFO, "speed %d ", ident->port.config.speed);
343         IONIC_PRINT(INFO, "mtu %d ", ident->port.config.mtu);
344         IONIC_PRINT(INFO, "state %d ", ident->port.config.state);
345         IONIC_PRINT(INFO, "an_enable %d ", ident->port.config.an_enable);
346         IONIC_PRINT(INFO, "fec_type %d ", ident->port.config.fec_type);
347         IONIC_PRINT(INFO, "pause_type %d ", ident->port.config.pause_type);
348         IONIC_PRINT(INFO, "loopback_mode %d",
349                 ident->port.config.loopback_mode);
350
351         return err;
352 }
353
354 static const struct rte_memzone *
355 ionic_memzone_reserve(const char *name, uint32_t len, int socket_id)
356 {
357         const struct rte_memzone *mz;
358
359         mz = rte_memzone_lookup(name);
360         if (mz)
361                 return mz;
362
363         mz = rte_memzone_reserve_aligned(name, len, socket_id,
364                 RTE_MEMZONE_IOVA_CONTIG, IONIC_ALIGN);
365         return mz;
366 }
367
368 int
369 ionic_port_init(struct ionic_adapter *adapter)
370 {
371         struct ionic_dev *idev = &adapter->idev;
372         struct ionic_identity *ident = &adapter->ident;
373         char z_name[RTE_MEMZONE_NAMESIZE];
374         unsigned int config_words = sizeof(ident->port.config.words) /
375                 sizeof(ident->port.config.words[0]);
376         unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
377                 sizeof(idev->dev_cmd->data[0]);
378         unsigned int nwords;
379         unsigned int i;
380         int err;
381
382         if (idev->port_info)
383                 return 0;
384
385         idev->port_info_sz = RTE_ALIGN(sizeof(*idev->port_info), PAGE_SIZE);
386
387         snprintf(z_name, sizeof(z_name), "%s_port_%s_info",
388                 IONIC_DRV_NAME,
389                 adapter->pci_dev->device.name);
390
391         idev->port_info_z = ionic_memzone_reserve(z_name, idev->port_info_sz,
392                 SOCKET_ID_ANY);
393         if (!idev->port_info_z) {
394                 IONIC_PRINT(ERR, "Cannot reserve port info DMA memory");
395                 return -ENOMEM;
396         }
397
398         idev->port_info = idev->port_info_z->addr;
399         idev->port_info_pa = idev->port_info_z->iova;
400
401         nwords = RTE_MIN(config_words, cmd_words);
402
403         for (i = 0; i < nwords; i++)
404                 iowrite32(ident->port.config.words[i], &idev->dev_cmd->data[i]);
405
406         ionic_dev_cmd_port_init(idev);
407         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
408         if (err) {
409                 IONIC_PRINT(ERR, "Failed to init port");
410                 return err;
411         }
412
413         ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP);
414         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
415         if (err) {
416                 IONIC_PRINT(WARNING, "Failed to bring port UP");
417                 return err;
418         }
419
420         return 0;
421 }
422
423 int
424 ionic_port_reset(struct ionic_adapter *adapter)
425 {
426         struct ionic_dev *idev = &adapter->idev;
427         int err;
428
429         if (!idev->port_info)
430                 return 0;
431
432         ionic_dev_cmd_port_reset(idev);
433         err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
434         if (err) {
435                 IONIC_PRINT(ERR, "Failed to reset port");
436                 return err;
437         }
438
439         idev->port_info = NULL;
440         idev->port_info_pa = 0;
441
442         return 0;
443 }