xref: /dpdk/drivers/net/ionic/ionic_main.c (revision 01a6c311df2fa78928d46eb9bf4f2658a3cc08ee)
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 }
442