dect
/
linux-2.6
Archived
13
0
Fork 0

arch/tile: provide kernel support for the tilegx mPIPE shim

The TILE-Gx chip includes a packet-processing network engine called
mPIPE ("Multicore Programmable Intelligent Packet Engine").  This
change adds support for using the mPIPE engine from within the
kernel.  The engine has more functionality than is exposed here,
but to keep the kernel code and binary simpler, this is a subset
of the full API designed to enable standard Linux networking only.

Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
This commit is contained in:
Chris Metcalf 2012-04-06 16:38:03 -04:00
parent 6369798037
commit 4875f69fec
14 changed files with 4658 additions and 0 deletions

View File

@ -9,3 +9,9 @@ config TILE_GXIO
config TILE_GXIO_DMA
bool
select TILE_GXIO
# Support direct access to the TILE-Gx mPIPE hardware from kernel space.
config TILE_GXIO_MPIPE
bool
select TILE_GXIO
select TILE_GXIO_DMA

View File

@ -4,3 +4,4 @@
obj-$(CONFIG_TILE_GXIO) += iorpc_globals.o kiorpc.o
obj-$(CONFIG_TILE_GXIO_DMA) += dma_queue.o
obj-$(CONFIG_TILE_GXIO_MPIPE) += mpipe.o iorpc_mpipe.o iorpc_mpipe_info.o

View File

