cregit-Linux how code gets into the kernel

Release 4.14 arch/tile/gxio/mpipe.c

Directory: arch/tile/gxio
/*
 * 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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf223100.00%2100.00%
Total223100.00%2100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf47100.00%1100.00%
Total47100.00%1100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf37100.00%1100.00%
Total37100.00%1100.00%

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]; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf24100.00%1100.00%
Total24100.00%1100.00%

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(); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf3697.30%150.00%
Andrea Gelmini12.70%150.00%
Total37100.00%2100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf80100.00%1100.00%
Total80100.00%1100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf38100.00%1100.00%
Total38100.00%1100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf159100.00%1100.00%
Total159100.00%1100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf53100.00%1100.00%
Total53100.00%1100.00%

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)); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf36100.00%1100.00%
Total36100.00%1100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf344100.00%1100.00%
Total344100.00%1100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf75100.00%1100.00%
Total75100.00%1100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf60100.00%1100.00%
Total60100.00%1100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf45100.00%1100.00%
Total45100.00%1100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf126100.00%1100.00%
Total126100.00%1100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf171100.00%2100.00%
Total171100.00%2100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf4597.83%150.00%
Richard Cochran12.17%150.00%
Total46100.00%2100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf11599.14%150.00%
Richard Cochran10.86%150.00%
Total116100.00%2100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf20100.00%1100.00%
Total20100.00%1100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf126100.00%1100.00%
Total126100.00%1100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf59100.00%3100.00%
Total59100.00%3100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf105100.00%3100.00%
Total105100.00%3100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf96100.00%3100.00%
Total96100.00%3100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf21100.00%1100.00%
Total21100.00%1100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf31100.00%1100.00%
Total31100.00%1100.00%

EXPORT_SYMBOL_GPL(gxio_mpipe_link_set_attr);

Overall Contributors

PersonTokensPropCommitsCommitProp
Chris Metcalf233299.02%562.50%
Chen Gang S200.85%112.50%
Richard Cochran20.08%112.50%
Andrea Gelmini10.04%112.50%
Total2355100.00%8100.00%
Directory: arch/tile/gxio
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.