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