@ -0,0 +1,529 @@
/*
* 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.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_mpipe.h"
struct alloc_buffer_stacks_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_buffer_stacks(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_buffer_stacks_param temp;
struct alloc_buffer_stacks_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_ALLOC_BUFFER_STACKS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_buffer_stacks);
struct init_buffer_stack_aux_param {
union iorpc_mem_buffer buffer;
unsigned int stack;
unsigned int buffer_size_enum;
};
int gxio_mpipe_init_buffer_stack_aux(gxio_mpipe_context_t * context,
void *mem_va, size_t mem_size,
unsigned int mem_flags, unsigned int stack,
unsigned int buffer_size_enum)
{
int __result;
unsigned long long __cpa;
pte_t __pte;
struct init_buffer_stack_aux_param temp;
struct init_buffer_stack_aux_param *params = &temp;
__result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
if (__result != 0)
return __result;
params->buffer.kernel.cpa = __cpa;
params->buffer.kernel.size = mem_size;
params->buffer.kernel.pte = __pte;
params->buffer.kernel.flags = mem_flags;
params->stack = stack;
params->buffer_size_enum = buffer_size_enum;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_INIT_BUFFER_STACK_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_init_buffer_stack_aux);
struct alloc_notif_rings_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_notif_rings(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_notif_rings_param temp;
struct alloc_notif_rings_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_NOTIF_RINGS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_notif_rings);
struct init_notif_ring_aux_param {
union iorpc_mem_buffer buffer;
unsigned int ring;
};
int gxio_mpipe_init_notif_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
size_t mem_size, unsigned int mem_flags,
unsigned int ring)
{
int __result;
unsigned long long __cpa;
pte_t __pte;
struct init_notif_ring_aux_param temp;
struct init_notif_ring_aux_param *params = &temp;
__result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
if (__result != 0)
return __result;
params->buffer.kernel.cpa = __cpa;
params->buffer.kernel.size = mem_size;
params->buffer.kernel.pte = __pte;
params->buffer.kernel.flags = mem_flags;
params->ring = ring;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_INIT_NOTIF_RING_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_init_notif_ring_aux);
struct request_notif_ring_interrupt_param {
union iorpc_interrupt interrupt;
unsigned int ring;
};
int gxio_mpipe_request_notif_ring_interrupt(gxio_mpipe_context_t * context,
int inter_x, int inter_y,
int inter_ipi, int inter_event,
unsigned int ring)
{
struct request_notif_ring_interrupt_param temp;
struct request_notif_ring_interrupt_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
params->ring = ring;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_REQUEST_NOTIF_RING_INTERRUPT);
}
EXPORT_SYMBOL(gxio_mpipe_request_notif_ring_interrupt);
struct enable_notif_ring_interrupt_param {
unsigned int ring;
};
int gxio_mpipe_enable_notif_ring_interrupt(gxio_mpipe_context_t * context,
unsigned int ring)
{
struct enable_notif_ring_interrupt_param temp;
struct enable_notif_ring_interrupt_param *params = &temp;
params->ring = ring;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_ENABLE_NOTIF_RING_INTERRUPT);
}
EXPORT_SYMBOL(gxio_mpipe_enable_notif_ring_interrupt);
struct alloc_notif_groups_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_notif_groups(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_notif_groups_param temp;
struct alloc_notif_groups_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_NOTIF_GROUPS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_notif_groups);
struct init_notif_group_param {
unsigned int group;
gxio_mpipe_notif_group_bits_t bits;
};
int gxio_mpipe_init_notif_group(gxio_mpipe_context_t * context,
unsigned int group,
gxio_mpipe_notif_group_bits_t bits)
{
struct init_notif_group_param temp;
struct init_notif_group_param *params = &temp;
params->group = group;
params->bits = bits;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_INIT_NOTIF_GROUP);
}
EXPORT_SYMBOL(gxio_mpipe_init_notif_group);
struct alloc_buckets_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_buckets(gxio_mpipe_context_t * context, unsigned int count,
unsigned int first, unsigned int flags)
{
struct alloc_buckets_param temp;
struct alloc_buckets_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_BUCKETS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_buckets);
struct init_bucket_param {
unsigned int bucket;
MPIPE_LBL_INIT_DAT_BSTS_TBL_t bucket_info;
};
int gxio_mpipe_init_bucket(gxio_mpipe_context_t * context, unsigned int bucket,
MPIPE_LBL_INIT_DAT_BSTS_TBL_t bucket_info)
{
struct init_bucket_param temp;
struct init_bucket_param *params = &temp;
params->bucket = bucket;
params->bucket_info = bucket_info;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_INIT_BUCKET);
}
EXPORT_SYMBOL(gxio_mpipe_init_bucket);
struct alloc_edma_rings_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_edma_rings(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_edma_rings_param temp;
struct alloc_edma_rings_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_EDMA_RINGS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_edma_rings);
struct init_edma_ring_aux_param {
union iorpc_mem_buffer buffer;
unsigned int ring;
unsigned int channel;
};
int gxio_mpipe_init_edma_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
size_t mem_size, unsigned int mem_flags,
unsigned int ring, unsigned int channel)
{
int __result;
unsigned long long __cpa;
pte_t __pte;
struct init_edma_ring_aux_param temp;
struct init_edma_ring_aux_param *params = &temp;
__result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
if (__result != 0)
return __result;
params->buffer.kernel.cpa = __cpa;
params->buffer.kernel.size = mem_size;
params->buffer.kernel.pte = __pte;
params->buffer.kernel.flags = mem_flags;
params->ring = ring;
params->channel = channel;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_INIT_EDMA_RING_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_init_edma_ring_aux);
int gxio_mpipe_commit_rules(gxio_mpipe_context_t * context, const void *blob,
size_t blob_size)
{
const void *params = blob;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params, blob_size,
GXIO_MPIPE_OP_COMMIT_RULES);
}
EXPORT_SYMBOL(gxio_mpipe_commit_rules);
struct register_client_memory_param {
unsigned int iotlb;
HV_PTE pte;
unsigned int flags;
};
int gxio_mpipe_register_client_memory(gxio_mpipe_context_t * context,
unsigned int iotlb, HV_PTE pte,
unsigned int flags)
{
struct register_client_memory_param temp;
struct register_client_memory_param *params = &temp;
params->iotlb = iotlb;
params->pte = pte;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY);
}
EXPORT_SYMBOL(gxio_mpipe_register_client_memory);
struct link_open_aux_param {
_gxio_mpipe_link_name_t name;
unsigned int flags;
};
int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context,
_gxio_mpipe_link_name_t name, unsigned int flags)
{
struct link_open_aux_param temp;
struct link_open_aux_param *params = &temp;
params->name = name;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_LINK_OPEN_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_link_open_aux);
struct link_close_aux_param {
int mac;
};
int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac)
{
struct link_close_aux_param temp;
struct link_close_aux_param *params = &temp;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_LINK_CLOSE_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_link_close_aux);
struct get_timestamp_aux_param {
uint64_t sec;
uint64_t nsec;
uint64_t cycles;
};
int gxio_mpipe_get_timestamp_aux(gxio_mpipe_context_t * context, uint64_t * sec,
uint64_t * nsec, uint64_t * cycles)
{
int __result;
struct get_timestamp_aux_param temp;
struct get_timestamp_aux_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_MPIPE_OP_GET_TIMESTAMP_AUX);
*sec = params->sec;
*nsec = params->nsec;
*cycles = params->cycles;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_get_timestamp_aux);
struct set_timestamp_aux_param {
uint64_t sec;
uint64_t nsec;
uint64_t cycles;
};
int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,
uint64_t nsec, uint64_t cycles)
{
struct set_timestamp_aux_param temp;
struct set_timestamp_aux_param *params = &temp;
params->sec = sec;
params->nsec = nsec;
params->cycles = cycles;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_SET_TIMESTAMP_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_set_timestamp_aux);
struct adjust_timestamp_aux_param {
int64_t nsec;
};
int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,
int64_t nsec)
{
struct adjust_timestamp_aux_param temp;
struct adjust_timestamp_aux_param *params = &temp;
params->nsec = nsec;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_adjust_timestamp_aux);
struct arm_pollfd_param {
union iorpc_pollfd pollfd;
};
int gxio_mpipe_arm_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie)
{
struct arm_pollfd_param temp;
struct arm_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ARM_POLLFD);
}
EXPORT_SYMBOL(gxio_mpipe_arm_pollfd);
struct close_pollfd_param {
union iorpc_pollfd pollfd;
};
int gxio_mpipe_close_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie)
{
struct close_pollfd_param temp;
struct close_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_CLOSE_POLLFD);
}
EXPORT_SYMBOL(gxio_mpipe_close_pollfd);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_mpipe_get_mmio_base(gxio_mpipe_context_t * context, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_MPIPE_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_mpipe_check_mmio_offset(gxio_mpipe_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_mpipe_check_mmio_offset);

View File

@ -0,0 +1,85 @@
/*
* 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.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_mpipe_info.h"
struct enumerate_aux_param {
_gxio_mpipe_link_name_t name;
_gxio_mpipe_link_mac_t mac;
};
int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
unsigned int idx,
_gxio_mpipe_link_name_t * name,
_gxio_mpipe_link_mac_t * mac)
{
int __result;
struct enumerate_aux_param temp;
struct enumerate_aux_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
(((uint64_t) idx << 32) |
GXIO_MPIPE_INFO_OP_ENUMERATE_AUX));
*name = params->name;
*mac = params->mac;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_info_enumerate_aux);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_MPIPE_INFO_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_info_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_mpipe_info_check_mmio_offset);

545
arch/tile/gxio/mpipe.c Normal file
View File

@ -0,0 +1,545 @@
/*
* 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 <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;
snprintf(file, sizeof(file), "mpipe/%d/iorpc", mpipe_index);
fd = hv_dev_open((HV_VirtAddr) file, 0);
if (fd < 0) {
if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
return fd;
else
return -ENODEV;
}
context->fd = fd;
/* 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;
return 0;
fast_failed:
iounmap((void __force __iomem *)(context->mmio_cfg_base));
cfg_failed:
hv_dev_close(context->fd);
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 cachlines. */
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 edma_ring_id,
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, edma_ring_id, 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 = edma_ring_id;
__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);
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_equeue_init);
int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,
const struct timespec *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);
}
int gxio_mpipe_get_timestamp(gxio_mpipe_context_t *context,
struct timespec *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;
}
int gxio_mpipe_adjust_timestamp(gxio_mpipe_context_t *context, int64_t delta)
{
return gxio_mpipe_adjust_timestamp_aux(context, delta);
}
/* 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_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) {
strncpy(link_name, name.name, sizeof(name.name));
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;
strncpy(name.name, link_name, sizeof(name.name));
name.name[GXIO_MPIPE_LINK_NAME_LEN - 1] = '\0';
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);

View File

@ -0,0 +1,359 @@
/*
* 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.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_H__
#define __ARCH_MPIPE_H__
#include <arch/abi.h>
#include <arch/mpipe_def.h>
#ifndef __ASSEMBLER__
/*
* MMIO Ingress DMA Release Region Address.
* This is a description of the physical addresses used to manipulate ingress
* credit counters. Accesses to this address space should use an address of
* this form and a value like that specified in IDMA_RELEASE_REGION_VAL.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* NotifRing to be released */
uint_reg_t ring : 8;
/* Bucket to be released */
uint_reg_t bucket : 13;
/* Enable NotifRing release */
uint_reg_t ring_enable : 1;
/* Enable Bucket release */
uint_reg_t bucket_enable : 1;
/*
* This field of the address selects the region (address space) to be
* accessed. For the iDMA release region, this field must be 4.
*/
uint_reg_t region : 3;
/* Reserved. */
uint_reg_t __reserved_1 : 6;
/* This field of the address indexes the 32 entry service domain table. */
uint_reg_t svc_dom : 5;
/* Reserved. */
uint_reg_t __reserved_2 : 24;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_2 : 24;
uint_reg_t svc_dom : 5;
uint_reg_t __reserved_1 : 6;
uint_reg_t region : 3;
uint_reg_t bucket_enable : 1;
uint_reg_t ring_enable : 1;
uint_reg_t bucket : 13;
uint_reg_t ring : 8;
uint_reg_t __reserved_0 : 3;
#endif
};
uint_reg_t word;
} MPIPE_IDMA_RELEASE_REGION_ADDR_t;
/*
* MMIO Ingress DMA Release Region Value - Release NotifRing and/or Bucket.
* Provides release of the associated NotifRing. The address of the MMIO
* operation is described in IDMA_RELEASE_REGION_ADDR.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Number of packets being released. The load balancer's count of
* inflight packets will be decremented by this amount for the associated
* Bucket and/or NotifRing
*/
uint_reg_t count : 16;
/* Reserved. */
uint_reg_t __reserved : 48;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 48;
uint_reg_t count : 16;
#endif
};
uint_reg_t word;
} MPIPE_IDMA_RELEASE_REGION_VAL_t;
/*
* MMIO Buffer Stack Manager Region Address.
* This MMIO region is used for posting or fetching buffers to/from the
* buffer stack manager. On an MMIO load, this pops a buffer descriptor from
* the top of stack if one is available. On an MMIO store, this pushes a
* buffer to the stack. The value read or written is described in
* BSM_REGION_VAL.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* BufferStack being accessed. */
uint_reg_t stack : 5;
/* Reserved. */
uint_reg_t __reserved_1 : 18;
/*
* This field of the address selects the region (address space) to be
* accessed. For the buffer stack manager region, this field must be 6.
*/
uint_reg_t region : 3;
/* Reserved. */
uint_reg_t __reserved_2 : 6;
/* This field of the address indexes the 32 entry service domain table. */
uint_reg_t svc_dom : 5;
/* Reserved. */
uint_reg_t __reserved_3 : 24;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_3 : 24;
uint_reg_t svc_dom : 5;
uint_reg_t __reserved_2 : 6;
uint_reg_t region : 3;
uint_reg_t __reserved_1 : 18;
uint_reg_t stack : 5;
uint_reg_t __reserved_0 : 3;
#endif
};
uint_reg_t word;
} MPIPE_BSM_REGION_ADDR_t;
/*
* MMIO Buffer Stack Manager Region Value.
* This MMIO region is used for posting or fetching buffers to/from the
* buffer stack manager. On an MMIO load, this pops a buffer descriptor from
* the top of stack if one is available. On an MMIO store, this pushes a
* buffer to the stack. The address of the MMIO operation is described in
* BSM_REGION_ADDR.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 7;
/*
* Base virtual address of the buffer. Must be sign extended by consumer.
*/
int_reg_t va : 35;
/* Reserved. */
uint_reg_t __reserved_1 : 6;
/*
* Index of the buffer stack to which this buffer belongs. Ignored on
* writes since the offset bits specify the stack being accessed.
*/
uint_reg_t stack_idx : 5;
/* Reserved. */
uint_reg_t __reserved_2 : 5;
/*
* Reads as one to indicate that this is a hardware managed buffer.
* Ignored on writes since all buffers on a given stack are the same size.
*/
uint_reg_t hwb : 1;
/*
* Encoded size of buffer (ignored on writes):
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t size : 3;
/*
* Valid indication for the buffer. Ignored on writes.
* 0 : Valid buffer descriptor popped from stack.
* 3 : Could not pop a buffer from the stack. Either the stack is empty,
* or the hardware's prefetch buffer is empty for this stack.
*/
uint_reg_t c : 2;
#else /* __BIG_ENDIAN__ */
uint_reg_t c : 2;
uint_reg_t size : 3;
uint_reg_t hwb : 1;
uint_reg_t __reserved_2 : 5;
uint_reg_t stack_idx : 5;
uint_reg_t __reserved_1 : 6;
int_reg_t va : 35;
uint_reg_t __reserved_0 : 7;
#endif
};
uint_reg_t word;
} MPIPE_BSM_REGION_VAL_t;
/*
* MMIO Egress DMA Post Region Address.
* Used to post descriptor locations to the eDMA descriptor engine. The
* value to be written is described in EDMA_POST_REGION_VAL
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* eDMA ring being accessed */
uint_reg_t ring : 5;
/* Reserved. */
uint_reg_t __reserved_1 : 18;
/*
* This field of the address selects the region (address space) to be
* accessed. For the egress DMA post region, this field must be 5.
*/
uint_reg_t region : 3;
/* Reserved. */
uint_reg_t __reserved_2 : 6;
/* This field of the address indexes the 32 entry service domain table. */
uint_reg_t svc_dom : 5;
/* Reserved. */
uint_reg_t __reserved_3 : 24;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_3 : 24;
uint_reg_t svc_dom : 5;
uint_reg_t __reserved_2 : 6;
uint_reg_t region : 3;
uint_reg_t __reserved_1 : 18;
uint_reg_t ring : 5;
uint_reg_t __reserved_0 : 3;
#endif
};
uint_reg_t word;
} MPIPE_EDMA_POST_REGION_ADDR_t;
/*
* MMIO Egress DMA Post Region Value.
* Used to post descriptor locations to the eDMA descriptor engine. The
* address is described in EDMA_POST_REGION_ADDR.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* For writes, this specifies the current ring tail pointer prior to any
* post. For example, to post 1 or more descriptors starting at location
* 23, this would contain 23 (not 24). On writes, this index must be
* masked based on the ring size. The new tail pointer after this post
* is COUNT+RING_IDX (masked by the ring size).
*
* For reads, this provides the hardware descriptor fetcher's head
* pointer. The descriptors prior to the head pointer, however, may not
* yet have been processed so this indicator is only used to determine
* how full the ring is and if software may post more descriptors.
*/
uint_reg_t ring_idx : 16;
/*
* For writes, this specifies number of contiguous descriptors that are
* being posted. Software may post up to RingSize descriptors with a
* single MMIO store. A zero in this field on a write will "wake up" an
* eDMA ring and cause it fetch descriptors regardless of the hardware's
* current view of the state of the tail pointer.
*
* For reads, this field provides a rolling count of the number of
* descriptors that have been completely processed. This may be used by
* software to determine when buffers associated with a descriptor may be
* returned or reused. When the ring's flush bit is cleared by software
* (after having been set by HW or SW), the COUNT will be cleared.
*/
uint_reg_t count : 16;
/*
* For writes, this specifies the generation number of the tail being
* posted. Note that if tail+cnt wraps to the beginning of the ring, the
* eDMA hardware assumes that the descriptors posted at the beginning of
* the ring are also valid so it is okay to post around the wrap point.
*
* For reads, this is the current generation number. Valid descriptors
* will have the inverse of this generation number.
*/
uint_reg_t gen : 1;
/* Reserved. */
uint_reg_t __reserved : 31;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 31;
uint_reg_t gen : 1;
uint_reg_t count : 16;
uint_reg_t ring_idx : 16;
#endif
};
uint_reg_t word;
} MPIPE_EDMA_POST_REGION_VAL_t;
/*
* Load Balancer Bucket Status Data.
* Read/Write data for load balancer Bucket-Status Table. 4160 entries
* indexed by LBL_INIT_CTL.IDX when LBL_INIT_CTL.STRUCT_SEL is BSTS_TBL
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* NotifRing currently assigned to this bucket. */
uint_reg_t notifring : 8;
/* Current reference count. */
uint_reg_t count : 16;
/* Group associated with this bucket. */
uint_reg_t group : 5;
/* Mode select for this bucket. */
uint_reg_t mode : 3;
/* Reserved. */
uint_reg_t __reserved : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 32;
uint_reg_t mode : 3;
uint_reg_t group : 5;
uint_reg_t count : 16;
uint_reg_t notifring : 8;
#endif
};
uint_reg_t word;
} MPIPE_LBL_INIT_DAT_BSTS_TBL_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_MPIPE_H__) */

