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