X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fraw%2Fifpga%2Fbase%2Fopae_hw_api.c;h=11c9887c7f01a75a69c15765c832872f8ba8d19d;hb=97005a6665f64f920695b0a64cb35bf7cfbd4c3d;hp=d0e66d6f932922b386442fdbaf5fbc611caea770;hpb=1911898915a789fc1d64ea824d8703c9a9228765;p=dpdk.git diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c index d0e66d6f93..11c9887c7f 100644 --- a/drivers/raw/ifpga/base/opae_hw_api.c +++ b/drivers/raw/ifpga/base/opae_hw_api.c @@ -2,6 +2,10 @@ * Copyright(c) 2010-2018 Intel Corporation */ +#include +#include +#include +#include #include "opae_hw_api.h" #include "opae_debug.h" #include "ifpga_api.h" @@ -305,6 +309,246 @@ static struct opae_adapter_ops *match_ops(struct opae_adapter *adapter) return NULL; } +static void opae_mutex_init(pthread_mutex_t *mutex) +{ + pthread_mutexattr_t mattr; + + pthread_mutexattr_init(&mattr); + pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); + pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST); + pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT); + pthread_mutex_init(mutex, &mattr); + pthread_mutexattr_destroy(&mattr); +} + +static int opae_shm_open(char *shm_name, u32 size, int *new_shm) +{ + int shm_id; + int ret; + + shm_id = shm_open(shm_name, O_CREAT | O_EXCL | O_RDWR, 0666); + if (shm_id == -1) { + if (errno == EEXIST) { + dev_info(NULL, "shared memory %s already exist\n", + shm_name); + shm_id = shm_open(shm_name, O_RDWR, 0666); + } else { + dev_err(NULL, "failed to create shared memory %s\n", + shm_name); + return -1; + } + } else { + *new_shm = 1; + ret = ftruncate(shm_id, size); + if (ret == -1) { + dev_err(NULL, + "failed to set shared memory size to %u\n", + size); + ret = shm_unlink(shm_name); + if (ret == -1) { + dev_err(NULL, + "failed to unlink shared memory %s\n", + shm_name); + } + return -1; + } + } + + return shm_id; +} + +static pthread_mutex_t *opae_adapter_mutex_open(struct opae_adapter *adapter) +{ + char shm_name[32]; + void *ptr; + int shm_id; + int new_shm = 0; + + if (!adapter->data) + return NULL; + adapter->lock = NULL; + + snprintf(shm_name, sizeof(shm_name), "/mutex.IFPGA:%s", adapter->name); + shm_id = opae_shm_open(shm_name, sizeof(pthread_mutex_t), &new_shm); + if (shm_id == -1) { + dev_err(NULL, "failed to open shared memory %s\n", shm_name); + } else { + dev_info(NULL, "shared memory %s id is %d\n", + shm_name, shm_id); + ptr = mmap(NULL, sizeof(pthread_mutex_t), + PROT_READ | PROT_WRITE, MAP_SHARED, + shm_id, 0); + adapter->lock = (pthread_mutex_t *)ptr; + if (ptr) { + dev_info(NULL, + "shared memory %s address is %p\n", + shm_name, ptr); + if (new_shm) + opae_mutex_init(adapter->lock); + } else { + dev_err(NULL, "failed to map shared memory %s\n", + shm_name); + } + } + + return adapter->lock; +} + +static void opae_adapter_mutex_close(struct opae_adapter *adapter) +{ + char shm_name[32]; + int ret; + + if (!adapter->lock) + return; + + snprintf(shm_name, sizeof(shm_name), "/mutex.IFPGA:%s", adapter->name); + + ret = munmap(adapter->lock, sizeof(pthread_mutex_t)); + if (ret == -1) + dev_err(NULL, "failed to unmap shared memory %s\n", shm_name); + else + adapter->lock = NULL; +} + +/** + * opae_adapter_lock - lock this adapter + * @adapter: adapter to lock. + * @timeout: maximum time to wait for lock done + * -1 wait until the lock is available + * 0 do not wait and return immediately + * t positive time in second to wait + * + * Return: 0 on success, otherwise error code. + */ +int opae_adapter_lock(struct opae_adapter *adapter, int timeout) +{ + struct timespec t; + int ret = -EINVAL; + + if (adapter && adapter->lock) { + if (timeout < 0) { + ret = pthread_mutex_lock(adapter->lock); + } else if (timeout == 0) { + ret = pthread_mutex_trylock(adapter->lock); + } else { + clock_gettime(CLOCK_REALTIME, &t); + t.tv_sec += timeout; + ret = pthread_mutex_timedlock(adapter->lock, &t); + } + } + return ret; +} + +/** + * opae_adapter_unlock - unlock this adapter + * @adapter: adapter to unlock. + * + * Return: 0 on success, otherwise error code. + */ +int opae_adapter_unlock(struct opae_adapter *adapter) +{ + int ret = -EINVAL; + + if (adapter && adapter->lock) + ret = pthread_mutex_unlock(adapter->lock); + + return ret; +} + +static void opae_adapter_shm_init(struct opae_adapter *adapter) +{ + opae_share_data *sd; + + if (!adapter->shm.ptr) + return; + + sd = (opae_share_data *)adapter->shm.ptr; + dev_info(NULL, "initialize shared memory\n"); + opae_mutex_init(&sd->spi_mutex); + opae_mutex_init(&sd->i2c_mutex); + sd->ref_cnt = 0; + sd->dtb_size = SHM_BLK_SIZE; + sd->rsu_ctrl = 0; + sd->rsu_stat = 0; +} + +static void *opae_adapter_shm_alloc(struct opae_adapter *adapter) +{ + char shm_name[32]; + opae_share_data *sd; + u32 size = sizeof(opae_share_data); + int shm_id; + int new_shm = 0; + + if (!adapter->data) + return NULL; + + snprintf(shm_name, sizeof(shm_name), "/IFPGA:%s", adapter->name); + adapter->shm.ptr = NULL; + + opae_adapter_lock(adapter, -1); + shm_id = opae_shm_open(shm_name, size, &new_shm); + if (shm_id == -1) { + dev_err(NULL, "failed to open shared memory %s\n", shm_name); + } else { + dev_info(NULL, "shared memory %s id is %d\n", + shm_name, shm_id); + adapter->shm.id = shm_id; + adapter->shm.size = size; + adapter->shm.ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, shm_id, 0); + if (adapter->shm.ptr) { + dev_info(NULL, + "shared memory %s address is %p\n", + shm_name, adapter->shm.ptr); + if (new_shm) + opae_adapter_shm_init(adapter); + sd = (opae_share_data *)adapter->shm.ptr; + sd->ref_cnt++; + } else { + dev_err(NULL, "failed to map shared memory %s\n", + shm_name); + } + } + opae_adapter_unlock(adapter); + + return adapter->shm.ptr; +} + +static void opae_adapter_shm_free(struct opae_adapter *adapter) +{ + char shm_name[32]; + opae_share_data *sd; + u32 ref_cnt; + int ret; + + if (!adapter->shm.ptr) + return; + + sd = (opae_share_data *)adapter->shm.ptr; + snprintf(shm_name, sizeof(shm_name), "/IFPGA:%s", adapter->name); + + opae_adapter_lock(adapter, -1); + ref_cnt = --sd->ref_cnt; + ret = munmap(adapter->shm.ptr, adapter->shm.size); + if (ret == -1) + dev_err(NULL, "failed to unmap shared memory %s\n", shm_name); + else + adapter->shm.ptr = NULL; + + if (ref_cnt == 0) { + dev_info(NULL, "unlink shared memory %s\n", shm_name); + ret = shm_unlink(shm_name); + if (ret == -1) { + dev_err(NULL, "failed to unlink shared memory %s\n", + shm_name); + } + } + opae_adapter_unlock(adapter); +} + /** * opae_adapter_init - init opae_adapter data structure * @adapter: pointer of opae_adapter data structure @@ -324,6 +568,12 @@ int opae_adapter_init(struct opae_adapter *adapter, adapter->name = name; adapter->ops = match_ops(adapter); + if (!opae_adapter_mutex_open(adapter)) + return -ENOMEM; + + if (!opae_adapter_shm_alloc(adapter)) + return -ENOMEM; + return 0; } @@ -357,8 +607,12 @@ int opae_adapter_enumerate(struct opae_adapter *adapter) */ void opae_adapter_destroy(struct opae_adapter *adapter) { - if (adapter && adapter->ops && adapter->ops->destroy) - adapter->ops->destroy(adapter); + if (adapter) { + if (adapter->ops && adapter->ops->destroy) + adapter->ops->destroy(adapter); + opae_adapter_shm_free(adapter); + opae_adapter_mutex_close(adapter); + } } /** @@ -583,11 +837,12 @@ int opae_manager_get_retimer_status(struct opae_manager *mgr, * Return: the pointer of the opae_sensor_info */ struct opae_sensor_info * -opae_mgr_get_sensor_by_id(unsigned int id) +opae_mgr_get_sensor_by_id(struct opae_manager *mgr, + unsigned int id) { struct opae_sensor_info *sensor; - opae_mgr_for_each_sensor(sensor) + opae_mgr_for_each_sensor(mgr, sensor) if (sensor->id == id) return sensor; @@ -601,11 +856,12 @@ opae_mgr_get_sensor_by_id(unsigned int id) * Return: the pointer of the opae_sensor_info */ struct opae_sensor_info * -opae_mgr_get_sensor_by_name(const char *name) +opae_mgr_get_sensor_by_name(struct opae_manager *mgr, + const char *name) { struct opae_sensor_info *sensor; - opae_mgr_for_each_sensor(sensor) + opae_mgr_for_each_sensor(mgr, sensor) if (!strcmp(sensor->name, name)) return sensor; @@ -630,7 +886,7 @@ opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr, if (!mgr) return -EINVAL; - sensor = opae_mgr_get_sensor_by_name(name); + sensor = opae_mgr_get_sensor_by_name(mgr, name); if (!sensor) return -ENODEV; @@ -658,7 +914,7 @@ opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr, if (!mgr) return -EINVAL; - sensor = opae_mgr_get_sensor_by_id(id); + sensor = opae_mgr_get_sensor_by_id(mgr, id); if (!sensor) return -ENODEV; @@ -690,3 +946,98 @@ opae_mgr_get_sensor_value(struct opae_manager *mgr, return -ENOENT; } + +/** + * opae_manager_get_board_info - get board info + * sensor value + * @info: opae_board_info for the card + * + * Return: 0 on success, otherwise error code + */ +int +opae_mgr_get_board_info(struct opae_manager *mgr, + struct opae_board_info **info) +{ + if (!mgr || !info) + return -EINVAL; + + if (mgr->ops && mgr->ops->get_board_info) + return mgr->ops->get_board_info(mgr, info); + + return -ENOENT; +} + +/** + * opae_mgr_get_uuid - get manager's UUID. + * @mgr: targeted manager + * @uuid: a pointer to UUID + * + * Return: 0 on success, otherwise error code. + */ +int opae_mgr_get_uuid(struct opae_manager *mgr, struct uuid *uuid) +{ + if (!mgr || !uuid) + return -EINVAL; + + if (mgr->ops && mgr->ops->get_uuid) + return mgr->ops->get_uuid(mgr, uuid); + + return -ENOENT; +} + +/** + * opae_mgr_update_flash - update image in flash. + * @mgr: targeted manager + * @image: name of image file + * @status: status of update + * + * Return: 0 on success, otherwise error code. + */ +int opae_mgr_update_flash(struct opae_manager *mgr, const char *image, + uint64_t *status) +{ + if (!mgr) + return -EINVAL; + + if (mgr->ops && mgr->ops->update_flash) + return mgr->ops->update_flash(mgr, image, status); + + return -ENOENT; +} + +/** + * opae_stop_flash_update - stop flash update. + * @mgr: targeted manager + * @force: make sure the update process is stopped + * + * Return: 0 on success, otherwise error code. + */ +int opae_mgr_stop_flash_update(struct opae_manager *mgr, int force) +{ + if (!mgr) + return -EINVAL; + + if (mgr->ops && mgr->ops->stop_flash_update) + return mgr->ops->stop_flash_update(mgr, force); + + return -ENOENT; +} + +/** + * opae_mgr_reload - reload FPGA. + * @mgr: targeted manager + * @type: FPGA type + * @page: reload from which page + * + * Return: 0 on success, otherwise error code. + */ +int opae_mgr_reload(struct opae_manager *mgr, int type, int page) +{ + if (!mgr) + return -EINVAL; + + if (mgr->ops && mgr->ops->reload) + return mgr->ops->reload(mgr, type, page); + + return -ENOENT; +}