View File

@ -0,0 +1,42 @@
/*
* 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.
*/
#ifndef __ARCH_MPIPE_CONSTANTS_H__
#define __ARCH_MPIPE_CONSTANTS_H__
#define MPIPE_NUM_CLASSIFIERS 10
#define MPIPE_CLS_MHZ 1200
#define MPIPE_NUM_EDMA_RINGS 32
#define MPIPE_NUM_SGMII_MACS 16
#define MPIPE_NUM_XAUI_MACS 4
#define MPIPE_NUM_LOOPBACK_CHANNELS 4
#define MPIPE_NUM_NON_LB_CHANNELS 28
#define MPIPE_NUM_IPKT_BLOCKS 1536
#define MPIPE_NUM_BUCKETS 4160
#define MPIPE_NUM_NOTIF_RINGS 256
#define MPIPE_NUM_NOTIF_GROUPS 32
#define MPIPE_NUM_TLBS_PER_ASID 16
#define MPIPE_TLB_IDX_WIDTH 4
#define MPIPE_MMIO_NUM_SVC_DOM 32
#endif /* __ARCH_MPIPE_CONSTANTS_H__ */

View File

@ -0,0 +1,39 @@
/*
* 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.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_DEF_H__
#define __ARCH_MPIPE_DEF_H__
#define MPIPE_MMIO_ADDR__REGION_SHIFT 26
#define MPIPE_MMIO_ADDR__REGION_VAL_CFG 0x0
#define MPIPE_MMIO_ADDR__REGION_VAL_IDMA 0x4
#define MPIPE_MMIO_ADDR__REGION_VAL_EDMA 0x5
#define MPIPE_MMIO_ADDR__REGION_VAL_BSM 0x6
#define MPIPE_BSM_REGION_VAL__VA_SHIFT 7
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_128 0x0
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_256 0x1
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_512 0x2
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_1024 0x3
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_1664 0x4
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_4096 0x5
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_10368 0x6
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_16384 0x7
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_DFA 0x0
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_FIXED 0x1
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_ALWAYS_PICK 0x2
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_STICKY 0x3
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_STICKY_RAND 0x7
#define MPIPE_LBL_NR_STATE__FIRST_WORD 0x2138
#endif /* !defined(__ARCH_MPIPE_DEF_H__) */

View File

