1e7a45f3cSGagandeep Singh /* SPDX-License-Identifier: BSD-3-Clause 2e7a45f3cSGagandeep Singh * Copyright 2017-2018 NXP 3e7a45f3cSGagandeep Singh */ 4e7a45f3cSGagandeep Singh 5e7a45f3cSGagandeep Singh #include <stdbool.h> 6e7a45f3cSGagandeep Singh #include <stdint.h> 7e7a45f3cSGagandeep Singh #include <stdio.h> 8e7a45f3cSGagandeep Singh #include <unistd.h> 9e7a45f3cSGagandeep Singh #include <stdlib.h> 10e7a45f3cSGagandeep Singh #include <dirent.h> 11e7a45f3cSGagandeep Singh #include <string.h> 12e7a45f3cSGagandeep Singh #include <sys/mman.h> 13e7a45f3cSGagandeep Singh #include <errno.h> 14e7a45f3cSGagandeep Singh #include <fcntl.h> 15e7a45f3cSGagandeep Singh 16e7a45f3cSGagandeep Singh #include <rte_common.h> 17e7a45f3cSGagandeep Singh #include <rte_malloc.h> 18e7a45f3cSGagandeep Singh #include <rte_crypto.h> 19e7a45f3cSGagandeep Singh #include <rte_security.h> 20e7a45f3cSGagandeep Singh 21e7a45f3cSGagandeep Singh #include <caam_jr_config.h> 22e7a45f3cSGagandeep Singh #include <caam_jr_hw_specific.h> 23e7a45f3cSGagandeep Singh #include <caam_jr_pvt.h> 24e7a45f3cSGagandeep Singh #include <caam_jr_log.h> 25e7a45f3cSGagandeep Singh 26e7a45f3cSGagandeep Singh /* Prefix path to sysfs directory where UIO device attributes are exported. 27e7a45f3cSGagandeep Singh * Path for UIO device X is /sys/class/uio/uioX 28e7a45f3cSGagandeep Singh */ 29e7a45f3cSGagandeep Singh #define SEC_UIO_DEVICE_SYS_ATTR_PATH "/sys/class/uio" 30e7a45f3cSGagandeep Singh 31e7a45f3cSGagandeep Singh /* Subfolder in sysfs where mapping attributes are exported 32e7a45f3cSGagandeep Singh * for each UIO device. Path for mapping Y for device X is: 33e7a45f3cSGagandeep Singh * /sys/class/uio/uioX/maps/mapY 34e7a45f3cSGagandeep Singh */ 35e7a45f3cSGagandeep Singh #define SEC_UIO_DEVICE_SYS_MAP_ATTR "maps/map" 36e7a45f3cSGagandeep Singh 37e7a45f3cSGagandeep Singh /* Name of UIO device file prefix. Each UIO device will have a device file 38e7a45f3cSGagandeep Singh * /dev/uioX, where X is the minor device number. 39e7a45f3cSGagandeep Singh */ 40e7a45f3cSGagandeep Singh #define SEC_UIO_DEVICE_FILE_NAME "/dev/uio" 41e7a45f3cSGagandeep Singh 42e7a45f3cSGagandeep Singh /* 43e7a45f3cSGagandeep Singh * Name of UIO device. Each user space SEC job ring will have a corresponding 44e7a45f3cSGagandeep Singh * UIO device with the name sec-channelX, where X is the job ring id. 45e7a45f3cSGagandeep Singh * Maximum length is #SEC_UIO_MAX_DEVICE_NAME_LENGTH. 46e7a45f3cSGagandeep Singh * 47e7a45f3cSGagandeep Singh * @note Must be kept in synch with SEC kernel driver 48e7a45f3cSGagandeep Singh * define #SEC_UIO_DEVICE_NAME ! 49e7a45f3cSGagandeep Singh */ 50e7a45f3cSGagandeep Singh #define SEC_UIO_DEVICE_NAME "fsl-jr" 51e7a45f3cSGagandeep Singh 52e7a45f3cSGagandeep Singh /* Maximum length for the name of an UIO device file. 53e7a45f3cSGagandeep Singh * Device file name format is: /dev/uioX. 54e7a45f3cSGagandeep Singh */ 55e7a45f3cSGagandeep Singh #define SEC_UIO_MAX_DEVICE_FILE_NAME_LENGTH 30 56e7a45f3cSGagandeep Singh 57e7a45f3cSGagandeep Singh /* Maximum length for the name of an attribute file for an UIO device. 58e7a45f3cSGagandeep Singh * Attribute files are exported in sysfs and have the name formatted as: 59e7a45f3cSGagandeep Singh * /sys/class/uio/uioX/<attribute_file_name> 60e7a45f3cSGagandeep Singh */ 61e7a45f3cSGagandeep Singh #define SEC_UIO_MAX_ATTR_FILE_NAME 100 62e7a45f3cSGagandeep Singh 63e7a45f3cSGagandeep Singh /* Command that is used by SEC user space driver and SEC kernel driver 64e7a45f3cSGagandeep Singh * to signal a request from the former to the later to disable job DONE 65e7a45f3cSGagandeep Singh * and error IRQs on a certain job ring. 66e7a45f3cSGagandeep Singh * The configuration is done at SEC Controller's level. 67e7a45f3cSGagandeep Singh * @note Need to be kept in synch with #SEC_UIO_DISABLE_IRQ_CMD from 68e7a45f3cSGagandeep Singh * linux/drivers/crypto/talitos.c ! 69e7a45f3cSGagandeep Singh */ 70e7a45f3cSGagandeep Singh #define SEC_UIO_DISABLE_IRQ_CMD 0 71e7a45f3cSGagandeep Singh 72e7a45f3cSGagandeep Singh /* Command that is used by SEC user space driver and SEC kernel driver 73e7a45f3cSGagandeep Singh * to signal a request from the former to the later to enable job DONE 74e7a45f3cSGagandeep Singh * and error IRQs on a certain job ring. 75e7a45f3cSGagandeep Singh * The configuration is done at SEC Controller's level. 76e7a45f3cSGagandeep Singh * @note Need to be kept in synch with #SEC_UIO_ENABLE_IRQ_CMD from 77e7a45f3cSGagandeep Singh * linux/drivers/crypto/talitos.c ! 78e7a45f3cSGagandeep Singh */ 79e7a45f3cSGagandeep Singh #define SEC_UIO_ENABLE_IRQ_CMD 1 80e7a45f3cSGagandeep Singh 81e7a45f3cSGagandeep Singh /** Command that is used by SEC user space driver and SEC kernel driver 82e7a45f3cSGagandeep Singh * to signal a request from the former to the later to do a SEC engine reset. 83e7a45f3cSGagandeep Singh * @note Need to be kept in synch with #SEC_UIO_RESET_SEC_ENGINE_CMD from 84e7a45f3cSGagandeep Singh * linux/drivers/crypto/talitos.c ! 85e7a45f3cSGagandeep Singh */ 86e7a45f3cSGagandeep Singh #define SEC_UIO_RESET_SEC_ENGINE_CMD 3 87e7a45f3cSGagandeep Singh 88e7a45f3cSGagandeep Singh /* The id for the mapping used to export SEC's registers to 89e7a45f3cSGagandeep Singh * user space through UIO devices. 90e7a45f3cSGagandeep Singh */ 91e7a45f3cSGagandeep Singh #define SEC_UIO_MAP_ID 0 92e7a45f3cSGagandeep Singh 93e7a45f3cSGagandeep Singh static struct uio_job_ring g_uio_job_ring[MAX_SEC_JOB_RINGS]; 94e7a45f3cSGagandeep Singh static int g_uio_jr_num; 95e7a45f3cSGagandeep Singh 96e7a45f3cSGagandeep Singh /** @brief Checks if a file name contains a certain substring. 97e7a45f3cSGagandeep Singh * If so, it extracts the number following the substring. 98e7a45f3cSGagandeep Singh * This function assumes a filename format of: [text][number]. 99e7a45f3cSGagandeep Singh * @param [in] filename File name 100e7a45f3cSGagandeep Singh * @param [in] match String to match in file name 101e7a45f3cSGagandeep Singh * @param [out] number The number extracted from filename 102e7a45f3cSGagandeep Singh * 103e7a45f3cSGagandeep Singh * @retval true if file name matches the criteria 104e7a45f3cSGagandeep Singh * @retval false if file name does not match the criteria 105e7a45f3cSGagandeep Singh */ 106e7a45f3cSGagandeep Singh static bool 107e7a45f3cSGagandeep Singh file_name_match_extract(const char filename[], const char match[], int *number) 108e7a45f3cSGagandeep Singh { 109e7a45f3cSGagandeep Singh char *substr = NULL; 110e7a45f3cSGagandeep Singh 111e7a45f3cSGagandeep Singh substr = strstr(filename, match); 112e7a45f3cSGagandeep Singh if (substr == NULL) 113e7a45f3cSGagandeep Singh return false; 114e7a45f3cSGagandeep Singh 115e7a45f3cSGagandeep Singh /* substring <match> was found in <filename> 116e7a45f3cSGagandeep Singh * read number following <match> substring in <filename> 117e7a45f3cSGagandeep Singh */ 118e7a45f3cSGagandeep Singh if (sscanf(filename + strlen(match), "%d", number) <= 0) 119e7a45f3cSGagandeep Singh return false; 120e7a45f3cSGagandeep Singh 121e7a45f3cSGagandeep Singh return true; 122e7a45f3cSGagandeep Singh } 123e7a45f3cSGagandeep Singh 124e7a45f3cSGagandeep Singh /** @brief Reads first line from a file. 125e7a45f3cSGagandeep Singh * Composes file name as: root/subdir/filename 126e7a45f3cSGagandeep Singh * 127e7a45f3cSGagandeep Singh * @param [in] root Root path 128e7a45f3cSGagandeep Singh * @param [in] subdir Subdirectory name 129e7a45f3cSGagandeep Singh * @param [in] filename File name 130e7a45f3cSGagandeep Singh * @param [out] line The first line read from file. 131e7a45f3cSGagandeep Singh * 132e7a45f3cSGagandeep Singh * @retval 0 for succes 133e7a45f3cSGagandeep Singh * @retval other value for error 134e7a45f3cSGagandeep Singh */ 135e7a45f3cSGagandeep Singh static int 136e7a45f3cSGagandeep Singh file_read_first_line(const char root[], const char subdir[], 137e7a45f3cSGagandeep Singh const char filename[], char *line) 138e7a45f3cSGagandeep Singh { 139e7a45f3cSGagandeep Singh char absolute_file_name[SEC_UIO_MAX_ATTR_FILE_NAME]; 140e7a45f3cSGagandeep Singh int fd = 0, ret = 0; 141e7a45f3cSGagandeep Singh 142e7a45f3cSGagandeep Singh /*compose the file name: root/subdir/filename */ 143e7a45f3cSGagandeep Singh memset(absolute_file_name, 0, sizeof(absolute_file_name)); 144e7a45f3cSGagandeep Singh snprintf(absolute_file_name, SEC_UIO_MAX_ATTR_FILE_NAME, 145e7a45f3cSGagandeep Singh "%s/%s/%s", root, subdir, filename); 146e7a45f3cSGagandeep Singh 147e7a45f3cSGagandeep Singh fd = open(absolute_file_name, O_RDONLY); 14861552661SYunjian Wang SEC_ASSERT(fd >= 0, fd, "Error opening file %s", 149e7a45f3cSGagandeep Singh absolute_file_name); 150e7a45f3cSGagandeep Singh 151e7a45f3cSGagandeep Singh /* read UIO device name from first line in file */ 152e7a45f3cSGagandeep Singh ret = read(fd, line, SEC_UIO_MAX_DEVICE_FILE_NAME_LENGTH); 153e7a45f3cSGagandeep Singh close(fd); 154e7a45f3cSGagandeep Singh 155e7a45f3cSGagandeep Singh /* NULL-ify string */ 156e7a45f3cSGagandeep Singh line[SEC_UIO_MAX_DEVICE_FILE_NAME_LENGTH - 1] = '\0'; 157e7a45f3cSGagandeep Singh 158e7a45f3cSGagandeep Singh if (ret <= 0) { 159e7a45f3cSGagandeep Singh CAAM_JR_ERR("Error reading from file %s", absolute_file_name); 160e7a45f3cSGagandeep Singh return ret; 161e7a45f3cSGagandeep Singh } 162e7a45f3cSGagandeep Singh 163e7a45f3cSGagandeep Singh return 0; 164e7a45f3cSGagandeep Singh } 165e7a45f3cSGagandeep Singh 166e7a45f3cSGagandeep Singh /** @brief Uses UIO control to send commands to SEC kernel driver. 167e7a45f3cSGagandeep Singh * The mechanism is to write a command word into the file descriptor 168e7a45f3cSGagandeep Singh * that the user-space driver obtained for each user-space SEC job ring. 169e7a45f3cSGagandeep Singh * Both user-space driver and kernel driver must have the same understanding 170e7a45f3cSGagandeep Singh * about the command codes. 171e7a45f3cSGagandeep Singh * 172e7a45f3cSGagandeep Singh * @param [in] UIO FD The UIO file descriptor 173e7a45f3cSGagandeep Singh * @param [in] uio_command Command word 174e7a45f3cSGagandeep Singh * 175e7a45f3cSGagandeep Singh * @retval Result of write operation on the job ring's UIO file descriptor. 176e7a45f3cSGagandeep Singh * Should be sizeof(int) for success operations. 177e7a45f3cSGagandeep Singh * Other values can be returned and used, if desired to add special 178e7a45f3cSGagandeep Singh * meaning to return values, but this has to be programmed in SEC 179e7a45f3cSGagandeep Singh * kernel driver as well. No special return values are used. 180e7a45f3cSGagandeep Singh */ 181e7a45f3cSGagandeep Singh static int 18261552661SYunjian Wang sec_uio_send_command(int uio_fd, int32_t uio_command) 183e7a45f3cSGagandeep Singh { 184e7a45f3cSGagandeep Singh int ret; 185e7a45f3cSGagandeep Singh 186e7a45f3cSGagandeep Singh /* Use UIO file descriptor we have for this job ring. 187e7a45f3cSGagandeep Singh * Writing a command code to this file descriptor will make the 188e7a45f3cSGagandeep Singh * SEC kernel driver execute the desired command. 189e7a45f3cSGagandeep Singh */ 190e7a45f3cSGagandeep Singh ret = write(uio_fd, &uio_command, sizeof(int)); 191e7a45f3cSGagandeep Singh return ret; 192e7a45f3cSGagandeep Singh } 193e7a45f3cSGagandeep Singh 194e7a45f3cSGagandeep Singh /** @brief Request to SEC kernel driver to enable interrupts for 195e7a45f3cSGagandeep Singh * descriptor finished processing 196e7a45f3cSGagandeep Singh * Use UIO to communicate with SEC kernel driver: write command 197e7a45f3cSGagandeep Singh * value that indicates an IRQ enable action into UIO file descriptor 198e7a45f3cSGagandeep Singh * of this job ring. 199e7a45f3cSGagandeep Singh * 200e7a45f3cSGagandeep Singh * @param [in] uio_fd Job Ring UIO File descriptor 201e7a45f3cSGagandeep Singh * @retval 0 for success 202e7a45f3cSGagandeep Singh * @retval -1 value for error 203e7a45f3cSGagandeep Singh */ 204c40b4fcdSYunjian Wang int 20561552661SYunjian Wang caam_jr_enable_irqs(int uio_fd) 206e7a45f3cSGagandeep Singh { 207e7a45f3cSGagandeep Singh int ret; 208e7a45f3cSGagandeep Singh 209e7a45f3cSGagandeep Singh /* Use UIO file descriptor we have for this job ring. 210e7a45f3cSGagandeep Singh * Writing a command code to this file descriptor will make the 211e7a45f3cSGagandeep Singh * SEC kernel driver enable DONE and Error IRQs for this job ring, 212e7a45f3cSGagandeep Singh * at Controller level. 213e7a45f3cSGagandeep Singh */ 214e7a45f3cSGagandeep Singh ret = sec_uio_send_command(uio_fd, SEC_UIO_ENABLE_IRQ_CMD); 215e7a45f3cSGagandeep Singh SEC_ASSERT(ret == sizeof(int), -1, 216e7a45f3cSGagandeep Singh "Failed to request SEC engine to enable job done and " 217e7a45f3cSGagandeep Singh "error IRQs through UIO control. UIO FD %d. Reset SEC driver!", 218e7a45f3cSGagandeep Singh uio_fd); 219e7a45f3cSGagandeep Singh CAAM_JR_DEBUG("Enabled IRQs on jr with uio_fd %d", uio_fd); 220e7a45f3cSGagandeep Singh return 0; 221e7a45f3cSGagandeep Singh } 222e7a45f3cSGagandeep Singh 223e7a45f3cSGagandeep Singh 224e7a45f3cSGagandeep Singh /** @brief Request to SEC kernel driver to disable interrupts for descriptor 225e7a45f3cSGagandeep Singh * finished processing 226e7a45f3cSGagandeep Singh * Use UIO to communicate with SEC kernel driver: write command 227e7a45f3cSGagandeep Singh * value that indicates an IRQ disable action into UIO file descriptor 228e7a45f3cSGagandeep Singh * of this job ring. 229e7a45f3cSGagandeep Singh * 2307be78d02SJosh Soref * @param [in] uio_fd UIO File descriptor 231e7a45f3cSGagandeep Singh * @retval 0 for success 232e7a45f3cSGagandeep Singh * @retval -1 value for error 233e7a45f3cSGagandeep Singh * 234e7a45f3cSGagandeep Singh */ 235c40b4fcdSYunjian Wang int 23661552661SYunjian Wang caam_jr_disable_irqs(int uio_fd) 237e7a45f3cSGagandeep Singh { 238e7a45f3cSGagandeep Singh int ret; 239e7a45f3cSGagandeep Singh 240e7a45f3cSGagandeep Singh /* Use UIO file descriptor we have for this job ring. 241e7a45f3cSGagandeep Singh * Writing a command code to this file descriptor will make the 242e7a45f3cSGagandeep Singh * SEC kernel driver disable IRQs for this job ring, 243e7a45f3cSGagandeep Singh * at Controller level. 244e7a45f3cSGagandeep Singh */ 245e7a45f3cSGagandeep Singh 246e7a45f3cSGagandeep Singh ret = sec_uio_send_command(uio_fd, SEC_UIO_DISABLE_IRQ_CMD); 247e7a45f3cSGagandeep Singh SEC_ASSERT(ret == sizeof(int), -1, 248e7a45f3cSGagandeep Singh "Failed to request SEC engine to disable job done and " 249e7a45f3cSGagandeep Singh "IRQs through UIO control. UIO_FD %d Reset SEC driver!", 250e7a45f3cSGagandeep Singh uio_fd); 251e7a45f3cSGagandeep Singh CAAM_JR_DEBUG("Disabled IRQs on jr with uio_fd %d", uio_fd); 252e7a45f3cSGagandeep Singh return 0; 253e7a45f3cSGagandeep Singh } 254e7a45f3cSGagandeep Singh 255e7a45f3cSGagandeep Singh /** @brief Maps register range assigned for a job ring. 256e7a45f3cSGagandeep Singh * 257e7a45f3cSGagandeep Singh * @param [in] uio_device_fd UIO device file descriptor 258e7a45f3cSGagandeep Singh * @param [in] uio_device_id UIO device id 259e7a45f3cSGagandeep Singh * @param [in] uio_map_id UIO allows maximum 5 different mapping for 260e7a45f3cSGagandeep Singh each device. Maps start with id 0. 261e7a45f3cSGagandeep Singh * @param [out] map_size Map size. 262e7a45f3cSGagandeep Singh * @retval NULL if failed to map registers 263e7a45f3cSGagandeep Singh * @retval Virtual address for mapped register address range 264e7a45f3cSGagandeep Singh */ 265e7a45f3cSGagandeep Singh static void * 266e7a45f3cSGagandeep Singh uio_map_registers(int uio_device_fd, int uio_device_id, 267e7a45f3cSGagandeep Singh int uio_map_id, int *map_size) 268e7a45f3cSGagandeep Singh { 269e7a45f3cSGagandeep Singh void *mapped_address = NULL; 270e7a45f3cSGagandeep Singh unsigned int uio_map_size = 0; 271e7a45f3cSGagandeep Singh char uio_sys_root[SEC_UIO_MAX_ATTR_FILE_NAME]; 272e7a45f3cSGagandeep Singh char uio_sys_map_subdir[SEC_UIO_MAX_ATTR_FILE_NAME]; 273e7a45f3cSGagandeep Singh char uio_map_size_str[32]; 274e7a45f3cSGagandeep Singh int ret = 0; 275e7a45f3cSGagandeep Singh 276e7a45f3cSGagandeep Singh /* compose the file name: root/subdir/filename */ 277e7a45f3cSGagandeep Singh memset(uio_sys_root, 0, sizeof(uio_sys_root)); 278e7a45f3cSGagandeep Singh memset(uio_sys_map_subdir, 0, sizeof(uio_sys_map_subdir)); 279e7a45f3cSGagandeep Singh memset(uio_map_size_str, 0, sizeof(uio_map_size_str)); 280e7a45f3cSGagandeep Singh 281e7a45f3cSGagandeep Singh /* Compose string: /sys/class/uio/uioX */ 282a1e8241aSPallantla Poornima snprintf(uio_sys_root, sizeof(uio_sys_root), "%s/%s%d", 283a1e8241aSPallantla Poornima SEC_UIO_DEVICE_SYS_ATTR_PATH, "uio", uio_device_id); 284e7a45f3cSGagandeep Singh /* Compose string: maps/mapY */ 285a1e8241aSPallantla Poornima snprintf(uio_sys_map_subdir, sizeof(uio_sys_map_subdir), "%s%d", 286a1e8241aSPallantla Poornima SEC_UIO_DEVICE_SYS_MAP_ATTR, uio_map_id); 287e7a45f3cSGagandeep Singh 288e7a45f3cSGagandeep Singh /* Read first (and only) line from file 289e7a45f3cSGagandeep Singh * /sys/class/uio/uioX/maps/mapY/size 290e7a45f3cSGagandeep Singh */ 291e7a45f3cSGagandeep Singh ret = file_read_first_line(uio_sys_root, uio_sys_map_subdir, 292e7a45f3cSGagandeep Singh "size", uio_map_size_str); 293e7a45f3cSGagandeep Singh SEC_ASSERT(ret == 0, NULL, "file_read_first_line() failed"); 294e7a45f3cSGagandeep Singh 295e7a45f3cSGagandeep Singh /* Read mapping size, expressed in hexa(base 16) */ 296e7a45f3cSGagandeep Singh uio_map_size = strtol(uio_map_size_str, NULL, 16); 297e7a45f3cSGagandeep Singh 298e7a45f3cSGagandeep Singh /* Map the region in user space */ 299e7a45f3cSGagandeep Singh mapped_address = mmap(0, /*dynamically choose virtual address */ 300e7a45f3cSGagandeep Singh uio_map_size, PROT_READ | PROT_WRITE, 301e7a45f3cSGagandeep Singh MAP_SHARED, uio_device_fd, 0); 302e7a45f3cSGagandeep Singh /* offset = 0 because UIO device has only one mapping 303e7a45f3cSGagandeep Singh * for the entire SEC register memory 304e7a45f3cSGagandeep Singh */ 305e7a45f3cSGagandeep Singh if (mapped_address == MAP_FAILED) { 306e7a45f3cSGagandeep Singh CAAM_JR_ERR( 307e7a45f3cSGagandeep Singh "Failed to map registers! errno = %d job ring fd = %d," 308e7a45f3cSGagandeep Singh "uio device id = %d, uio map id = %d", errno, 309e7a45f3cSGagandeep Singh uio_device_fd, uio_device_id, uio_map_id); 310e7a45f3cSGagandeep Singh return NULL; 311e7a45f3cSGagandeep Singh } 312e7a45f3cSGagandeep Singh 313e7a45f3cSGagandeep Singh /* 314e7a45f3cSGagandeep Singh * Save the map size to use it later on for munmap-ing. 315e7a45f3cSGagandeep Singh */ 316e7a45f3cSGagandeep Singh *map_size = uio_map_size; 317e7a45f3cSGagandeep Singh 318e7a45f3cSGagandeep Singh CAAM_JR_INFO("UIO dev[%d] mapped region [id =%d] size 0x%x at %p", 319e7a45f3cSGagandeep Singh uio_device_id, uio_map_id, uio_map_size, mapped_address); 320e7a45f3cSGagandeep Singh 321e7a45f3cSGagandeep Singh return mapped_address; 322e7a45f3cSGagandeep Singh } 323e7a45f3cSGagandeep Singh 324e7a45f3cSGagandeep Singh void 32561552661SYunjian Wang free_job_ring(int uio_fd) 326e7a45f3cSGagandeep Singh { 327e7a45f3cSGagandeep Singh struct uio_job_ring *job_ring = NULL; 328e7a45f3cSGagandeep Singh int i; 329e7a45f3cSGagandeep Singh 33061552661SYunjian Wang if (uio_fd == -1) 331e7a45f3cSGagandeep Singh return; 332e7a45f3cSGagandeep Singh 333e7a45f3cSGagandeep Singh for (i = 0; i < MAX_SEC_JOB_RINGS; i++) { 334e7a45f3cSGagandeep Singh if (g_uio_job_ring[i].uio_fd == uio_fd) { 335e7a45f3cSGagandeep Singh job_ring = &g_uio_job_ring[i]; 336e7a45f3cSGagandeep Singh break; 337e7a45f3cSGagandeep Singh } 338e7a45f3cSGagandeep Singh } 339e7a45f3cSGagandeep Singh 340e7a45f3cSGagandeep Singh if (job_ring == NULL) { 341*f665790aSDavid Marchand CAAM_JR_ERR("JR not available for fd = %x", uio_fd); 342e7a45f3cSGagandeep Singh return; 343e7a45f3cSGagandeep Singh } 344e7a45f3cSGagandeep Singh 345e7a45f3cSGagandeep Singh /* Open device file */ 346e7a45f3cSGagandeep Singh CAAM_JR_INFO("Closed device file for job ring %d , fd = %d", 347e7a45f3cSGagandeep Singh job_ring->jr_id, job_ring->uio_fd); 348e7a45f3cSGagandeep Singh close(job_ring->uio_fd); 349e7a45f3cSGagandeep Singh g_uio_jr_num--; 35061552661SYunjian Wang job_ring->uio_fd = -1; 351e7a45f3cSGagandeep Singh if (job_ring->register_base_addr == NULL) 352e7a45f3cSGagandeep Singh return; 353e7a45f3cSGagandeep Singh 354e7a45f3cSGagandeep Singh /* Unmap the PCI memory resource of device */ 355e7a45f3cSGagandeep Singh if (munmap(job_ring->register_base_addr, job_ring->map_size)) { 356e7a45f3cSGagandeep Singh CAAM_JR_INFO("cannot munmap(%p, 0x%lx): %s", 357e7a45f3cSGagandeep Singh job_ring->register_base_addr, 358e7a45f3cSGagandeep Singh (unsigned long)job_ring->map_size, strerror(errno)); 359e7a45f3cSGagandeep Singh } else 360c761bffeSGagandeep Singh CAAM_JR_DEBUG("JR UIO memory is unmapped"); 361c761bffeSGagandeep Singh 362e7a45f3cSGagandeep Singh job_ring->register_base_addr = NULL; 363e7a45f3cSGagandeep Singh } 364e7a45f3cSGagandeep Singh 365e7a45f3cSGagandeep Singh struct 366e7a45f3cSGagandeep Singh uio_job_ring *config_job_ring(void) 367e7a45f3cSGagandeep Singh { 368e7a45f3cSGagandeep Singh char uio_device_file_name[32]; 369e7a45f3cSGagandeep Singh struct uio_job_ring *job_ring = NULL; 370e7a45f3cSGagandeep Singh int i; 371e7a45f3cSGagandeep Singh 372e7a45f3cSGagandeep Singh for (i = 0; i < MAX_SEC_JOB_RINGS; i++) { 37361552661SYunjian Wang if (g_uio_job_ring[i].uio_fd == -1) { 374e7a45f3cSGagandeep Singh job_ring = &g_uio_job_ring[i]; 375e7a45f3cSGagandeep Singh g_uio_jr_num++; 376e7a45f3cSGagandeep Singh break; 377e7a45f3cSGagandeep Singh } 378e7a45f3cSGagandeep Singh } 379e7a45f3cSGagandeep Singh 380e7a45f3cSGagandeep Singh if (job_ring == NULL) { 381*f665790aSDavid Marchand CAAM_JR_ERR("No free job ring"); 382e7a45f3cSGagandeep Singh return NULL; 383e7a45f3cSGagandeep Singh } 384e7a45f3cSGagandeep Singh 385e7a45f3cSGagandeep Singh /* Find UIO device created by SEC kernel driver for this job ring. */ 386e7a45f3cSGagandeep Singh memset(uio_device_file_name, 0, sizeof(uio_device_file_name)); 387a1e8241aSPallantla Poornima snprintf(uio_device_file_name, sizeof(uio_device_file_name), "%s%d", 388a1e8241aSPallantla Poornima SEC_UIO_DEVICE_FILE_NAME, job_ring->uio_minor_number); 389e7a45f3cSGagandeep Singh 390e7a45f3cSGagandeep Singh /* Open device file */ 391e7a45f3cSGagandeep Singh job_ring->uio_fd = open(uio_device_file_name, O_RDWR); 39261552661SYunjian Wang SEC_ASSERT(job_ring->uio_fd >= 0, NULL, 393e7a45f3cSGagandeep Singh "Failed to open UIO device file for job ring %d", 394e7a45f3cSGagandeep Singh job_ring->jr_id); 395e7a45f3cSGagandeep Singh 396e7a45f3cSGagandeep Singh CAAM_JR_INFO("Open device(%s) file for job ring=%d , uio_fd = %d", 397e7a45f3cSGagandeep Singh uio_device_file_name, job_ring->jr_id, job_ring->uio_fd); 398e7a45f3cSGagandeep Singh 399e7a45f3cSGagandeep Singh ASSERT(job_ring->register_base_addr == NULL); 400e7a45f3cSGagandeep Singh job_ring->register_base_addr = uio_map_registers( 401e7a45f3cSGagandeep Singh job_ring->uio_fd, job_ring->uio_minor_number, 402e7a45f3cSGagandeep Singh SEC_UIO_MAP_ID, &job_ring->map_size); 403e7a45f3cSGagandeep Singh 404e7a45f3cSGagandeep Singh SEC_ASSERT(job_ring->register_base_addr != NULL, NULL, 405e7a45f3cSGagandeep Singh "Failed to map SEC registers"); 406e7a45f3cSGagandeep Singh return job_ring; 407e7a45f3cSGagandeep Singh } 408e7a45f3cSGagandeep Singh 409e7a45f3cSGagandeep Singh int 410e7a45f3cSGagandeep Singh sec_configure(void) 411e7a45f3cSGagandeep Singh { 412e7a45f3cSGagandeep Singh char uio_name[32]; 413e7a45f3cSGagandeep Singh int config_jr_no = 0, jr_id = -1; 414e7a45f3cSGagandeep Singh int uio_minor_number = -1; 415e7a45f3cSGagandeep Singh int ret; 416e7a45f3cSGagandeep Singh DIR *d = NULL; 417e7a45f3cSGagandeep Singh struct dirent *dir; 418e7a45f3cSGagandeep Singh 419e7a45f3cSGagandeep Singh d = opendir(SEC_UIO_DEVICE_SYS_ATTR_PATH); 420e7a45f3cSGagandeep Singh if (d == NULL) { 4210fcdbde0SHemant Agrawal CAAM_JR_ERR("Error opening directory '%s': %s", 422e7a45f3cSGagandeep Singh SEC_UIO_DEVICE_SYS_ATTR_PATH, strerror(errno)); 423e7a45f3cSGagandeep Singh return -1; 424e7a45f3cSGagandeep Singh } 425e7a45f3cSGagandeep Singh 426e7a45f3cSGagandeep Singh /* Iterate through all subdirs */ 427e7a45f3cSGagandeep Singh while ((dir = readdir(d)) != NULL) { 428e7a45f3cSGagandeep Singh if (!strncmp(dir->d_name, ".", 1) || 429e7a45f3cSGagandeep Singh !strncmp(dir->d_name, "..", 2)) 430e7a45f3cSGagandeep Singh continue; 431e7a45f3cSGagandeep Singh 432e7a45f3cSGagandeep Singh if (file_name_match_extract 433e7a45f3cSGagandeep Singh (dir->d_name, "uio", &uio_minor_number)) { 434e7a45f3cSGagandeep Singh /* 435e7a45f3cSGagandeep Singh * Open file uioX/name and read first line which contains 436e7a45f3cSGagandeep Singh * the name for the device. Based on the name check if this 437e7a45f3cSGagandeep Singh * UIO device is UIO device for job ring with id jr_id. 438e7a45f3cSGagandeep Singh */ 439e7a45f3cSGagandeep Singh memset(uio_name, 0, sizeof(uio_name)); 440e7a45f3cSGagandeep Singh ret = file_read_first_line(SEC_UIO_DEVICE_SYS_ATTR_PATH, 441e7a45f3cSGagandeep Singh dir->d_name, "name", uio_name); 442e7a45f3cSGagandeep Singh CAAM_JR_INFO("sec device uio name: %s", uio_name); 443c761bffeSGagandeep Singh if (ret != 0) { 444*f665790aSDavid Marchand CAAM_JR_ERR("file_read_first_line failed"); 445c761bffeSGagandeep Singh closedir(d); 446c761bffeSGagandeep Singh return -1; 447c761bffeSGagandeep Singh } 448e7a45f3cSGagandeep Singh 449e7a45f3cSGagandeep Singh if (file_name_match_extract(uio_name, 450e7a45f3cSGagandeep Singh SEC_UIO_DEVICE_NAME, 451e7a45f3cSGagandeep Singh &jr_id)) { 452e7a45f3cSGagandeep Singh g_uio_job_ring[config_jr_no].jr_id = jr_id; 453e7a45f3cSGagandeep Singh g_uio_job_ring[config_jr_no].uio_minor_number = 454e7a45f3cSGagandeep Singh uio_minor_number; 455e7a45f3cSGagandeep Singh CAAM_JR_INFO("Detected logical JRID:%d", jr_id); 456e7a45f3cSGagandeep Singh config_jr_no++; 457e7a45f3cSGagandeep Singh 458e7a45f3cSGagandeep Singh /* todo find the actual ring id 459e7a45f3cSGagandeep Singh * OF_FULLNAME=/soc/crypto@1700000/jr@20000 460e7a45f3cSGagandeep Singh */ 461e7a45f3cSGagandeep Singh } 462e7a45f3cSGagandeep Singh } 463e7a45f3cSGagandeep Singh } 464e7a45f3cSGagandeep Singh closedir(d); 465e7a45f3cSGagandeep Singh 466e7a45f3cSGagandeep Singh if (config_jr_no == 0) { 467e7a45f3cSGagandeep Singh CAAM_JR_ERR("! No SEC Job Rings assigned for userspace usage!"); 468e7a45f3cSGagandeep Singh return 0; 469e7a45f3cSGagandeep Singh } 470e7a45f3cSGagandeep Singh CAAM_JR_INFO("Total JR detected =%d", config_jr_no); 471e7a45f3cSGagandeep Singh return config_jr_no; 472e7a45f3cSGagandeep Singh } 473e7a45f3cSGagandeep Singh 474e7a45f3cSGagandeep Singh int 475e7a45f3cSGagandeep Singh sec_cleanup(void) 476e7a45f3cSGagandeep Singh { 477e7a45f3cSGagandeep Singh int i; 478e7a45f3cSGagandeep Singh struct uio_job_ring *job_ring; 479e7a45f3cSGagandeep Singh 480e7a45f3cSGagandeep Singh for (i = 0; i < g_uio_jr_num; i++) { 481e7a45f3cSGagandeep Singh job_ring = &g_uio_job_ring[i]; 482e7a45f3cSGagandeep Singh /* munmap SEC's register memory */ 483e7a45f3cSGagandeep Singh if (job_ring->register_base_addr) { 484e7a45f3cSGagandeep Singh munmap(job_ring->register_base_addr, 485e7a45f3cSGagandeep Singh job_ring->map_size); 486e7a45f3cSGagandeep Singh job_ring->register_base_addr = NULL; 487e7a45f3cSGagandeep Singh } 488e7a45f3cSGagandeep Singh /* I need to close the fd after shutdown UIO commands need to be 489e7a45f3cSGagandeep Singh * sent using the fd 490e7a45f3cSGagandeep Singh */ 49161552661SYunjian Wang if (job_ring->uio_fd != -1) { 492e7a45f3cSGagandeep Singh CAAM_JR_INFO( 493e7a45f3cSGagandeep Singh "Closed device file for job ring %d , fd = %d", 494e7a45f3cSGagandeep Singh job_ring->jr_id, job_ring->uio_fd); 495e7a45f3cSGagandeep Singh close(job_ring->uio_fd); 49661552661SYunjian Wang job_ring->uio_fd = -1; 497e7a45f3cSGagandeep Singh } 498e7a45f3cSGagandeep Singh } 499e7a45f3cSGagandeep Singh return 0; 500e7a45f3cSGagandeep Singh } 50161552661SYunjian Wang 50261552661SYunjian Wang void 50361552661SYunjian Wang sec_uio_job_rings_init(void) 50461552661SYunjian Wang { 50561552661SYunjian Wang int i; 50661552661SYunjian Wang 50761552661SYunjian Wang for (i = 0; i < MAX_SEC_JOB_RINGS; i++) 50861552661SYunjian Wang g_uio_job_ring[i].uio_fd = -1; 50961552661SYunjian Wang } 510