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)21static 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)54int 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