@ -0,0 +1,509 @@
/*
* 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.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_SHM_H__
#define __ARCH_MPIPE_SHM_H__
#include <arch/abi.h>
#include <arch/mpipe_shm_def.h>
#ifndef __ASSEMBLER__
/**
* MPIPE eDMA Descriptor.
* The eDMA descriptor is written by software and consumed by hardware. It
* is used to specify the location of egress packet data to be sent out of
* the chip via one of the packet interfaces.
*/
__extension__
typedef union
{
struct
{
/* Word 0 */
#ifndef __BIG_ENDIAN__
/**
* Generation number. Used to indicate a valid descriptor in ring. When
* a new descriptor is written into the ring, software must toggle this
* bit. The net effect is that the GEN bit being written into new
* descriptors toggles each time the ring tail pointer wraps.
*/
uint_reg_t gen : 1;
/** Reserved. Must be zero. */
uint_reg_t r0 : 7;
/** Checksum generation enabled for this transfer. */
uint_reg_t csum : 1;
/**
* Nothing to be sent. Used, for example, when software has dropped a
* packet but still wishes to return all of the associated buffers.
*/
uint_reg_t ns : 1;
/**
* Notification interrupt will be delivered when packet has been egressed.
*/
uint_reg_t notif : 1;
/**
* Boundary indicator. When 1, this transfer includes the EOP for this
* command. Must be clear on all but the last descriptor for an egress
* packet.
*/
uint_reg_t bound : 1;
/** Reserved. Must be zero. */
uint_reg_t r1 : 4;
/**
* Number of bytes to be sent for this descriptor. When zero, no data
* will be moved and the buffer descriptor will be ignored. If the
* buffer descriptor indicates that it is chained, the low 7 bits of the
* VA indicate the offset within the first buffer (e.g. 127 bytes is the
* maximum offset into the first buffer). If the size exceeds a single
* buffer, subsequent buffer descriptors will be fetched prior to
* processing the next eDMA descriptor in the ring.
*/
uint_reg_t xfer_size : 14;
/** Reserved. Must be zero. */
uint_reg_t r2 : 2;
/**
* Destination of checksum relative to CSUM_START relative to the first
* byte moved by this descriptor. Must be zero if CSUM=0 in this
* descriptor. Must be less than XFER_SIZE (e.g. the first byte of the
* CSUM_DEST must be within the span of this descriptor).
*/
uint_reg_t csum_dest : 8;
/**
* Start byte of checksum relative to the first byte moved by this
* descriptor. If this is not the first descriptor for the egress
* packet, CSUM_START is still relative to the first byte in this
* descriptor. Must be zero if CSUM=0 in this descriptor.
*/
uint_reg_t csum_start : 8;
/**
* Initial value for 16-bit 1's compliment checksum if enabled via CSUM.
* Specified in network order. That is, bits[7:0] will be added to the
* byte pointed to by CSUM_START and bits[15:8] will be added to the byte
* pointed to by CSUM_START+1 (with appropriate 1's compliment carries).
* Must be zero if CSUM=0 in this descriptor.
*/
uint_reg_t csum_seed : 16;
#else /* __BIG_ENDIAN__ */
uint_reg_t csum_seed : 16;
uint_reg_t csum_start : 8;
uint_reg_t csum_dest : 8;
uint_reg_t r2 : 2;
uint_reg_t xfer_size : 14;
uint_reg_t r1 : 4;
uint_reg_t bound : 1;
uint_reg_t notif : 1;
uint_reg_t ns : 1;
uint_reg_t csum : 1;
uint_reg_t r0 : 7;
uint_reg_t gen : 1;
#endif
/* Word 1 */
#ifndef __BIG_ENDIAN__
/** Virtual address. Must be sign extended by consumer. */
int_reg_t va : 42;
/** Reserved. */
uint_reg_t __reserved_0 : 6;
/** Index of the buffer stack to which this buffer belongs. */
uint_reg_t stack_idx : 5;
/** Reserved. */
uint_reg_t __reserved_1 : 3;
/**
* Instance ID. For devices that support more than one mPIPE instance,
* this field indicates the buffer owner. If the INST field does not
* match the mPIPE's instance number when a packet is egressed, buffers
* with HWB set will be returned to the other mPIPE instance.
*/
uint_reg_t inst : 1;
/** Reserved. */
uint_reg_t __reserved_2 : 1;
/**
* Always set to one by hardware in iDMA packet descriptors. For eDMA,
* indicates whether the buffer will be released to the buffer stack
* manager. When 0, software is responsible for releasing the buffer.
*/
uint_reg_t hwb : 1;
/**
* Encoded size of buffer. Set by the ingress hardware for iDMA packet
* descriptors. For eDMA descriptors, indicates the buffer size if .c
* indicates a chained packet. If an eDMA descriptor is not chained and
* the .hwb bit is not set, this field is ignored and the size is
* specified by the .xfer_size field.
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t size : 3;
/**
* Chaining configuration for the buffer. Indicates that an ingress
* packet or egress command is chained across multiple buffers, with each
* buffer's size indicated by the .size field.
*/
uint_reg_t c : 2;
#else /* __BIG_ENDIAN__ */
uint_reg_t c : 2;
uint_reg_t size : 3;
uint_reg_t hwb : 1;
uint_reg_t __reserved_2 : 1;
uint_reg_t inst : 1;
uint_reg_t __reserved_1 : 3;
uint_reg_t stack_idx : 5;
uint_reg_t __reserved_0 : 6;
int_reg_t va : 42;
#endif
};
/** Word access */
uint_reg_t words[2];
} MPIPE_EDMA_DESC_t;
/**
* MPIPE Packet Descriptor.
* The packet descriptor is filled by the mPIPE's classification,
* load-balancing, and buffer management services. Some fields are consumed
* by mPIPE hardware, and others are consumed by Tile software.
*/
__extension__
typedef union
{
struct
{
/* Word 0 */
#ifndef __BIG_ENDIAN__
/**
* Notification ring into which this packet descriptor is written.
* Typically written by load balancer, but can be overridden by
* classification program if NR is asserted.
*/
uint_reg_t notif_ring : 8;
/** Source channel for this packet. Written by mPIPE DMA hardware. */
uint_reg_t channel : 5;
/** Reserved. */
uint_reg_t __reserved_0 : 1;
/**
* MAC Error.
* Generated by the MAC interface. Asserted if there was an overrun of
* the MAC's receive FIFO. This condition generally only occurs if the
* mPIPE clock is running too slowly.
*/
uint_reg_t me : 1;
/**
* Truncation Error.
* Written by the iDMA hardware. Asserted if packet was truncated due to
* insufficient space in iPkt buffer
*/
uint_reg_t tr : 1;
/**
* Written by the iDMA hardware. Indicates the number of bytes written
* to Tile memory. In general, this is the actual size of the packet as
* received from the MAC. But if the packet is truncated due to running
* out of buffers or due to the iPkt buffer filling up, then the L2_SIZE
* will be reduced to reflect the actual number of valid bytes written to
* Tile memory.
*/
uint_reg_t l2_size : 14;
/**
* CRC Error.
* Generated by the MAC. Asserted if MAC indicated an L2 CRC error or
* other L2 error (bad length etc.) on the packet.
*/
uint_reg_t ce : 1;
/**
* Cut Through.
* Written by the iDMA hardware. Asserted if packet was not completely
* received before being sent to classifier. L2_Size will indicate
* number of bytes received so far.
*/
uint_reg_t ct : 1;
/**
* Written by the classification program. Used by the load balancer to
* select the ring into which this packet descriptor is written.
*/
uint_reg_t bucket_id : 13;
/** Reserved. */
uint_reg_t __reserved_1 : 3;
/**
* Checksum.
* Written by classification program. When 1, the checksum engine will
* perform checksum based on the CSUM_SEED, CSUM_START, and CSUM_BYTES
* fields. The result will be placed in CSUM_VAL.
*/
uint_reg_t cs : 1;
/**
* Notification Ring Select.
* Written by the classification program. When 1, the NotifRingIDX is
* set by classification program rather than being set by load balancer.
*/
uint_reg_t nr : 1;
/**
* Written by classification program. Indicates whether packet and
* descriptor should both be dropped, both be delivered, or only the
* descriptor should be delivered.
*/
uint_reg_t dest : 2;
/**
* General Purpose Sequence Number Enable.
* Written by the classification program. When 1, the GP_SQN_SEL field
* contains the sequence number selector and the GP_SQN field will be
* replaced with the associated sequence number. When clear, the GP_SQN
* field is left intact and be used as "Custom" bytes.
*/
uint_reg_t sq : 1;
/**
* TimeStamp Enable.
* Enable TimeStamp insertion. When clear, timestamp field may be filled
* with custom data by classifier. When set, hardware inserts the
* timestamp when the start of packet is received from the MAC.
*/
uint_reg_t ts : 1;
/**
* Packet Sequence Number Enable.
* Enable PacketSQN insertion. When clear, PacketSQN field may be filled
* with custom data by classifier. When set, hardware inserts the packet
* sequence number when the packet descriptor is written to a
* notification ring.
*/
uint_reg_t ps : 1;
/**
* Buffer Error.
* Written by the iDMA hardware. Asserted if iDMA ran out of buffers
* while writing the packet. Software must still return any buffer
* descriptors whose C field indicates a valid descriptor was consumed.
*/
uint_reg_t be : 1;
/**
* Written by the classification program. The associated counter is
* incremented when the packet is sent.
*/
uint_reg_t ctr0 : 5;
/** Reserved. */
uint_reg_t __reserved_2 : 3;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_2 : 3;
uint_reg_t ctr0 : 5;
uint_reg_t be : 1;
uint_reg_t ps : 1;
uint_reg_t ts : 1;
uint_reg_t sq : 1;
uint_reg_t dest : 2;
uint_reg_t nr : 1;
uint_reg_t cs : 1;
uint_reg_t __reserved_1 : 3;
uint_reg_t bucket_id : 13;
uint_reg_t ct : 1;
uint_reg_t ce : 1;
uint_reg_t l2_size : 14;
uint_reg_t tr : 1;
uint_reg_t me : 1;
uint_reg_t __reserved_0 : 1;
uint_reg_t channel : 5;
uint_reg_t notif_ring : 8;
#endif
/* Word 1 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. The associated counter is
* incremented when the packet is sent.
*/
uint_reg_t ctr1 : 5;
/** Reserved. */
uint_reg_t __reserved_3 : 3;
/**
* Written by classification program. Indicates the start byte for
* checksum. Relative to 1st byte received from MAC.
*/
uint_reg_t csum_start : 8;
/**
* Checksum seed written by classification program. Overwritten with
* resultant checksum if CS bit is asserted. The endianness of the CSUM
* value bits when viewed by Tile software match the packet byte order.
* That is, bits[7:0] of the resulting checksum value correspond to
* earlier (more significant) bytes in the packet. To avoid classifier
* software from having to byte swap the CSUM_SEED, the iDMA checksum
* engine byte swaps the classifier's result before seeding the checksum
* calculation. Thus, the CSUM_START byte of packet data is added to
* bits[15:8] of the CSUM_SEED field generated by the classifier. This
* byte swap will be visible to Tile software if the CS bit is clear.
*/
uint_reg_t csum_seed_val : 16;
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom0 : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom0 : 32;
uint_reg_t csum_seed_val : 16;
uint_reg_t csum_start : 8;
uint_reg_t __reserved_3 : 3;
uint_reg_t ctr1 : 5;
#endif
/* Word 2 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom1 : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom1 : 64;
#endif
/* Word 3 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom2 : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom2 : 64;
#endif
/* Word 4 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom3 : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom3 : 64;
#endif
/* Word 5 */
#ifndef __BIG_ENDIAN__
/**
* Sequence number applied when packet is distributed. Classifier
* selects which sequence number is to be applied by writing the 13-bit
* SQN-selector into this field.
*/
uint_reg_t gp_sqn : 16;
/**
* Written by notification hardware. The packet sequence number is
* incremented for each packet that wasn't dropped.
*/
uint_reg_t packet_sqn : 48;
#else /* __BIG_ENDIAN__ */
uint_reg_t packet_sqn : 48;
uint_reg_t gp_sqn : 16;
#endif
/* Word 6 */
#ifndef __BIG_ENDIAN__
/**
* Written by hardware when the start-of-packet is received by the mPIPE
* from the MAC. This is the nanoseconds part of the packet timestamp.
*/
uint_reg_t time_stamp_ns : 32;
/**
* Written by hardware when the start-of-packet is received by the mPIPE
* from the MAC. This is the seconds part of the packet timestamp.
*/
uint_reg_t time_stamp_sec : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t time_stamp_sec : 32;
uint_reg_t time_stamp_ns : 32;
#endif
/* Word 7 */
#ifndef __BIG_ENDIAN__
/** Virtual address. Must be sign extended by consumer. */
int_reg_t va : 42;
/** Reserved. */
uint_reg_t __reserved_4 : 6;
/** Index of the buffer stack to which this buffer belongs. */
uint_reg_t stack_idx : 5;
/** Reserved. */
uint_reg_t __reserved_5 : 3;
/**
* Instance ID. For devices that support more than one mPIPE instance,
* this field indicates the buffer owner. If the INST field does not
* match the mPIPE's instance number when a packet is egressed, buffers
* with HWB set will be returned to the other mPIPE instance.
*/
uint_reg_t inst : 1;
/** Reserved. */
uint_reg_t __reserved_6 : 1;
/**
* Always set to one by hardware in iDMA packet descriptors. For eDMA,
* indicates whether the buffer will be released to the buffer stack
* manager. When 0, software is responsible for releasing the buffer.
*/
uint_reg_t hwb : 1;
/**
* Encoded size of buffer. Set by the ingress hardware for iDMA packet
* descriptors. For eDMA descriptors, indicates the buffer size if .c
* indicates a chained packet. If an eDMA descriptor is not chained and
* the .hwb bit is not set, this field is ignored and the size is
* specified by the .xfer_size field.
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t size : 3;
/**
* Chaining configuration for the buffer. Indicates that an ingress
* packet or egress command is chained across multiple buffers, with each
* buffer's size indicated by the .size field.
*/
uint_reg_t c : 2;
#else /* __BIG_ENDIAN__ */
uint_reg_t c : 2;
uint_reg_t size : 3;
uint_reg_t hwb : 1;
uint_reg_t __reserved_6 : 1;
uint_reg_t inst : 1;
uint_reg_t __reserved_5 : 3;
uint_reg_t stack_idx : 5;
uint_reg_t __reserved_4 : 6;
int_reg_t va : 42;
#endif
};
/** Word access */
uint_reg_t words[8];
} MPIPE_PDESC_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_MPIPE_SHM_H__) */

