xref: /f-stack/dpdk/drivers/bus/fslmc/mc/mc_sys.c (revision d30ea906)
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2013-2015 Freescale Semiconductor Inc.
4  * Copyright 2017 NXP
5  *
6  */
7 #include <fsl_mc_sys.h>
8 #include <fsl_mc_cmd.h>
9 
10 #include <rte_spinlock.h>
11 
12 /** User space framework uses MC Portal in shared mode. Following change
13  * introduces lock in MC FLIB
14  */
15 
16 /**
17  * A static spinlock initializer.
18  */
19 static rte_spinlock_t mc_portal_lock = RTE_SPINLOCK_INITIALIZER;
20 
mc_status_to_error(enum mc_cmd_status status)21 static int mc_status_to_error(enum mc_cmd_status status)
22 {
23 	switch (status) {
24 	case MC_CMD_STATUS_OK:
25 		return 0;
26 	case MC_CMD_STATUS_AUTH_ERR:
27 		return -EACCES; /* Token error */
28 	case MC_CMD_STATUS_NO_PRIVILEGE:
29 		return -EPERM; /* Permission denied */
30 	case MC_CMD_STATUS_DMA_ERR:
31 		return -EIO; /* Input/Output error */
32 	case MC_CMD_STATUS_CONFIG_ERR:
33 		return -EINVAL; /* Device not configured */
34 	case MC_CMD_STATUS_TIMEOUT:
35 		return -ETIMEDOUT; /* Operation timed out */
36 	case MC_CMD_STATUS_NO_RESOURCE:
37 		return -ENAVAIL; /* Resource temporarily unavailable */
38 	case MC_CMD_STATUS_NO_MEMORY:
39 		return -ENOMEM; /* Cannot allocate memory */
40 	case MC_CMD_STATUS_BUSY:
41 		return -EBUSY; /* Device busy */
42 	case MC_CMD_STATUS_UNSUPPORTED_OP:
43 		return -ENOTSUP; /* Operation not supported by device */
44 	case MC_CMD_STATUS_INVALID_STATE:
45 		return -ENODEV; /* Invalid device state */
46 	default:
47 		break;
48 	}
49 
50 	/* Not expected to reach here */
51 	return -EINVAL;
52 }
53 
mc_send_command(struct fsl_mc_io * mc_io,struct mc_command * cmd)54 int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
55 {
56 	enum mc_cmd_status status;
57 	uint64_t response;
58 
59 	if (!mc_io || !mc_io->regs)
60 		return -EACCES;
61 
62 	/* --- Call lock function here in case portal is shared --- */
63 	rte_spinlock_lock(&mc_portal_lock);
64 
65 	mc_write_command(mc_io->regs, cmd);
66 
67 	/* Spin until status changes */
68 	do {
69 		response = ioread64(mc_io->regs);
70 		status = mc_cmd_read_status((struct mc_command *)&response);
71 
72 		/* --- Call wait function here to prevent blocking ---
73 		 * Change the loop condition accordingly to exit on timeout.
74 		 */
75 	} while (status == MC_CMD_STATUS_READY);
76 
77 	/* Read the response back into the command buffer */
78 	mc_read_response(mc_io->regs, cmd);
79 
80 	/* --- Call unlock function here in case portal is shared --- */
81 	rte_spinlock_unlock(&mc_portal_lock);
82 
83 	return mc_status_to_error(status);
84 }
85