diff options
Diffstat (limited to 'arch/tile/gxio/mpipe.c')
-rw-r--r-- | arch/tile/gxio/mpipe.c | 584 |
1 files changed, 0 insertions, 584 deletions
diff --git a/arch/tile/gxio/mpipe.c b/arch/tile/gxio/mpipe.c deleted file mode 100644 index 34de300ab320..000000000000 --- a/arch/tile/gxio/mpipe.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Copyright 2012 Tilera Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - */ - -/* - * Implementation of mpipe gxio calls. - */ - -#include <linux/errno.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/string.h> - -#include <gxio/iorpc_globals.h> -#include <gxio/iorpc_mpipe.h> -#include <gxio/iorpc_mpipe_info.h> -#include <gxio/kiorpc.h> -#include <gxio/mpipe.h> - -/* HACK: Avoid pointless "shadow" warnings. */ -#define link link_shadow - -int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index) -{ - char file[32]; - - int fd; - int i; - - if (mpipe_index >= GXIO_MPIPE_INSTANCE_MAX) - return -EINVAL; - - snprintf(file, sizeof(file), "mpipe/%d/iorpc", mpipe_index); - fd = hv_dev_open((HV_VirtAddr) file, 0); - - context->fd = fd; - - if (fd < 0) { - if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX) - return fd; - else - return -ENODEV; - } - - /* Map in the MMIO space. */ - context->mmio_cfg_base = (void __force *) - iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET, - HV_MPIPE_CONFIG_MMIO_SIZE); - if (context->mmio_cfg_base == NULL) - goto cfg_failed; - - context->mmio_fast_base = (void __force *) - iorpc_ioremap(fd, HV_MPIPE_FAST_MMIO_OFFSET, - HV_MPIPE_FAST_MMIO_SIZE); - if (context->mmio_fast_base == NULL) - goto fast_failed; - - /* Initialize the stacks. */ - for (i = 0; i < 8; i++) - context->__stacks.stacks[i] = 255; - - context->instance = mpipe_index; - - return 0; - - fast_failed: - iounmap((void __force __iomem *)(context->mmio_cfg_base)); - cfg_failed: - hv_dev_close(context->fd); - context->fd = -1; - return -ENODEV; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_init); - -int gxio_mpipe_destroy(gxio_mpipe_context_t *context) -{ - iounmap((void __force __iomem *)(context->mmio_cfg_base)); - iounmap((void __force __iomem *)(context->mmio_fast_base)); - return hv_dev_close(context->fd); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_destroy); - -static int16_t gxio_mpipe_buffer_sizes[8] = - { 128, 256, 512, 1024, 1664, 4096, 10368, 16384 }; - -gxio_mpipe_buffer_size_enum_t gxio_mpipe_buffer_size_to_buffer_size_enum(size_t - size) -{ - int i; - for (i = 0; i < 7; i++) - if (size <= gxio_mpipe_buffer_sizes[i]) - break; - return i; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_buffer_size_to_buffer_size_enum); - -size_t gxio_mpipe_buffer_size_enum_to_buffer_size(gxio_mpipe_buffer_size_enum_t - buffer_size_enum) -{ - if (buffer_size_enum > 7) - buffer_size_enum = 7; - - return gxio_mpipe_buffer_sizes[buffer_size_enum]; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_buffer_size_enum_to_buffer_size); - -size_t gxio_mpipe_calc_buffer_stack_bytes(unsigned long buffers) -{ - const int BUFFERS_PER_LINE = 12; - - /* Count the number of cachelines. */ - unsigned long lines = - (buffers + BUFFERS_PER_LINE - 1) / BUFFERS_PER_LINE; - - /* Convert to bytes. */ - return lines * CHIP_L2_LINE_SIZE(); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_calc_buffer_stack_bytes); - -int gxio_mpipe_init_buffer_stack(gxio_mpipe_context_t *context, - unsigned int stack, - gxio_mpipe_buffer_size_enum_t - buffer_size_enum, void *mem, size_t mem_size, - unsigned int mem_flags) -{ - int result; - - memset(mem, 0, mem_size); - - result = gxio_mpipe_init_buffer_stack_aux(context, mem, mem_size, - mem_flags, stack, - buffer_size_enum); - if (result < 0) - return result; - - /* Save the stack. */ - context->__stacks.stacks[buffer_size_enum] = stack; - - return 0; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_init_buffer_stack); - -int gxio_mpipe_init_notif_ring(gxio_mpipe_context_t *context, - unsigned int ring, - void *mem, size_t mem_size, - unsigned int mem_flags) -{ - return gxio_mpipe_init_notif_ring_aux(context, mem, mem_size, - mem_flags, ring); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_init_notif_ring); - -int gxio_mpipe_init_notif_group_and_buckets(gxio_mpipe_context_t *context, - unsigned int group, - unsigned int ring, - unsigned int num_rings, - unsigned int bucket, - unsigned int num_buckets, - gxio_mpipe_bucket_mode_t mode) -{ - int i; - int result; - - gxio_mpipe_bucket_info_t bucket_info = { { - .group = group, - .mode = mode, - } - }; - - gxio_mpipe_notif_group_bits_t bits = { {0} }; - - for (i = 0; i < num_rings; i++) - gxio_mpipe_notif_group_add_ring(&bits, ring + i); - - result = gxio_mpipe_init_notif_group(context, group, bits); - if (result != 0) - return result; - - for (i = 0; i < num_buckets; i++) { - bucket_info.notifring = ring + (i % num_rings); - - result = gxio_mpipe_init_bucket(context, bucket + i, - bucket_info); - if (result != 0) - return result; - } - - return 0; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_init_notif_group_and_buckets); - -int gxio_mpipe_init_edma_ring(gxio_mpipe_context_t *context, - unsigned int ring, unsigned int channel, - void *mem, size_t mem_size, - unsigned int mem_flags) -{ - memset(mem, 0, mem_size); - - return gxio_mpipe_init_edma_ring_aux(context, mem, mem_size, mem_flags, - ring, channel); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_init_edma_ring); - -void gxio_mpipe_rules_init(gxio_mpipe_rules_t *rules, - gxio_mpipe_context_t *context) -{ - rules->context = context; - memset(&rules->list, 0, sizeof(rules->list)); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_rules_init); - -int gxio_mpipe_rules_begin(gxio_mpipe_rules_t *rules, - unsigned int bucket, unsigned int num_buckets, - gxio_mpipe_rules_stacks_t *stacks) -{ - int i; - int stack = 255; - - gxio_mpipe_rules_list_t *list = &rules->list; - - /* Current rule. */ - gxio_mpipe_rules_rule_t *rule = - (gxio_mpipe_rules_rule_t *) (list->rules + list->head); - - unsigned int head = list->tail; - - /* - * Align next rule properly. - *Note that "dmacs_and_vlans" will also be aligned. - */ - unsigned int pad = 0; - while (((head + pad) % __alignof__(gxio_mpipe_rules_rule_t)) != 0) - pad++; - - /* - * Verify room. - * ISSUE: Mark rules as broken on error? - */ - if (head + pad + sizeof(*rule) >= sizeof(list->rules)) - return GXIO_MPIPE_ERR_RULES_FULL; - - /* Verify num_buckets is a power of 2. */ - if (__builtin_popcount(num_buckets) != 1) - return GXIO_MPIPE_ERR_RULES_INVALID; - - /* Add padding to previous rule. */ - rule->size += pad; - - /* Start a new rule. */ - list->head = head + pad; - - rule = (gxio_mpipe_rules_rule_t *) (list->rules + list->head); - - /* Default some values. */ - rule->headroom = 2; - rule->tailroom = 0; - rule->capacity = 16384; - - /* Save the bucket info. */ - rule->bucket_mask = num_buckets - 1; - rule->bucket_first = bucket; - - for (i = 8 - 1; i >= 0; i--) { - int maybe = - stacks ? stacks->stacks[i] : rules->context->__stacks. - stacks[i]; - if (maybe != 255) - stack = maybe; - rule->stacks.stacks[i] = stack; - } - - if (stack == 255) - return GXIO_MPIPE_ERR_RULES_INVALID; - - /* NOTE: Only entries at the end of the array can be 255. */ - for (i = 8 - 1; i > 0; i--) { - if (rule->stacks.stacks[i] == 255) { - rule->stacks.stacks[i] = stack; - rule->capacity = - gxio_mpipe_buffer_size_enum_to_buffer_size(i - - 1); - } - } - - rule->size = sizeof(*rule); - list->tail = list->head + rule->size; - - return 0; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_rules_begin); - -int gxio_mpipe_rules_add_channel(gxio_mpipe_rules_t *rules, - unsigned int channel) -{ - gxio_mpipe_rules_list_t *list = &rules->list; - - gxio_mpipe_rules_rule_t *rule = - (gxio_mpipe_rules_rule_t *) (list->rules + list->head); - - /* Verify channel. */ - if (channel >= 32) - return GXIO_MPIPE_ERR_RULES_INVALID; - - /* Verify begun. */ - if (list->tail == 0) - return GXIO_MPIPE_ERR_RULES_EMPTY; - - rule->channel_bits |= (1UL << channel); - - return 0; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_rules_add_channel); - -int gxio_mpipe_rules_set_headroom(gxio_mpipe_rules_t *rules, uint8_t headroom) -{ - gxio_mpipe_rules_list_t *list = &rules->list; - - gxio_mpipe_rules_rule_t *rule = - (gxio_mpipe_rules_rule_t *) (list->rules + list->head); - - /* Verify begun. */ - if (list->tail == 0) - return GXIO_MPIPE_ERR_RULES_EMPTY; - - rule->headroom = headroom; - - return 0; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_rules_set_headroom); - -int gxio_mpipe_rules_commit(gxio_mpipe_rules_t *rules) -{ - gxio_mpipe_rules_list_t *list = &rules->list; - unsigned int size = - offsetof(gxio_mpipe_rules_list_t, rules) + list->tail; - return gxio_mpipe_commit_rules(rules->context, list, size); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_rules_commit); - -int gxio_mpipe_iqueue_init(gxio_mpipe_iqueue_t *iqueue, - gxio_mpipe_context_t *context, - unsigned int ring, - void *mem, size_t mem_size, unsigned int mem_flags) -{ - /* The init call below will verify that "mem_size" is legal. */ - unsigned int num_entries = mem_size / sizeof(gxio_mpipe_idesc_t); - - iqueue->context = context; - iqueue->idescs = (gxio_mpipe_idesc_t *)mem; - iqueue->ring = ring; - iqueue->num_entries = num_entries; - iqueue->mask_num_entries = num_entries - 1; - iqueue->log2_num_entries = __builtin_ctz(num_entries); - iqueue->head = 1; -#ifdef __BIG_ENDIAN__ - iqueue->swapped = 0; -#endif - - /* Initialize the "tail". */ - __gxio_mmio_write(mem, iqueue->head); - - return gxio_mpipe_init_notif_ring(context, ring, mem, mem_size, - mem_flags); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_iqueue_init); - -int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, - gxio_mpipe_context_t *context, - unsigned int ering, - unsigned int channel, - void *mem, unsigned int mem_size, - unsigned int mem_flags) -{ - /* The init call below will verify that "mem_size" is legal. */ - unsigned int num_entries = mem_size / sizeof(gxio_mpipe_edesc_t); - - /* Offset used to read number of completed commands. */ - MPIPE_EDMA_POST_REGION_ADDR_t offset; - - int result = gxio_mpipe_init_edma_ring(context, ering, channel, - mem, mem_size, mem_flags); - if (result < 0) - return result; - - memset(equeue, 0, sizeof(*equeue)); - - offset.word = 0; - offset.region = - MPIPE_MMIO_ADDR__REGION_VAL_EDMA - - MPIPE_MMIO_ADDR__REGION_VAL_IDMA; - offset.ring = ering; - - __gxio_dma_queue_init(&equeue->dma_queue, - context->mmio_fast_base + offset.word, - num_entries); - equeue->edescs = mem; - equeue->mask_num_entries = num_entries - 1; - equeue->log2_num_entries = __builtin_ctz(num_entries); - equeue->context = context; - equeue->ering = ering; - equeue->channel = channel; - - return 0; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_equeue_init); - -int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context, - const struct timespec64 *ts) -{ - cycles_t cycles = get_cycles(); - return gxio_mpipe_set_timestamp_aux(context, (uint64_t)ts->tv_sec, - (uint64_t)ts->tv_nsec, - (uint64_t)cycles); -} -EXPORT_SYMBOL_GPL(gxio_mpipe_set_timestamp); - -int gxio_mpipe_get_timestamp(gxio_mpipe_context_t *context, - struct timespec64 *ts) -{ - int ret; - cycles_t cycles_prev, cycles_now, clock_rate; - cycles_prev = get_cycles(); - ret = gxio_mpipe_get_timestamp_aux(context, (uint64_t *)&ts->tv_sec, - (uint64_t *)&ts->tv_nsec, - (uint64_t *)&cycles_now); - if (ret < 0) { - return ret; - } - - clock_rate = get_clock_rate(); - ts->tv_nsec -= (cycles_now - cycles_prev) * 1000000000LL / clock_rate; - if (ts->tv_nsec < 0) { - ts->tv_nsec += 1000000000LL; - ts->tv_sec -= 1; - } - return ret; -} -EXPORT_SYMBOL_GPL(gxio_mpipe_get_timestamp); - -int gxio_mpipe_adjust_timestamp(gxio_mpipe_context_t *context, int64_t delta) -{ - return gxio_mpipe_adjust_timestamp_aux(context, delta); -} -EXPORT_SYMBOL_GPL(gxio_mpipe_adjust_timestamp); - -/* Get our internal context used for link name access. This context is - * special in that it is not associated with an mPIPE service domain. - */ -static gxio_mpipe_context_t *_gxio_get_link_context(void) -{ - static gxio_mpipe_context_t context; - static gxio_mpipe_context_t *contextp; - static int tried_open = 0; - static DEFINE_MUTEX(mutex); - - mutex_lock(&mutex); - - if (!tried_open) { - int i = 0; - tried_open = 1; - - /* - * "4" here is the maximum possible number of mPIPE shims; it's - * an exaggeration but we shouldn't ever go beyond 2 anyway. - */ - for (i = 0; i < 4; i++) { - char file[80]; - - snprintf(file, sizeof(file), "mpipe/%d/iorpc_info", i); - context.fd = hv_dev_open((HV_VirtAddr) file, 0); - if (context.fd < 0) - continue; - - contextp = &context; - break; - } - } - - mutex_unlock(&mutex); - - return contextp; -} - -int gxio_mpipe_link_instance(const char *link_name) -{ - _gxio_mpipe_link_name_t name; - gxio_mpipe_context_t *context = _gxio_get_link_context(); - - if (!context) - return GXIO_ERR_NO_DEVICE; - - if (strscpy(name.name, link_name, sizeof(name.name)) < 0) - return GXIO_ERR_NO_DEVICE; - - return gxio_mpipe_info_instance_aux(context, name); -} -EXPORT_SYMBOL_GPL(gxio_mpipe_link_instance); - -int gxio_mpipe_link_enumerate_mac(int idx, char *link_name, uint8_t *link_mac) -{ - int rv; - _gxio_mpipe_link_name_t name; - _gxio_mpipe_link_mac_t mac; - - gxio_mpipe_context_t *context = _gxio_get_link_context(); - if (!context) - return GXIO_ERR_NO_DEVICE; - - rv = gxio_mpipe_info_enumerate_aux(context, idx, &name, &mac); - if (rv >= 0) { - if (strscpy(link_name, name.name, sizeof(name.name)) < 0) - return GXIO_ERR_INVAL_MEMORY_SIZE; - memcpy(link_mac, mac.mac, sizeof(mac.mac)); - } - - return rv; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_link_enumerate_mac); - -int gxio_mpipe_link_open(gxio_mpipe_link_t *link, - gxio_mpipe_context_t *context, const char *link_name, - unsigned int flags) -{ - _gxio_mpipe_link_name_t name; - int rv; - - if (strscpy(name.name, link_name, sizeof(name.name)) < 0) - return GXIO_ERR_NO_DEVICE; - - rv = gxio_mpipe_link_open_aux(context, name, flags); - if (rv < 0) - return rv; - - link->context = context; - link->channel = rv >> 8; - link->mac = rv & 0xFF; - - return 0; -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_link_open); - -int gxio_mpipe_link_close(gxio_mpipe_link_t *link) -{ - return gxio_mpipe_link_close_aux(link->context, link->mac); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_link_close); - -int gxio_mpipe_link_set_attr(gxio_mpipe_link_t *link, uint32_t attr, - int64_t val) -{ - return gxio_mpipe_link_set_attr_aux(link->context, link->mac, attr, - val); -} - -EXPORT_SYMBOL_GPL(gxio_mpipe_link_set_attr); |