View File

@ -0,0 +1,23 @@
/*
* 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.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_SHM_DEF_H__
#define __ARCH_MPIPE_SHM_DEF_H__
#define MPIPE_EDMA_DESC_WORD1__C_VAL_UNCHAINED 0x0
#define MPIPE_EDMA_DESC_WORD1__C_VAL_CHAINED 0x1
#define MPIPE_EDMA_DESC_WORD1__C_VAL_NOT_RDY 0x2
#define MPIPE_EDMA_DESC_WORD1__C_VAL_INVALID 0x3
#endif /* !defined(__ARCH_MPIPE_SHM_DEF_H__) */

View File

@ -0,0 +1,136 @@
/*
* 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.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __GXIO_MPIPE_LINUX_RPC_H__
#define __GXIO_MPIPE_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <hv/drv_mpipe_intf.h>
#include <asm/page.h>
#include <gxio/kiorpc.h>
#include <gxio/mpipe.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define GXIO_MPIPE_OP_ALLOC_BUFFER_STACKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1200)
#define GXIO_MPIPE_OP_INIT_BUFFER_STACK_AUX IORPC_OPCODE(IORPC_FORMAT_KERNEL_MEM, 0x1201)
#define GXIO_MPIPE_OP_ALLOC_NOTIF_RINGS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1203)
#define GXIO_MPIPE_OP_INIT_NOTIF_RING_AUX IORPC_OPCODE(IORPC_FORMAT_KERNEL_MEM, 0x1204)
#define GXIO_MPIPE_OP_REQUEST_NOTIF_RING_INTERRUPT IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1205)
#define GXIO_MPIPE_OP_ENABLE_NOTIF_RING_INTERRUPT IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1206)
#define GXIO_MPIPE_OP_ALLOC_NOTIF_GROUPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1207)
#define GXIO_MPIPE_OP_INIT_NOTIF_GROUP IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1208)
#define GXIO_MPIPE_OP_ALLOC_BUCKETS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1209)
#define GXIO_MPIPE_OP_INIT_BUCKET IORPC_OPCODE(IORPC_FORMAT_NONE, 0x120a)
#define GXIO_MPIPE_OP_ALLOC_EDMA_RINGS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x120b)
#define GXIO_MPIPE_OP_INIT_EDMA_RING_AUX IORPC_OPCODE(IORPC_FORMAT_KERNEL_MEM, 0x120c)
#define GXIO_MPIPE_OP_COMMIT_RULES IORPC_OPCODE(IORPC_FORMAT_NONE, 0x120f)
#define GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1210)
#define GXIO_MPIPE_OP_LINK_OPEN_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1211)
#define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212)
#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e)
#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f)
#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220)
#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)
#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)
#define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define GXIO_MPIPE_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int gxio_mpipe_alloc_buffer_stacks(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags);
int gxio_mpipe_init_buffer_stack_aux(gxio_mpipe_context_t * context,
void *mem_va, size_t mem_size,
unsigned int mem_flags, unsigned int stack,
unsigned int buffer_size_enum);
int gxio_mpipe_alloc_notif_rings(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags);
int gxio_mpipe_init_notif_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
size_t mem_size, unsigned int mem_flags,
unsigned int ring);
int gxio_mpipe_request_notif_ring_interrupt(gxio_mpipe_context_t * context,
int inter_x, int inter_y,
int inter_ipi, int inter_event,
unsigned int ring);
int gxio_mpipe_enable_notif_ring_interrupt(gxio_mpipe_context_t * context,
unsigned int ring);
int gxio_mpipe_alloc_notif_groups(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags);
int gxio_mpipe_init_notif_group(gxio_mpipe_context_t * context,
unsigned int group,
gxio_mpipe_notif_group_bits_t bits);
int gxio_mpipe_alloc_buckets(gxio_mpipe_context_t * context, unsigned int count,
unsigned int first, unsigned int flags);
int gxio_mpipe_init_bucket(gxio_mpipe_context_t * context, unsigned int bucket,
MPIPE_LBL_INIT_DAT_BSTS_TBL_t bucket_info);
int gxio_mpipe_alloc_edma_rings(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags);
int gxio_mpipe_init_edma_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
size_t mem_size, unsigned int mem_flags,
unsigned int ring, unsigned int channel);
int gxio_mpipe_commit_rules(gxio_mpipe_context_t * context, const void *blob,
size_t blob_size);
int gxio_mpipe_register_client_memory(gxio_mpipe_context_t * context,
unsigned int iotlb, HV_PTE pte,
unsigned int flags);
int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context,
_gxio_mpipe_link_name_t name, unsigned int flags);
int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac);
int gxio_mpipe_get_timestamp_aux(gxio_mpipe_context_t * context, uint64_t * sec,
uint64_t * nsec, uint64_t * cycles);
int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,
uint64_t nsec, uint64_t cycles);
int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,
int64_t nsec);
int gxio_mpipe_arm_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie);
int gxio_mpipe_close_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie);
int gxio_mpipe_get_mmio_base(gxio_mpipe_context_t * context, HV_PTE *base);
int gxio_mpipe_check_mmio_offset(gxio_mpipe_context_t * context,
unsigned long offset, unsigned long size);
#endif /* !__GXIO_MPIPE_LINUX_RPC_H__ */

View File

@ -0,0 +1,46 @@
/*
* 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.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __GXIO_MPIPE_INFO_LINUX_RPC_H__
#define __GXIO_MPIPE_INFO_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <hv/drv_mpipe_intf.h>
#include <asm/page.h>
#include <gxio/kiorpc.h>
#include <gxio/mpipe.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251)
#define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
unsigned int idx,
_gxio_mpipe_link_name_t * name,
_gxio_mpipe_link_mac_t * mac);
int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
HV_PTE *base);
int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
unsigned long offset, unsigned long size);
#endif /* !__GXIO_MPIPE_INFO_LINUX_RPC_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,602 @@
/*
* Copyright 2011 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.
*/
/**
* Interface definitions for the mpipe driver.
*/
#ifndef _SYS_HV_DRV_MPIPE_INTF_H
#define _SYS_HV_DRV_MPIPE_INTF_H
#include <arch/mpipe.h>
#include <arch/mpipe_constants.h>
/** Number of buffer stacks (32). */
#define HV_MPIPE_NUM_BUFFER_STACKS \
(MPIPE_MMIO_INIT_DAT_GX36_1__BUFFER_STACK_MASK_WIDTH)
/** Number of NotifRings (256). */
#define HV_MPIPE_NUM_NOTIF_RINGS (MPIPE_NUM_NOTIF_RINGS)
/** Number of NotifGroups (32). */
#define HV_MPIPE_NUM_NOTIF_GROUPS (MPIPE_NUM_NOTIF_GROUPS)
/** Number of buckets (4160). */
#define HV_MPIPE_NUM_BUCKETS (MPIPE_NUM_BUCKETS)
/** Number of "lo" buckets (4096). */
#define HV_MPIPE_NUM_LO_BUCKETS 4096
/** Number of "hi" buckets (64). */
#define HV_MPIPE_NUM_HI_BUCKETS \
(HV_MPIPE_NUM_BUCKETS - HV_MPIPE_NUM_LO_BUCKETS)
/** Number of edma rings (24). */
#define HV_MPIPE_NUM_EDMA_RINGS \
(MPIPE_MMIO_INIT_DAT_GX36_1__EDMA_POST_MASK_WIDTH)
/** A flag bit indicating a fixed resource allocation. */
#define HV_MPIPE_ALLOC_FIXED 0x01
/** Offset for the config register MMIO region. */
#define HV_MPIPE_CONFIG_MMIO_OFFSET \
(MPIPE_MMIO_ADDR__REGION_VAL_CFG << MPIPE_MMIO_ADDR__REGION_SHIFT)
/** Size of the config register MMIO region. */
#define HV_MPIPE_CONFIG_MMIO_SIZE (64 * 1024)
/** Offset for the config register MMIO region. */
#define HV_MPIPE_FAST_MMIO_OFFSET \
(MPIPE_MMIO_ADDR__REGION_VAL_IDMA << MPIPE_MMIO_ADDR__REGION_SHIFT)
/** Size of the fast register MMIO region (IDMA, EDMA, buffer stack). */
#define HV_MPIPE_FAST_MMIO_SIZE \
((MPIPE_MMIO_ADDR__REGION_VAL_BSM + 1 - MPIPE_MMIO_ADDR__REGION_VAL_IDMA) \
<< MPIPE_MMIO_ADDR__REGION_SHIFT)
/*
* Each type of resource allocation comes in quantized chunks, where
* XXX_BITS is the number of chunks, and XXX_RES_PER_BIT is the number
* of resources in each chunk.
*/
/** Number of buffer stack chunks available (32). */
#define HV_MPIPE_ALLOC_BUFFER_STACKS_BITS \
MPIPE_MMIO_INIT_DAT_GX36_1__BUFFER_STACK_MASK_WIDTH
/** Granularity of buffer stack allocation (1). */
#define HV_MPIPE_ALLOC_BUFFER_STACKS_RES_PER_BIT \
(HV_MPIPE_NUM_BUFFER_STACKS / HV_MPIPE_ALLOC_BUFFER_STACKS_BITS)
/** Number of NotifRing chunks available (32). */
#define HV_MPIPE_ALLOC_NOTIF_RINGS_BITS \
MPIPE_MMIO_INIT_DAT_GX36_0__NOTIF_RING_MASK_WIDTH
/** Granularity of NotifRing allocation (8). */
#define HV_MPIPE_ALLOC_NOTIF_RINGS_RES_PER_BIT \
(HV_MPIPE_NUM_NOTIF_RINGS / HV_MPIPE_ALLOC_NOTIF_RINGS_BITS)
/** Number of NotifGroup chunks available (32). */
#define HV_MPIPE_ALLOC_NOTIF_GROUPS_BITS \
HV_MPIPE_NUM_NOTIF_GROUPS
/** Granularity of NotifGroup allocation (1). */
#define HV_MPIPE_ALLOC_NOTIF_GROUPS_RES_PER_BIT \
(HV_MPIPE_NUM_NOTIF_GROUPS / HV_MPIPE_ALLOC_NOTIF_GROUPS_BITS)
/** Number of lo bucket chunks available (16). */
#define HV_MPIPE_ALLOC_LO_BUCKETS_BITS \
MPIPE_MMIO_INIT_DAT_GX36_0__BUCKET_RELEASE_MASK_LO_WIDTH
/** Granularity of lo bucket allocation (256). */
#define HV_MPIPE_ALLOC_LO_BUCKETS_RES_PER_BIT \
(HV_MPIPE_NUM_LO_BUCKETS / HV_MPIPE_ALLOC_LO_BUCKETS_BITS)
/** Number of hi bucket chunks available (16). */
#define HV_MPIPE_ALLOC_HI_BUCKETS_BITS \
MPIPE_MMIO_INIT_DAT_GX36_0__BUCKET_RELEASE_MASK_HI_WIDTH
/** Granularity of hi bucket allocation (4). */
#define HV_MPIPE_ALLOC_HI_BUCKETS_RES_PER_BIT \
(HV_MPIPE_NUM_HI_BUCKETS / HV_MPIPE_ALLOC_HI_BUCKETS_BITS)
/** Number of eDMA ring chunks available (24). */
#define HV_MPIPE_ALLOC_EDMA_RINGS_BITS \
MPIPE_MMIO_INIT_DAT_GX36_1__EDMA_POST_MASK_WIDTH
/** Granularity of eDMA ring allocation (1). */
#define HV_MPIPE_ALLOC_EDMA_RINGS_RES_PER_BIT \
(HV_MPIPE_NUM_EDMA_RINGS / HV_MPIPE_ALLOC_EDMA_RINGS_BITS)
/** Bit vector encoding which NotifRings are in a NotifGroup. */
typedef struct
{
/** The actual bits. */
uint64_t ring_mask[4];
} gxio_mpipe_notif_group_bits_t;
/** Another name for MPIPE_LBL_INIT_DAT_BSTS_TBL_t. */
typedef MPIPE_LBL_INIT_DAT_BSTS_TBL_t gxio_mpipe_bucket_info_t;
/** Eight buffer stack ids. */
typedef struct
{
/** The stacks. */
uint8_t stacks[8];
} gxio_mpipe_rules_stacks_t;
/** A destination mac address. */
typedef struct
{
/** The octets. */
uint8_t octets[6];
} gxio_mpipe_rules_dmac_t;
/** A vlan. */
typedef uint16_t gxio_mpipe_rules_vlan_t;
/** Maximum number of characters in a link name. */
#define GXIO_MPIPE_LINK_NAME_LEN 32
/** Structure holding a link name. Only needed, and only typedef'ed,
* because the IORPC stub generator only handles types which are single
* words coming before the parameter name. */
typedef struct
{
/** The name itself. */
char name[GXIO_MPIPE_LINK_NAME_LEN];
}
_gxio_mpipe_link_name_t;
/** Maximum number of characters in a symbol name. */
#define GXIO_MPIPE_SYMBOL_NAME_LEN 128
/** Structure holding a symbol name. Only needed, and only typedef'ed,
* because the IORPC stub generator only handles types which are single
* words coming before the parameter name. */
typedef struct
{
/** The name itself. */
char name[GXIO_MPIPE_SYMBOL_NAME_LEN];
}
_gxio_mpipe_symbol_name_t;
/** Structure holding a MAC address. */
typedef struct
{
/** The address. */
uint8_t mac[6];
}
_gxio_mpipe_link_mac_t;
/** Request shared data permission -- that is, the ability to send and
* receive packets -- on the specified link. Other processes may also
* request shared data permission on the same link.
*
* No more than one of ::GXIO_MPIPE_LINK_DATA, ::GXIO_MPIPE_LINK_NO_DATA,
* or ::GXIO_MPIPE_LINK_EXCL_DATA may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_DATA is assumed.
*/
#define GXIO_MPIPE_LINK_DATA 0x00000001UL
/** Do not request data permission on the specified link.
*
* No more than one of ::GXIO_MPIPE_LINK_DATA, ::GXIO_MPIPE_LINK_NO_DATA,
* or ::GXIO_MPIPE_LINK_EXCL_DATA may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_DATA is assumed.
*/
#define GXIO_MPIPE_LINK_NO_DATA 0x00000002UL
/** Request exclusive data permission -- that is, the ability to send and
* receive packets -- on the specified link. No other processes may
* request data permission on this link, and if any process already has
* data permission on it, this open will fail.
*
* No more than one of ::GXIO_MPIPE_LINK_DATA, ::GXIO_MPIPE_LINK_NO_DATA,
* or ::GXIO_MPIPE_LINK_EXCL_DATA may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_DATA is assumed.
*/
#define GXIO_MPIPE_LINK_EXCL_DATA 0x00000004UL
/** Request shared stats permission -- that is, the ability to read and write
* registers which contain link statistics, and to get link attributes --
* on the specified link. Other processes may also request shared stats
* permission on the same link.
*
* No more than one of ::GXIO_MPIPE_LINK_STATS, ::GXIO_MPIPE_LINK_NO_STATS,
* or ::GXIO_MPIPE_LINK_EXCL_STATS may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_STATS is assumed.
*/
#define GXIO_MPIPE_LINK_STATS 0x00000008UL
/** Do not request stats permission on the specified link.
*
* No more than one of ::GXIO_MPIPE_LINK_STATS, ::GXIO_MPIPE_LINK_NO_STATS,
* or ::GXIO_MPIPE_LINK_EXCL_STATS may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_STATS is assumed.
*/
#define GXIO_MPIPE_LINK_NO_STATS 0x00000010UL
/** Request exclusive stats permission -- that is, the ability to read and
* write registers which contain link statistics, and to get link
* attributes -- on the specified link. No other processes may request
* stats permission on this link, and if any process already
* has stats permission on it, this open will fail.
*
* Requesting exclusive stats permission is normally a very bad idea, since
* it prevents programs like mpipe-stat from providing information on this
* link. Applications should only do this if they use MAC statistics
* registers, and cannot tolerate any of the clear-on-read registers being
* reset by other statistics programs.
*
* No more than one of ::GXIO_MPIPE_LINK_STATS, ::GXIO_MPIPE_LINK_NO_STATS,
* or ::GXIO_MPIPE_LINK_EXCL_STATS may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_STATS is assumed.
*/
#define GXIO_MPIPE_LINK_EXCL_STATS 0x00000020UL
/** Request shared control permission -- that is, the ability to modify link
* attributes, and read and write MAC and MDIO registers -- on the
* specified link. Other processes may also request shared control
* permission on the same link.
*
* No more than one of ::GXIO_MPIPE_LINK_CTL, ::GXIO_MPIPE_LINK_NO_CTL,
* or ::GXIO_MPIPE_LINK_EXCL_CTL may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_CTL is assumed.
*/
#define GXIO_MPIPE_LINK_CTL 0x00000040UL
/** Do not request control permission on the specified link.
*
* No more than one of ::GXIO_MPIPE_LINK_CTL, ::GXIO_MPIPE_LINK_NO_CTL,
* or ::GXIO_MPIPE_LINK_EXCL_CTL may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_CTL is assumed.
*/
#define GXIO_MPIPE_LINK_NO_CTL 0x00000080UL
/** Request exclusive control permission -- that is, the ability to modify
* link attributes, and read and write MAC and MDIO registers -- on the
* specified link. No other processes may request control permission on
* this link, and if any process already has control permission on it,
* this open will fail.
*
* Requesting exclusive control permission is not always a good idea, since
* it prevents programs like mpipe-link from configuring the link.
*
* No more than one of ::GXIO_MPIPE_LINK_CTL, ::GXIO_MPIPE_LINK_NO_CTL,
* or ::GXIO_MPIPE_LINK_EXCL_CTL may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_CTL is assumed.
*/
#define GXIO_MPIPE_LINK_EXCL_CTL 0x00000100UL
/** Set the desired state of the link to up, allowing any speeds which are
* supported by the link hardware, as part of this open operation; do not
* change the desired state of the link when it is closed or the process
* exits. No more than one of ::GXIO_MPIPE_LINK_AUTO_UP,
* ::GXIO_MPIPE_LINK_AUTO_UPDOWN, ::GXIO_MPIPE_LINK_AUTO_DOWN, or
* ::GXIO_MPIPE_LINK_AUTO_NONE may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed.
*/
#define GXIO_MPIPE_LINK_AUTO_UP 0x00000200UL
/** Set the desired state of the link to up, allowing any speeds which are
* supported by the link hardware, as part of this open operation; when the
* link is closed or this process exits, if no other process has the link
* open, set the desired state of the link to down. No more than one of
* ::GXIO_MPIPE_LINK_AUTO_UP, ::GXIO_MPIPE_LINK_AUTO_UPDOWN,
* ::GXIO_MPIPE_LINK_AUTO_DOWN, or ::GXIO_MPIPE_LINK_AUTO_NONE may be
* specifed in a gxio_mpipe_link_open() call. If none are specified,
* ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed.
*/
#define GXIO_MPIPE_LINK_AUTO_UPDOWN 0x00000400UL
/** Do not change the desired state of the link as part of the open
* operation; when the link is closed or this process exits, if no other
* process has the link open, set the desired state of the link to down.
* No more than one of ::GXIO_MPIPE_LINK_AUTO_UP,
* ::GXIO_MPIPE_LINK_AUTO_UPDOWN, ::GXIO_MPIPE_LINK_AUTO_DOWN, or
* ::GXIO_MPIPE_LINK_AUTO_NONE may be specifed in a gxio_mpipe_link_open()
* call. If none are specified, ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed.
*/
#define GXIO_MPIPE_LINK_AUTO_DOWN 0x00000800UL
/** Do not change the desired state of the link as part of the open
* operation; do not change the desired state of the link when it is
* closed or the process exits. No more than one of
* ::GXIO_MPIPE_LINK_AUTO_UP, ::GXIO_MPIPE_LINK_AUTO_UPDOWN,
* ::GXIO_MPIPE_LINK_AUTO_DOWN, or ::GXIO_MPIPE_LINK_AUTO_NONE may be
* specifed in a gxio_mpipe_link_open() call. If none are specified,
* ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed.
*/
#define GXIO_MPIPE_LINK_AUTO_NONE 0x00001000UL
/** Request that this open call not complete until the network link is up.
* The process will wait as long as necessary for this to happen;
* applications which wish to abandon waiting for the link after a
* specific time period should not specify this flag when opening a link,
* but should instead call gxio_mpipe_link_wait() afterward. The link
* must be opened with stats permission. Note that this flag by itself
* does not change the desired link state; if other open flags or previous
* link state changes have not requested a desired state of up, the open
* call will never complete. This flag is not available to kernel
* clients.
*/
#define GXIO_MPIPE_LINK_WAIT 0x00002000UL
/*
* Note: link attributes must fit in 24 bits, since we use the top 8 bits
* of the IORPC offset word for the channel number.
*/
/** Determine whether jumbo frames may be received. If this attribute's
* value value is nonzero, the MAC will accept frames of up to 10240 bytes.
* If the value is zero, the MAC will only accept frames of up to 1544
* bytes. The default value is zero. */
#define GXIO_MPIPE_LINK_RECEIVE_JUMBO 0x010000
/** Determine whether to send pause frames on this link if the mPIPE packet
* FIFO is nearly full. If the value is zero, pause frames are not sent.
* If the value is nonzero, it is the delay value which will be sent in any
* pause frames which are output, in units of 512 bit times.
*
* Bear in mind that in almost all circumstances, the mPIPE packet FIFO
* will never fill up, since mPIPE will empty it as fast as or faster than
* the incoming data rate, by either delivering or dropping packets. The
* only situation in which this is not true is if the memory and cache
* subsystem is extremely heavily loaded, and mPIPE cannot perform DMA of
* packet data to memory in a timely fashion. In particular, pause frames
* will <em>not</em> be sent if packets cannot be delivered because
* NotifRings are full, buckets are full, or buffers are not available in
* a buffer stack. */
#define GXIO_MPIPE_LINK_SEND_PAUSE 0x020000
/** Determine whether to suspend output on the receipt of pause frames.
* If the value is nonzero, mPIPE shim will suspend output on the link's
* channel when a pause frame is received. If the value is zero, pause
* frames will be ignored. The default value is zero. */
#define GXIO_MPIPE_LINK_RECEIVE_PAUSE 0x030000
/** Interface MAC address. The value is a 6-byte MAC address, in the least
* significant 48 bits of the value; in other words, an address which would
* be printed as '12:34:56:78:90:AB' in IEEE 802 canonical format would
* be returned as 0x12345678ab.
*
* Depending upon the overall system design, a MAC address may or may not
* be available for each interface. Note that the interface's MAC address
* does not limit the packets received on its channel, although the
* classifier's rules could be configured to do that. Similarly, the MAC
* address is not used when transmitting packets, although applications
* could certainly decide to use the assigned address as a source MAC
* address when doing so. This attribute may only be retrieved with
* gxio_mpipe_link_get_attr(); it may not be modified.
*/
#define GXIO_MPIPE_LINK_MAC 0x040000
/** Determine whether to discard egress packets on link down. If this value
* is nonzero, packets sent on this link while the link is down will be
* discarded. If this value is zero, no packets will be sent on this link
* while it is down. The default value is one. */
#define GXIO_MPIPE_LINK_DISCARD_IF_DOWN 0x050000
/** Possible link state. The value is a combination of link state flags,
* ORed together, that indicate link modes which are actually supported by
* the hardware. This attribute may only be retrieved with
* gxio_mpipe_link_get_attr(); it may not be modified. */
#define GXIO_MPIPE_LINK_POSSIBLE_STATE 0x060000
/** Current link state. The value is a combination of link state flags,
* ORed together, that indicate the current state of the hardware. If the
* link is down, the value ANDed with ::GXIO_MPIPE_LINK_SPEED will be zero;
* if the link is up, the value ANDed with ::GXIO_MPIPE_LINK_SPEED will
* result in exactly one of the speed values, indicating the current speed.
* This attribute may only be retrieved with gxio_mpipe_link_get_attr(); it
* may not be modified. */
#define GXIO_MPIPE_LINK_CURRENT_STATE 0x070000
/** Desired link state. The value is a conbination of flags, which specify
* the desired state for the link. With gxio_mpipe_link_set_attr(), this
* will, in the background, attempt to bring up the link using whichever of
* the requested flags are reasonable, or take down the link if the flags
* are zero. The actual link up or down operation may happen after this
* call completes. If the link state changes in the future, the system
* will continue to try to get back to the desired link state; for
* instance, if the link is brought up successfully, and then the network
* cable is disconnected, the link will go down. However, the desired
* state of the link is still up, so if the cable is reconnected, the link
* will be brought up again.
*
* With gxio_mpipe_link_set_attr(), this will indicate the desired state
* for the link, as set with a previous gxio_mpipe_link_set_attr() call,
* or implicitly by a gxio_mpipe_link_open() or link close operation.
* This may not reflect the current state of the link; to get that, use
* ::GXIO_MPIPE_LINK_CURRENT_STATE.
*/
#define GXIO_MPIPE_LINK_DESIRED_STATE 0x080000
/** Link can run, should run, or is running at 10 Mbps. */
#define GXIO_MPIPE_LINK_10M 0x0000000000000001UL
/** Link can run, should run, or is running at 100 Mbps. */
#define GXIO_MPIPE_LINK_100M 0x0000000000000002UL
/** Link can run, should run, or is running at 1 Gbps. */
#define GXIO_MPIPE_LINK_1G 0x0000000000000004UL
/** Link can run, should run, or is running at 10 Gbps. */
#define GXIO_MPIPE_LINK_10G 0x0000000000000008UL
/** Link can run, should run, or is running at 20 Gbps. */
#define GXIO_MPIPE_LINK_20G 0x0000000000000010UL
/** Link can run, should run, or is running at 25 Gbps. */
#define GXIO_MPIPE_LINK_25G 0x0000000000000020UL
/** Link can run, should run, or is running at 50 Gbps. */
#define GXIO_MPIPE_LINK_50G 0x0000000000000040UL
/** Link should run at the highest speed supported by the link and by
* the device connected to the link. Only usable as a value for
* the link's desired state; never returned as a value for the current
* or possible states. */
#define GXIO_MPIPE_LINK_ANYSPEED 0x0000000000000800UL
/** All legal link speeds. This value is provided for use in extracting
* the speed-related subset of the link state flags; it is not intended
* to be set directly as a value for one of the GXIO_MPIPE_LINK_xxx_STATE
* attributes. A link is up or is requested to be up if its current or
* desired state, respectively, ANDED with this value, is nonzero. */
#define GXIO_MPIPE_LINK_SPEED_MASK 0x0000000000000FFFUL
/** Link can run, should run, or is running in MAC loopback mode. This
* loops transmitted packets back to the receiver, inside the Tile
* Processor. */
#define GXIO_MPIPE_LINK_LOOP_MAC 0x0000000000001000UL
/** Link can run, should run, or is running in PHY loopback mode. This
* loops transmitted packets back to the receiver, inside the external
* PHY chip. */
#define GXIO_MPIPE_LINK_LOOP_PHY 0x0000000000002000UL
/** Link can run, should run, or is running in external loopback mode.
* This requires that an external loopback plug be installed on the
* Ethernet port. Note that only some links require that this be
* configured via the gxio_mpipe_link routines; other links can do
* external loopack with the plug and no special configuration. */
#define GXIO_MPIPE_LINK_LOOP_EXT 0x0000000000004000UL
/** All legal loopback types. */
#define GXIO_MPIPE_LINK_LOOP_MASK 0x000000000000F000UL
/** Link can run, should run, or is running in full-duplex mode.
* If neither ::GXIO_MPIPE_LINK_FDX nor ::GXIO_MPIPE_LINK_HDX are
* specified in a set of desired state flags, both are assumed. */
#define GXIO_MPIPE_LINK_FDX 0x0000000000010000UL
/** Link can run, should run, or is running in half-duplex mode.
* If neither ::GXIO_MPIPE_LINK_FDX nor ::GXIO_MPIPE_LINK_HDX are
* specified in a set of desired state flags, both are assumed. */
#define GXIO_MPIPE_LINK_HDX 0x0000000000020000UL
/** An individual rule. */
typedef struct
{
/** The total size. */
uint16_t size;
/** The priority. */
int16_t priority;
/** The "headroom" in each buffer. */
uint8_t headroom;
/** The "tailroom" in each buffer. */
uint8_t tailroom;
/** The "capacity" of the largest buffer. */
uint16_t capacity;
/** The mask for converting a flow hash into a bucket. */
uint16_t bucket_mask;
/** The offset for converting a flow hash into a bucket. */
uint16_t bucket_first;
/** The buffer stack ids. */
gxio_mpipe_rules_stacks_t stacks;
/** The actual channels. */
uint32_t channel_bits;
/** The number of dmacs. */
uint16_t num_dmacs;
/** The number of vlans. */
uint16_t num_vlans;
/** The actual dmacs and vlans. */
uint8_t dmacs_and_vlans[];
} gxio_mpipe_rules_rule_t;
/** A list of classifier rules. */
typedef struct
{
/** The offset to the end of the current rule. */
uint16_t tail;
/** The offset to the start of the current rule. */
uint16_t head;
/** The actual rules. */
uint8_t rules[4096 - 4];
} gxio_mpipe_rules_list_t;
/** mPIPE statistics structure. These counters include all relevant
* events occurring on all links within the mPIPE shim. */
typedef struct
{
/** Number of ingress packets dropped for any reason. */
uint64_t ingress_drops;
/** Number of ingress packets dropped because a buffer stack was empty. */
uint64_t ingress_drops_no_buf;
/** Number of ingress packets dropped or truncated due to lack of space in
* the iPkt buffer. */
uint64_t ingress_drops_ipkt;
/** Number of ingress packets dropped by the classifier or load balancer */
uint64_t ingress_drops_cls_lb;
/** Total number of ingress packets. */
uint64_t ingress_packets;
/** Total number of egress packets. */
uint64_t egress_packets;
/** Total number of ingress bytes. */
uint64_t ingress_bytes;
/** Total number of egress bytes. */
uint64_t egress_bytes;
}
gxio_mpipe_stats_t;
#endif /* _SYS_HV_DRV_MPIPE_INTF_H */