Merge branch 'u-boot-pxa/master' into 'u-boot-arm/master'

This commit is contained in:
Albert ARIBAUD 2014-02-19 07:15:01 +01:00
commit a87a0ce702
200 changed files with 5 additions and 70403 deletions

View File

@ -398,8 +398,6 @@ LIST_at91="$(targets_by_soc at91)"
LIST_pxa="$(targets_by_cpu pxa)"
LIST_ixp="$(targets_by_cpu ixp)"
#########################################################################
## SPEAr Systems
#########################################################################

View File

@ -227,7 +227,6 @@ LIBS-y += $(CPUDIR)/
ifdef SOC
LIBS-y += $(CPUDIR)/$(SOC)/
endif
LIBS-$(CONFIG_IXP4XX_NPE) += drivers/net/npe/
LIBS-$(CONFIG_OF_EMBED) += dts/
LIBS-y += arch/$(ARCH)/lib/
LIBS-y += fs/

1
README
View File

@ -141,7 +141,6 @@ Directory Hierarchy:
/s3c24x0 Files specific to Samsung S3C24X0 CPUs
/arm926ejs Files specific to ARM 926 CPUs
/arm1136 Files specific to ARM 1136 CPUs
/ixp Files specific to Intel XScale IXP CPUs
/pxa Files specific to Intel XScale PXA CPUs
/sa1100 Files specific to Intel StrongARM SA1100 CPUs
/lib Architecture specific library files

View File

@ -1,12 +0,0 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
extra-y = start.o
obj-y += cpu.o
obj-$(CONFIG_USE_IRQ) += interrupts.o
obj-y += timer.o

View File

@ -1,16 +0,0 @@
#
# (C) Copyright 2002
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
# Marius Groeger <mgroeger@sysgo.de>
#
# SPDX-License-Identifier: GPL-2.0+
#
BIG_ENDIAN = y
PLATFORM_RELFLAGS += -mbig-endian
PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100
PLATFORM_LDFLAGS += -EB
USE_PRIVATE_LIBGCC = yes

View File

@ -1,100 +0,0 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* CPU specific code
*/
#include <common.h>
#include <command.h>
#include <netdev.h>
#include <asm/arch/ixp425.h>
#include <asm/system.h>
static void cache_flush(void);
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo (void)
{
unsigned long id;
int speed = 0;
asm ("mrc p15, 0, %0, c0, c0, 0":"=r" (id));
puts("CPU: Intel IXP425 at ");
switch ((id & 0x000003f0) >> 4) {
case 0x1c:
speed = 533;
break;
case 0x1d:
speed = 400;
break;
case 0x1f:
speed = 266;
break;
}
if (speed)
printf("%d MHz\n", speed);
else
puts("unknown revision\n");
return 0;
}
#endif /* CONFIG_DISPLAY_CPUINFO */
int cleanup_before_linux (void)
{
/*
* this function is called just before we call linux
* it prepares the processor for linux
*
* just disable everything that can disturb booting linux
*/
disable_interrupts ();
/* turn off I-cache */
icache_disable();
dcache_disable();
/* flush I-cache */
cache_flush();
return 0;
}
/* flush I/D-cache */
static void cache_flush (void)
{
unsigned long i = 0;
asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
}
/* FIXME */
/*
void pci_init(void)
{
return;
}
*/
int cpu_eth_init(bd_t *bis)
{
#ifdef CONFIG_IXP4XX_NPE
npe_initialize(bis);
#endif
return 0;
}

View File

@ -1,66 +0,0 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/ixp425.h>
#include <asm/proc-armv/ptrace.h>
struct _irq_handler {
void *m_data;
void (*m_func)( void *data);
};
static struct _irq_handler IRQ_HANDLER[N_IRQS];
static void default_isr(void *data)
{
printf("default_isr(): called for IRQ %d, Interrupt Status=%x PR=%x\n",
(int)data, *IXP425_ICIP, *IXP425_ICIH);
}
static int next_irq(void)
{
return (((*IXP425_ICIH & 0x000000fc) >> 2) - 1);
}
void do_irq (struct pt_regs *pt_regs)
{
int irq = next_irq();
IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data);
}
void irq_install_handler (int irq, interrupt_handler_t handle_irq, void *data)
{
if (irq >= N_IRQS || !handle_irq)
return;
IRQ_HANDLER[irq].m_data = data;
IRQ_HANDLER[irq].m_func = handle_irq;
}
int arch_interrupt_init (void)
{
int i;
/* install default interrupt handlers */
for (i = 0; i < N_IRQS; i++)
irq_install_handler(i, default_isr, (void *)i);
/* configure interrupts for IRQ mode */
*IXP425_ICLR = 0x00000000;
return (0);
}

View File

@ -1,430 +0,0 @@
/* vi: set ts=8 sw=8 noet: */
/*
* u-boot - Startup Code for XScale IXP
*
* Copyright (C) 2003 Kyle Harris <kharris@nexus-tech.net>
*
* Based on startup code example contained in the
* Intel IXP4xx Programmer's Guide and past u-boot Start.S
* samples.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm-offsets.h>
#include <config.h>
#include <version.h>
#include <asm/arch/ixp425.h>
#define MMU_Control_M 0x001 /* Enable MMU */
#define MMU_Control_A 0x002 /* Enable address alignment faults */
#define MMU_Control_C 0x004 /* Enable cache */
#define MMU_Control_W 0x008 /* Enable write-buffer */
#define MMU_Control_P 0x010 /* Compatability: 32 bit code */
#define MMU_Control_D 0x020 /* Compatability: 32 bit data */
#define MMU_Control_L 0x040 /* Compatability: */
#define MMU_Control_B 0x080 /* Enable Big-Endian */
#define MMU_Control_S 0x100 /* Enable system protection */
#define MMU_Control_R 0x200 /* Enable ROM protection */
#define MMU_Control_I 0x1000 /* Enable Instruction cache */
#define MMU_Control_X 0x2000 /* Set interrupt vectors at 0xFFFF0000 */
#define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
/*
* Macro definitions
*/
/* Delay a bit */
.macro DELAY_FOR cycles, reg0
ldr \reg0, =\cycles
subs \reg0, \reg0, #1
subne pc, pc, #0xc
.endm
/* wait for coprocessor write complete */
.macro CPWAIT reg
mrc p15,0,\reg,c2,c0,0
mov \reg,\reg
sub pc,pc,#4
.endm
.globl _start
_start:
ldr pc, _reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_reset: .word reset
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
/*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* - relocate armboot to ram
* - setup stack
* - jump to second stage
*/
.globl _TEXT_BASE
_TEXT_BASE:
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
.word CONFIG_SPL_TEXT_BASE
#else
.word CONFIG_SYS_TEXT_BASE
#endif
/*
* These are defined in the board-specific linker script.
* Subtracting _start from them lets the linker put their
* relative position in the executable instead of leaving
* them null.
*/
.globl _bss_start_ofs
_bss_start_ofs:
.word __bss_start - _start
.globl _bss_end_ofs
_bss_end_ofs:
.word __bss_end - _start
.globl _end_ofs
_end_ofs:
.word _end - _start
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/* IRQ stack memory (calculated at run-time) + 8 bytes */
.globl IRQ_STACK_START_IN
IRQ_STACK_START_IN:
.word 0x0badc0de
/*
* the actual reset code
*/
reset:
/* disable mmu, set big-endian */
mov r0, #0xf8
mcr p15, 0, r0, c1, c0, 0
CPWAIT r0
/* invalidate I & D caches & BTB */
mcr p15, 0, r0, c7, c7, 0
CPWAIT r0
/* invalidate I & Data TLB */
mcr p15, 0, r0, c8, c7, 0
CPWAIT r0
/* drain write and fill buffers */
mcr p15, 0, r0, c7, c10, 4
CPWAIT r0
/* disable write buffer coalescing */
mrc p15, 0, r0, c1, c0, 1
orr r0, r0, #1
mcr p15, 0, r0, c1, c0, 1
CPWAIT r0
/* set EXP CS0 to the optimum timing */
ldr r1, =CONFIG_SYS_EXP_CS0
ldr r2, =IXP425_EXP_CS0
str r1, [r2]
/* make sure flash is visible at 0 */
mov r1, #CONFIG_SYS_SDR_CONFIG
ldr r2, =IXP425_SDR_CONFIG
str r1, [r2]
/* disable refresh cycles */
mov r1, #0
ldr r3, =IXP425_SDR_REFRESH
str r1, [r3]
/* send nop command */
mov r1, #3
ldr r4, =IXP425_SDR_IR
str r1, [r4]
DELAY_FOR 0x4000, r0
/* set SDRAM internal refresh val */
ldr r1, =CONFIG_SYS_SDRAM_REFRESH_CNT
str r1, [r3]
DELAY_FOR 0x4000, r0
/* send precharge-all command to close all open banks */
mov r1, #2
str r1, [r4]
DELAY_FOR 0x4000, r0
/* provide 8 auto-refresh cycles */
mov r1, #4
mov r5, #8
111: str r1, [r4]
DELAY_FOR 0x100, r0
subs r5, r5, #1
bne 111b
/* set mode register in sdram */
mov r1, #CONFIG_SYS_SDR_MODE_CONFIG
str r1, [r4]
DELAY_FOR 0x4000, r0
/* send normal operation command */
mov r1, #6
str r1, [r4]
DELAY_FOR 0x4000, r0
/* invalidate I & D caches & BTB */
mcr p15, 0, r0, c7, c7, 0
CPWAIT r0
/* invalidate I & Data TLB */
mcr p15, 0, r0, c8, c7, 0
CPWAIT r0
/* drain write and fill buffers */
mcr p15, 0, r0, c7, c10, 4
CPWAIT r0
/* remove flash mirror at 0x00000000 */
ldr r2, =IXP425_EXP_CFG0
ldr r1, [r2]
bic r1, r1, #0x80000000
str r1, [r2]
/* invalidate I & Data TLB */
mcr p15, 0, r0, c8, c7, 0
CPWAIT r0
/* enable I cache */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #MMU_Control_I
mcr p15, 0, r0, c1, c0, 0
CPWAIT r0
mrs r0,cpsr /* set the cpu to SVC32 mode */
bic r0,r0,#0x1f /* (superviser mode, M=10011) */
orr r0,r0,#0x13
msr cpsr,r0
bl _main
/*------------------------------------------------------------------------------*/
.globl c_runtime_cpu_setup
c_runtime_cpu_setup:
bx lr
/****************************************************************************/
/* */
/* Interrupt handling */
/* */
/****************************************************************************/
/* IRQ stack frame */
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
/* use bad_save_user_regs for abort/prefetch/undef/swi ... */
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} /* Calling r0-r12 */
add r8, sp, #S_PC
ldr r2, IRQ_STACK_START_IN
ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
mov r0, sp
.endm
/* use irq_save_user_regs / irq_restore_user_regs for */
/* IRQ/FIQ handling */
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} /* Calling r0-r12 */
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ /* Calling SP, LR */
str lr, [r8, #0] /* Save calling PC */
mrs r6, spsr
str r6, [r8, #4] /* Save CPSR */
str r0, [r8, #8] /* Save OLD_R0 */
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
str lr, [r13, #4]
mov r13, #MODE_SVC @ prepare SVC-Mode
msr spsr_c, r13
mov lr, pc
movs pc, lr
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/****************************************************************************/
/* */
/* exception handlers */
/* */
/****************************************************************************/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
irq_save_user_regs /* someone ought to write a more */
bl do_fiq /* effiction fiq_save_user_regs */
irq_restore_user_regs
#else
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
#endif
/****************************************************************************/
/* */
/* Reset function: Use Watchdog to reset */
/* */
/****************************************************************************/
.align 5
.globl reset_cpu
reset_cpu:
ldr r1, =0x482e
ldr r2, =IXP425_OSWK
str r1, [r2]
ldr r1, =0x0fff
ldr r2, =IXP425_OSWT
str r1, [r2]
ldr r1, =0x5
ldr r2, =IXP425_OSWE
str r1, [r2]
b reset_endless
reset_endless:
b reset_endless

View File

@ -1,101 +0,0 @@
/*
* (C) Copyright 2010
* Michael Schwingen, michael@schwingen.org
*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/ixp425.h>
#include <asm/io.h>
#include <div64.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* The IXP42x time-stamp timer runs at 2*OSC_IN (66.666MHz when using a
* 33.333MHz crystal).
*/
static inline unsigned long long tick_to_time(unsigned long long tick)
{
tick *= CONFIG_SYS_HZ;
do_div(tick, CONFIG_IXP425_TIMER_CLK);
return tick;
}
static inline unsigned long long time_to_tick(unsigned long long time)
{
time *= CONFIG_IXP425_TIMER_CLK;
do_div(time, CONFIG_SYS_HZ);
return time;
}
static inline unsigned long long us_to_tick(unsigned long long us)
{
us = us * CONFIG_IXP425_TIMER_CLK + 999999;
do_div(us, 1000000);
return us;
}
unsigned long long get_ticks(void)
{
ulong now = readl(IXP425_OSTS_B);
if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
/* rollover of timestamp timer register */
gd->arch.timestamp += (0xFFFFFFFF - gd->arch.lastinc) + now + 1;
writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
} else {
/* move stamp forward with absolut diff ticks */
gd->arch.timestamp += (now - gd->arch.lastinc);
}
gd->arch.lastinc = now;
return gd->arch.timestamp;
}
void reset_timer_masked(void)
{
/* capture current timestamp counter */
gd->arch.lastinc = readl(IXP425_OSTS_B);
/* start "advancing" time stamp from 0 */
gd->arch.timestamp = 0;
}
ulong get_timer_masked(void)
{
return tick_to_time(get_ticks());
}
ulong get_timer(ulong base)
{
return get_timer_masked() - base;
}
/* delay x useconds AND preserve advance timestamp value */
void __udelay(unsigned long usec)
{
unsigned long long tmp;
tmp = get_ticks() + us_to_tick(usec);
while (get_ticks() < tmp)
;
}
int timer_init(void)
{
writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
return 0;
}

View File

@ -1,91 +0,0 @@
/*
* (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.__image_copy_start)
arch/arm/cpu/ixp/start.o(.text*)
*(.text*)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
*(.data*)
}
. = ALIGN(4);
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
_end = .;
/*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)
*/
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.hash : { *(.hash*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
}

View File

@ -1,548 +0,0 @@
/*
* include/asm-arm/arch-ixp425/ixp425.h
*
* Register definitions for IXP425
*
* Copyright (C) 2002 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#ifndef _ASM_ARM_IXP425_H_
#define _ASM_ARM_IXP425_H_
#define BIT(x) (1<<(x))
/* FIXME: Only this does work for u-boot... find out why... [RS] */
#define UBOOT_REG_FIX 1
#ifdef UBOOT_REG_FIX
# undef io_p2v
# undef __REG
# ifndef __ASSEMBLY__
# define io_p2v(PhAdd) (PhAdd)
# define __REG(x) (*((volatile u32 *)io_p2v(x)))
# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y)))
# else
# define __REG(x) (x)
# endif
#endif /* UBOOT_REG_FIX */
/*
*
* IXP425 Memory map:
*
* Phy Phy Size Map Size Virt Description
* =========================================================================
*
* 0x00000000 0x10000000 SDRAM 1
*
* 0x10000000 0x10000000 SDRAM 2
*
* 0x20000000 0x10000000 SDRAM 3
*
* 0x30000000 0x10000000 SDRAM 4
*
* The above four are aliases to the same memory location (0x00000000)
*
* 0x48000000 0x4000000 PCI Memory
*
* 0x50000000 0x10000000 Not Mapped EXP BUS
*
* 0x6000000 0x00004000 0x4000 0xFFFEB000 QMgr
*
* 0xC0000000 0x100 0x1000 0xFFFDD000 PCI CFG
*
* 0xC4000000 0x100 0x1000 0xFFFDE000 EXP CFG
*
* 0xC8000000 0xC000 0xC000 0xFFFDF000 PERIPHERAL
*
* 0xCC000000 0x100 0x1000 Not Mapped SDRAM CFG
*/
/*
* SDRAM
*/
#define IXP425_SDRAM_BASE (0x00000000)
#define IXP425_SDRAM_BASE_ALT (0x10000000)
/*
* PCI Configuration space
*/
#define IXP425_PCI_CFG_BASE_PHYS (0xC0000000)
#define IXP425_PCI_CFG_REGION_SIZE (0x00001000)
/*
* Expansion BUS Configuration registers
*/
#define IXP425_EXP_CFG_BASE_PHYS (0xC4000000)
#define IXP425_EXP_CFG_REGION_SIZE (0x00001000)
/*
* Peripheral space
*/
#define IXP425_PERIPHERAL_BASE_PHYS (0xC8000000)
#define IXP425_PERIPHERAL_REGION_SIZE (0x0000C000)
/*
* SDRAM configuration registers
*/
#define IXP425_SDRAM_CFG_BASE_PHYS (0xCC000000)
/*
* Q Manager space .. not static mapped
*/
#define IXP425_QMGR_BASE_PHYS (0x60000000)
#define IXP425_QMGR_REGION_SIZE (0x00004000)
/*
* Expansion BUS
*
* Expansion Bus 'lives' at either base1 or base 2 depending on the value of
* Exp Bus config registers:
*
* Setting bit 31 of IXP425_EXP_CFG0 puts SDRAM at zero,
* and The expansion bus to IXP425_EXP_BUS_BASE2
*/
#define IXP425_EXP_BUS_BASE1_PHYS (0x00000000)
#define IXP425_EXP_BUS_BASE2_PHYS (0x50000000)
#define IXP425_EXP_BUS_BASE_PHYS IXP425_EXP_BUS_BASE2_PHYS
#define IXP425_EXP_BUS_REGION_SIZE (0x08000000)
#define IXP425_EXP_BUS_CSX_REGION_SIZE (0x01000000)
#define IXP425_EXP_BUS_CS0_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x00000000)
#define IXP425_EXP_BUS_CS1_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x01000000)
#define IXP425_EXP_BUS_CS2_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x02000000)
#define IXP425_EXP_BUS_CS3_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x03000000)
#define IXP425_EXP_BUS_CS4_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x04000000)
#define IXP425_EXP_BUS_CS5_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x05000000)
#define IXP425_EXP_BUS_CS6_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x06000000)
#define IXP425_EXP_BUS_CS7_BASE_PHYS (IXP425_EXP_BUS_BASE2_PHYS + 0x07000000)
#define IXP425_FLASH_WRITABLE (0x2)
#define IXP425_FLASH_DEFAULT (0xbcd23c40)
#define IXP425_FLASH_WRITE (0xbcd23c42)
#define IXP425_EXP_CS0_OFFSET 0x00
#define IXP425_EXP_CS1_OFFSET 0x04
#define IXP425_EXP_CS2_OFFSET 0x08
#define IXP425_EXP_CS3_OFFSET 0x0C
#define IXP425_EXP_CS4_OFFSET 0x10
#define IXP425_EXP_CS5_OFFSET 0x14
#define IXP425_EXP_CS6_OFFSET 0x18
#define IXP425_EXP_CS7_OFFSET 0x1C
#define IXP425_EXP_CFG0_OFFSET 0x20
#define IXP425_EXP_CFG1_OFFSET 0x24
#define IXP425_EXP_CFG2_OFFSET 0x28
#define IXP425_EXP_CFG3_OFFSET 0x2C
/*
* Expansion Bus Controller registers.
*/
#ifndef __ASSEMBLY__
#define IXP425_EXP_REG(x) ((volatile u32 *)(IXP425_EXP_CFG_BASE_PHYS+(x)))
#else
#define IXP425_EXP_REG(x) (IXP425_EXP_CFG_BASE_PHYS+(x))
#endif
#define IXP425_EXP_CS0 IXP425_EXP_REG(IXP425_EXP_CS0_OFFSET)
#define IXP425_EXP_CS1 IXP425_EXP_REG(IXP425_EXP_CS1_OFFSET)
#define IXP425_EXP_CS2 IXP425_EXP_REG(IXP425_EXP_CS2_OFFSET)
#define IXP425_EXP_CS3 IXP425_EXP_REG(IXP425_EXP_CS3_OFFSET)
#define IXP425_EXP_CS4 IXP425_EXP_REG(IXP425_EXP_CS4_OFFSET)
#define IXP425_EXP_CS5 IXP425_EXP_REG(IXP425_EXP_CS5_OFFSET)
#define IXP425_EXP_CS6 IXP425_EXP_REG(IXP425_EXP_CS6_OFFSET)
#define IXP425_EXP_CS7 IXP425_EXP_REG(IXP425_EXP_CS7_OFFSET)
#define IXP425_EXP_CFG0 IXP425_EXP_REG(IXP425_EXP_CFG0_OFFSET)
#define IXP425_EXP_CFG1 IXP425_EXP_REG(IXP425_EXP_CFG1_OFFSET)
#define IXP425_EXP_CFG2 IXP425_EXP_REG(IXP425_EXP_CFG2_OFFSET)
#define IXP425_EXP_CFG3 IXP425_EXP_REG(IXP425_EXP_CFG3_OFFSET)
/*
* SDRAM Controller registers.
*/
#define IXP425_SDR_CONFIG_OFFSET 0x00
#define IXP425_SDR_REFRESH_OFFSET 0x04
#define IXP425_SDR_IR_OFFSET 0x08
#define IXP425_SDRAM_REG(x) (IXP425_SDRAM_CFG_BASE_PHYS+(x))
#define IXP425_SDR_CONFIG IXP425_SDRAM_REG(IXP425_SDR_CONFIG_OFFSET)
#define IXP425_SDR_REFRESH IXP425_SDRAM_REG(IXP425_SDR_REFRESH_OFFSET)
#define IXP425_SDR_IR IXP425_SDRAM_REG(IXP425_SDR_IR_OFFSET)
/*
* UART registers
*/
#define IXP425_UART1 0
#define IXP425_UART2 0x1000
#define IXP425_UART_RBR_OFFSET 0x00
#define IXP425_UART_THR_OFFSET 0x00
#define IXP425_UART_DLL_OFFSET 0x00
#define IXP425_UART_IER_OFFSET 0x04
#define IXP425_UART_DLH_OFFSET 0x04
#define IXP425_UART_IIR_OFFSET 0x08
#define IXP425_UART_FCR_OFFSET 0x00
#define IXP425_UART_LCR_OFFSET 0x0c
#define IXP425_UART_MCR_OFFSET 0x10
#define IXP425_UART_LSR_OFFSET 0x14
#define IXP425_UART_MSR_OFFSET 0x18
#define IXP425_UART_SPR_OFFSET 0x1c
#define IXP425_UART_ISR_OFFSET 0x20
#define IXP425_UART_CFG_BASE_PHYS (0xc8000000)
#define RBR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_RBR_OFFSET)
#define THR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_THR_OFFSET)
#define DLL(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_DLL_OFFSET)
#define IER(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_IER_OFFSET)
#define DLH(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_DLH_OFFSET)
#define IIR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_IIR_OFFSET)
#define FCR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_FCR_OFFSET)
#define LCR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_LCR_OFFSET)
#define MCR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_MCR_OFFSET)
#define LSR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_LSR_OFFSET)
#define MSR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_MSR_OFFSET)
#define SPR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_SPR_OFFSET)
#define ISR(x) __REG(IXP425_UART_CFG_BASE_PHYS+(x)+IXP425_UART_ISR_OFFSET)
#define IER_DMAE (1 << 7) /* DMA Requests Enable */
#define IER_UUE (1 << 6) /* UART Unit Enable */
#define IER_NRZE (1 << 5) /* NRZ coding Enable */
#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */
#define IER_MIE (1 << 3) /* Modem Interrupt Enable */
#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */
#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */
#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */
#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */
#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */
#define IIR_TOD (1 << 3) /* Time Out Detected */
#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */
#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */
#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */
#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */
#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */
#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */
#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */
#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */
#define FCR_ITL_1 (0)
#define FCR_ITL_8 (FCR_ITL1)
#define FCR_ITL_16 (FCR_ITL2)
#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1)
#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */
#define LCR_SB (1 << 6) /* Set Break */
#define LCR_STKYP (1 << 5) /* Sticky Parity */
#define LCR_EPS (1 << 4) /* Even Parity Select */
#define LCR_PEN (1 << 3) /* Parity Enable */
#define LCR_STB (1 << 2) /* Stop Bit */
#define LCR_WLS1 (1 << 1) /* Word Length Select */
#define LCR_WLS0 (1 << 0) /* Word Length Select */
#define LSR_FIFOE (1 << 7) /* FIFO Error Status */
#define LSR_TEMT (1 << 6) /* Transmitter Empty */
#define LSR_TDRQ (1 << 5) /* Transmit Data Request */
#define LSR_BI (1 << 4) /* Break Interrupt */
#define LSR_FE (1 << 3) /* Framing Error */
#define LSR_PE (1 << 2) /* Parity Error */
#define LSR_OE (1 << 1) /* Overrun Error */
#define LSR_DR (1 << 0) /* Data Ready */
#define MCR_LOOP (1 << 4) */
#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */
#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */
#define MCR_RTS (1 << 1) /* Request to Send */
#define MCR_DTR (1 << 0) /* Data Terminal Ready */
#define MSR_DCD (1 << 7) /* Data Carrier Detect */
#define MSR_RI (1 << 6) /* Ring Indicator */
#define MSR_DSR (1 << 5) /* Data Set Ready */
#define MSR_CTS (1 << 4) /* Clear To Send */
#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */
#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */
#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */
#define MSR_DCTS (1 << 0) /* Delta Clear To Send */
#define IXP425_CONSOLE_UART_BASE_PHYS IXP425_UART1_BASE_PHYS
/*
* Peripheral Space Registers
*/
#define IXP425_UART1_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x0000)
#define IXP425_UART2_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x1000)
#define IXP425_PMU_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x2000)
#define IXP425_INTC_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x3000)
#define IXP425_GPIO_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x4000)
#define IXP425_TIMER_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x5000)
#define IXP425_NPEA_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x6000)
#define IXP425_NPEB_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x7000)
#define IXP425_NPEC_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x8000)
#define IXP425_EthA_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0x9000)
#define IXP425_EthB_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0xA000)
#define IXP425_USB_BASE_PHYS (IXP425_PERIPHERAL_BASE_PHYS + 0xB000)
/*
* UART Register Definitions , Offsets only as there are 2 UARTS.
* IXP425_UART1_BASE , IXP425_UART2_BASE.
*/
#undef UART_NO_RX_INTERRUPT
#define IXP425_UART_XTAL 14745600
/*
* Constants to make it easy to access Interrupt Controller registers
*/
#define IXP425_ICPR_OFFSET 0x00 /* Interrupt Status */
#define IXP425_ICMR_OFFSET 0x04 /* Interrupt Enable */
#define IXP425_ICLR_OFFSET 0x08 /* Interrupt IRQ/FIQ Select */
#define IXP425_ICIP_OFFSET 0x0C /* IRQ Status */
#define IXP425_ICFP_OFFSET 0x10 /* FIQ Status */
#define IXP425_ICHR_OFFSET 0x14 /* Interrupt Priority */
#define IXP425_ICIH_OFFSET 0x18 /* IRQ Highest Pri Int */
#define IXP425_ICFH_OFFSET 0x1C /* FIQ Highest Pri Int */
#define N_IRQS 32
#define IXP425_TIMER_2_IRQ 11
/*
* Interrupt Controller Register Definitions.
*/
#ifndef __ASSEMBLY__
#define IXP425_INTC_REG(x) ((volatile u32 *)(IXP425_INTC_BASE_PHYS+(x)))
#else
#define IXP425_INTC_REG(x) (IXP425_INTC_BASE_PHYS+(x))
#endif
#define IXP425_ICPR IXP425_INTC_REG(IXP425_ICPR_OFFSET)
#define IXP425_ICMR IXP425_INTC_REG(IXP425_ICMR_OFFSET)
#define IXP425_ICLR IXP425_INTC_REG(IXP425_ICLR_OFFSET)
#define IXP425_ICIP IXP425_INTC_REG(IXP425_ICIP_OFFSET)
#define IXP425_ICFP IXP425_INTC_REG(IXP425_ICFP_OFFSET)
#define IXP425_ICHR IXP425_INTC_REG(IXP425_ICHR_OFFSET)
#define IXP425_ICIH IXP425_INTC_REG(IXP425_ICIH_OFFSET)
#define IXP425_ICFH IXP425_INTC_REG(IXP425_ICFH_OFFSET)
/*
* Constants to make it easy to access GPIO registers
*/
#define IXP425_GPIO_GPOUTR_OFFSET 0x00
#define IXP425_GPIO_GPOER_OFFSET 0x04
#define IXP425_GPIO_GPINR_OFFSET 0x08
#define IXP425_GPIO_GPISR_OFFSET 0x0C
#define IXP425_GPIO_GPIT1R_OFFSET 0x10
#define IXP425_GPIO_GPIT2R_OFFSET 0x14
#define IXP425_GPIO_GPCLKR_OFFSET 0x18
#define IXP425_GPIO_GPDBSELR_OFFSET 0x1C
/*
* GPIO Register Definitions.
* [Only perform 32bit reads/writes]
*/
#define IXP425_GPIO_REG(x) ((volatile u32 *)(IXP425_GPIO_BASE_PHYS+(x)))
#define IXP425_GPIO_GPOUTR IXP425_GPIO_REG(IXP425_GPIO_GPOUTR_OFFSET)
#define IXP425_GPIO_GPOER IXP425_GPIO_REG(IXP425_GPIO_GPOER_OFFSET)
#define IXP425_GPIO_GPINR IXP425_GPIO_REG(IXP425_GPIO_GPINR_OFFSET)
#define IXP425_GPIO_GPISR IXP425_GPIO_REG(IXP425_GPIO_GPISR_OFFSET)
#define IXP425_GPIO_GPIT1R IXP425_GPIO_REG(IXP425_GPIO_GPIT1R_OFFSET)
#define IXP425_GPIO_GPIT2R IXP425_GPIO_REG(IXP425_GPIO_GPIT2R_OFFSET)
#define IXP425_GPIO_GPCLKR IXP425_GPIO_REG(IXP425_GPIO_GPCLKR_OFFSET)
#define IXP425_GPIO_GPDBSELR IXP425_GPIO_REG(IXP425_GPIO_GPDBSELR_OFFSET)
#define IXP425_GPIO_GPITR(line) (((line) >= 8) ? \
IXP425_GPIO_GPIT2R : IXP425_GPIO_GPIT1R)
/*
* Macros to make it easy to access the GPIO registers
*/
#define GPIO_OUTPUT_ENABLE(line) *IXP425_GPIO_GPOER &= ~(1 << (line))
#define GPIO_OUTPUT_DISABLE(line) *IXP425_GPIO_GPOER |= (1 << (line))
#define GPIO_OUTPUT_SET(line) *IXP425_GPIO_GPOUTR |= (1 << (line))
#define GPIO_OUTPUT_CLEAR(line) *IXP425_GPIO_GPOUTR &= ~(1 << (line))
#define GPIO_INT_ACT_LOW_SET(line) \
*IXP425_GPIO_GPITR(line) = \
(*IXP425_GPIO_GPITR(line) & \
~(0x7 << (((line) & 0x7) * 3))) | \
(0x1 << (((line) & 0x7) * 3)) \
/*
* Constants to make it easy to access Timer Control/Status registers
*/
#define IXP425_OSTS_OFFSET 0x00 /* Continious TimeStamp */
#define IXP425_OST1_OFFSET 0x04 /* Timer 1 Timestamp */
#define IXP425_OSRT1_OFFSET 0x08 /* Timer 1 Reload */
#define IXP425_OST2_OFFSET 0x0C /* Timer 2 Timestamp */
#define IXP425_OSRT2_OFFSET 0x10 /* Timer 2 Reload */
#define IXP425_OSWT_OFFSET 0x14 /* Watchdog Timer */
#define IXP425_OSWE_OFFSET 0x18 /* Watchdog Enable */
#define IXP425_OSWK_OFFSET 0x1C /* Watchdog Key */
#define IXP425_OSST_OFFSET 0x20 /* Timer Status */
/*
* Operating System Timer Register Definitions.
*/
#ifndef __ASSEMBLY__
#define IXP425_TIMER_REG(x) ((volatile u32 *)(IXP425_TIMER_BASE_PHYS+(x)))
#else
#define IXP425_TIMER_REG(x) (IXP425_TIMER_BASE_PHYS+(x))
#endif
/* _B to avoid collision: also defined in npe/include/... */
#define IXP425_OSTS_B IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
#define IXP425_OST1 IXP425_TIMER_REG(IXP425_OST1_OFFSET)
#define IXP425_OSRT1 IXP425_TIMER_REG(IXP425_OSRT1_OFFSET)
#define IXP425_OST2 IXP425_TIMER_REG(IXP425_OST2_OFFSET)
#define IXP425_OSRT2 IXP425_TIMER_REG(IXP425_OSRT2_OFFSET)
#define IXP425_OSWT IXP425_TIMER_REG(IXP425_OSWT_OFFSET)
#define IXP425_OSWE IXP425_TIMER_REG(IXP425_OSWE_OFFSET)
#define IXP425_OSWK IXP425_TIMER_REG(IXP425_OSWK_OFFSET)
#define IXP425_OSST IXP425_TIMER_REG(IXP425_OSST_OFFSET)
/*
* Timer register values and bit definitions
*/
#define IXP425_OST_ENABLE BIT(0)
#define IXP425_OST_ONE_SHOT BIT(1)
/* Low order bits of reload value ignored */
#define IXP425_OST_RELOAD_MASK (0x3)
#define IXP425_OST_DISABLED (0x0)
#define IXP425_OSST_TIMER_1_PEND BIT(0)
#define IXP425_OSST_TIMER_2_PEND BIT(1)
#define IXP425_OSST_TIMER_TS_PEND BIT(2)
#define IXP425_OSST_TIMER_WDOG_PEND BIT(3)
#define IXP425_OSST_TIMER_WARM_RESET BIT(4)
/*
* Constants to make it easy to access PCI Control/Status registers
*/
#define PCI_NP_AD_OFFSET 0x00
#define PCI_NP_CBE_OFFSET 0x04
#define PCI_NP_WDATA_OFFSET 0x08
#define PCI_NP_RDATA_OFFSET 0x0c
#define PCI_CRP_AD_CBE_OFFSET 0x10
#define PCI_CRP_WDATA_OFFSET 0x14
#define PCI_CRP_RDATA_OFFSET 0x18
#define PCI_CSR_OFFSET 0x1c
#define PCI_ISR_OFFSET 0x20
#define PCI_INTEN_OFFSET 0x24
#define PCI_DMACTRL_OFFSET 0x28
#define PCI_AHBMEMBASE_OFFSET 0x2c
#define PCI_AHBIOBASE_OFFSET 0x30
#define PCI_PCIMEMBASE_OFFSET 0x34
#define PCI_AHBDOORBELL_OFFSET 0x38
#define PCI_PCIDOORBELL_OFFSET 0x3C
#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
/*
* PCI Control/Status Registers
*/
#define IXP425_PCI_CSR(x) ((volatile u32 *)(IXP425_PCI_CFG_BASE_PHYS+(x)))
#define PCI_NP_AD IXP425_PCI_CSR(PCI_NP_AD_OFFSET)
#define PCI_NP_CBE IXP425_PCI_CSR(PCI_NP_CBE_OFFSET)
#define PCI_NP_WDATA IXP425_PCI_CSR(PCI_NP_WDATA_OFFSET)
#define PCI_NP_RDATA IXP425_PCI_CSR(PCI_NP_RDATA_OFFSET)
#define PCI_CRP_AD_CBE IXP425_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
#define PCI_CRP_WDATA IXP425_PCI_CSR(PCI_CRP_WDATA_OFFSET)
#define PCI_CRP_RDATA IXP425_PCI_CSR(PCI_CRP_RDATA_OFFSET)
#define PCI_CSR IXP425_PCI_CSR(PCI_CSR_OFFSET)
#define PCI_ISR IXP425_PCI_CSR(PCI_ISR_OFFSET)
#define PCI_INTEN IXP425_PCI_CSR(PCI_INTEN_OFFSET)
#define PCI_DMACTRL IXP425_PCI_CSR(PCI_DMACTRL_OFFSET)
#define PCI_AHBMEMBASE IXP425_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
#define PCI_AHBIOBASE IXP425_PCI_CSR(PCI_AHBIOBASE_OFFSET)
#define PCI_PCIMEMBASE IXP425_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
#define PCI_AHBDOORBELL IXP425_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
#define PCI_PCIDOORBELL IXP425_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
#define PCI_ATPDMA0_AHBADDR IXP425_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
#define PCI_ATPDMA0_PCIADDR IXP425_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
#define PCI_ATPDMA0_LENADDR IXP425_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
#define PCI_ATPDMA1_AHBADDR IXP425_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
#define PCI_ATPDMA1_PCIADDR IXP425_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
#define PCI_ATPDMA1_LENADDR IXP425_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
/*
* PCI register values and bit definitions
*/
/* CSR bit definitions */
#define PCI_CSR_HOST BIT(0)
#define PCI_CSR_ARBEN BIT(1)
#define PCI_CSR_ADS BIT(2)
#define PCI_CSR_PDS BIT(3)
#define PCI_CSR_ABE BIT(4)
#define PCI_CSR_DBT BIT(5)
#define PCI_CSR_ASE BIT(8)
#define PCI_CSR_IC BIT(15)
/* ISR (Interrupt status) Register bit definitions */
#define PCI_ISR_PSE BIT(0)
#define PCI_ISR_PFE BIT(1)
#define PCI_ISR_PPE BIT(2)
#define PCI_ISR_AHBE BIT(3)
#define PCI_ISR_APDC BIT(4)
#define PCI_ISR_PADC BIT(5)
#define PCI_ISR_ADB BIT(6)
#define PCI_ISR_PDB BIT(7)
/* INTEN (Interrupt Enable) Register bit definitions */
#define PCI_INTEN_PSE BIT(0)
#define PCI_INTEN_PFE BIT(1)
#define PCI_INTEN_PPE BIT(2)
#define PCI_INTEN_AHBE BIT(3)
#define PCI_INTEN_APDC BIT(4)
#define PCI_INTEN_PADC BIT(5)
#define PCI_INTEN_ADB BIT(6)
#define PCI_INTEN_PDB BIT(7)
/*
* Shift value for byte enable on NP cmd/byte enable register
*/
#define IXP425_PCI_NP_CBE_BESL 4
/*
* PCI commands supported by NP access unit
*/
#define NP_CMD_IOREAD 0x2
#define NP_CMD_IOWRITE 0x3
#define NP_CMD_CONFIGREAD 0xa
#define NP_CMD_CONFIGWRITE 0xb
#define NP_CMD_MEMREAD 0x6
#define NP_CMD_MEMWRITE 0x7
#if 0
#ifndef __ASSEMBLY__
extern int ixp425_pci_read(u32 addr, u32 cmd, u32* data);
extern int ixp425_pci_write(u32 addr, u32 cmd, u32 data);
extern void ixp425_pci_init(void *);
#endif
#endif
/*
* Constants for CRP access into local config space
*/
#define CRP_AD_CBE_BESL 20
#define CRP_AD_CBE_WRITE BIT(16)
/*
* Clock Speed Definitions.
*/
#define IXP425_PERIPHERAL_BUS_CLOCK (66) /* 66Mhzi APB BUS */
#endif

View File

@ -1,174 +0,0 @@
/*
* IXP PCI Init
* (C) Copyright 2004 eslab.whut.edu.cn
* Yue Hu(huyue_whut@yahoo.com.cn), Ligong Xue(lgxue@hotmail.com)
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _IXP425PCI_H
#define _IXP425PCI_H
#define OK 0
#define ERROR -1
struct pci_controller;
extern void pci_ixp_init(struct pci_controller *hose);
/* Mask definitions*/
#define IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK 0x0000000f
#define PCI_NP_CBE_BESL (4)
#define PCI_NP_AD_FUNCSL (8)
/*Register addressing definitions for PCI controller configuration
and status registers*/
#define PCI_CSR_BASE (0xC0000000)
/*
#define PCI_NP_AD_OFFSET (0x00)
#define PCI_NP_CBE_OFFSET (0x04)
#define PCI_NP_WDATA_OFFSET (0x08)
#define PCI_NP_RDATA_OFFSET (0x0C)
#define PCI_CRP_OFFSET (0x10)
#define PCI_CRP_WDATA_OFFSET (0x14)
#define PCI_CRP_RDATA_OFFSET (0x18)
#define PCI_CSR_OFFSET (0x1C)
#define PCI_ISR_OFFSET (0x20)
#define PCI_INTEN_OFFSET (0x24)
#define PCI_DMACTRL_OFFSET (0x28)
#define PCI_AHBMEMBASE_OFFSET (0x2C)
#define PCI_AHBIOBASE_OFFSET (0x30)
#define PCI_PCIMEMBASE_OFFSET (0x34)
#define PCI_AHBDOORBELL_OFFSET (0x38)
#define PCI_PCIDOORBELL_OFFSET (0x3C)
#define PCI_ATPDMA0_AHBADDR (0x40)
#define PCI_ATPDMA0_PCIADDR (0x44)
#define PCI_ATPDMA0_LENADDR (0x48)
#define PCI_ATPDMA1_AHBADDR (0x4C)
#define PCI_ATPDMA1_PCIADDR (0x50)
#define PCI_ATPDMA1_LENADDR (0x54)
#define PCI_PTADMA0_AHBADDR (0x58)
#define PCI_PTADMA0_PCIADDR (0x5C)
#define PCI_PTADMA0_LENADDR (0x60)
#define PCI_PTADMA1_AHBADDR (0x64)
#define PCI_PTADMA1_PCIADDR (0x68)
#define PCI_PTADMA1_LENADDR (0x6C)
*/
/*Non prefetch registers bit definitions*/
/*
#define NP_CMD_INTACK (0x0)
#define NP_CMD_SPECIAL (0x1)
#define NP_CMD_IOREAD (0x2)
#define NP_CMD_IOWRITE (0x3)
#define NP_CMD_MEMREAD (0x6)
#define NP_CMD_MEMWRITE (0x7)
#define NP_CMD_CONFIGREAD (0xa)
#define NP_CMD_CONFIGWRITE (0xb)
*/
/*Configuration Port register bit definitions*/
#define PCI_CRP_WRITE BIT(16)
/*ISR (Interrupt status) Register bit definitions*/
#define PCI_ISR_PSE BIT(0)
#define PCI_ISR_PFE BIT(1)
#define PCI_ISR_PPE BIT(2)
#define PCI_ISR_AHBE BIT(3)
#define PCI_ISR_APDC BIT(4)
#define PCI_ISR_PADC BIT(5)
#define PCI_ISR_ADB BIT(6)
#define PCI_ISR_PDB BIT(7)
/*INTEN (Interrupt Enable) Register bit definitions*/
#define PCI_INTEN_PSE BIT(0)
#define PCI_INTEN_PFE BIT(1)
#define PCI_INTEN_PPE BIT(2)
#define PCI_INTEN_AHBE BIT(3)
#define PCI_INTEN_APDC BIT(4)
#define PCI_INTEN_PADC BIT(5)
#define PCI_INTEN_ADB BIT(6)
#define PCI_INTEN_PDB BIT(7)
/*PCI configuration regs.*/
#define PCI_CFG_VENDOR_ID 0x00
#define PCI_CFG_DEVICE_ID 0x02
#define PCI_CFG_COMMAND 0x04
#define PCI_CFG_STATUS 0x06
#define PCI_CFG_REVISION 0x08
#define PCI_CFG_PROGRAMMING_IF 0x09
#define PCI_CFG_SUBCLASS 0x0a
#define PCI_CFG_CLASS 0x0b
#define PCI_CFG_CACHE_LINE_SIZE 0x0c
#define PCI_CFG_LATENCY_TIMER 0x0d
#define PCI_CFG_HEADER_TYPE 0x0e
#define PCI_CFG_BIST 0x0f
#define PCI_CFG_BASE_ADDRESS_0 0x10
#define PCI_CFG_BASE_ADDRESS_1 0x14
#define PCI_CFG_BASE_ADDRESS_2 0x18
#define PCI_CFG_BASE_ADDRESS_3 0x1c
#define PCI_CFG_BASE_ADDRESS_4 0x20
#define PCI_CFG_BASE_ADDRESS_5 0x24
#define PCI_CFG_CIS 0x28
#define PCI_CFG_SUB_VENDOR_ID 0x2c
#define PCI_CFG_SUB_SYSTEM_ID 0x2e
#define PCI_CFG_EXPANSION_ROM 0x30
#define PCI_CFG_RESERVED_0 0x34
#define PCI_CFG_RESERVED_1 0x38
#define PCI_CFG_DEV_INT_LINE 0x3c
#define PCI_CFG_DEV_INT_PIN 0x3d
#define PCI_CFG_MIN_GRANT 0x3e
#define PCI_CFG_MAX_LATENCY 0x3f
#define PCI_CFG_SPECIAL_USE 0x41
#define PCI_CFG_MODE 0x43
#define PCI_CMD_IO_ENABLE 0x0001 /* IO access enable */
#define PCI_CMD_MEM_ENABLE 0x0002 /* memory access enable */
#define PCI_CMD_MASTER_ENABLE 0x0004 /* bus master enable */
#define PCI_CMD_MON_ENABLE 0x0008 /* monitor special cycles enable */
#define PCI_CMD_WI_ENABLE 0x0010 /* write and invalidate enable */
#define PCI_CMD_SNOOP_ENABLE 0x0020 /* palette snoop enable */
#define PCI_CMD_PERR_ENABLE 0x0040 /* parity error enable */
#define PCI_CMD_WC_ENABLE 0x0080 /* wait cycle enable */
#define PCI_CMD_SERR_ENABLE 0x0100 /* system error enable */
#define PCI_CMD_FBTB_ENABLE 0x0200 /* fast back to back enable */
/*CSR Register bit definitions*/
#define PCI_CSR_HOST BIT(0)
#define PCI_CSR_ARBEN BIT(1)
#define PCI_CSR_ADS BIT(2)
#define PCI_CSR_PDS BIT(3)
#define PCI_CSR_ABE BIT(4)
#define PCI_CSR_DBT BIT(5)
#define PCI_CSR_ASE BIT(8)
#define PCI_CSR_IC BIT(15)
/*Configuration command bit definitions*/
#define PCI_CFG_CMD_IOAE BIT(0)
#define PCI_CFG_CMD_MAE BIT(1)
#define PCI_CFG_CMD_BME BIT(2)
#define PCI_CFG_CMD_MWIE BIT(4)
#define PCI_CFG_CMD_SER BIT(8)
#define PCI_CFG_CMD_FBBE BIT(9)
#define PCI_CFG_CMD_MDPE BIT(24)
#define PCI_CFG_CMD_STA BIT(27)
#define PCI_CFG_CMD_RTA BIT(28)
#define PCI_CFG_CMD_RMA BIT(29)
#define PCI_CFG_CMD_SSE BIT(30)
#define PCI_CFG_CMD_DPE BIT(31)
/*DMACTRL DMA Control and status Register*/
#define PCI_DMACTRL_APDCEN BIT(0)
#define PCI_DMACTRL_APDC0 BIT(4)
#define PCI_DMACTRL_APDE0 BIT(5)
#define PCI_DMACTRL_APDC1 BIT(6)
#define PCI_DMACTRL_APDE1 BIT(7)
#define PCI_DMACTRL_PADCEN BIT(8)
#define PCI_DMACTRL_PADC0 BIT(12)
#define PCI_DMACTRL_PADE0 BIT(13)
#define PCI_DMACTRL_PADC1 BIT(14)
#define PCI_DMACTRL_PADE1 BIT(15)
#endif

View File

@ -32,9 +32,6 @@ struct arch_global_data {
unsigned long tbl;
unsigned long lastinc;
unsigned long long timer_reset_value;
#ifdef CONFIG_IXP425
unsigned long timestamp;
#endif
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
unsigned long tlb_addr;
unsigned long tlb_size;

View File

@ -1,8 +0,0 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := actux1.o

View File

@ -1,148 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/arch/ixp425.h>
#include <asm/io.h>
#include <miiphy.h>
#ifdef CONFIG_PCI
#include <pci.h>
#include <asm/arch/ixp425pci.h>
#endif
#include "actux1_hw.h"
DECLARE_GLOBAL_DATA_PTR;
int board_early_init_f(void)
{
/* CS5: Debug port */
writel(0x9d520003, IXP425_EXP_CS5);
/* CS6: HwRel */
writel(0x81860001, IXP425_EXP_CS6);
/* CS7: LEDs */
writel(0x80900003, IXP425_EXP_CS7);
return 0;
}
int board_init(void)
{
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
/* Setup GPIOs for PCI INTA */
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_PCI1_INTA);
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_PCI1_INTA);
/* Setup GPIOs for 33MHz clock output */
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
writel(0x011001FF, IXP425_GPIO_GPCLKR);
udelay(533);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
ACTUX1_LED1(2);
ACTUX1_LED2(2);
ACTUX1_LED3(0);
ACTUX1_LED4(0);
ACTUX1_LED5(0);
ACTUX1_LED6(0);
ACTUX1_LED7(0);
ACTUX1_HS(ACTUX1_HS_DCD);
return 0;
}
/*
* Check Board Identity
*/
int checkboard(void)
{
char buf[64];
int i = getenv_f("serial#", buf, sizeof(buf));
puts("Board: AcTux-1 rev.");
putc(ACTUX1_BOARDREL + 'A' - 1);
if (i > 0) {
puts(", serial# ");
puts(buf);
}
putc('\n');
return 0;
}
/*************************************************************************
* get_board_rev() - setup to pass kernel board revision information
* 0 = reserved
* 1 = Rev. A
* 2 = Rev. B
*************************************************************************/
u32 get_board_rev(void)
{
return ACTUX1_BOARDREL;
}
int dram_init(void)
{
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
return 0;
}
#ifdef CONFIG_PCI
struct pci_controller hose;
void pci_init_board(void)
{
pci_ixp_init(&hose);
}
#endif
void reset_phy(void)
{
u16 id1, id2;
/* initialize the PHY */
miiphy_reset("NPE0", CONFIG_PHY_ADDR);
miiphy_read("NPE0", CONFIG_PHY_ADDR, MII_PHYSID1, &id1);
miiphy_read("NPE0", CONFIG_PHY_ADDR, MII_PHYSID2, &id2);
id2 &= 0xFFF0; /* mask out revision bits */
if (id1 == 0x13 && id2 == 0x78e0) {
/*
* LXT971/LXT972 PHY: set LED outputs:
* LED1(green) = Link/ACT,
* LED2 (unused) = LINK,
* LED3(red) = Coll
*/
miiphy_write("NPE0", CONFIG_PHY_ADDR, 20, 0xD432);
} else if (id1 == 0x143 && id2 == 0xbc30) {
/* BCM5241: default values are OK */
} else
printf("unknown ethernet PHY ID: %x %x\n", id1, id2);
}

View File

@ -1,41 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* hardware register definitions for the AcTux-1 board.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ACTUX1_HW_H
#define _ACTUX1_HW_H
/* 0 = LED off,1 = green, 2 = red, 3 = orange */
#define ACTUX1_LED1(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 0)
#define ACTUX1_LED2(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 1)
#define ACTUX1_LED3(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 2)
#define ACTUX1_LED4(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 3)
#define ACTUX1_LED5(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 4)
#define ACTUX1_LED6(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 5)
#define ACTUX1_LED7(a) writeb((a)^3, IXP425_EXP_BUS_CS7_BASE_PHYS + 6)
#define ACTUX1_HS(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 7)
#define ACTUX1_HS_DCD 0x01
#define ACTUX1_HS_DSR 0x02
#define ACTUX1_DBG_PORT IXP425_EXP_BUS_CS5_BASE_PHYS
#define ACTUX1_BOARDREL (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0x0F)
/* GPIO settings */
#define CONFIG_SYS_GPIO_PCI1_INTA 2
#define CONFIG_SYS_GPIO_PCI2_INTA 3
#define CONFIG_SYS_GPIO_I2C_SDA 4
#define CONFIG_SYS_GPIO_I2C_SCL 5
#define CONFIG_SYS_GPIO_DBGJUMPER 9
#define CONFIG_SYS_GPIO_BUTTON1 10
#define CONFIG_SYS_GPIO_DBGSENSE 11
#define CONFIG_SYS_GPIO_DTR 12
#define CONFIG_SYS_GPIO_IORST 13 /* Out */
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
#endif

View File

@ -1,99 +0,0 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
OUTPUT_ARCH (arm)
ENTRY (_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN (4);
.text : {
*(.__image_copy_start)
arch/arm/cpu/ixp/start.o(.text*)
net/built-in.o(.text*)
board/actux1/built-in.o(.text*)
arch/arm/cpu/ixp/built-in.o(.text*)
drivers/input/built-in.o(.text*)
. = env_offset;
common/env_embedded.o(.ppcenv)
*(.text*)
}
. = ALIGN(4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
}
. = ALIGN(4);
.data : {
*(.data*)
}
. = ALIGN(4);
.got : {
*(.got)
}
. =.;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN (4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
_end = .;
/*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)
*/
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.hash : { *(.hash*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
}

View File

@ -1,8 +0,0 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := actux2.o

View File

@ -1,122 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/arch/ixp425.h>
#include <asm/io.h>
#include <miiphy.h>
#include "actux2_hw.h"
DECLARE_GLOBAL_DATA_PTR;
int board_early_init_f(void)
{
/* CS1: IPAC-X */
writel(0x94d10013, IXP425_EXP_CS1);
/* CS5: Debug port */
writel(0x9d520003, IXP425_EXP_CS5);
/* CS6: HW release register */
writel(0x81860001, IXP425_EXP_CS6);
/* CS7: LEDs */
writel(0x80900003, IXP425_EXP_CS7);
return 0;
}
int board_init(void)
{
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_ETHRST);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DSR);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DCD);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_ETHRST);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_DSR);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_DCD);
/* Setup GPIOs for Interrupt inputs */
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_DBGINT);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_ETHINT);
/* Setup GPIOs for 33MHz clock output */
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
writel(0x011001FF, IXP425_GPIO_GPCLKR);
udelay(533);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_ETHRST);
ACTUX2_LED1(1);
ACTUX2_LED2(0);
ACTUX2_LED3(0);
ACTUX2_LED4(0);
return 0;
}
/*
* Check Board Identity
*/
int checkboard(void)
{
char buf[64];
int i = getenv_f("serial#", buf, sizeof(buf));
puts("Board: AcTux-2 rev.");
putc(ACTUX2_BOARDREL + 'A' - 1);
if (i > 0) {
puts(", serial# ");
puts(buf);
}
putc('\n');
return 0;
}
int dram_init(void)
{
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
return 0;
}
/*************************************************************************
* get_board_rev() - setup to pass kernel board revision information
* 0 = reserved
* 1 = Rev. A
* 2 = Rev. B
*************************************************************************/
u32 get_board_rev(void)
{
return ACTUX2_BOARDREL;
}
void reset_phy(void)
{
/* init IcPlus IP175C ethernet switch to native IP175C mode */
miiphy_write("NPE0", 29, 31, 0x175C);
}

View File

@ -1,43 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* hardware register definitions for the AcTux-2 board.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ACTUX2_HW_H
#define _ACTUX2_HW_H
/* 0 = LED off,1 = green, 2 = red, 3 = orange */
#define ACTUX2_LED1(a) writeb((a ? 2 : 0), IXP425_EXP_BUS_CS7_BASE_PHYS + 0)
#define ACTUX2_LED2(a) writeb((a ? 2 : 0), IXP425_EXP_BUS_CS7_BASE_PHYS + 1)
#define ACTUX2_LED3(a) writeb((a ? 0 : 2), IXP425_EXP_BUS_CS7_BASE_PHYS + 2)
#define ACTUX2_LED4(a) writeb((a ? 0 : 2), IXP425_EXP_BUS_CS7_BASE_PHYS + 3)
#define ACTUX2_DBG_PORT IXP425_EXP_BUS_CS5_BASE_PHYS
#define ACTUX2_BOARDREL (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0x0F)
#define ACTUX2_OPTION (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0xF0)
/*
* GPIO settings
*/
#define CONFIG_SYS_GPIO_DBGINT 0
#define CONFIG_SYS_GPIO_ETHINT 1
#define CONFIG_SYS_GPIO_ETHRST 2 /* Out */
#define CONFIG_SYS_GPIO_LED5_GN 3 /* Out */
#define CONFIG_SYS_GPIO_UNUSED4 4
#define CONFIG_SYS_GPIO_UNUSED5 5
#define CONFIG_SYS_GPIO_DSR 6 /* Out */
#define CONFIG_SYS_GPIO_DCD 7 /* Out */
#define CONFIG_SYS_GPIO_IPAC_INT 8
#define CONFIG_SYS_GPIO_DBGJUMPER 9
#define CONFIG_SYS_GPIO_BUTTON1 10
#define CONFIG_SYS_GPIO_DBGSENSE 11
#define CONFIG_SYS_GPIO_DTR 12
#define CONFIG_SYS_GPIO_IORST 13 /* Out */
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
#endif

View File

@ -1,99 +0,0 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
OUTPUT_ARCH (arm)
ENTRY (_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN (4);
.text : {
*(.__image_copy_start)
arch/arm/cpu/ixp/start.o(.text*)
net/built-in.o(.text*)
board/actux2/built-in.o(.text*)
arch/arm/cpu/ixp/built-in.o(.text*)
drivers/input/built-in.o(.text*)
. = env_offset;
common/env_embedded.o(.ppcenv)
*(.text*)
}
. = ALIGN(4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
}
. = ALIGN(4);
.data : {
*(.data*)
}
. = ALIGN(4);
.got : {
*(.got)
}
. =.;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN (4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
_end = .;
/*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)
*/
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.hash : { *(.hash*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
}

View File

@ -1,8 +0,0 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := actux3.o

View File

@ -1,149 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/arch/ixp425.h>
#include <asm/io.h>
#include <miiphy.h>
#include "actux3_hw.h"
DECLARE_GLOBAL_DATA_PTR;
int board_early_init_f(void)
{
/* CS1: IPAC-X */
writel(0x94d10013, IXP425_EXP_CS1);
/* CS5: Debug port */
writel(0x9d520003, IXP425_EXP_CS5);
/* CS6: Release/Option register */
writel(0x81860001, IXP425_EXP_CS6);
/* CS7: LEDs */
writel(0x80900003, IXP425_EXP_CS7);
return 0;
}
int board_init(void)
{
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_ETHRST);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DSR);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DCD);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED5_GN);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED6_RT);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED6_GN);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_ETHRST);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_DSR);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_DCD);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_LED5_GN);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_LED6_RT);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_LED6_GN);
/*
* Setup GPIO's for Interrupt inputs
*/
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_DBGINT);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_ETHINT);
/*
* Setup GPIO's for 33MHz clock output
*/
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
writel(0x011001FF, IXP425_GPIO_GPCLKR);
/* we need a minimum PCI reset pulse width after enabling the clock */
udelay(533);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_ETHRST);
ACTUX3_LED1_RT(1);
ACTUX3_LED1_GN(0);
ACTUX3_LED2_RT(0);
ACTUX3_LED2_GN(0);
ACTUX3_LED3_RT(0);
ACTUX3_LED3_GN(0);
ACTUX3_LED4_GN(0);
ACTUX3_LED5_RT(0);
return 0;
}
/*
* Check Board Identity
*/
int checkboard(void)
{
char buf[64];
int i = getenv_f("serial#", buf, sizeof(buf));
puts("Board: AcTux-3 rev.");
putc(ACTUX3_BOARDREL + 'A' - 1);
if (i > 0) {
puts (", serial# ");
puts (buf);
}
putc('\n');
return 0;
}
/*************************************************************************
* get_board_rev() - setup to pass kernel board revision information
* 0 = reserved
* 1 = Rev. A
* 2 = Rev. B
*************************************************************************/
u32 get_board_rev(void)
{
return ACTUX3_BOARDREL;
}
int dram_init(void)
{
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
return 0;
}
void reset_phy(void)
{
int i;
/* initialize the PHY */
miiphy_reset("NPE0", CONFIG_PHY_ADDR);
/* all LED outputs = Link/Act */
miiphy_write("NPE0", CONFIG_PHY_ADDR, 0x16, 0x0AAA);
/*
* The Marvell 88E6060 switch comes up with all ports disabled.
* set all ethernet switch ports to forwarding state
*/
for (i = 1; i <= 5; i++)
miiphy_write("NPE0", CONFIG_PHY_ADDR + 8 + i, 0x04, 0x03);
}

View File

@ -1,44 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* hardware register definitions for the AcTux-3 board.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ACTUX3_HW_H
#define _ACTUX3_HW_H
/* 0 = LED off,1 = ON */
#define ACTUX3_LED1_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 0)
#define ACTUX3_LED1_GN(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 1)
#define ACTUX3_LED2_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 2)
#define ACTUX3_LED2_GN(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 3)
#define ACTUX3_LED3_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 4)
#define ACTUX3_LED3_GN(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 5)
#define ACTUX3_LED4_GN(a) writeb((a)^1, IXP425_EXP_BUS_CS7_BASE_PHYS + 6)
#define ACTUX3_LED5_RT(a) writeb((a), IXP425_EXP_BUS_CS7_BASE_PHYS + 7)
#define ACTUX3_DBG_PORT IXP425_EXP_BUS_CS5_BASE_PHYS
#define ACTUX3_BOARDREL (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0x0F)
#define ACTUX3_OPTION (readb(IXP425_EXP_BUS_CS6_BASE_PHYS) & 0xF0)
/* GPIO settings */
#define CONFIG_SYS_GPIO_DBGINT 0
#define CONFIG_SYS_GPIO_ETHINT 1
#define CONFIG_SYS_GPIO_ETHRST 2 /* Out */
#define CONFIG_SYS_GPIO_LED5_GN 3 /* Out */
#define CONFIG_SYS_GPIO_LED6_RT 4 /* Out */
#define CONFIG_SYS_GPIO_LED6_GN 5 /* Out */
#define CONFIG_SYS_GPIO_DSR 6 /* Out */
#define CONFIG_SYS_GPIO_DCD 7 /* Out */
#define CONFIG_SYS_GPIO_DBGJUMPER 9
#define CONFIG_SYS_GPIO_BUTTON1 10
#define CONFIG_SYS_GPIO_DBGSENSE 11
#define CONFIG_SYS_GPIO_DTR 12
#define CONFIG_SYS_GPIO_IORST 13 /* Out */
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
#endif

View File

@ -1,99 +0,0 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
OUTPUT_ARCH (arm)
ENTRY (_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN (4);
.text : {
*(.__image_copy_start)
arch/arm/cpu/ixp/start.o(.text*)
net/built-in.o(.text*)
board/actux3/built-in.o(.text*)
arch/arm/cpu/ixp/built-in.o(.text*)
drivers/input/built-in.o(.text*)
. = env_offset;
common/env_embedded.o(.ppcenv)
*(.text*)
}
. = ALIGN(4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
}
. = ALIGN(4);
.data : {
*(.data*)
}
. = ALIGN(4);
.got : {
*(.got)
}
. =.;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN (4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
_end = .;
/*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)
*/
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.hash : { *(.hash*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
}

View File

@ -1,8 +0,0 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := actux4.o

View File

@ -1,129 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/arch/ixp425.h>
#include <asm/io.h>
#include <miiphy.h>
#ifdef CONFIG_PCI
#include <pci.h>
#include <asm/arch/ixp425pci.h>
#endif
#include "actux4_hw.h"
DECLARE_GLOBAL_DATA_PTR;
int board_early_init_f(void)
{
writel(0xbd113c42, IXP425_EXP_CS1);
return 0;
}
int board_init(void)
{
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_nPWRON);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_nPWRON);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_IORST);
/* led not populated on board*/
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED3);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_LED3);
/* middle LED */
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_LED2);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_LED2);
/* right LED */
/* weak pulldown = LED weak on */
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_LED1);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_LED1);
/* Setup GPIO's for Interrupt inputs */
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_USBINTA);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_USBINTB);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_USBINTC);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_RTCINT);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_PCI_INTA);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_PCI_INTB);
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_USBINTA);
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_USBINTB);
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_USBINTC);
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_RTCINT);
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_PCI_INTA);
GPIO_INT_ACT_LOW_SET(CONFIG_SYS_GPIO_PCI_INTB);
/* Setup GPIO's for 33MHz clock output */
writel(0x011001FF, IXP425_GPIO_GPCLKR);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
udelay(10000);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
udelay(10000);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_IORST);
udelay(10000);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_IORST);
return 0;
}
/* Check Board Identity */
int checkboard(void)
{
puts("Board: AcTux-4\n");
return 0;
}
int dram_init(void)
{
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
return 0;
}
#ifdef CONFIG_PCI
struct pci_controller hose;
void pci_init_board(void)
{
pci_ixp_init(&hose);
}
#endif
/*
* Hardcoded flash setup:
* Flash 0 is a non-CFI SST 39VF020 flash, 8 bit flash / 8 bit bus.
* Flash 1 is an Intel *16 flash using the CFI driver.
*/
ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
{
if (banknum == 0) { /* non-CFI boot flash */
info->portwidth = 1;
info->chipwidth = 1;
info->interface = FLASH_CFI_X8;
return 1;
} else
return 0;
}

View File

@ -1,33 +0,0 @@
/*
* (C) Copyright 2007
* Michael Schwingen, michael@schwingen.org
*
* hardware register definitions for the AcTux-4 board.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ACTUX4_HW_H
#define _ACTUX4_HW_H
/*
* GPIO settings
*/
#define CONFIG_SYS_GPIO_USBINTA 0
#define CONFIG_SYS_GPIO_USBINTB 1
#define CONFIG_SYS_GPIO_USBINTC 2
#define CONFIG_SYS_GPIO_nPWRON 3 /* Out */
#define CONFIG_SYS_GPIO_I2C_SCL 4
#define CONFIG_SYS_GPIO_I2C_SDA 5
#define CONFIG_SYS_GPIO_PCI_INTB 6
#define CONFIG_SYS_GPIO_BUTTON1 7
#define CONFIG_SYS_GPIO_LED1 8 /* Out */
#define CONFIG_SYS_GPIO_RTCINT 9
#define CONFIG_SYS_GPIO_LED2 10 /* Out */
#define CONFIG_SYS_GPIO_PCI_INTA 11
#define CONFIG_SYS_GPIO_IORST 12 /* Out */
#define CONFIG_SYS_GPIO_LED3 13 /* Out */
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
#endif

View File

@ -1,8 +0,0 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := dvlhost.o watchdog.o

View File

@ -1,112 +0,0 @@
/*
* (C) Copyright 2009
* Michael Schwingen, michael@schwingen.org
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <config.h>
#include <command.h>
#include <malloc.h>
#include <asm/arch/ixp425.h>
#include <asm/io.h>
#include <miiphy.h>
#ifdef CONFIG_PCI
#include <pci.h>
#include <asm/arch/ixp425pci.h>
#endif
#include "dvlhost_hw.h"
DECLARE_GLOBAL_DATA_PTR;
int board_early_init_f(void)
{
/* CS1: LED Latch */
writel(0xBFFF0002, IXP425_EXP_CS1);
return 0;
}
int board_init(void)
{
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
/* Setup GPIOs used as output */
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_WDGTRIGGER);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_DLAN_PAIRING);
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_PCIRST);
/*
* LED latch enable and watchdog enable are tied to the same GPIO,
* so we need to trigger the watchdog if we want to enable the LEDs.
*/
#ifdef CONFIG_HW_WATCHDOG
GPIO_OUTPUT_CLEAR(CONFIG_SYS_GPIO_WDG_LED_EN);
#else
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_WDG_LED_EN);
#endif
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_WDGTRIGGER);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_DLAN_PAIRING);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_WDG_LED_EN);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCIRST);
/* Setup GPIOs for Interrupt inputs */
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_BTN_WLAN);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_BTN_PAIRING);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_BTN_RESET);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_IRQA);
GPIO_OUTPUT_DISABLE(CONFIG_SYS_GPIO_IRQB);
/* Setup GPIO's for 33MHz clock output */
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_PCI_CLK);
GPIO_OUTPUT_ENABLE(CONFIG_SYS_GPIO_EXTBUS_CLK);
writel(0x01FF01FF, IXP425_GPIO_GPCLKR);
/* turn off all LEDs */
writew(0x0000, DVLHOST_LED_LATCH);
udelay(533);
GPIO_OUTPUT_SET(CONFIG_SYS_GPIO_PCIRST);
return 0;
}
/* Check Board Identity */
int checkboard(void)
{
char *s = getenv("serial#");
puts("Board: dLAN 200AV (dvlhost)");
if (s != NULL) {
puts(", serial# ");
puts(s);
}
putc('\n');
return 0;
}
int dram_init(void)
{
gd->ram_size = get_ram_size(CONFIG_SYS_SDRAM_BASE, 128<<20);
return 0;
}
#ifdef CONFIG_PCI
struct pci_controller hose;
void pci_init_board(void)
{
pci_ixp_init(&hose);
}
#endif
void reset_phy(void)
{
/* init IcPlus IP175C ethernet switch to native IP175C mode */
miiphy_write("NPE1", 29, 31, 0x175C);
}

View File

@ -1,31 +0,0 @@
/*
* (C) Copyright 2009
* Michael Schwingen, michael@schwingen.org
*
* hardware register definitions for the
* dLAN200 AV Wireless G ("dvlhost") board.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _DVLHOST_HW_H
#define _DVLHOST_HW_H
/*
* GPIO settings
*/
#define CONFIG_SYS_GPIO_WDGTRIGGER 0 /* Out */
#define CONFIG_SYS_GPIO_BTN_WLAN 1
#define CONFIG_SYS_GPIO_BTN_PAIRING 6
#define CONFIG_SYS_GPIO_DLAN_PAIRING 7 /* Out */
#define CONFIG_SYS_GPIO_BTN_RESET 9
#define CONFIG_SYS_GPIO_IRQB 10
#define CONFIG_SYS_GPIO_IRQA 11
#define CONFIG_SYS_GPIO_WDG_LED_EN 12 /* Out */
#define CONFIG_SYS_GPIO_PCIRST 13 /* Out */
#define CONFIG_SYS_GPIO_PCI_CLK 14 /* Out */
#define CONFIG_SYS_GPIO_EXTBUS_CLK 15 /* Out */
#define DVLHOST_LED_LATCH IXP425_EXP_BUS_CS1_BASE_PHYS
#endif

View File

@ -1,99 +0,0 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT ("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
OUTPUT_ARCH (arm)
ENTRY (_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN (4);
.text : {
*(.__image_copy_start)
arch/arm/cpu/ixp/start.o(.text*)
net/built-in.o(.text*)
board/dvlhost/built-in.o(.text*)
arch/arm/cpu/ixp/built-in.o(.text*)
drivers/serial/built-in.o(.text*)
. = env_offset;
common/env_embedded.o(.ppcenv)
*(.text*)
}
. = ALIGN (4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
}
. = ALIGN (4);
.data : {
*(.data*)
}
. = ALIGN (4);
.got : {
*(.got)
}
. =.;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN (4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
_end = .;
/*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)
*/
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.hash : { *(.hash*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
}

View File

@ -1,27 +0,0 @@
/*
* (C) Copyright 2009
* Michael Schwingen, michael@schwingen.org
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <config.h>
#include <asm/io.h>
#include "dvlhost_hw.h"
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_HW_WATCHDOG
#include <watchdog.h>
#include <asm/arch/ixp425.h>
void hw_watchdog_reset(void)
{
unsigned int x;
x = readl(IXP425_GPIO_GPOUTR);
x ^= (1 << (CONFIG_SYS_GPIO_WDGTRIGGER));
writel(x, IXP425_GPIO_GPOUTR);
}
#endif /* CONFIG_HW_WATCHDOG */

View File

@ -379,14 +379,6 @@ Active arm armv7:arm720t tegra20 toradex colibri_t20_iris
Active arm armv7:arm720t tegra30 avionic-design tec-ng tec-ng - Alban Bedel <alban.bedel@avionic-design.de>
Active arm armv7:arm720t tegra30 nvidia beaver beaver - Tom Warren <twarren@nvidia.com>:Stephen Warren <swarren@nvidia.com>
Active arm armv7:arm720t tegra30 nvidia cardhu cardhu - Tom Warren <twarren@nvidia.com>
Active arm ixp - - - actux2 - Michael Schwingen <michael@schwingen.org>
Active arm ixp - - - actux3 - Michael Schwingen <michael@schwingen.org>
Active arm ixp - - - actux4 - Michael Schwingen <michael@schwingen.org>
Active arm ixp - - - dvlhost - Michael Schwingen <michael@schwingen.org>
Active arm ixp - - actux1 actux1_4_16 actux1:FLASH2X2 Michael Schwingen <michael@schwingen.org>
Active arm ixp - - actux1 actux1_4_32 actux1:FLASH2X2,RAM_32MB Michael Schwingen <michael@schwingen.org>
Active arm ixp - - actux1 actux1_8_16 actux1:FLASH1X8 Michael Schwingen <michael@schwingen.org>
Active arm ixp - - actux1 actux1_8_32 actux1:FLASH1X8,RAM_32MB Michael Schwingen <michael@schwingen.org>
Active arm pxa - - - balloon3 - Marek Vasut <marek.vasut@gmail.com>
Active arm pxa - - - h2200 - Lukasz Dalek <luk0104@gmail.com>
Active arm pxa - - - palmld - Marek Vasut <marek.vasut@gmail.com>

View File

@ -11,6 +11,11 @@ easily if here is something they might want to dig for...
Board Arch CPU Commit Removed Last known maintainer/contact
=================================================================================================
dvl_host arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
actux4 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
actux3 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
actux2 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
actux1 arm ixp - 2014-01-28 Michael Schwingen <michael@schwingen.org>
mx1ads arm arm920t - 2014-01-13
mini2440 arm arm920t - 2014-01-13 Gabriel Huau <contact@huau-gabriel.fr>
omap730p2 arm arm926ejs 79c5c08d 2013-11-11

View File

@ -125,10 +125,6 @@ III) Analysis of in-tree drivers
Shared driver for indirect PCI bridges, several CONFIG macros - will
require significant cleanup.
pci_ixp.c
---------
Standard driver, specifies all read/write functions separately.
pci_sh4.c
---------
Shared init function for SH4 drivers, uses dword for read/write ops.

View File

@ -101,10 +101,6 @@ III) Analysis of in-tree drivers
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. This driver
might be removed in favor of serial_mxc.c .
serial_ixp.c
------------
No support for CONFIG_SERIAL_MULTI. Simple conversion possible.
serial_ks8695.c
---------------
No support for CONFIG_SERIAL_MULTI. Simple conversion possible.

View File

@ -29,9 +29,6 @@
#include <asm/arch/gpio.h>
#endif
#endif
#ifdef CONFIG_IXP425 /* only valid for IXP425 */
#include <asm/arch/ixp425.h>
#endif
#if defined(CONFIG_MPC852T) || defined(CONFIG_MPC866)
#include <asm/io.h>
#endif

View File

@ -1,237 +0,0 @@
/**
* @file IxEthAcc.c
*
* @author Intel Corporation
* @date 20-Feb-2001
*
* @brief This file contains the implementation of the IXP425 Ethernet Access Component
*
* Design Notes:
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthAcc.h"
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
#include "IxEthDB.h"
#endif
#include "IxFeatureCtrl.h"
#include "IxEthAcc_p.h"
#include "IxEthAccMac_p.h"
#include "IxEthAccMii_p.h"
/**
* @addtogroup IxEthAcc
*@{
*/
/**
* @brief System-wide information data strucure.
*
* @ingroup IxEthAccPri
*
*/
IxEthAccInfo ixEthAccDataInfo;
extern PUBLIC IxEthAccMacState ixEthAccMacState[];
extern PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
/**
* @brief System-wide information
*
* @ingroup IxEthAccPri
*
*/
BOOL ixEthAccServiceInit = false;
/* global filtering bit mask */
PUBLIC UINT32 ixEthAccNewSrcMask;
/**
* @brief Per port information data strucure.
*
* @ingroup IxEthAccPri
*
*/
IxEthAccPortDataInfo ixEthAccPortData[IX_ETH_ACC_NUMBER_OF_PORTS];
PUBLIC IxEthAccStatus ixEthAccInit()
{
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
/*
* Initialize Control plane
*/
if (ixEthDBInit() != IX_ETH_DB_SUCCESS)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
#endif
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
{
ixEthAccNewSrcMask = (~0); /* want all the bits */
}
else
{
ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */
}
/*
* Initialize Data plane
*/
if ( ixEthAccInitDataPlane() != IX_ETH_ACC_SUCCESS )
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS )
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/*
* Initialize MII
*/
if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS )
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/*
* Initialize MAC I/O memory
*/
if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/*
* Initialize control plane interface lock
*/
if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
/* initialiasation is complete */
ixEthAccServiceInit = true;
return IX_ETH_ACC_SUCCESS;
}
PUBLIC void ixEthAccUnload(void)
{
IxEthAccPortId portId;
if ( IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
{
/* check none of the port is still active */
for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
{
if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
{
if (ixEthAccMacState[portId].portDisableState == ACTIVE)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccUnload: port %u still active, bail out\n", portId, 0, 0, 0, 0, 0);
return;
}
}
}
/* unmap the memory areas */
ixEthAccMiiUnload();
ixEthAccMacUnload();
/* set all ports as uninitialized */
for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
{
ixEthAccPortData[portId].portInitialized = false;
}
/* uninitialize the service */
ixEthAccServiceInit = false;
}
}
PUBLIC IxEthAccStatus ixEthAccPortInit( IxEthAccPortId portId)
{
IxEthAccStatus ret=IX_ETH_ACC_SUCCESS;
if ( ! IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
{
return(IX_ETH_ACC_FAIL);
}
/*
* Check for valid port
*/
if ( ! IX_ETH_ACC_IS_PORT_VALID(portId) )
{
return (IX_ETH_ACC_INVALID_PORT);
}
if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
{
IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Eth port.\n",(INT32) portId,0,0,0,0,0);
return IX_ETH_ACC_SUCCESS ;
}
if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
{
/* Already initialized */
return(IX_ETH_ACC_FAIL);
}
if(ixEthAccMacInit(portId)!=IX_ETH_ACC_SUCCESS)
{
return IX_ETH_ACC_FAIL;
}
/*
* Set the port init flag.
*/
ixEthAccPortData[portId].portInitialized = true;
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
/* init learning/filtering database structures for this port */
ixEthDBPortInit(portId);
#endif
return(ret);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,509 +0,0 @@
/**
* @file IxEthAccControlInterface.c
*
* @author Intel Corporation
* @date
*
* @brief IX_ETH_ACC_PUBLIC wrappers for control plane functions
*
* Design Notes:
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxEthAcc.h"
#include "IxEthAcc_p.h"
PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
printf("EthAcc: (Mac) cannot enable port %d, service not initialized\n", portId);
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
/* check the context is iinitialized */
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortEnabledQueryPriv(portId, enabled);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortPromiscuousModeClearPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortPromiscuousModeSetPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortUnicastMacAddressSetPriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortUnicastMacAddressGetPriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressJoinPriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressJoinAllPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressLeavePriv(portId, macAddr);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMulticastAddressLeaveAllPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortUnicastAddressShow(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortUnicastAddressShowPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC void
ixEthAccPortMulticastAddressShow(IxEthAccPortId portId)
{
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return;
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
ixEthAccPortMulticastAddressShowPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortDuplexModeSet(IxEthAccPortId portId, IxEthAccDuplexMode mode)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortDuplexModeSetPriv(portId, mode);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortDuplexModeGet(IxEthAccPortId portId, IxEthAccDuplexMode *mode)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortDuplexModeGetPriv(portId, mode);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendPaddingEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendPaddingDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendFCSEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxFrameAppendFCSDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxFrameAppendFCSEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxFrameAppendFCSDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccTxSchedulingDisciplineSetPriv(portId, sched);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccRxSchedulingDisciplineSetPriv(sched);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccNpeLoopbackEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxEnable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxEnablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccNpeLoopbackDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortTxDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortTxDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortRxDisable(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortRxDisablePriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}
IX_ETH_ACC_PUBLIC IxEthAccStatus
ixEthAccPortMacReset(IxEthAccPortId portId)
{
IxEthAccStatus result;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
result = ixEthAccPortMacResetPriv(portId);
ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
return result;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,386 +0,0 @@
/**
* @file IxEthAccMii.c
*
* @author Intel Corporation
* @date
*
* @brief MII control functions
*
* Design Notes:
*
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxEthAcc.h"
#include "IxEthAcc_p.h"
#include "IxEthAccMac_p.h"
#include "IxEthAccMii_p.h"
PRIVATE UINT32 miiBaseAddressVirt;
PRIVATE IxOsalMutex miiAccessLock;
PUBLIC UINT32 ixEthAccMiiRetryCount = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
/* -----------------------------------
* private function prototypes
*/
PRIVATE void
ixEthAccMdioCmdWrite(UINT32 mdioCommand);
PRIVATE void
ixEthAccMdioCmdRead(UINT32 *data);
PRIVATE void
ixEthAccMdioStatusRead(UINT32 *data);
PRIVATE void
ixEthAccMdioCmdWrite(UINT32 mdioCommand)
{
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_1,
mdioCommand & 0xff);
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_2,
(mdioCommand >> 8) & 0xff);
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_3,
(mdioCommand >> 16) & 0xff);
REG_WRITE(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_4,
(mdioCommand >> 24) & 0xff);
}
PRIVATE void
ixEthAccMdioCmdRead(UINT32 *data)
{
UINT32 regval;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_1,
regval);
*data = regval & 0xff;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_2,
regval);
*data |= (regval & 0xff) << 8;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_3,
regval);
*data |= (regval & 0xff) << 16;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_CMD_4,
regval);
*data |= (regval & 0xff) << 24;
}
PRIVATE void
ixEthAccMdioStatusRead(UINT32 *data)
{
UINT32 regval;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_1,
regval);
*data = regval & 0xff;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_2,
regval);
*data |= (regval & 0xff) << 8;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_3,
regval);
*data |= (regval & 0xff) << 16;
REG_READ(miiBaseAddressVirt,
IX_ETH_ACC_MAC_MDIO_STS_4,
regval);
*data |= (regval & 0xff) << 24;
}
/********************************************************************
* ixEthAccMiiInit
*/
IxEthAccStatus
ixEthAccMiiInit()
{
if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS)
{
return IX_ETH_ACC_FAIL;
}
miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE);
if (miiBaseAddressVirt == 0)
{
ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDOUT,
"EthAcc: Could not map MII I/O mapped memory\n",
0, 0, 0, 0, 0, 0);
return IX_ETH_ACC_FAIL;
}
return IX_ETH_ACC_SUCCESS;
}
void
ixEthAccMiiUnload(void)
{
IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
miiBaseAddressVirt = 0;
}
PUBLIC IxEthAccStatus
ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount)
{
if (retryCount < 1) return IX_ETH_ACC_FAIL;
ixEthAccMiiRetryCount = retryCount;
ixEthAccMiiAccessTimeout = timeout;
return IX_ETH_ACC_SUCCESS;
}
/*********************************************************************
* ixEthAccMiiReadRtn - read a 16 bit value from a PHY
*/
IxEthAccStatus
ixEthAccMiiReadRtn (UINT8 phyAddr,
UINT8 phyReg,
UINT16 *value)
{
UINT32 mdioCommand;
UINT32 regval;
UINT32 miiTimeout;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
{
return (IX_ETH_ACC_FAIL);
}
if (value == NULL)
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
| phyAddr << IX_ETH_ACC_MII_ADDR_SHL;
mdioCommand |= IX_ETH_ACC_MII_GO;
ixEthAccMdioCmdWrite(mdioCommand);
miiTimeout = ixEthAccMiiRetryCount;
while(miiTimeout)
{
ixEthAccMdioCmdRead(&regval);
if((regval & IX_ETH_ACC_MII_GO) == 0x0)
{
break;
}
/* Sleep for a while */
ixOsalSleep(ixEthAccMiiAccessTimeout);
miiTimeout--;
}
if(miiTimeout == 0)
{
ixOsalMutexUnlock(&miiAccessLock);
*value = 0xffff;
return IX_ETH_ACC_FAIL;
}
ixEthAccMdioStatusRead(&regval);
if(regval & IX_ETH_ACC_MII_READ_FAIL)
{
ixOsalMutexUnlock(&miiAccessLock);
*value = 0xffff;
return IX_ETH_ACC_FAIL;
}
*value = regval & 0xffff;
ixOsalMutexUnlock(&miiAccessLock);
return IX_ETH_ACC_SUCCESS;
}
/*********************************************************************
* ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
*/
IxEthAccStatus
ixEthAccMiiWriteRtn (UINT8 phyAddr,
UINT8 phyReg,
UINT16 value)
{
UINT32 mdioCommand;
UINT32 regval;
UINT16 readVal;
UINT32 miiTimeout;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
{
return (IX_ETH_ACC_FAIL);
}
/* ensure that a PHY is present at this address */
if(ixEthAccMiiReadRtn(phyAddr,
IX_ETH_ACC_MII_CTRL_REG,
&readVal) != IX_ETH_ACC_SUCCESS)
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
| phyAddr << IX_ETH_ACC_MII_ADDR_SHL ;
mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value;
ixEthAccMdioCmdWrite(mdioCommand);
miiTimeout = ixEthAccMiiRetryCount;
while(miiTimeout)
{
ixEthAccMdioCmdRead(&regval);
/*The "GO" bit is reset to 0 when the write completes*/
if((regval & IX_ETH_ACC_MII_GO) == 0x0)
{
break;
}
/* Sleep for a while */
ixOsalSleep(ixEthAccMiiAccessTimeout);
miiTimeout--;
}
ixOsalMutexUnlock(&miiAccessLock);
if(miiTimeout == 0)
{
return IX_ETH_ACC_FAIL;
}
return IX_ETH_ACC_SUCCESS;
}
/*****************************************************************
*
* Phy query functions
*
*/
IxEthAccStatus
ixEthAccMiiStatsShow (UINT32 phyAddr)
{
UINT16 regval;
printf("Regisers on PHY at address 0x%x\n", phyAddr);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, &regval);
printf(" Control Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, &regval);
printf(" Status Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, &regval);
printf(" PHY ID1 Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, &regval);
printf(" PHY ID2 Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, &regval);
printf(" Auto Neg ADS Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, &regval);
printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, &regval);
printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, &regval);
printf(" Auto Neg Next Register : 0x%4.4x\n", regval);
return IX_ETH_ACC_SUCCESS;
}
/*****************************************************************
*
* Interface query functions
*
*/
IxEthAccStatus
ixEthAccMdioShow (void)
{
UINT32 regval;
if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
{
return (IX_ETH_ACC_FAIL);
}
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
ixEthAccMdioCmdRead(&regval);
ixOsalMutexUnlock(&miiAccessLock);
printf("MDIO command register\n");
printf(" Go bit : 0x%x\n", (regval & BIT(31)) >> 31);
printf(" MDIO Write : 0x%x\n", (regval & BIT(26)) >> 26);
printf(" PHY address : 0x%x\n", (regval >> 21) & 0x1f);
printf(" Reg address : 0x%x\n", (regval >> 16) & 0x1f);
ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
ixEthAccMdioStatusRead(&regval);
ixOsalMutexUnlock(&miiAccessLock);
printf("MDIO status register\n");
printf(" Read OK : 0x%x\n", (regval & BIT(31)) >> 31);
printf(" Read Data : 0x%x\n", (regval >> 16) & 0xff);
return IX_ETH_ACC_SUCCESS;
}

View File

@ -1,424 +0,0 @@
/**
* @file IxEthDBAPI.c
*
* @brief Implementation of the public API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
#include "IxFeatureCtrl.h"
extern HashTable dbHashtable;
extern IxEthDBPortMap overflowUpdatePortList;
extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
return ixEthDBTriggerAddPortUpdate(macAddr, portID, true);
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
return ixEthDBTriggerAddPortUpdate(macAddr, portID, false);
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
IX_ETH_DB_CHECK_REFERENCE(macAddr);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
ixEthDBReleaseHashNode(searchResult);
/* build a remove event and place it on the event queue */
return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
}
IX_ETH_DB_PUBLIC
void ixEthDBDatabaseMaintenance()
{
HashIterator iterator;
UINT32 portIndex;
BOOL agingRequired = false;
/* ports who will have deleted records and therefore will need updating */
IxEthDBPortMap triggerPorts;
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
{
return;
}
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
/* check if there's at least a port that needs aging */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
{
agingRequired = true;
}
}
if (agingRequired)
{
/* ask each NPE port to write back the database for aging inspection */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
&& ixEthDBPortInfo[portIndex].agingEnabled
&& ixEthDBPortInfo[portIndex].enabled)
{
IxNpeMhMessage message;
IX_STATUS result;
/* send EDB_GetMACAddressDatabase message */
FILL_GETMACADDRESSDATABASE(message,
0 /* unused */,
IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
if (result == IX_SUCCESS)
{
/* analyze NPE copy */
ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
}
else
{
ixEthDBPortInfo[portIndex].agingEnabled = false;
ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = false;
ixEthDBPortInfo[portIndex].updateMethod.userControlled = true;
ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDOUT,
"EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
portIndex, 0, 0, 0, 0, 0);
ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
}
}
}
/* browse database and age entries */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
UINT32 *age = NULL;
BOOL staticEntry = true;
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
age = &descriptor->recordData.filteringData.age;
staticEntry = descriptor->recordData.filteringData.staticEntry;
}
else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
age = &descriptor->recordData.filteringVlanData.age;
staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
}
else
{
staticEntry = true;
}
if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == false))
{
/* manually increment the age if the port has no such capability */
if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
{
*age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
}
/* age entry if it exceeded the maximum time to live */
if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
{
/* add port to the set of update trigger ports */
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
/* delete entry */
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
}
else
{
/* move to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
}
else
{
/* move to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
}
/* update ports which lost records */
ixEthDBUpdatePortLearningTrees(triggerPorts);
}
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
{
IxEthDBPortMap triggerPorts;
HashIterator iterator;
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
{
return IX_ETH_DB_INVALID_PORT;
}
/* check if the user passes some extra bits */
if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
{
return IX_ETH_DB_INVALID_ARG;
}
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
/* browse database and age entries */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
&& ((descriptor->type & recordType) != 0))
{
/* add to trigger if automatic updates are required */
if (ixEthDBPortUpdateRequired[descriptor->type])
{
/* add port to the set of update trigger ports */
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
}
/* delete entry */
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
}
else
{
/* move to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
}
/* update ports which lost records */
ixEthDBUpdatePortLearningTrees(triggerPorts);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
if (((MacDescriptor *) (searchResult->data))->portID == portID)
{
result = IX_ETH_DB_SUCCESS; /* address and port match */
}
ixEthDBReleaseHashNode(searchResult);
return result;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
IX_ETH_DB_CHECK_REFERENCE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
/* return the port ID */
*portID = ((MacDescriptor *) searchResult->data)->portID;
ixEthDBReleaseHashNode(searchResult);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
ixEthDBPortInfo[portID].agingEnabled = false;
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
ixEthDBPortInfo[portID].agingEnabled = true;
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
{
HashNode *searchResult;
MacDescriptor *descriptor;
IX_ETH_DB_CHECK_REFERENCE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
if (searchResult == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
descriptor = (MacDescriptor *) searchResult->data;
/* return the port ID */
*portID = descriptor->portID;
/* reset entry age */
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
descriptor->recordData.filteringData.age = 0;
}
else
{
descriptor->recordData.filteringVlanData.age = 0;
}
ixEthDBReleaseHashNode(searchResult);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
/* force bit at offset 255 to 0 (reserved) */
dependencyPortMap[31] &= 0xFE;
COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate;
ixEthDBPortInfo[portID].updateMethod.userControlled = true;
return IX_ETH_DB_SUCCESS;
}

View File

@ -1,651 +0,0 @@
/**
* @file IxEthDBAPISupport.c
*
* @brief Public API support functions
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include <IxEthDB.h>
#include <IxNpeMh.h>
#include <IxFeatureCtrl.h>
#include "IxEthDB_p.h"
#include "IxEthDBMessages_p.h"
#include "IxEthDB_p.h"
#include "IxEthDBLog_p.h"
#ifdef IX_UNIT_TEST
int dbAccessCounter = 0;
int overflowEvent = 0;
#endif
/*
* External declaration
*/
extern HashTable dbHashtable;
/*
* Internal declaration
*/
IX_ETH_DB_PUBLIC
PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
IX_ETH_DB_PRIVATE
struct
{
BOOL saved;
IxEthDBPriorityTable priorityTable;
IxEthDBVlanSet vlanMembership;
IxEthDBVlanSet transmitTaggingInfo;
IxEthDBFrameFilter frameFilter;
IxEthDBTaggingAction taggingAction;
IxEthDBFirewallMode firewallMode;
BOOL stpBlocked;
BOOL srcAddressFilterEnabled;
UINT32 maxRxFrameSize;
UINT32 maxTxFrameSize;
} ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS];
#define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518)
/**
* @brief initializes a port
*
* @param portID ID of the port to be initialized
*
* Note that redundant initializations are silently
* dealt with and do not constitute an error
*
* This function is fully documented in the main
* header file, IxEthDB.h
*/
IX_ETH_DB_PUBLIC
void ixEthDBPortInit(IxEthDBPortId portID)
{
PortInfo *portInfo;
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
{
return;
}
portInfo = &ixEthDBPortInfo[portID];
if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS)
{
WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID);
return;
}
if (portInfo->initialized)
{
/* redundant */
return;
}
/* initialize core fields */
portInfo->portID = portID;
SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID);
/* default values */
portInfo->agingEnabled = false;
portInfo->enabled = false;
portInfo->macAddressUploaded = false;
portInfo->maxRxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
portInfo->maxTxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
/* default update control values */
portInfo->updateMethod.searchTree = NULL;
portInfo->updateMethod.searchTreePendingWrite = false;
portInfo->updateMethod.treeInitialized = false;
portInfo->updateMethod.updateEnabled = false;
portInfo->updateMethod.userControlled = false;
/* default WiFi parameters */
memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid));
portInfo->frameControlDurationID = 0;
/* Ethernet NPE-specific initializations */
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
/* update handler */
portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler;
}
/* initialize state save */
ixEthDBPortState[portID].saved = false;
portInfo->initialized = true;
}
/**
* @brief enables a port
*
* @param portID ID of the port to enable
*
* This function is fully documented in the main
* header file, IxEthDB.h
*
* @return IX_ETH_DB_SUCCESS if enabling was
* accomplished, or a meaningful error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
{
IxEthDBPortMap triggerPorts;
PortInfo *portInfo;
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
portInfo = &ixEthDBPortInfo[portID];
if (portInfo->enabled)
{
/* redundant */
return IX_ETH_DB_SUCCESS;
}
SET_DEPENDENCY_MAP(triggerPorts, portID);
/* mark as enabled */
portInfo->enabled = true;
/* Operation stops here when Ethernet Learning is not enabled */
if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
{
return IX_ETH_DB_SUCCESS;
}
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded)
{
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID);
/* must use UnicastAddressSet() before enabling an NPE port */
return IX_ETH_DB_MAC_UNINITIALIZED;
}
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID);
if (!portInfo->updateMethod.userControlled
&& ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0))
{
portInfo->updateMethod.updateEnabled = true;
}
/* if this is first time initialization then we already have
write access to the tree and can AccessRelease directly */
if (!portInfo->updateMethod.treeInitialized)
{
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID);
/* create an initial tree and release access into it */
ixEthDBUpdatePortLearningTrees(triggerPorts);
/* mark tree as being initialized */
portInfo->updateMethod.treeInitialized = true;
}
}
if (ixEthDBPortState[portID].saved)
{
/* previous configuration data stored, restore state */
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
{
ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode);
ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled);
}
#if 0 /* test-only */
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
{
ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter);
ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction);
ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo);
ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership);
ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable);
}
#endif
if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
{
ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked);
}
ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize);
ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize);
/* discard previous save */
ixEthDBPortState[portID].saved = false;
}
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief disables a port
*
* @param portID ID of the port to disable
*
* This function is fully documented in the
* main header file, IxEthDB.h
*
* @return IX_ETH_DB_SUCCESS if disabling was
* successful or an appropriate error message
* otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
{
HashIterator iterator;
IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */
BOOL result;
PortInfo *portInfo;
IxEthDBFeature learningEnabled;
#if 0 /* test-only */
IxEthDBPriorityTable classZeroTable;
#endif
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
portInfo = &ixEthDBPortInfo[portID];
if (!portInfo->enabled)
{
/* redundant */
return IX_ETH_DB_SUCCESS;
}
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
/* save filtering state */
ixEthDBPortState[portID].firewallMode = portInfo->firewallMode;
ixEthDBPortState[portID].frameFilter = portInfo->frameFilter;
ixEthDBPortState[portID].taggingAction = portInfo->taggingAction;
ixEthDBPortState[portID].stpBlocked = portInfo->stpBlocked;
ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled;
ixEthDBPortState[portID].maxRxFrameSize = portInfo->maxRxFrameSize;
ixEthDBPortState[portID].maxTxFrameSize = portInfo->maxTxFrameSize;
memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet));
memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet));
memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable));
ixEthDBPortState[portID].saved = true;
/* now turn off all EthDB filtering features on the port */
#if 0 /* test-only */
/* VLAN & QoS */
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
{
ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, false);
ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH);
memset(classZeroTable, 0, sizeof (classZeroTable));
ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable);
}
#endif
/* STP */
if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
{
ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, false);
}
/* Firewall */
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
{
ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
ixEthDBFirewallTableDownload((IxEthDBPortId) portID);
ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, false);
}
/* Frame size filter */
ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE);
/* WiFi */
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
{
ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID);
}
/* save and disable the learning feature bit */
learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
portInfo->featureStatus &= ~IX_ETH_DB_LEARNING;
}
else
{
/* save the learning feature bit */
learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
}
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
ixEthDBUpdateLock();
/* wipe out current entries for this port */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
/* check if the port match. If so, remove the entry */
if (descriptor->portID == portID
&& (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
&& !descriptor->recordData.filteringData.staticEntry)
{
/* delete entry */
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
/* add port to the set of update trigger ports */
JOIN_PORT_TO_MAP(triggerPorts, portID);
}
else
{
/* move to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
}
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
if (portInfo->updateMethod.searchTree != NULL)
{
ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree);
portInfo->updateMethod.searchTree = NULL;
}
ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD);
}
/* mark as disabled */
portInfo->enabled = false;
/* disable updates unless the user has specifically altered the default behavior */
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
if (!portInfo->updateMethod.userControlled)
{
portInfo->updateMethod.updateEnabled = false;
}
/* make sure we re-initialize the NPE learning tree when the port is re-enabled */
portInfo->updateMethod.treeInitialized = false;
}
ixEthDBUpdateUnlock();
/* restore learning feature bit */
portInfo->featureStatus |= learningEnabled;
/* if we've removed any records or lost any events make sure to force an update */
IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts);
if (!result)
{
ixEthDBUpdatePortLearningTrees(triggerPorts);
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief sends the updated maximum Tx/Rx frame lengths to the NPE
*
* @param portID ID of the port to update
*
* @return IX_ETH_DB_SUCCESS if the update completed
* successfully or an appropriate error message otherwise
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID)
{
IxNpeMhMessage message;
PortInfo *portInfo = &ixEthDBPortInfo[portID];
IX_STATUS result;
FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize);
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief sets the port maximum Rx frame size
*
* @param portID ID of the port to set the frame size on
* @param maximumRxFrameSize maximum Rx frame size
*
* This function updates the internal data structures and
* calls ixEthDBPortFrameLengthsUpdate() for NPE update.
*
* This function is fully documented in the main header
* file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation was
* successfull or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
if (!ixEthDBPortInfo[portID].initialized)
{
return IX_ETH_DB_PORT_UNINITIALIZED;
}
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
(maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
{
return IX_ETH_DB_INVALID_ARG;
}
}
else
{
return IX_ETH_DB_NO_PERMISSION;
}
/* update internal structure */
ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize;
/* update the maximum frame size in the NPE */
return ixEthDBPortFrameLengthsUpdate(portID);
}
/**
* @brief sets the port maximum Tx frame size
*
* @param portID ID of the port to set the frame size on
* @param maximumTxFrameSize maximum Tx frame size
*
* This function updates the internal data structures and
* calls ixEthDBPortFrameLengthsUpdate() for NPE update.
*
* This function is fully documented in the main header
* file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation was
* successfull or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
if (!ixEthDBPortInfo[portID].initialized)
{
return IX_ETH_DB_PORT_UNINITIALIZED;
}
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
(maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
{
return IX_ETH_DB_INVALID_ARG;
}
}
else
{
return IX_ETH_DB_NO_PERMISSION;
}
/* update internal structure */
ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize;
/* update the maximum frame size in the NPE */
return ixEthDBPortFrameLengthsUpdate(portID);
}
/**
* @brief sets the port maximum Tx and Rx frame sizes
*
* @param portID ID of the port to set the frame size on
* @param maximumFrameSize maximum Tx and Rx frame sizes
*
* This function updates the internal data structures and
* calls ixEthDBPortFrameLengthsUpdate() for NPE update.
*
* Note that both the maximum Tx and Rx frame size are set
* to the same value. This function is kept for compatibility
* reasons.
*
* This function is fully documented in the main header
* file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation was
* successfull or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
if (!ixEthDBPortInfo[portID].initialized)
{
return IX_ETH_DB_PORT_UNINITIALIZED;
}
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
(maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
{
return IX_ETH_DB_INVALID_ARG;
}
}
else
{
return IX_ETH_DB_NO_PERMISSION;
}
/* update internal structure */
ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize;
ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize;
/* update the maximum frame size in the NPE */
return ixEthDBPortFrameLengthsUpdate(portID);
}
/**
* @brief sets the MAC address of an NPE port
*
* @param portID port ID to set the MAC address on
* @param macAddr pointer to the 6-byte MAC address
*
* This function is called by the EthAcc
* ixEthAccUnicastMacAddressSet() and should not be
* manually invoked unless required by special circumstances.
*
* @return IX_ETH_DB_SUCCESS if the operation succeeded
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
IxNpeMhMessage message;
IX_STATUS result;
/* use this macro instead CHECK_PORT
as the port doesn't need to be enabled */
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
if (!ixEthDBPortInfo[portID].initialized)
{
return IX_ETH_DB_PORT_UNINITIALIZED;
}
/* Operation stops here when Ethernet Learning is not enabled */
if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
{
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
/* exit if the port is not an Ethernet NPE */
if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
{
return IX_ETH_DB_INVALID_PORT;
}
/* populate message */
FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
/* send a SetPortAddress message */
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
if (result == IX_SUCCESS)
{
ixEthDBPortInfo[portID].macAddressUploaded = true;
}
return result;
}

View File

@ -1,439 +0,0 @@
/**
* @file IxEthDBDBCore.c
*
* @brief Database support functions
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/* list of database hashtables */
IX_ETH_DB_PUBLIC HashTable dbHashtable;
IX_ETH_DB_PUBLIC MatchFunction matchFunctions[IX_ETH_DB_MAX_KEY_INDEX + 1];
IX_ETH_DB_PUBLIC BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyType[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
/* private initialization flag */
IX_ETH_DB_PRIVATE BOOL ethDBInitializationComplete = false;
/**
* @brief initializes EthDB
*
* This function must be called to initialize the component.
*
* It does the following things:
* - checks the port definition structure
* - scans the capabilities of the NPE images and sets the
* capabilities of the ports accordingly
* - initializes the memory pools internally used in EthDB
* for storing database records and handling data
* - registers automatic update handlers for add and remove
* operations
* - registers hashing match functions, depending on key sets
* - initializes the main database hashtable
* - allocates contiguous memory zones to be used for NPE
* updates
* - registers the serialize methods used to convert data
* into NPE-readable format
* - starts the event processor
*
* Note that this function is documented in the public
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS or an appropriate error if the
* component failed to initialize correctly
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBInit(void)
{
IxEthDBStatus result;
if (ethDBInitializationComplete)
{
/* redundant */
return IX_ETH_DB_SUCCESS;
}
/* trap an invalid port definition structure */
IX_ETH_DB_PORTS_ASSERTION;
/* memory management */
ixEthDBInitMemoryPools();
/* register hashing search methods */
ixEthDBMatchMethodsRegister(matchFunctions);
/* register type-based automatic port updates */
ixEthDBUpdateTypeRegister(ixEthDBPortUpdateRequired);
/* register record to key type mappings */
ixEthDBKeyTypeRegister(ixEthDBKeyType);
/* hash table */
ixEthDBInitHash(&dbHashtable, NUM_BUCKETS, ixEthDBEntryXORHash, matchFunctions, (FreeFunction) ixEthDBFreeMacDescriptor);
/* NPE update zones */
ixEthDBNPEUpdateAreasInit();
/* register record serialization methods */
ixEthDBRecordSerializeMethodsRegister();
/* start the event processor */
result = ixEthDBEventProcessorInit();
/* scan NPE features */
if (result == IX_ETH_DB_SUCCESS)
{
ixEthDBFeatureCapabilityScan();
}
ethDBInitializationComplete = true;
return result;
}
/**
* @brief prepares EthDB for unloading
*
* This function must be called before removing the
* EthDB component from memory (e.g. doing rmmod in
* Linux) if the component is to be re-initialized again
* without rebooting the platform.
*
* All the EthDB ports must be disabled before this
* function is to be called. Failure to disable all
* the ports will return the IX_ETH_DB_BUSY error.
*
* This function will destroy mutexes, deallocate
* memory and stop the event processor.
*
* Note that this function is fully documented in the
* main component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if de-initialization
* completed successfully or an appropriate error
* message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUnload(void)
{
IxEthDBPortId portIndex;
if (!ethDBInitializationComplete)
{
/* redundant */
return IX_ETH_DB_SUCCESS;
}
/* check if any ports are enabled */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortInfo[portIndex].enabled)
{
return IX_ETH_DB_BUSY;
}
}
/* free port resources */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
{
ixOsalMutexDestroy(&ixEthDBPortInfo[portIndex].npeAckLock);
}
ixEthDBPortInfo[portIndex].initialized = false;
}
/* shutdown event processor */
ixEthDBStopLearningFunction();
/* deallocate NPE update zones */
ixEthDBNPEUpdateAreasUnload();
ethDBInitializationComplete = false;
return IX_ETH_DB_SUCCESS;
}
/**
* @brief adds a new entry to the Ethernet database
*
* @param newRecordTemplate address of the record template to use
* @param updateTrigger port map containing the update triggers
* resulting from this update operation
*
* Creates a new database entry, populates it with the data
* copied from the given template and adds the record to the
* database hash table.
* It also checks whether the new record type is registered to trigger
* automatic updates; if it is, the update trigger will contain the
* port on which the record insertion was performed, as well as the
* old port in case the addition was a record migration (from one port
* to the other). The caller can use the updateTrigger to trigger
* automatic updates on the ports changed as a result of this addition.
*
* @retval IX_ETH_DB_SUCCESS addition successful
* @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool
* @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger)
{
IxEthDBStatus result;
MacDescriptor *newDescriptor;
IxEthDBPortId originalPortID;
HashNode *node = NULL;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node));
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
if (node == NULL)
{
/* not found, create a new one */
newDescriptor = ixEthDBAllocMacDescriptor();
if (newDescriptor == NULL)
{
return IX_ETH_DB_NOMEM; /* no memory */
}
/* old port does not exist, avoid unnecessary updates */
originalPortID = newRecordTemplate->portID;
}
else
{
/* a node with the same key exists, will update node */
newDescriptor = (MacDescriptor *) node->data;
/* save original port id */
originalPortID = newDescriptor->portID;
}
/* copy/update fields into new record */
memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr));
memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData));
newDescriptor->type = newRecordTemplate->type;
newDescriptor->portID = newRecordTemplate->portID;
newDescriptor->user = newRecordTemplate->user;
if (node == NULL)
{
/* new record, insert into hashtable */
BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result);
if (result != IX_ETH_DB_SUCCESS)
{
ixEthDBFreeMacDescriptor(newDescriptor);
return result; /* insertion failed */
}
}
if (node != NULL)
{
/* release access */
ixEthDBReleaseHashNode(node);
}
/* trigger add/remove update if required by type */
if (updateTrigger != NULL &&
ixEthDBPortUpdateRequired[newRecordTemplate->type])
{
/* add new port to update list */
JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID);
/* check if record has moved, we'll need to update the old port as well */
if (originalPortID != newDescriptor->portID)
{
JOIN_PORT_TO_MAP(updateTrigger, originalPortID);
}
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief remove a record from the Ethernet database
*
* @param templateRecord template record used to determine
* what record is to be removed
* @param updateTrigger port map containing the update triggers
* resulting from this update operation
*
* This function will examine the template record it receives
* and attempts to delete a record of the same type and containing
* the same keys as the template record. If deletion is successful
* and the record type is registered for automatic port updates the
* port will also be set in the updateTrigger port map, so that the
* client can perform an update of the port.
*
* @retval IX_ETH_DB_SUCCESS removal was successful
* @retval IX_ETH_DB_NO_SUCH_ADDR the record with the given MAC address was not found
* @retval IX_ETH_DB_BUSY database busy, cannot remove due to locking
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger)
{
IxEthDBStatus result;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
BUSY_RETRY_WITH_RESULT(ixEthDBRemoveHashEntry(&dbHashtable, ixEthDBKeyType[templateRecord->type], templateRecord), result);
if (result != IX_ETH_DB_SUCCESS)
{
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
}
/* trigger add/remove update if required by type */
if (updateTrigger != NULL
&&ixEthDBPortUpdateRequired[templateRecord->type])
{
/* add new port to update list */
JOIN_PORT_TO_MAP(updateTrigger, templateRecord->portID);
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief register record key types
*
* This function registers the appropriate key types,
* depending on record types.
*
* All filtering records use the MAC address as the key.
* WiFi and Firewall records use a compound key consisting
* in both the MAC address and the port ID.
*
* @return the number of registered record types
*/
IX_ETH_DB_PUBLIC
UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType)
{
/* safety */
memset(keyType, 0, sizeof (keyType));
/* register all known record types */
keyType[IX_ETH_DB_FILTERING_RECORD] = IX_ETH_DB_MAC_KEY;
keyType[IX_ETH_DB_FILTERING_VLAN_RECORD] = IX_ETH_DB_MAC_KEY;
keyType[IX_ETH_DB_ALL_FILTERING_RECORDS] = IX_ETH_DB_MAC_KEY;
keyType[IX_ETH_DB_WIFI_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
keyType[IX_ETH_DB_FIREWALL_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
return 5;
}
/**
* @brief Sets a user-defined field into a database record
*
* Note that this function is fully documented in the main component
* header file.
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field)
{
HashNode *result = NULL;
if (macAddr == NULL)
{
return IX_ETH_DB_INVALID_ARG;
}
if (recordType == IX_ETH_DB_FILTERING_RECORD)
{
result = ixEthDBSearch(macAddr, recordType);
}
else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
}
else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
result = ixEthDBPortSearch(macAddr, portID, recordType);
}
else
{
return IX_ETH_DB_INVALID_ARG;
}
if (result == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR;
}
((MacDescriptor *) result->data)->user = field;
ixEthDBReleaseHashNode(result);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief Retrieves a user-defined field from a database record
*
* Note that this function is fully documented in the main component
* header file.
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field)
{
HashNode *result = NULL;
if (macAddr == NULL || field == NULL)
{
return IX_ETH_DB_INVALID_ARG;
}
if (recordType == IX_ETH_DB_FILTERING_RECORD)
{
result = ixEthDBSearch(macAddr, recordType);
}
else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
}
else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
result = ixEthDBPortSearch(macAddr, portID, recordType);
}
else
{
return IX_ETH_DB_INVALID_ARG;
}
if (result == NULL)
{
return IX_ETH_DB_NO_SUCH_ADDR;
}
*field = ((MacDescriptor *) result->data)->user;
ixEthDBReleaseHashNode(result);
return IX_ETH_DB_SUCCESS;
}

View File

@ -1,496 +0,0 @@
/**
* @file IxEthDBEvents.c
*
* @brief Implementation of the event processor component
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include <IxNpeMh.h>
#include <IxFeatureCtrl.h>
#include "IxEthDB_p.h"
/* forward prototype declarations */
IX_ETH_DB_PUBLIC void ixEthDBEventProcessorLoop(void *);
IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
IX_ETH_DB_PRIVATE void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts);
IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
/* data */
IX_ETH_DB_PRIVATE IxOsalSemaphore eventQueueSemaphore;
IX_ETH_DB_PRIVATE PortEventQueue eventQueue;
IX_ETH_DB_PRIVATE IxOsalMutex eventQueueLock;
IX_ETH_DB_PRIVATE IxOsalMutex portUpdateLock;
IX_ETH_DB_PRIVATE BOOL ixEthDBLearningShutdown = false;
IX_ETH_DB_PRIVATE BOOL ixEthDBEventProcessorRunning = false;
/* imported data */
extern HashTable dbHashtable;
/**
* @brief initializes the event processor
*
* Initializes the event processor queue and processing thread.
* Called from ixEthDBInit() DB-subcomponent master init function.
*
* @warning do not call directly
*
* @retval IX_ETH_DB_SUCCESS initialization was successful
* @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure)
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBEventProcessorInit(void)
{
if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
{
/* start processor loop thread */
if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief initializes the event queue and the event processor
*
* This function is called by the component initialization
* function, ixEthDBInit().
*
* @warning do not call directly
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBStartLearningFunction(void)
{
IxOsalThread eventProcessorThread;
IxOsalThreadAttr threadAttr;
threadAttr.name = "EthDB event thread";
threadAttr.stackSize = 32 * 1024; /* 32kbytes */
threadAttr.priority = 128;
/* reset event queue */
ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
RESET_QUEUE(&eventQueue);
ixOsalMutexUnlock(&eventQueueLock);
/* init event queue semaphore */
if (ixOsalSemaphoreInit(&eventQueueSemaphore, 0) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
ixEthDBLearningShutdown = false;
/* create processor loop thread */
if (ixOsalThreadCreate(&eventProcessorThread, &threadAttr, ixEthDBEventProcessorLoop, NULL) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
/* start event processor */
ixOsalThreadStart(&eventProcessorThread);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief stops the event processor
*
* Stops the event processor and frees the event queue semaphore
* Called by the component de-initialization function, ixEthDBUnload()
*
* @warning do not call directly
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise;
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBStopLearningFunction(void)
{
ixEthDBLearningShutdown = true;
/* wake up event processing loop to actually process the shutdown event */
ixOsalSemaphorePost(&eventQueueSemaphore);
if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS)
{
return IX_ETH_DB_FAIL;
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief default NPE event processing callback
*
* @param npeID ID of the NPE that generated the event
* @param msg NPE message (encapsulated event)
*
* Creates an event object on the Ethernet event processor queue
* and signals the new event by incrementing the event queue semaphore.
* Events are processed by @ref ixEthDBEventProcessorLoop() which runs
* at user level.
*
* @see ixEthDBEventProcessorLoop()
*
* @warning do not call directly
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
{
PortEvent *local_event;
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETH_DB_NPE_TO_PORT_ID(npeID), NPE_MSG_ID(msg), 0, 0, 0, 0);
if (CAN_ENQUEUE(&eventQueue))
{
TEST_FIXTURE_LOCK_EVENT_QUEUE;
local_event = QUEUE_HEAD(&eventQueue);
/* create event structure on queue */
local_event->eventType = NPE_MSG_ID(msg);
local_event->portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
/* update queue */
PUSH_UPDATE_QUEUE(&eventQueue);
TEST_FIXTURE_UNLOCK_EVENT_QUEUE;
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0);
/* increment event queue semaphore */
ixOsalSemaphorePost(&eventQueueSemaphore);
}
else
{
IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0);
}
}
/**
* @brief Ethernet event processor loop
*
* Extracts at most EVENT_PROCESSING_LIMIT batches of events and
* sends them for processing to @ref ixEthDBProcessEvent().
* Triggers port updates which normally follow learning events.
*
* @warning do not call directly, executes in separate thread
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBEventProcessorLoop(void *unused1)
{
IxEthDBPortMap triggerPorts;
IxEthDBPortId portIndex;
ixEthDBEventProcessorRunning = true;
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n");
while (!ixEthDBLearningShutdown)
{
BOOL keepProcessing = true;
UINT32 processedEvents = 0;
IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n");
ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER);
IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n");
if (!ixEthDBLearningShutdown)
{
/* port update handling */
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
while (keepProcessing)
{
PortEvent local_event;
UINT32 intLockKey;
/* lock queue */
ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
/* lock NPE interrupts */
intLockKey = ixOsalIrqLock();
/* extract event */
local_event = *(QUEUE_TAIL(&eventQueue));
SHIFT_UPDATE_QUEUE(&eventQueue);
ixOsalIrqUnlock(intLockKey);
ixOsalMutexUnlock(&eventQueueLock);
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType);
ixEthDBProcessEvent(&local_event, triggerPorts);
processedEvents++;
if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */
|| ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */
{
keepProcessing = false;
}
}
ixEthDBUpdatePortLearningTrees(triggerPorts);
}
}
/* turn off automatic updates */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = false;
}
ixEthDBEventProcessorRunning = false;
}
/**
* @brief event processor routine
*
* @param event event to be processed
* @param triggerPorts port map accumulating ports to be updated
*
* Processes learning events by synchronizing the database with
* newly learnt data. Called only by @ref ixEthDBEventProcessorLoop().
*
* @warning do not call directly
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts)
{
MacDescriptor recordTemplate;
switch (local_event->eventType)
{
case IX_ETH_DB_ADD_FILTERING_RECORD:
/* add record */
memset(&recordTemplate, 0, sizeof (recordTemplate));
memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FILTERING_RECORD;
recordTemplate.portID = local_event->portID;
recordTemplate.recordData.filteringData.staticEntry = local_event->staticEntry;
ixEthDBAdd(&recordTemplate, triggerPorts);
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Added record on port %d\n", local_event->portID);
break;
case IX_ETH_DB_REMOVE_FILTERING_RECORD:
/* remove record */
memset(&recordTemplate, 0, sizeof (recordTemplate));
memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD;
ixEthDBRemove(&recordTemplate, triggerPorts);
IX_ETH_DB_EVENTS_TRACE("DB: (Events) Removed record on port %d\n", local_event->portID);
break;
default:
/* can't handle/not interested in this event type */
ERROR_LOG("DB: (Events) Event processor received an unknown event type (0x%X)\n", local_event->eventType);
return;
}
}
/**
* @brief asynchronously adds a filtering record
* by posting an ADD_FILTERING_RECORD event to the event queue
*
* @param macAddr MAC address of the new record
* @param portID port ID of the new record
* @param staticEntry true if record is static, false if dynamic
*
* @return IX_ETH_DB_SUCCESS if the event creation was
* successfull or IX_ETH_DB_BUSY if the event queue is full
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
{
MacDescriptor reference;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
/* fill search fields */
memcpy(reference.macAddress, macAddr, sizeof (IxEthDBMacAddr));
reference.portID = portID;
/* set acceptable record types */
reference.type = IX_ETH_DB_ALL_FILTERING_RECORDS;
if (ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference) == IX_ETH_DB_SUCCESS)
{
/* already have an identical record */
return IX_ETH_DB_SUCCESS;
}
else
{
return ixEthDBTriggerPortUpdate(IX_ETH_DB_ADD_FILTERING_RECORD, macAddr, portID, staticEntry);
}
}
/**
* @brief asynchronously removes a filtering record
* by posting a REMOVE_FILTERING_RECORD event to the event queue
*
* @param macAddr MAC address of the record to remove
* @param portID port ID of the record to remove
*
* @return IX_ETH_DB_SUCCESS if the event creation was
* successfull or IX_ETH_DB_BUSY if the event queue is full
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID)
{
if (ixEthDBPeek(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS) != IX_ETH_DB_NO_SUCH_ADDR)
{
return ixEthDBTriggerPortUpdate(IX_ETH_DB_REMOVE_FILTERING_RECORD, macAddr, portID, false);
}
else
{
return IX_ETH_DB_NO_SUCH_ADDR;
}
}
/**
* @brief adds an ADD or REMOVE event to the main event queue
*
* @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD
* to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a
* record.
*
* @return IX_ETH_DB_SUCCESS if the event was successfully
* sent or IX_ETH_DB_BUSY if the event queue is full
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
{
UINT32 intLockKey;
/* lock interrupts to protect queue */
intLockKey = ixOsalIrqLock();
if (CAN_ENQUEUE(&eventQueue))
{
PortEvent *queueEvent = QUEUE_HEAD(&eventQueue);
/* update fields on the queue */
memcpy(queueEvent->macAddr.macAddress, macAddr->macAddress, sizeof (IxEthDBMacAddr));
queueEvent->eventType = eventType;
queueEvent->portID = portID;
queueEvent->staticEntry = staticEntry;
PUSH_UPDATE_QUEUE(&eventQueue);
/* imcrement event queue semaphore */
ixOsalSemaphorePost(&eventQueueSemaphore);
/* unlock interrupts */
ixOsalIrqUnlock(intLockKey);
return IX_ETH_DB_SUCCESS;
}
else /* event queue full */
{
/* unlock interrupts */
ixOsalIrqUnlock(intLockKey);
return IX_ETH_DB_BUSY;
}
}
/**
* @brief Locks learning tree updates and port disable
*
*
* This function locks portUpdateLock single mutex. It is primarily used
* to avoid executing 'port disable' during ELT maintenance.
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBUpdateLock(void)
{
ixOsalMutexLock(&portUpdateLock, IX_OSAL_WAIT_FOREVER);
}
/**
* @brief Unlocks learning tree updates and port disable
*
*
* This function unlocks a portUpdateLock mutex. It is primarily used
* to avoid executing 'port disable' during ELT maintenance.
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBUpdateUnlock(void)
{
ixOsalMutexUnlock(&portUpdateLock);
}

View File

@ -1,638 +0,0 @@
/**
* @file IxEthDBFeatures.c
*
* @brief Implementation of the EthDB feature control API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxNpeDl.h"
#include "IxEthDBQoS.h"
#include "IxEthDB_p.h"
/**
* @brief scans the capabilities of the loaded NPE images
*
* This function MUST be called by the ixEthDBInit() function.
* No EthDB features (including learning and filtering) are enabled
* before this function is called.
*
* @return none
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFeatureCapabilityScan(void)
{
IxNpeDlImageId imageId, npeAImageId;
IxEthDBPortId portIndex;
PortInfo *portInfo;
IxEthDBPriorityTable defaultPriorityTable;
IX_STATUS result;
UINT32 queueIndex;
UINT32 queueStructureIndex;
UINT32 trafficClassDefinitionIndex;
/* read version of NPE A - required to set the AQM queues for B and C */
npeAImageId.functionalityId = 0;
ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId);
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
IxNpeMhMessage msg;
portInfo = &ixEthDBPortInfo[portIndex];
/* check and bypass if NPE B or C is fused out */
if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue;
/* all ports are capable of LEARNING by default */
portInfo->featureCapability |= IX_ETH_DB_LEARNING;
portInfo->featureStatus |= IX_ETH_DB_LEARNING;
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
{
if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS)
{
WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex);
}
else
{
/* initialize and empty NPE response mutex */
ixOsalMutexInit(&portInfo->npeAckLock);
ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER);
/* check NPE response to GetStatus */
msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24;
msg.data[1] = 0;
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result);
if (result != IX_SUCCESS)
{
WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n");
continue;
}
if (imageId.functionalityId == 0x00
|| imageId.functionalityId == 0x03
|| imageId.functionalityId == 0x04
|| imageId.functionalityId == 0x80)
{
portInfo->featureCapability |= IX_ETH_DB_FILTERING;
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
}
else if (imageId.functionalityId == 0x01
|| imageId.functionalityId == 0x81)
{
portInfo->featureCapability |= IX_ETH_DB_FILTERING;
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
}
else if (imageId.functionalityId == 0x02
|| imageId.functionalityId == 0x82)
{
portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION;
portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
}
/* reset AQM queues */
memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments));
/* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */
IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h");
/* find the traffic class definition index compatible with the current NPE A functionality ID */
for (trafficClassDefinitionIndex = 0 ;
trafficClassDefinitionIndex < ARRAY_SIZE(ixEthDBTrafficClassDefinitions);
trafficClassDefinitionIndex++)
{
if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId)
{
/* found it */
break;
}
}
/* select the default case if we went over the array boundary */
if (trafficClassDefinitionIndex == ARRAY_SIZE(ixEthDBTrafficClassDefinitions))
{
trafficClassDefinitionIndex = 0; /* the first record is the default case */
}
/* select queue assignment structure based on the traffic class configuration index */
queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX];
/* only traffic class 0 is active at initialization time */
portInfo->ixEthDBTrafficClassCount = 1;
/* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */
portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS;
portInfo->featureStatus |= IX_ETH_DB_FIREWALL;
portInfo->enabled = true;
#define CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
/* set VLAN initial configuration (permissive) */
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */
{
/* QoS capable */
portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX];
/* set AQM queues */
for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
{
portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex];
}
/* set default PVID (0) and default traffic class 0 */
ixEthDBPortVlanTagSet(portIndex, 0);
/* enable reception of all frames */
ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES);
/* clear full VLAN membership */
ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
/* clear TTI table - no VLAN tagged frames will be transmitted */
ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, false);
/* set membership on 0, otherwise no Tx or Rx is working */
ixEthDBPortVlanMembershipAdd(portIndex, 0);
}
else /* QoS not available in this image */
#endif /* test-only */
{
/* initialize traffic class availability (only class 0 is available) */
portInfo->ixEthDBTrafficClassAvailable = 1;
/* point all AQM queues to traffic class 0 */
for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
{
portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] =
ixEthDBQueueAssignments[queueStructureIndex][0];
}
}
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
/* download priority mapping table and Rx queue configuration */
memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable);
#endif
/* by default we turn off invalid source MAC address filtering */
ixEthDBFirewallInvalidAddressFilterEnable(portIndex, false);
/* disable port, VLAN, Firewall feature bits */
portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS;
portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL;
portInfo->enabled = false;
/* enable filtering by default if present */
if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)
{
portInfo->featureStatus |= IX_ETH_DB_FILTERING;
}
}
}
}
}
/**
* @brief returns the capability of a port
*
* @param portID ID of the port
* @param featureSet location to store the port capability in
*
* This function will save the capability set of the given port
* into the given location. Capabilities are bit-ORed, each representing
* a bit of the feature set.
*
* Note that this function is documented in the main component
* public header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or IX_ETH_DB_INVALID_PORT if the given port is invalid
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
{
IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
IX_ETH_DB_CHECK_REFERENCE(featureSet);
*featureSet = ixEthDBPortInfo[portID].featureCapability;
return IX_ETH_DB_SUCCESS;
}
/**
* @brief enables or disables a port capability
*
* @param portID ID of the port
* @param feature feature to enable or disable
* @param enabled true to enable the selected feature or false to disable it
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable)
{
PortInfo *portInfo;
IxEthDBPriorityTable defaultPriorityTable;
IxEthDBVlanSet vlanSet;
IxEthDBStatus status = IX_ETH_DB_SUCCESS;
BOOL portEnabled;
IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
portInfo = &ixEthDBPortInfo[portID];
portEnabled = portInfo->enabled;
/* check that only one feature is selected */
if (!ixEthDBCheckSingleBitValue(feature))
{
return IX_ETH_DB_FEATURE_UNAVAILABLE;
}
/* port capable of this feature? */
if ((portInfo->featureCapability & feature) == 0)
{
return IX_ETH_DB_FEATURE_UNAVAILABLE;
}
/* mutual exclusion between learning and WiFi header conversion */
if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
== (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
{
return IX_ETH_DB_NO_PERMISSION;
}
/* learning must be enabled before filtering */
if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0))
{
return IX_ETH_DB_NO_PERMISSION;
}
/* filtering must be disabled before learning */
if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0))
{
return IX_ETH_DB_NO_PERMISSION;
}
/* redundant enabling or disabling */
if ((!enable && ((portInfo->featureStatus & feature) == 0))
|| (enable && ((portInfo->featureStatus & feature) != 0)))
{
/* do nothing */
return IX_ETH_DB_SUCCESS;
}
/* force port enabled */
portInfo->enabled = true;
if (enable)
{
/* turn on enable bit */
portInfo->featureStatus |= feature;
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
/* if this is VLAN/QoS set the default priority table */
if (feature == IX_ETH_DB_VLAN_QOS)
{
/* turn on VLAN/QoS (most permissive mode):
- set default 802.1Q priority mapping table, in accordance to the
availability of traffic classes
- set the acceptable frame filter to accept all
- set the Ingress tagging mode to pass-through
- set full VLAN membership list
- set full TTI table
- set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
- enable TPID port extraction
*/
portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable;
/* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */
memcpy (defaultPriorityTable,
(const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1],
sizeof (defaultPriorityTable));
/* update priority mapping and AQM queue assignments */
status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
}
/* set membership and TTI tables */
memset (vlanSet, 0xFF, sizeof (vlanSet));
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
}
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
}
/* reset the PVID */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBPortVlanTagSet(portID, 0);
}
/* enable TPID port extraction */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBVlanPortExtractionEnable(portID, true);
}
}
else if (feature == IX_ETH_DB_FIREWALL)
#endif
{
/* firewall starts in black-list mode unless otherwise configured before *
* note that invalid source MAC address filtering is disabled by default */
if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST
&& portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST)
{
status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallInvalidAddressFilterEnable(portID, false);
}
}
}
if (status != IX_ETH_DB_SUCCESS)
{
/* checks failed, disable */
portInfo->featureStatus &= ~feature;
}
}
else
{
/* turn off features */
if (feature == IX_ETH_DB_FIREWALL)
{
/* turning off the firewall is equivalent to:
- set to black-list mode
- clear all the entries and download the new table
- turn off the invalid source address checking
*/
status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallInvalidAddressFilterEnable(portID, false);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBFirewallTableDownload(portID);
}
}
else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION)
{
/* turn off header conversion */
status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBWiFiConversionTableDownload(portID);
}
}
#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
else if (feature == IX_ETH_DB_VLAN_QOS)
{
/* turn off VLAN/QoS:
- set a priority mapping table with one traffic class
- set the acceptable frame filter to accept all
- set the Ingress tagging mode to pass-through
- clear the VLAN membership list
- clear the TTI table
- set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
- disable TPID port extraction
*/
/* initialize all => traffic class 0 priority mapping table */
memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
portInfo->ixEthDBTrafficClassCount = 1;
status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
}
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
}
/* clear membership and TTI tables */
memset (vlanSet, 0, sizeof (vlanSet));
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
}
if (status == IX_ETH_DB_SUCCESS)
{
/* use the internal function to bypass PVID check */
status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
}
/* reset the PVID */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBPortVlanTagSet(portID, 0);
}
/* disable TPID port extraction */
if (status == IX_ETH_DB_SUCCESS)
{
status = ixEthDBVlanPortExtractionEnable(portID, false);
}
}
#endif
if (status == IX_ETH_DB_SUCCESS)
{
/* checks passed, disable */
portInfo->featureStatus &= ~feature;
}
}
/* restore port enabled state */
portInfo->enabled = portEnabled;
return status;
}
/**
* @brief returns the status of a feature
*
* @param portID port ID
* @param present location to store a boolean value indicating
* if the feature is present (true) or not (false)
* @param enabled location to store a booleam value indicating
* if the feature is present (true) or not (false)
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
{
PortInfo *portInfo;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_REFERENCE(present);
IX_ETH_DB_CHECK_REFERENCE(enabled);
portInfo = &ixEthDBPortInfo[portID];
*present = (portInfo->featureCapability & feature) != 0;
*enabled = (portInfo->featureStatus & feature) != 0;
return IX_ETH_DB_SUCCESS;
}
/**
* @brief returns the value of an EthDB property
*
* @param portID ID of the port
* @param feature feature owning the property
* @param property ID of the property
* @param type location to store the property type into
* @param value location to store the property value into
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
IX_ETH_DB_CHECK_REFERENCE(type);
IX_ETH_DB_CHECK_REFERENCE(value);
if (feature == IX_ETH_DB_VLAN_QOS)
{
if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY)
{
* (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
*type = IX_ETH_DB_INTEGER_PROPERTY;
return IX_ETH_DB_SUCCESS;
}
else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
&& property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY)
{
UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
{
return IX_ETH_DB_FAIL;
}
* (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta];
*type = IX_ETH_DB_INTEGER_PROPERTY;
return IX_ETH_DB_SUCCESS;
}
}
return IX_ETH_DB_INVALID_ARG;
}
/**
* @brief sets the value of an EthDB property
*
* @param portID ID of the port
* @param feature feature owning the property
* @param property ID of the property
* @param value location containing the property value
*
* This function implements a private property intended
* only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
* property (the value is ignored), the availability of traffic classes is
* frozen to whatever traffic class structure is currently in use.
* This means that if VLAN_QOS has been enabled before EthAcc
* initialization then all the defined traffic classes will be available;
* otherwise only one traffic class (0) will be available.
*
* Note that this function is documented in the main component
* header file, IxEthDB.h as not accepting any parameters. The
* current implementation is only intended for the private use of EthAcc.
*
* Also note that once this function is called the effect is irreversible,
* unless EthDB is complete unloaded and re-initialized.
*
* @return IX_ETH_DB_INVALID_ARG (no read-write properties are
* supported in this release)
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
{
IX_ETH_DB_CHECK_PORT_EXISTS(portID);
if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE))
{
ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
return IX_ETH_DB_SUCCESS;
}
return IX_ETH_DB_INVALID_ARG;
}

View File

@ -1,242 +0,0 @@
/**
* @file IxEthDBFirewall.c
*
* @brief Implementation of the firewall API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/**
* @brief updates the NPE firewall operating mode and
* firewall address table
*
* @param portID ID of the port
* @param epDelta initial entry point for binary searches (NPE optimization)
* @param address address of the firewall MAC address table
*
* This function will send a message to the NPE configuring the
* firewall mode (white list or black list), invalid source
* address filtering and downloading a new MAC address database
* to be used for firewall matching.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta)
{
IxNpeMhMessage message;
IX_STATUS result;
UINT32 mode = 0;
PortInfo *portInfo = &ixEthDBPortInfo[portID];
mode = (portInfo->srcAddressFilterEnabled != false) << 1 | (portInfo->firewallMode == IX_ETH_DB_FIREWALL_WHITE_LIST);
FILL_SETFIREWALLMODE_MSG(message,
IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
epDelta,
mode,
IX_OSAL_MMU_VIRT_TO_PHYS(address));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief configures the firewall white list/black list
* access mode
*
* @param portID ID of the port
* @param mode firewall filtering mode (IX_ETH_DB_FIREWALL_WHITE_LIST
* or IX_ETH_DB_FIREWALL_BLACK_LIST)
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
if (mode != IX_ETH_DB_FIREWALL_WHITE_LIST
&& mode != IX_ETH_DB_FIREWALL_BLACK_LIST)
{
return IX_ETH_DB_INVALID_ARG;
}
ixEthDBPortInfo[portID].firewallMode = mode;
return ixEthDBFirewallTableDownload(portID);
}
/**
* @brief enables or disables the invalid source MAC address filter
*
* @param portID ID of the port
* @param enable true to enable invalid source MAC address filtering
* or false to disable it
*
* The invalid source MAC address filter will discard, when enabled,
* frames whose source MAC address is a multicast or the broadcast MAC
* address.
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
ixEthDBPortInfo[portID].srcAddressFilterEnabled = enable;
return ixEthDBFirewallTableDownload(portID);
}
/**
* @brief adds a firewall record
*
* @param portID ID of the port
* @param macAddr MAC address of the new record
*
* This function will add a new firewall record
* on the specified port, using the specified
* MAC address. If the record already exists this
* function will silently return IX_ETH_DB_SUCCESS,
* although no duplicate records are added.
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
recordTemplate.portID = portID;
return ixEthDBAdd(&recordTemplate, NULL);
}
/**
* @brief removes a firewall record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to remove
*
* This function will attempt to remove a firewall
* record from the given port, using the specified
* MAC address.
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully of an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
recordTemplate.portID = portID;
return ixEthDBRemove(&recordTemplate, NULL);
}
/**
* @brief downloads the firewall address table to an NPE
*
* @param portID ID of the port
*
* This function will download the firewall address table to
* an NPE port.
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_FAIL otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID)
{
IxEthDBPortMap query;
IxEthDBStatus result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
SET_DEPENDENCY_MAP(query, portID);
ixEthDBUpdateLock();
ixEthDBPortInfo[portID].updateMethod.searchTree = ixEthDBQuery(NULL, query, IX_ETH_DB_FIREWALL_RECORD, MAX_FW_SIZE);
result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FIREWALL_RECORD);
ixEthDBUpdateUnlock();
return result;
}

View File

@ -1,618 +0,0 @@
/**
* @file ethHash.c
*
* @brief Hashtable implementation
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
#include "IxEthDBLocks_p.h"
/**
* @addtogroup EthDB
*
* @{
*/
/**
* @brief initializes a hash table object
*
* @param hashTable uninitialized hash table structure
* @param numBuckets number of buckets to use
* @param entryHashFunction hash function used
* to hash entire hash node data block (for adding)
* @param matchFunctions array of match functions, indexed on type,
* used to differentiate records with the same hash value
* @param freeFunction function used to free node data blocks
*
* Initializes the given hash table object.
*
* @internal
*/
void ixEthDBInitHash(HashTable *hashTable,
UINT32 numBuckets,
HashFunction entryHashFunction,
MatchFunction *matchFunctions,
FreeFunction freeFunction)
{
UINT32 bucketIndex;
UINT32 hashSize = numBuckets * sizeof(HashNode *);
/* entry hashing, matching and freeing methods */
hashTable->entryHashFunction = entryHashFunction;
hashTable->matchFunctions = matchFunctions;
hashTable->freeFunction = freeFunction;
/* buckets */
hashTable->numBuckets = numBuckets;
/* set to 0 all buckets */
memset(hashTable->hashBuckets, 0, hashSize);
/* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/
for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++)
{
ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]);
}
}
/**
* @brief adds an entry to the hash table
*
* @param hashTable hash table to add the entry to
* @param entry entry to add
*
* The entry will be hashed using the entry hashing function and added to the
* hash table, unless a locking blockage occurs, in which case the caller
* should retry.
*
* @retval IX_ETH_DB_SUCCESS if adding <i>entry</i> has succeeded
* @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool
* @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path
*
* @internal
*/
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry)
{
UINT32 hashValue = hashTable->entryHashFunction(entry);
UINT32 bucketIndex = hashValue % hashTable->numBuckets;
HashNode *bucket = hashTable->hashBuckets[bucketIndex];
HashNode *newNode;
LockStack locks;
INIT_STACK(&locks);
/* lock bucket */
PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
/* lock insertion element (first in chain), if any */
if (bucket != NULL)
{
PUSH_LOCK(&locks, &bucket->lock);
}
/* get new node */
newNode = ixEthDBAllocHashNode();
if (newNode == NULL)
{
/* unlock everything */
UNROLL_STACK(&locks);
return IX_ETH_DB_NOMEM;
}
/* init lock - note that mutexes are unlocked after MutexInit */
ixOsalFastMutexInit(&newNode->lock);
/* populate new link */
newNode->data = entry;
/* add to bucket */
newNode->next = bucket;
hashTable->hashBuckets[bucketIndex] = newNode;
/* unlock bucket and insertion point */
UNROLL_STACK(&locks);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief removes an entry from the hashtable
*
* @param hashTable hash table to remove entry from
* @param keyType type of record key used for matching
* @param reference reference key used to identify the entry
*
* The reference key will be hashed using the key hashing function,
* the entry is searched using the hashed value and then examined
* against the reference entry using the match function. A positive
* match will trigger the deletion of the entry.
* Locking failures are reported and the caller should retry.
*
* @retval IX_ETH_DB_SUCCESS if the removal was successful
* @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found
* @retval IX_ETH_DB_BUSY if a locking failure occured during the process
*
* @internal
*/
IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference)
{
UINT32 hashValue = hashTable->entryHashFunction(reference);
UINT32 bucketIndex = hashValue % hashTable->numBuckets;
HashNode *node = hashTable->hashBuckets[bucketIndex];
HashNode *previousNode = NULL;
LockStack locks;
INIT_STACK(&locks);
while (node != NULL)
{
/* try to lock node */
PUSH_LOCK(&locks, &node->lock);
if (hashTable->matchFunctions[keyType](reference, node->data))
{
/* found entry */
if (node->next != NULL)
{
PUSH_LOCK(&locks, &node->next->lock);
}
if (previousNode == NULL)
{
/* node is head of chain */
PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
hashTable->hashBuckets[bucketIndex] = node->next;
POP_LOCK(&locks);
}
else
{
/* relink */
previousNode->next = node->next;
}
UNROLL_STACK(&locks);
/* free node */
hashTable->freeFunction(node->data);
ixEthDBFreeHashNode(node);
return IX_ETH_DB_SUCCESS;
}
else
{
if (previousNode != NULL)
{
/* unlock previous node */
SHIFT_STACK(&locks);
}
/* advance to next element in chain */
previousNode = node;
node = node->next;
}
}
UNROLL_STACK(&locks);
/* not found */
return IX_ETH_DB_NO_SUCH_ADDR;
}
/**
* @brief retrieves an entry from the hash table
*
* @param hashTable hash table to perform the search into
* @param reference search key (a MAC address)
* @param keyType type of record key used for matching
* @param searchResult pointer where a reference to the located hash node
* is placed
*
* Searches the entry with the same key as <i>reference</i> and places the
* pointer to the resulting node in <i>searchResult</i>.
* An implicit write access lock is granted after a search, which gives the
* caller the opportunity to modify the entry.
* Access should be released as soon as possible using @ref ixEthDBReleaseHashNode().
*
* @see ixEthDBReleaseHashNode()
*
* @retval IX_ETH_DB_SUCCESS if the search was completed successfully
* @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
* the caller should retry
*
* @warning unless the return value is <b>IX_ETH_DB_SUCCESS</b> the searchResult
* location is NOT modified and therefore using a NULL comparison test when the
* value was not properly initialized would be an error
*
* @internal
*/
IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult)
{
UINT32 hashValue;
HashNode *node;
hashValue = hashTable->entryHashFunction(reference);
node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
while (node != NULL)
{
TRY_LOCK(&node->lock);
if (hashTable->matchFunctions[keyType](reference, node->data))
{
*searchResult = node;
return IX_ETH_DB_SUCCESS;
}
else
{
UNLOCK(&node->lock);
node = node->next;
}
}
/* not found */
return IX_ETH_DB_NO_SUCH_ADDR;
}
/**
* @brief reports the existence of an entry in the hash table
*
* @param hashTable hash table to perform the search into
* @param reference search key (a MAC address)
* @param keyType type of record key used for matching
*
* Searches the entry with the same key as <i>reference</i>.
* No implicit write access lock is granted after a search, hence the
* caller cannot access or modify the entry. The result is only temporary.
*
* @see ixEthDBReleaseHashNode()
*
* @retval IX_ETH_DB_SUCCESS if the search was completed successfully
* @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
* the caller should retry
*
* @internal
*/
IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference)
{
UINT32 hashValue;
HashNode *node;
hashValue = hashTable->entryHashFunction(reference);
node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
while (node != NULL)
{
TRY_LOCK(&node->lock);
if (hashTable->matchFunctions[keyType](reference, node->data))
{
UNLOCK(&node->lock);
return IX_ETH_DB_SUCCESS;
}
else
{
UNLOCK(&node->lock);
node = node->next;
}
}
/* not found */
return IX_ETH_DB_NO_SUCH_ADDR;
}
/**
* @brief releases the write access lock
*
* @pre the node should have been obtained via @ref ixEthDBSearchHashEntry()
*
* @see ixEthDBSearchHashEntry()
*
* @internal
*/
void ixEthDBReleaseHashNode(HashNode *node)
{
UNLOCK(&node->lock);
}
/**
* @brief initializes a hash iterator
*
* @param hashTable hash table to be iterated
* @param iterator iterator object
*
* If the initialization is successful the iterator will point to the
* first hash table record (if any).
* Testing if the iterator has not passed the end of the table should be
* done using the IS_ITERATOR_VALID(iteratorPtr) macro.
* An implicit write access lock is granted on the entry pointed by the iterator.
* The access is automatically revoked when the iterator is incremented.
* If the caller decides to terminate the iteration before the end of the table is
* passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
* must be called.
*
* @see ixEthDBReleaseHashIterator()
*
* @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points
* to the first valid table node
* @retval IX_ETH_DB_FAIL if the table is empty
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
* should retry
*
* @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
* might place the database in a permanent invalid lock state
*
* @internal
*/
IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator)
{
iterator->bucketIndex = 0;
iterator->node = NULL;
iterator->previousNode = NULL;
return ixEthDBIncrementHashIterator(hashTable, iterator);
}
/**
* @brief releases the write access locks of the iterator nodes
*
* @warning use of this function is required only when the caller terminates an iteration
* before reaching the end of the table
*
* @see ixEthDBInitHashIterator()
* @see ixEthDBIncrementHashIterator()
*
* @param iterator iterator whose node(s) should be unlocked
*
* @internal
*/
void ixEthDBReleaseHashIterator(HashIterator *iterator)
{
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
if (iterator->node != NULL)
{
UNLOCK(&iterator->node->lock);
}
}
/**
* @brief incremenents an iterator so that it points to the next valid entry of the table
* (if any)
*
* @param hashTable hash table to iterate
* @param iterator iterator object
*
* @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator()
*
* If the increment operation is successful the iterator will point to the
* next hash table record (if any).
* Testing if the iterator has not passed the end of the table should be
* done using the IS_ITERATOR_VALID(iteratorPtr) macro.
* An implicit write access lock is granted on the entry pointed by the iterator.
* The access is automatically revoked when the iterator is re-incremented.
* If the caller decides to terminate the iteration before the end of the table is
* passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
* must be called.
* Is is guaranteed that no other thread can remove or change the iterated entry until
* the iterator is incremented successfully.
*
* @see ixEthDBReleaseHashIterator()
*
* @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points
* to the next valid table node
* @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
* should retry
*
* @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
* might place the database in a permanent invalid lock state
*
* @internal
*/
IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator)
{
/* unless iterator is just initialized... */
if (iterator->node != NULL)
{
/* try next in chain */
if (iterator->node->next != NULL)
{
TRY_LOCK(&iterator->node->next->lock);
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
iterator->previousNode = iterator->node;
iterator->node = iterator->node->next;
return IX_ETH_DB_SUCCESS;
}
else
{
/* last in chain, prepare for next bucket */
iterator->bucketIndex++;
}
}
/* try next used bucket */
for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++)
{
HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]);
HashNode *node = *nodePtr;
#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) &&
(iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD)))
{
/* preload next cache line (2 cache line ahead) */
nodePtr += IX_ETHDB_BUCKETPTR_AHEAD;
__asm__ ("pld [%0];\n": : "r" (nodePtr));
}
#endif
if (node != NULL)
{
TRY_LOCK(&node->lock);
/* unlock last one or two nodes in the previous chain */
if (iterator->node != NULL)
{
UNLOCK(&iterator->node->lock);
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
}
/* redirect iterator */
iterator->previousNode = NULL;
iterator->node = node;
return IX_ETH_DB_SUCCESS;
}
}
/* could not advance iterator */
if (iterator->node != NULL)
{
UNLOCK(&iterator->node->lock);
if (iterator->previousNode != NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
iterator->node = NULL;
}
return IX_ETH_DB_END;
}
/**
* @brief removes an entry pointed by an iterator
*
* @param hashTable iterated hash table
* @param iterator iterator object
*
* Removes the entry currently pointed by the iterator and repositions the iterator
* on the next valid entry (if any). Handles locking issues automatically and
* implicitely grants write access lock to the new pointed entry.
* Failures due to concurrent threads having write access locks in the same region
* preserve the state of the database and the iterator object, leaving the caller
* free to retry without loss of access. It is guaranteed that only the thread owning
* the iterator can remove the object pointed by the iterator.
*
* @retval IX_ETH_DB_SUCCESS if removal has succeeded
* @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
* should retry
*
* @internal
*/
IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator)
{
HashIterator nextIteratorPos;
LockStack locks;
INIT_STACK(&locks);
/* set initial bucket index for next position */
nextIteratorPos.bucketIndex = iterator->bucketIndex;
/* compute iterator position before removing anything and lock ahead */
if (iterator->node->next != NULL)
{
PUSH_LOCK(&locks, &iterator->node->next->lock);
/* reposition on the next node in the chain */
nextIteratorPos.node = iterator->node->next;
nextIteratorPos.previousNode = iterator->previousNode;
}
else
{
/* try next chain - don't know yet if we'll find anything */
nextIteratorPos.node = NULL;
/* if we find something it's a chain head */
nextIteratorPos.previousNode = NULL;
/* browse up in the buckets to find a non-null chain */
while (++nextIteratorPos.bucketIndex < hashTable->numBuckets)
{
nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex];
if (nextIteratorPos.node != NULL)
{
/* found a non-empty chain, try to lock head */
PUSH_LOCK(&locks, &nextIteratorPos.node->lock);
break;
}
}
}
/* restore links over the to-be-deleted item */
if (iterator->previousNode == NULL)
{
/* first in chain, lock bucket */
PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]);
hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next;
POP_LOCK(&locks);
}
else
{
/* relink */
iterator->previousNode->next = iterator->node->next;
/* unlock last remaining node in current chain when moving between chains */
if (iterator->node->next == NULL)
{
UNLOCK(&iterator->previousNode->lock);
}
}
/* delete entry */
hashTable->freeFunction(iterator->node->data);
ixEthDBFreeHashNode(iterator->node);
/* reposition iterator */
*iterator = nextIteratorPos;
return IX_ETH_DB_SUCCESS;
}
/**
* @}
*/

View File

@ -1,125 +0,0 @@
/**
* @file IxEthDBLearning.c
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/**
* @brief hashes the mac address in a mac descriptor with a XOR function
*
* @param entry pointer to a mac descriptor to be hashed
*
* This function only extracts the mac address and employs ixEthDBKeyXORHash()
* to do the actual hashing.
* Used only to add a whole entry to a hash table, as opposed to searching which
* takes only a key and uses the key hashing directly.
*
* @see ixEthDBKeyXORHash()
*
* @return the hash value
*
* @internal
*/
UINT32 ixEthDBEntryXORHash(void *entry)
{
MacDescriptor *descriptor = (MacDescriptor *) entry;
return ixEthDBKeyXORHash(descriptor->macAddress);
}
/**
* @brief hashes a mac address
*
* @param key pointer to a 6 byte structure (typically an IxEthDBMacAddr pointer)
* to be hashed
*
* Given a 6 bytes MAC address, the hash used is:
*
* hash(MAC[0:5]) = MAC[0:1] ^ MAC[2:3] ^ MAC[4:5]
*
* Used by the hash table to search and remove entries based
* solely on their keys (mac addresses).
*
* @return the hash value
*
* @internal
*/
UINT32 ixEthDBKeyXORHash(void *key)
{
UINT32 hashValue;
UINT8 *value = (UINT8 *) key;
hashValue = (value[5] << 8) | value[4];
hashValue ^= (value[3] << 8) | value[2];
hashValue ^= (value[1] << 8) | value[0];
return hashValue;
}
/**
* @brief mac descriptor match function
*
* @param reference mac address (typically an IxEthDBMacAddr pointer) structure
* @param entry pointer to a mac descriptor whose key (mac address) is to be
* matched against the reference key
*
* Used by the hash table to retrieve entries. Hashing entries can produce
* collisions, i.e. descriptors with different mac addresses and the same
* hash value, where this function is used to differentiate entries.
*
* @retval true if the entry matches the reference key (equal addresses)
* @retval false if the entry does not match the reference key
*
* @internal
*/
BOOL ixEthDBAddressMatch(void *reference, void *entry)
{
return (ixEthDBAddressCompare(reference, ((MacDescriptor *) entry)->macAddress) == 0);
}
/**
* @brief compares two mac addresses
*
* @param mac1 first mac address to compare
* @param mac2 second mac address to compare
*
* This comparison works in a similar way to strcmp, producing similar results.
* Used to insert values keyed on mac addresses into binary search trees.
*
* @retval -1 if mac1 < mac2
* @retval 0 if ma1 == mac2
* @retval 1 if mac1 > mac2
*/
UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2)
{
UINT32 local_index;
for (local_index = 0 ; local_index < IX_IEEE803_MAC_ADDRESS_SIZE ; local_index++)
{
if (mac1[local_index] > mac2[local_index])
{
return 1;
}
else if (mac1[local_index] < mac2[local_index])
{
return -1;
}
}
return 0;
}

View File

@ -1,625 +0,0 @@
/**
* @file IxEthDBDBMem.c
*
* @brief Memory handling routines for the MAC address database
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
IX_ETH_DB_PRIVATE HashNode *nodePool = NULL;
IX_ETH_DB_PRIVATE MacDescriptor *macPool = NULL;
IX_ETH_DB_PRIVATE MacTreeNode *treePool = NULL;
IX_ETH_DB_PRIVATE HashNode nodePoolArea[NODE_POOL_SIZE];
IX_ETH_DB_PRIVATE MacDescriptor macPoolArea[MAC_POOL_SIZE];
IX_ETH_DB_PRIVATE MacTreeNode treePoolArea[TREE_POOL_SIZE];
IX_ETH_DB_PRIVATE IxOsalMutex nodePoolLock;
IX_ETH_DB_PRIVATE IxOsalMutex macPoolLock;
IX_ETH_DB_PRIVATE IxOsalMutex treePoolLock;
#define LOCK_NODE_POOL { ixOsalMutexLock(&nodePoolLock, IX_OSAL_WAIT_FOREVER); }
#define UNLOCK_NODE_POOL { ixOsalMutexUnlock(&nodePoolLock); }
#define LOCK_MAC_POOL { ixOsalMutexLock(&macPoolLock, IX_OSAL_WAIT_FOREVER); }
#define UNLOCK_MAC_POOL { ixOsalMutexUnlock(&macPoolLock); }
#define LOCK_TREE_POOL { ixOsalMutexLock(&treePoolLock, IX_OSAL_WAIT_FOREVER); }
#define UNLOCK_TREE_POOL { ixOsalMutexUnlock(&treePoolLock); }
/* private function prototypes */
IX_ETH_DB_PRIVATE MacDescriptor* ixEthDBPoolAllocMacDescriptor(void);
IX_ETH_DB_PRIVATE void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor);
/**
* @addtogroup EthMemoryManagement
*
* @{
*/
/**
* @brief initializes the memory pools used by the ethernet database component
*
* Initializes the hash table node, mac descriptor and mac tree node pools.
* Called at initialization time by @ref ixEthDBInit().
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBInitMemoryPools(void)
{
int local_index;
/* HashNode pool */
ixOsalMutexInit(&nodePoolLock);
for (local_index = 0 ; local_index < NODE_POOL_SIZE ; local_index++)
{
HashNode *freeNode = &nodePoolArea[local_index];
freeNode->nextFree = nodePool;
nodePool = freeNode;
}
/* MacDescriptor pool */
ixOsalMutexInit(&macPoolLock);
for (local_index = 0 ; local_index < MAC_POOL_SIZE ; local_index++)
{
MacDescriptor *freeDescriptor = &macPoolArea[local_index];
freeDescriptor->nextFree = macPool;
macPool = freeDescriptor;
}
/* MacTreeNode pool */
ixOsalMutexInit(&treePoolLock);
for (local_index = 0 ; local_index < TREE_POOL_SIZE ; local_index++)
{
MacTreeNode *freeNode = &treePoolArea[local_index];
freeNode->nextFree = treePool;
treePool = freeNode;
}
}
/**
* @brief allocates a hash node from the pool
*
* Allocates a hash node and resets its value.
*
* @return the allocated hash node or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBAllocHashNode(void)
{
HashNode *allocatedNode = NULL;
if (nodePool != NULL)
{
LOCK_NODE_POOL;
allocatedNode = nodePool;
nodePool = nodePool->nextFree;
UNLOCK_NODE_POOL;
memset(allocatedNode, 0, sizeof(HashNode));
}
return allocatedNode;
}
/**
* @brief frees a hash node into the pool
*
* @param hashNode node to be freed
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFreeHashNode(HashNode *hashNode)
{
if (hashNode != NULL)
{
LOCK_NODE_POOL;
hashNode->nextFree = nodePool;
nodePool = hashNode;
UNLOCK_NODE_POOL;
}
}
/**
* @brief allocates a mac descriptor from the pool
*
* Allocates a mac descriptor and resets its value.
* This function is not used directly, instead @ref ixEthDBAllocMacDescriptor()
* is used, which keeps track of the pointer reference count.
*
* @see ixEthDBAllocMacDescriptor()
*
* @warning this function is not used directly by any other function
* apart from ixEthDBAllocMacDescriptor()
*
* @return the allocated mac descriptor or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PRIVATE
MacDescriptor* ixEthDBPoolAllocMacDescriptor(void)
{
MacDescriptor *allocatedDescriptor = NULL;
if (macPool != NULL)
{
LOCK_MAC_POOL;
allocatedDescriptor = macPool;
macPool = macPool->nextFree;
UNLOCK_MAC_POOL;
memset(allocatedDescriptor, 0, sizeof(MacDescriptor));
}
return allocatedDescriptor;
}
/**
* @brief allocates and initializes a mac descriptor smart pointer
*
* Uses @ref ixEthDBPoolAllocMacDescriptor() to allocate a mac descriptor
* from the pool and initializes its reference count.
*
* @see ixEthDBPoolAllocMacDescriptor()
*
* @return the allocated mac descriptor or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacDescriptor* ixEthDBAllocMacDescriptor(void)
{
MacDescriptor *allocatedDescriptor = ixEthDBPoolAllocMacDescriptor();
if (allocatedDescriptor != NULL)
{
LOCK_MAC_POOL;
allocatedDescriptor->refCount++;
UNLOCK_MAC_POOL;
}
return allocatedDescriptor;
}
/**
* @brief frees a mac descriptor back into the pool
*
* @param macDescriptor mac descriptor to be freed
*
* @warning this function is not to be called by anyone but
* ixEthDBFreeMacDescriptor()
*
* @see ixEthDBFreeMacDescriptor()
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor)
{
LOCK_MAC_POOL;
macDescriptor->nextFree = macPool;
macPool = macDescriptor;
UNLOCK_MAC_POOL;
}
/**
* @brief frees or reduces the usage count of a mac descriptor smart pointer
*
* If the reference count reaches 0 (structure is no longer used anywhere)
* then the descriptor is freed back into the pool using ixEthDBPoolFreeMacDescriptor().
*
* @see ixEthDBPoolFreeMacDescriptor()
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFreeMacDescriptor(MacDescriptor *macDescriptor)
{
if (macDescriptor != NULL)
{
LOCK_MAC_POOL;
if (macDescriptor->refCount > 0)
{
macDescriptor->refCount--;
if (macDescriptor->refCount == 0)
{
UNLOCK_MAC_POOL;
ixEthDBPoolFreeMacDescriptor(macDescriptor);
}
else
{
UNLOCK_MAC_POOL;
}
}
else
{
UNLOCK_MAC_POOL;
}
}
}
/**
* @brief clones a mac descriptor smart pointer
*
* @param macDescriptor mac descriptor to clone
*
* Increments the usage count of the smart pointer
*
* @returns the cloned smart pointer
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor)
{
LOCK_MAC_POOL;
if (macDescriptor->refCount == 0)
{
UNLOCK_MAC_POOL;
return NULL;
}
macDescriptor->refCount++;
UNLOCK_MAC_POOL;
return macDescriptor;
}
/**
* @brief allocates a mac tree node from the pool
*
* Allocates and initializes a mac tree node from the pool.
*
* @return the allocated mac tree node or NULL if the pool is empty
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacTreeNode* ixEthDBAllocMacTreeNode(void)
{
MacTreeNode *allocatedNode = NULL;
if (treePool != NULL)
{
LOCK_TREE_POOL;
allocatedNode = treePool;
treePool = treePool->nextFree;
UNLOCK_TREE_POOL;
memset(allocatedNode, 0, sizeof(MacTreeNode));
}
return allocatedNode;
}
/**
* @brief frees a mac tree node back into the pool
*
* @param macNode mac tree node to be freed
*
* @warning not to be used except from ixEthDBFreeMacTreeNode().
*
* @see ixEthDBFreeMacTreeNode()
*
* @internal
*/
void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode)
{
if (macNode != NULL)
{
LOCK_TREE_POOL;
macNode->nextFree = treePool;
treePool = macNode;
UNLOCK_TREE_POOL;
}
}
/**
* @brief frees or reduces the usage count of a mac tree node smart pointer
*
* @param macNode mac tree node to free
*
* Reduces the usage count of the given mac node. If the usage count
* reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode()
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBFreeMacTreeNode(MacTreeNode *macNode)
{
if (macNode->descriptor != NULL)
{
ixEthDBFreeMacDescriptor(macNode->descriptor);
}
if (macNode->left != NULL)
{
ixEthDBFreeMacTreeNode(macNode->left);
}
if (macNode->right != NULL)
{
ixEthDBFreeMacTreeNode(macNode->right);
}
ixEthDBPoolFreeMacTreeNode(macNode);
}
/**
* @brief clones a mac tree node
*
* @param macNode mac tree node to be cloned
*
* Increments the usage count of the node, <i>its associated descriptor
* and <b>recursively</b> of all its child nodes</i>.
*
* @warning this function is recursive and clones whole trees/subtrees, use only for
* root nodes
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode)
{
if (macNode != NULL)
{
MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode();
if (clonedMacNode != NULL)
{
if (macNode->right != NULL)
{
clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right);
}
if (macNode->left != NULL)
{
clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left);
}
if (macNode->descriptor != NULL)
{
clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor);
}
}
return clonedMacNode;
}
else
{
return NULL;
}
}
#ifndef NDEBUG
/* Debug statistical functions for memory usage */
extern HashTable dbHashtable;
int ixEthDBNumHashElements(void);
int ixEthDBNumHashElements(void)
{
UINT32 bucketIndex;
int numElements = 0;
HashTable *hashTable = &dbHashtable;
for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++)
{
if (hashTable->hashBuckets[bucketIndex] != NULL)
{
HashNode *node = hashTable->hashBuckets[bucketIndex];
while (node != NULL)
{
numElements++;
node = node->next;
}
}
}
return numElements;
}
UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree)
{
if (tree == NULL)
{
return 0;
}
else
{
return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right);
}
}
int ixEthDBShowMemoryStatus(void)
{
MacDescriptor *mac;
MacTreeNode *tree;
HashNode *node;
int macCounter = 0;
int treeCounter = 0;
int nodeCounter = 0;
int totalTreeUsage = 0;
int totalDescriptorUsage = 0;
int totalCloneDescriptorUsage = 0;
int totalNodeUsage = 0;
UINT32 portIndex;
LOCK_NODE_POOL;
LOCK_MAC_POOL;
LOCK_TREE_POOL;
mac = macPool;
tree = treePool;
node = nodePool;
while (mac != NULL)
{
macCounter++;
mac = mac->nextFree;
if (macCounter > MAC_POOL_SIZE)
{
break;
}
}
while (tree != NULL)
{
treeCounter++;
tree = tree->nextFree;
if (treeCounter > TREE_POOL_SIZE)
{
break;
}
}
while (node != NULL)
{
nodeCounter++;
node = node->nextFree;
if (nodeCounter > NODE_POOL_SIZE)
{
break;
}
}
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree);
totalTreeUsage += treeUsage;
totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */
}
totalNodeUsage = ixEthDBNumHashElements();
totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */
UNLOCK_NODE_POOL;
UNLOCK_MAC_POOL;
UNLOCK_TREE_POOL;
printf("Ethernet database memory usage stats:\n\n");
if (macCounter <= MAC_POOL_SIZE)
{
printf("\tMAC descriptor pool : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE);
}
else
{
printf("\tMAC descriptor pool : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE);
}
if (treeCounter <= TREE_POOL_SIZE)
{
printf("\tTree node pool : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE);
}
else
{
printf("\tTREE descriptor pool : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE);
}
if (nodeCounter <= NODE_POOL_SIZE)
{
printf("\tHash node pool : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE);
}
else
{
printf("\tNODE descriptor pool : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE);
}
printf("\n");
printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage);
printf("\tTree node usage : %d entries\n", totalTreeUsage);
printf("\tHash node usage : %d entries\n", totalNodeUsage);
printf("\n");
/* search for duplicate nodes in the mac pool */
{
MacDescriptor *reference = macPool;
while (reference != NULL)
{
MacDescriptor *comparison = reference->nextFree;
while (comparison != NULL)
{
if (reference == comparison)
{
printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference);
return 1;
}
comparison = comparison->nextFree;
}
reference = reference->nextFree;
}
}
printf("No duplicates found in the MAC pool (sanity check ok)\n");
return 0;
}
#endif /* NDEBUG */
/**
* @} EthMemoryManagement
*/

View File

@ -1,695 +0,0 @@
/**
* @file IxEthDBDBNPEAdaptor.c
*
* @brief Routines that read and write learning/search trees in NPE-specific format
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
#include "IxEthDBLog_p.h"
/* forward prototype declarations */
IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID);
IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void);
/* data */
UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS];
UINT32 dumpEltSize;
/* private data */
IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
#define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */
IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
/**
* @brief allocates non-cached or contiguous NPE tree update areas for all the ports
*
* This function is called only once at initialization time from
* @ref ixEthDBInit().
*
* @warning do not call manually
*
* @see ixEthDBInit()
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNPEUpdateAreasInit(void)
{
UINT32 portIndex;
PortUpdateMethod *update;
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
update = &ixEthDBPortInfo[portIndex].updateMethod;
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
{
update->npeUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE);
update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE);
update->vlanUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE);
if (update->npeUpdateZone == NULL
|| update->npeGwUpdateZone == NULL
|| update->vlanUpdateZone == NULL)
{
ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n");
}
else
{
memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE);
memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE);
memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE);
}
}
else
{
/* unused */
update->npeUpdateZone = NULL;
update->npeGwUpdateZone = NULL;
update->vlanUpdateZone = NULL;
}
}
}
/**
* @brief deallocates the NPE update areas for all the ports
*
* This function is called at component de-initialization time
* by @ref ixEthDBUnload().
*
* @warning do not call manually
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNPEUpdateAreasUnload(void)
{
UINT32 portIndex;
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
{
IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone);
IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeGwUpdateZone);
IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.vlanUpdateZone);
}
}
}
/**
* @brief general-purpose NPE callback function
*
* @param npeID NPE ID
* @param msg NPE message
*
* This function will unblock the caller by unlocking
* the npeAckLock mutex defined for each NPE port
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
{
IxEthDBPortId portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
PortInfo *portInfo;
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
{
/* invalid port */
return;
}
if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
{
/* not an NPE */
return;
}
portInfo = &ixEthDBPortInfo[portID];
ixOsalMutexUnlock(&portInfo->npeAckLock);
}
/**
* @brief synchronizes the database with tree
*
* @param portID port ID of the NPE whose tree is to be scanned
* @param eltBaseAddress memory base address of the NPE serialized tree
* @param eltSize size in bytes of the NPE serialized tree
*
* Scans the NPE learning tree and resets the age of active database records.
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize)
{
UINT32 eltEntryOffset;
UINT32 entryPortID;
/* invalidate cache */
IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize);
for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
{
/* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
*
* the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
* therefore we can just use the pointer for database searches as only the first 6 bytes are checked
*/
void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
/* debug */
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE);
if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != true)
{
IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n");
}
else if (eltEntryOffset == ELT_ROOT_OFFSET)
{
IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n");
}
if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
{
entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
/* check only active entries belonging to this port */
if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID)
&& ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0))
{
/* search record */
HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS);
/* safety check, maybe user deleted record right before sync? */
if (node != NULL)
{
/* found record */
MacDescriptor *descriptor = (MacDescriptor *) node->data;
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress));
/* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */
if (!descriptor->recordData.filteringData.staticEntry)
{
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
descriptor->recordData.filteringData.age = AGE_RESET;
}
else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
descriptor->recordData.filteringVlanData.age = AGE_RESET;
}
}
/* end transaction */
ixEthDBReleaseHashNode(node);
}
}
else
{
IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID);
}
}
}
}
/**
* @brief writes a search tree in NPE format
*
* @param type type of records to be written into the NPE update zone
* @param totalSize maximum size of the linearized tree
* @param baseAddress memory base address where to write the NPE tree into
* @param tree search tree to write in NPE format
* @param blocks number of written 64-byte blocks
* @param startIndex optimal binary search start index
*
* Serializes the given tree in NPE linear format
*
* @return none
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *epDelta, UINT32 *blocks)
{
MacTreeNodeStack *stack;
UINT32 maxOffset = 0;
UINT32 emptyOffset;
stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
if (stack == NULL)
{
ERROR_LOG("DB: (NPEAdaptor) failed to allocate the node stack for learning tree linearization, out of memory?\n");
return;
}
/* zero out empty root */
memset(baseAddress, 0, ELT_ENTRY_SIZE);
NODE_STACK_INIT(stack);
if (tree != NULL)
{
/* push tree root at offset 1 */
NODE_STACK_PUSH(stack, tree, 1);
maxOffset = 1;
}
while (NODE_STACK_NONEMPTY(stack))
{
MacTreeNode *node;
UINT32 offset;
NODE_STACK_POP(stack, node, offset);
/* update maximum offset */
if (offset > maxOffset)
{
maxOffset = offset;
}
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing MAC [%s] at offset %d\n", mac2string(node->descriptor->macAddress), offset);
/* add node to NPE ELT at position indicated by offset */
if (offset < MAX_ELT_SIZE)
{
ixEthDBNPENodeWrite[type]((void *) (((UINT32) baseAddress) + offset * ELT_ENTRY_SIZE), node);
}
if (node->left != NULL)
{
NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
}
else
{
/* ensure this entry is zeroed */
memset((void *) ((UINT32) baseAddress + LEFT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
}
if (node->right != NULL)
{
NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
}
else
{
/* ensure this entry is zeroed */
memset((void *) ((UINT32) baseAddress + RIGHT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
}
}
emptyOffset = maxOffset + 1;
/* zero out rest of the tree */
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Emptying tree from offset %d, address 0x%08X, %d bytes\n",
emptyOffset, ((UINT32) baseAddress) + emptyOffset * ELT_ENTRY_SIZE, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
if (emptyOffset < MAX_ELT_SIZE - 1)
{
memset((void *) (((UINT32) baseAddress) + (emptyOffset * ELT_ENTRY_SIZE)), 0, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
}
/* flush cache */
IX_OSAL_CACHE_FLUSH(baseAddress, totalSize);
/* debug */
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Ethernet learning/filtering tree XScale wrote at address 0x%08X (max %d bytes):\n\n",
(UINT32) baseAddress, FULL_ELT_BYTE_SIZE);
IX_ETH_DB_NPE_DUMP_ELT(baseAddress, FULL_ELT_BYTE_SIZE);
/* compute number of 64-byte blocks */
if (blocks != NULL)
{
*blocks = maxOffset != 0 ? 1 + maxOffset / 8 : 0;
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Wrote %d 64-byte blocks\n", *blocks);
}
/* compute epDelta - start index for binary search */
if (epDelta != NULL)
{
UINT32 deltaIndex = 0;
*epDelta = 0;
for (; deltaIndex < IX_ETH_DB_MAX_DELTA_ZONES ; deltaIndex ++)
{
if (ixEthDBEPDeltaOffset[type][deltaIndex] >= maxOffset)
{
*epDelta = ixEthDBEPDelta[type][deltaIndex];
break;
}
}
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Computed epDelta %d (based on maxOffset %d)\n", *epDelta, maxOffset);
}
ixOsalCacheDmaFree(stack);
}
/**
* @brief implements a dummy node serialization function
*
* @param address address of where the node is to be serialized (unused)
* @param node tree node to be serialized (unused)
*
* This function is registered for safety reasons and should
* never be called. It will display an error message if this
* function is called.
*
* @return none
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBNullSerialize(void *address, MacTreeNode *node)
{
IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Warning, the NullSerialize function was called, wrong record type?\n");
}
/**
* @brief writes a filtering entry in NPE linear format
*
* @param address memory address to write node to
* @param node node to be written
*
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
* in NPE-readable format.
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBNPELearningNodeWrite(void *address, MacTreeNode *node)
{
/* copy mac address */
memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
/* copy port ID */
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET) = IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(node->descriptor->portID);
/* copy flags (valid and not active, as the NPE sets it to active) and clear reserved section (bits 2-7) */
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) = (UINT8) IX_EDB_FLAGS_INACTIVE_VALID;
IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing ELT node 0x%08x:0x%08x\n", * (UINT32 *) address, * (((UINT32 *) (address)) + 1));
}
/**
* @brief writes a WiFi header conversion record in
* NPE linear format
*
* @param address memory address to write node to
* @param node node to be written
*
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
* in NPE-readable format.
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBNPEWiFiNodeWrite(void *address, MacTreeNode *node)
{
/* copy mac address */
memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
/* copy index */
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET) = node->descriptor->recordData.wifiData.gwAddressIndex;
/* copy flags (type and valid) */
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET) = node->descriptor->recordData.wifiData.type << 1 | IX_EDB_FLAGS_VALID;
}
/**
* @brief writes a WiFi gateway header conversion record in
* NPE linear format
*
* @param address memory address to write node to
* @param node node to be written
*
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
* in NPE-readable format.
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node)
{
/* copy mac address */
memcpy(address, node->descriptor->recordData.wifiData.gwMacAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
/* set reserved field, two bytes */
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET + 1) = 0;
}
/**
* @brief writes a firewall record in
* NPE linear format
*
* @param address memory address to write node to
* @param node node to be written
*
* Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
* in NPE-readable format.
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBNPEFirewallNodeWrite(void *address, MacTreeNode *node)
{
/* set reserved field */
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
/* set flags */
NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_FLAGS_OFFSET) = IX_EDB_FLAGS_VALID;
/* copy mac address */
memcpy((void *) ((UINT32) address + IX_EDB_NPE_NODE_FW_ADDR_OFFSET), node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
}
/**
* @brief registers the NPE serialization methods
*
* This functions registers NPE serialization methods
* for writing the following types of records in NPE
* readable linear format:
* - filtering records
* - WiFi header conversion records
* - WiFi gateway header conversion records
* - firewall records
*
* Note that this function should be called by the
* component initialization function.
*
* @return number of registered record types
*
* @internal
*/
IX_ETH_DB_PUBLIC
UINT32 ixEthDBRecordSerializeMethodsRegister()
{
int i;
/* safety - register a blank method for everybody first */
for ( i = 0 ; i < IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1 ; i++)
{
ixEthDBNPENodeWrite[i] = ixEthDBNullSerialize;
}
/* register real methods */
ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_RECORD] = ixEthDBNPELearningNodeWrite;
ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_VLAN_RECORD] = ixEthDBNPELearningNodeWrite;
ixEthDBNPENodeWrite[IX_ETH_DB_WIFI_RECORD] = ixEthDBNPEWiFiNodeWrite;
ixEthDBNPENodeWrite[IX_ETH_DB_FIREWALL_RECORD] = ixEthDBNPEFirewallNodeWrite;
ixEthDBNPENodeWrite[IX_ETH_DB_GATEWAY_RECORD] = ixEthDBNPEGatewayNodeWrite;
/* EP Delta arrays */
memset(ixEthDBEPDeltaOffset, 0, sizeof (ixEthDBEPDeltaOffset));
memset(ixEthDBEPDelta, 0, sizeof (ixEthDBEPDelta));
/* filtering records */
ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][0] = 1;
ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][0] = 0;
ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][1] = 3;
ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][1] = 7;
ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][2] = 511;
ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][2] = 14;
/* wifi records */
ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][0] = 1;
ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][0] = 0;
ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][1] = 3;
ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][1] = 7;
ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][2] = 511;
ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][2] = 14;
/* firewall records */
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][1] = 1;
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][1] = 5;
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][2] = 3;
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][2] = 13;
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][3] = 7;
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][3] = 21;
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][4] = 15;
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][4] = 29;
ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][5] = 31;
ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][5] = 37;
return 5; /* 5 methods registered */
}
#ifndef IX_NDEBUG
IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen = 0;
/**
* When compiled in DEBUG mode, this function can be used to display
* the history of messages sent to the NPEs (up to 100).
*/
IX_ETH_DB_PUBLIC
void ixEthDBShowNpeMsgHistory()
{
UINT32 i = 0;
UINT32 base, len;
if (npeMsgHistoryLen <= IX_ETH_DB_NPE_MSG_HISTORY_DEPTH)
{
base = 0;
len = npeMsgHistoryLen;
}
else
{
base = npeMsgHistoryLen % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
len = IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
}
printf("NPE message history [last %d messages, from least to most recent]:\n", len);
for (; i < len ; i++)
{
UINT32 pos = (base + i) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
printf("msg[%d]: 0x%08x:0x%08x\n", i, npeMsgHistory[pos][0], npeMsgHistory[pos][1]);
}
}
IX_ETH_DB_PUBLIC
void ixEthDBELTShow(IxEthDBPortId portID)
{
IxNpeMhMessage message;
IX_STATUS result;
/* send EDB_GetMACAddressDatabase message */
FILL_GETMACADDRESSDATABASE(message,
0 /* reserved */,
IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
if (result == IX_SUCCESS)
{
/* analyze NPE copy */
UINT32 eltEntryOffset;
UINT32 entryPortID;
UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone;
UINT32 eltSize = FULL_ELT_BYTE_SIZE;
/* invalidate cache */
IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize);
printf("Listing records in main learning tree for port %d\n", portID);
for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
{
/* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
*
* the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
* therefore we can just use the pointer for database searches as only the first 6 bytes are checked
*/
void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
{
HashNode *node;
entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
/* search record */
node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES);
printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID,
IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive");
/* safety check, maybe user deleted record right before sync? */
if (node != NULL)
{
/* found record */
MacDescriptor *descriptor = (MacDescriptor *) node->data;
printf("- %s ",
descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" :
descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" :
descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)");
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ",
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ",
descriptor->recordData.filteringVlanData.age,
descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
descriptor->recordData.filteringVlanData.ieee802_1qTag);
/* end transaction */
ixEthDBReleaseHashNode(node);
}
else
{
printf("- not synced");
}
printf("\n");
}
}
}
else
{
ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT,
"EthDB: (ShowELT) Could not complete action (communication failure)\n",
portID, 0, 0, 0, 0, 0);
}
}
#endif

View File

@ -1,716 +0,0 @@
/**
* @file IxEthDBDBPortUpdate.c
*
* @brief Implementation of dependency and port update handling
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/* forward prototype declarations */
IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor);
IX_ETH_DB_PRIVATE void ixEthDBCreateTrees(IxEthDBPortMap updatePorts);
IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree);
IX_ETH_DB_PRIVATE void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size);
IX_ETH_DB_PRIVATE void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size);
IX_ETH_DB_PRIVATE void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count);
IX_ETH_DB_PRIVATE UINT32 ixEthDBRebalanceLog2Floor(UINT32 x);
extern HashTable dbHashtable;
/**
* @brief register types requiring automatic updates
*
* @param typeArray array indexed on record types, each
* element indicating whether the record type requires an
* automatic update (true) or not (false)
*
* Automatic updates are done for registered record types
* upon adding, updating (that is, updating the record portID)
* and removing records. Whenever an automatic update is triggered
* the appropriate ports will be provided with new database
* information.
*
* It is assumed that the typeArray parameter is allocated large
* enough to hold all the user defined types. Also, the type
* array should be initialized to false as this function only
* caters for types which do require automatic updates.
*
* Note that this function should be called by the component
* initialization function.
*
* @return number of record types registered for automatic
* updates
*
* @internal
*/
IX_ETH_DB_PUBLIC
UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray)
{
typeArray[IX_ETH_DB_FILTERING_RECORD] = true;
typeArray[IX_ETH_DB_FILTERING_VLAN_RECORD] = true;
return 2;
}
/**
* @brief computes dependencies and triggers port learning tree updates
*
* @param triggerPorts port map consisting in the ports which triggered the update
*
* This function browses through all the ports and determines how to waterfall the update
* event from the trigger ports to all other ports depending on them.
*
* Once the list of ports to be updated is determined this function
* calls @ref ixEthDBCreateTrees.
*
* @internal
*/
IX_ETH_DB_PUBLIC
void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts)
{
IxEthDBPortMap updatePorts;
UINT32 portIndex;
ixEthDBUpdateLock();
SET_EMPTY_DEPENDENCY_MAP(updatePorts);
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
PortInfo *port = &ixEthDBPortInfo[portIndex];
BOOL mapsCollide;
MAPS_COLLIDE(mapsCollide, triggerPorts, port->dependencyPortMap);
if (mapsCollide /* do triggers influence this port? */
&& !IS_PORT_INCLUDED(portIndex, updatePorts) /* and it's not already in the update list */
&& port->updateMethod.updateEnabled) /* and we're allowed to update it */
{
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding port %d to update set\n", portIndex);
JOIN_PORT_TO_MAP(updatePorts, portIndex);
}
else
{
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Didn't add port %d to update set, reasons follow:\n", portIndex);
if (!mapsCollide)
{
IX_ETH_DB_UPDATE_TRACE("\tMaps don't collide on port %d\n", portIndex);
}
if (IS_PORT_INCLUDED(portIndex, updatePorts))
{
IX_ETH_DB_UPDATE_TRACE("\tPort %d is already in the update set\n", portIndex);
}
if (!port->updateMethod.updateEnabled)
{
IX_ETH_DB_UPDATE_TRACE("\tPort %d doesn't have updateEnabled set\n", portIndex);
}
}
}
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Updating port set\n");
ixEthDBCreateTrees(updatePorts);
ixEthDBUpdateUnlock();
}
/**
* @brief creates learning trees and calls the port update handlers
*
* @param updatePorts set of ports in need of learning trees
*
* This function determines the optimal method of creating learning
* trees using a minimal number of database queries, keeping in mind
* that different ports can either use the same learning trees or they
* can partially share them. The actual tree building routine is
* @ref ixEthDBQuery.
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBCreateTrees(IxEthDBPortMap updatePorts)
{
UINT32 portIndex;
BOOL result;
BOOL portsLeft = true;
while (portsLeft)
{
/* get port with minimal dependency map and NULL search tree */
UINT32 minPortIndex = MAX_PORT_SIZE;
UINT32 minimalSize = MAX_PORT_SIZE;
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
UINT32 size;
PortInfo *port = &ixEthDBPortInfo[portIndex];
/* generate trees only for ports that need them */
if (!port->updateMethod.searchTreePendingWrite && IS_PORT_INCLUDED(portIndex, updatePorts))
{
GET_MAP_SIZE(port->dependencyPortMap, size);
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Dependency map for port %d: size %d\n",
portIndex, size);
if (size < minimalSize)
{
minPortIndex = portIndex;
minimalSize = size;
}
}
else
{
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Skipped port %d from tree diff (%s)\n", portIndex,
port->updateMethod.searchTreePendingWrite ? "pending write access" : "ignored by query");
}
}
/* if a port was found than minimalSize is not MAX_PORT_SIZE */
if (minimalSize != MAX_PORT_SIZE)
{
/* minPortIndex is the port we seek */
PortInfo *port = &ixEthDBPortInfo[minPortIndex];
IxEthDBPortMap query;
MacTreeNode *baseTree;
/* now try to find a port with minimal map difference */
PortInfo *minimalDiffPort = NULL;
UINT32 minimalDiff = MAX_PORT_SIZE;
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal size port is %d\n", minPortIndex);
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
PortInfo *diffPort = &ixEthDBPortInfo[portIndex];
BOOL mapIsSubset;
IS_MAP_SUBSET(mapIsSubset, diffPort->dependencyPortMap, port->dependencyPortMap);
if (portIndex != minPortIndex
&& diffPort->updateMethod.searchTree != NULL
&& mapIsSubset)
{
/* compute size and pick only minimal size difference */
UINT32 diffPortSize;
UINT32 sizeDifference;
GET_MAP_SIZE(diffPort->dependencyPortMap, diffPortSize);
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Checking port %d for differences...\n", portIndex);
sizeDifference = minimalSize - diffPortSize;
if (sizeDifference < minimalDiff)
{
minimalDiffPort = diffPort;
minimalDiff = sizeDifference;
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal difference 0x%x was found on port %d\n",
minimalDiff, portIndex);
}
}
}
/* check if filtering is enabled on this port */
if ((port->featureStatus & IX_ETH_DB_FILTERING) != 0)
{
/* if minimalDiff is not MAX_PORT_SIZE minimalDiffPort points to the most similar port */
if (minimalDiff != MAX_PORT_SIZE)
{
baseTree = ixEthDBCloneMacTreeNode(minimalDiffPort->updateMethod.searchTree);
DIFF_MAPS(query, port->dependencyPortMap , minimalDiffPort->dependencyPortMap);
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Found minimal diff, extending tree %d on query\n",
minimalDiffPort->portID);
}
else /* .. otherwise no similar port was found, build tree from scratch */
{
baseTree = NULL;
COPY_DEPENDENCY_MAP(query, port->dependencyPortMap);
IX_ETH_DB_UPDATE_TRACE("DB: (Update) No similar diff, creating tree from query\n");
}
IS_EMPTY_DEPENDENCY_MAP(result, query);
if (!result) /* otherwise we don't need anything more on top of the cloned tree */
{
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding query tree to port %d\n", minPortIndex);
/* build learning tree */
port->updateMethod.searchTree = ixEthDBQuery(baseTree, query, IX_ETH_DB_ALL_FILTERING_RECORDS, MAX_ELT_SIZE);
}
else
{
IX_ETH_DB_UPDATE_TRACE("DB: (Update) Query is empty, assuming identical nearest tree\n");
port->updateMethod.searchTree = baseTree;
}
}
else
{
/* filtering is not enabled, will download an empty tree */
if (port->updateMethod.searchTree != NULL)
{
ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
}
port->updateMethod.searchTree = NULL;
}
/* mark tree as valid */
port->updateMethod.searchTreePendingWrite = true;
}
else
{
portsLeft = false;
IX_ETH_DB_UPDATE_TRACE("DB: (Update) No trees to create this round\n");
}
}
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
PortInfo *updatePort = &ixEthDBPortInfo[portIndex];
if (updatePort->updateMethod.searchTreePendingWrite)
{
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Starting procedure to upload new search tree (%snull) into NPE %d\n",
updatePort->updateMethod.searchTree != NULL ? "not " : "",
portIndex);
updatePort->updateMethod.updateHandler(portIndex, IX_ETH_DB_FILTERING_RECORD);
}
}
}
/**
* @brief standard NPE update handler
*
* @param portID id of the port to be updated
* @param type record type to be pushed during this update
*
* The NPE update handler manages updating the NPE databases
* given a certain record type.
*
* @internal
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type)
{
UINT32 epDelta, blockCount;
IxNpeMhMessage message;
UINT32 treeSize = 0;
PortInfo *port = &ixEthDBPortInfo[portID];
/* size selection and type check */
if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
{
treeSize = FULL_ELT_BYTE_SIZE;
}
else if (type == IX_ETH_DB_FIREWALL_RECORD)
{
treeSize = FULL_FW_BYTE_SIZE;
}
else
{
return IX_ETH_DB_INVALID_ARG;
}
/* serialize tree into memory */
ixEthDBNPETreeWrite(type, treeSize, port->updateMethod.npeUpdateZone, port->updateMethod.searchTree, &epDelta, &blockCount);
/* free internal copy */
if (port->updateMethod.searchTree != NULL)
{
ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
}
/* forget last used search tree */
port->updateMethod.searchTree = NULL;
port->updateMethod.searchTreePendingWrite = false;
/* dependending on the update type we do different things */
if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
{
IX_STATUS result;
FILL_SETMACADDRESSDATABASE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
epDelta, blockCount,
IX_OSAL_MMU_VIRT_TO_PHYS(port->updateMethod.npeUpdateZone));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
if (result == IX_SUCCESS)
{
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Finished downloading NPE tree on port %d\n", portID);
}
else
{
ixEthDBPortInfo[portID].agingEnabled = false;
ixEthDBPortInfo[portID].updateMethod.updateEnabled = false;
ixEthDBPortInfo[portID].updateMethod.userControlled = true;
ERROR_LOG("EthDB: (PortUpdate) disabling aging and updates on port %d (assumed dead)\n", portID);
ixEthDBDatabaseClear(portID, IX_ETH_DB_ALL_RECORD_TYPES);
return IX_ETH_DB_FAIL;
}
return IX_ETH_DB_SUCCESS;
}
else if (type == IX_ETH_DB_FIREWALL_RECORD)
{
return ixEthDBFirewallUpdate(portID, port->updateMethod.npeUpdateZone, epDelta);
}
return IX_ETH_DB_INVALID_ARG;
}
/**
* @brief queries the database for a set of records to be inserted into a given tree
*
* @param searchTree pointer to a tree where insertions will be performed; can be NULL
* @param query set of ports that a database record must match to be inserted into the tree
*
* The query method browses through the database, extracts all the descriptors matching
* the given query parameter and inserts them into the given learning tree.
* Note that this is an append procedure, the given tree needs not to be empty.
* A "descriptor matching the query" is a descriptor whose port id is in the query map.
* If the given tree is empty (NULL) a new tree is created and returned.
*
* @return the tree root
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maxEntries)
{
HashIterator iterator;
UINT32 entryCount = 0;
/* browse database */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) querying [%s]:%d on port map ... ",
mac2string(descriptor->macAddress),
descriptor->portID);
if ((descriptor->type & recordFilter) != 0
&& IS_PORT_INCLUDED(descriptor->portID, query))
{
MacDescriptor *descriptorClone = ixEthDBCloneMacDescriptor(descriptor);
IX_ETH_DB_UPDATE_TRACE("match\n");
if (descriptorClone != NULL)
{
/* add descriptor to tree */
searchTree = ixEthDBTreeInsert(searchTree, descriptorClone);
entryCount++;
}
}
else
{
IX_ETH_DB_UPDATE_TRACE("no match\n");
}
if (entryCount < maxEntries)
{
/* advance to the next record */
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
}
else
{
/* the NPE won't accept more entries so we can stop now */
ixEthDBReleaseHashIterator(&iterator);
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) number of elements reached maximum supported by port\n");
break;
}
}
IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) query inserted %d records in the search tree\n", entryCount);
return ixEthDBTreeRebalance(searchTree);
}
/**
* @brief inserts a mac descriptor into an tree
*
* @param searchTree tree where the insertion is to be performed (may be NULL)
* @param descriptor descriptor to insert into tree
*
* @return the tree root
*
* @internal
*/
IX_ETH_DB_PRIVATE
MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor)
{
MacTreeNode *currentNode = searchTree;
MacTreeNode *insertLocation = NULL;
MacTreeNode *newNode;
INT32 insertPosition = RIGHT;
if (descriptor == NULL)
{
return searchTree;
}
/* create a new node */
newNode = ixEthDBAllocMacTreeNode();
if (newNode == NULL)
{
/* out of memory */
ERROR_LOG("Warning: ixEthDBAllocMacTreeNode returned NULL in file %s:%d (out of memory?)\n", __FILE__, __LINE__);
ixEthDBFreeMacDescriptor(descriptor);
return NULL;
}
/* populate node */
newNode->descriptor = descriptor;
/* an empty initial tree is a special case */
if (searchTree == NULL)
{
return newNode;
}
/* get insertion location */
while (insertLocation == NULL)
{
MacTreeNode *nextNode;
/* compare given key with current node key */
insertPosition = ixEthDBAddressCompare(descriptor->macAddress, currentNode->descriptor->macAddress);
/* navigate down */
if (insertPosition == RIGHT)
{
nextNode = currentNode->right;
}
else if (insertPosition == LEFT)
{
nextNode = currentNode->left;
}
else
{
/* error, duplicate key */
ERROR_LOG("Warning: trapped insertion of a duplicate MAC address in an NPE search tree\n");
/* this will free the MAC descriptor as well */
ixEthDBFreeMacTreeNode(newNode);
return searchTree;
}
/* when we can no longer dive through the tree we found the insertion place */
if (nextNode != NULL)
{
currentNode = nextNode;
}
else
{
insertLocation = currentNode;
}
}
/* insert node */
if (insertPosition == RIGHT)
{
insertLocation->right = newNode;
}
else
{
insertLocation->left = newNode;
}
return searchTree;
}
/**
* @brief balance a tree
*
* @param searchTree tree to balance
*
* Converts a tree into a balanced tree and returns the root of
* the balanced tree. The resulting tree is <i>route balanced</i>
* not <i>perfectly balanced</i>. This makes no difference to the
* average tree search time which is the same in both cases, O(log2(n)).
*
* @return root of the balanced tree or NULL if there's no memory left
*
* @internal
*/
IX_ETH_DB_PRIVATE
MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree)
{
MacTreeNode *pseudoRoot = ixEthDBAllocMacTreeNode();
UINT32 size;
if (pseudoRoot == NULL)
{
/* out of memory */
return NULL;
}
pseudoRoot->right = searchTree;
ixEthDBRebalanceTreeToVine(pseudoRoot, &size);
ixEthDBRebalanceVineToTree(pseudoRoot, size);
searchTree = pseudoRoot->right;
/* remove pseudoRoot right branch, otherwise it will free the entire tree */
pseudoRoot->right = NULL;
ixEthDBFreeMacTreeNode(pseudoRoot);
return searchTree;
}
/**
* @brief converts a tree into a vine
*
* @param root root of tree to convert
* @param size depth of vine (equal to the number of nodes in the tree)
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size)
{
MacTreeNode *vineTail = root;
MacTreeNode *remainder = vineTail->right;
MacTreeNode *tempPtr;
*size = 0;
while (remainder != NULL)
{
if (remainder->left == NULL)
{
/* move tail down one */
vineTail = remainder;
remainder = remainder->right;
(*size)++;
}
else
{
/* rotate around remainder */
tempPtr = remainder->left;
remainder->left = tempPtr->right;
tempPtr->right = remainder;
remainder = tempPtr;
vineTail->right = tempPtr;
}
}
}
/**
* @brief converts a vine into a balanced tree
*
* @param root vine to convert
* @param size depth of vine
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size)
{
UINT32 leafCount = size + 1 - (1 << ixEthDBRebalanceLog2Floor(size + 1));
ixEthDBRebalanceCompression(root, leafCount);
size = size - leafCount;
while (size > 1)
{
ixEthDBRebalanceCompression(root, size / 2);
size /= 2;
}
}
/**
* @brief compresses a vine/tree stage into a more balanced vine/tree
*
* @param root root of the tree to compress
* @param count number of "spine" nodes
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count)
{
MacTreeNode *scanner = root;
MacTreeNode *child;
UINT32 local_index;
for (local_index = 0 ; local_index < count ; local_index++)
{
child = scanner->right;
scanner->right = child->right;
scanner = scanner->right;
child->right = scanner->left;
scanner->left = child;
}
}
/**
* @brief computes |_log2(x)_| (a.k.a. floor(log2(x)))
*
* @param x number to compute |_log2(x)_| for
*
* @return |_log2(x)_|
*
* @internal
*/
IX_ETH_DB_PRIVATE
UINT32 ixEthDBRebalanceLog2Floor(UINT32 x)
{
UINT32 log = 0;
UINT32 val = 1;
while (val < x)
{
log++;
val <<= 1;
}
return val == x ? log : log - 1;
}

View File

@ -1,628 +0,0 @@
/**
* @file IxEthDBAPI.c
*
* @brief Implementation of the public API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
extern HashTable dbHashtable;
IX_ETH_DB_PRIVATE void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter);
IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter);
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map);
/**
* @brief displays a port dependency map
*
* @param portID ID of the port
* @param map port map to display
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map)
{
UINT32 portIndex;
BOOL mapSelf = true, mapNone = true, firstPort = true;
/* dependency port maps */
printf("Dependency port map: ");
/* browse the port map */
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
if (IS_PORT_INCLUDED(portIndex, map))
{
mapNone = false;
if (portIndex != portID)
{
mapSelf = false;
}
printf("%s%d", firstPort ? "{" : ", ", portIndex);
firstPort = false;
}
}
if (mapNone)
{
mapSelf = false;
}
printf("%s (%s)\n", firstPort ? "" : "}", mapSelf ? "self" : mapNone ? "none" : "group");
return IX_ETH_DB_SUCCESS;
}
/**
* @brief displays all the filtering records belonging to a port
*
* @param portID ID of the port to display
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
* instead. Calling this function is equivalent to calling
* ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD)
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID)
{
IxEthDBStatus local_result;
HashIterator iterator;
PortInfo *portInfo;
UINT32 recordCount = 0;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
portInfo = &ixEthDBPortInfo[portID];
/* display table header */
printf("Ethernet database records for port ID [%d]\n", portID);
ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
}
else
{
printf("updates disabled (not an NPE)\n\n");
}
printf(" MAC address | Age | Type \n");
printf("___________________________________\n");
/* browse database */
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
recordCount++;
/* display entry */
printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d | %s\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
}
/* move to the next record */
BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
/* debug */
if (local_result == IX_ETH_DB_BUSY)
{
return IX_ETH_DB_FAIL;
}
}
/* display number of records */
printf("\nFound %d records\n", recordCount);
return IX_ETH_DB_SUCCESS;
}
/**
* @brief displays all the filtering records belonging to all the ports
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
* instead. Calling this function is equivalent to calling
* ixEthDBFilteringDatabaseShowRecords(IX_ETH_DB_ALL_PORTS, IX_ETH_DB_FILTERING_RECORD)
*/
IX_ETH_DB_PUBLIC
void ixEthDBFilteringDatabaseShowAll()
{
IxEthDBPortId portIndex;
printf("\nEthernet learning/filtering database: listing %d ports\n\n", (UINT32) IX_ETH_DB_NUMBER_OF_PORTS);
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
{
ixEthDBFilteringDatabaseShow(portIndex);
if (portIndex < IX_ETH_DB_NUMBER_OF_PORTS - 1)
{
printf("\n");
}
}
}
/**
* @brief displays one record in a format depending on the record filter
*
* @param descriptor pointer to the record
* @param recordFilter format filter
*
* This function will display the fields in a record depending on the
* selected record filter.
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBRecordShow(MacDescriptor *descriptor, IxEthDBRecordType recordFilter)
{
if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
|| recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
{
/* display VLAN record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
printf("___________________________________________________________________\n"); */
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | %d | %d | %d\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringVlanData.age,
descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
(descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
}
else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | - | - | -\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
}
}
else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
{
/* display filtering record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | Age | Type \n");
printf("_______________________________________\n"); */
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
}
}
else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
{
/* display WiFi record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | GW MAC address \n");
printf("_______________________________________\n"); */
if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
{
if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
{
/* gateway address present */
printf("%02X:%02X:%02X:%02X:%02X:%02X | %02X:%02X:%02X:%02X:%02X:%02X \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.wifiData.gwMacAddress[0],
descriptor->recordData.wifiData.gwMacAddress[1],
descriptor->recordData.wifiData.gwMacAddress[2],
descriptor->recordData.wifiData.gwMacAddress[3],
descriptor->recordData.wifiData.gwMacAddress[4],
descriptor->recordData.wifiData.gwMacAddress[5]);
}
else
{
/* no gateway */
printf("%02X:%02X:%02X:%02X:%02X:%02X | ----no gateway----- \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
}
else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
{
/* display Firewall record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address \n");
printf("__________________\n"); */
if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
{
/* display composite record header - leave this commented code in place, its purpose is to align the print format with the header
printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
printf("_______________________________________________________________________________\n"); */
if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | VLAN | %2d | %s | %4d | %1d | %1d | -----------------\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringVlanData.age,
descriptor->recordData.filteringVlanData.staticEntry ? "static " : "dynamic",
IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
(descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
}
else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | Filter | %2d | %s | ---- | - | --- | -----------------\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.filteringData.age,
descriptor->recordData.filteringData.staticEntry ? "static " : "dynamic");
}
else if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
{
if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
{
/* gateway address present */
printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>AP | ---- | - | --- | %02X:%02X:%02X:%02X:%02X:%02X\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5],
descriptor->recordData.wifiData.gwMacAddress[0],
descriptor->recordData.wifiData.gwMacAddress[1],
descriptor->recordData.wifiData.gwMacAddress[2],
descriptor->recordData.wifiData.gwMacAddress[3],
descriptor->recordData.wifiData.gwMacAddress[4],
descriptor->recordData.wifiData.gwMacAddress[5]);
}
else
{
/* no gateway */
printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>ST | ---- | - | --- | -- no gateway -- \n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
else if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
{
printf("%02X:%02X:%02X:%02X:%02X:%02X | FW | -- | ------- | ---- | - | --- | -----------------\n",
descriptor->macAddress[0],
descriptor->macAddress[1],
descriptor->macAddress[2],
descriptor->macAddress[3],
descriptor->macAddress[4],
descriptor->macAddress[5]);
}
}
else
{
printf("invalid record filter\n");
}
}
/**
* @brief displays the status, records and configuration information of a port
*
* @param portID ID of the port
* @param recordFilter record filter to display
*
* @internal
*/
IX_ETH_DB_PRIVATE
void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
{
PortInfo *portInfo = &ixEthDBPortInfo[portID];
UINT32 recordCount = 0;
HashIterator iterator;
IxEthDBStatus local_result;
/* display port status */
printf("== Port ID %d ==\n", portID);
/* display capabilities */
printf("- Capabilities: ");
if ((portInfo->featureCapability & IX_ETH_DB_LEARNING) != 0)
{
printf("Learning (%s) ", ((portInfo->featureStatus & IX_ETH_DB_LEARNING) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
{
printf("VLAN/QoS (%s) ", ((portInfo->featureStatus & IX_ETH_DB_VLAN_QOS) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
{
printf("Firewall (%s) ", ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
{
printf("WiFi (%s) ", ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) ? "on" : "off");
}
if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
{
printf("STP (%s) ", ((portInfo->featureStatus & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) ? "on" : "off");
}
printf("\n");
/* dependency map */
ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
/* NPE dynamic updates */
if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
{
printf(" - NPE dynamic update is %s\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
}
else
{
printf(" - dynamic update disabled (not an NPE)\n");
}
if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
{
if ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
{
/* WiFi header conversion */
if ((portInfo->frameControlDurationID
+ portInfo->bbsid[0]
+ portInfo->bbsid[1]
+ portInfo->bbsid[2]
+ portInfo->bbsid[3]
+ portInfo->bbsid[4]
+ portInfo->bbsid[5]) == 0)
{
printf(" - WiFi header conversion not configured\n");
}
else
{
printf(" - WiFi header conversion: BBSID [%02X:%02X:%02X:%02X:%02X:%02X], Frame Control 0x%X, Duration/ID 0x%X\n",
portInfo->bbsid[0],
portInfo->bbsid[1],
portInfo->bbsid[2],
portInfo->bbsid[3],
portInfo->bbsid[4],
portInfo->bbsid[5],
portInfo->frameControlDurationID >> 16,
portInfo->frameControlDurationID & 0xFFFF);
}
}
else
{
printf(" - WiFi header conversion not enabled\n");
}
}
/* Firewall */
if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
{
if ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0)
{
printf(" - Firewall is in %s-list mode\n", portInfo->firewallMode == IX_ETH_DB_FIREWALL_BLACK_LIST ? "black" : "white");
printf(" - Invalid source MAC address filtering is %s\n", portInfo->srcAddressFilterEnabled ? "enabled" : "disabled");
}
else
{
printf(" - Firewall not enabled\n");
}
}
/* browse database if asked to display records */
if (recordFilter != IX_ETH_DB_NO_RECORD_TYPE)
{
printf("\n");
ixEthDBHeaderShow(recordFilter);
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
while (IS_ITERATOR_VALID(&iterator))
{
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
if (descriptor->portID == portID && (descriptor->type & recordFilter) != 0)
{
recordCount++;
/* display entry */
ixEthDBRecordShow(descriptor, recordFilter);
}
/* move to the next record */
BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
/* debug */
if (local_result == IX_ETH_DB_BUSY)
{
printf("EthDB (API): Error, database browser failed (no access), giving up\n");
}
}
printf("\nFound %d records\n\n", recordCount);
}
}
/**
* @brief displays a record header
*
* @param recordFilter record type filter
*
* This function displays a record header, depending on
* the given record type filter. It is useful when used
* in conjunction with ixEthDBRecordShow which will display
* record fields formatted for the header, provided the same
* record filter is used.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or IX_ETH_DB_INVALID_ARG if the recordFilter
* parameter is invalid or not supported
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter)
{
if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
|| recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
{
/* display VLAN record header */
printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
printf("___________________________________________________________________\n");
}
else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
{
/* display filtering record header */
printf(" MAC address | Age | Type \n");
printf("_______________________________________\n");
}
else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
{
/* display WiFi record header */
printf(" MAC address | GW MAC address \n");
printf("_______________________________________\n");
}
else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
{
/* display Firewall record header */
printf(" MAC address \n");
printf("__________________\n");
}
else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
{
/* display composite record header */
printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
printf("_______________________________________________________________________________\n");
}
else
{
return IX_ETH_DB_INVALID_ARG;
}
return IX_ETH_DB_SUCCESS;
}
/**
* @brief displays database information (records and port information)
*
* @param portID ID of the port to display (or IX_ETH_DB_ALL_PORTS for all the ports)
* @param recordFilter record filter (use IX_ETH_DB_NO_RECORD_TYPE to display only
* port information)
*
* Note that this function is documented in the main component header
* file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully or
* an appropriate error code otherwise
*
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
{
IxEthDBPortId currentPort;
BOOL showAllPorts = (portID == IX_ETH_DB_ALL_PORTS);
IX_ETH_DB_CHECK_PORT_ALL(portID);
printf("\nEthernet learning/filtering database: listing %d port(s)\n\n", showAllPorts ? (UINT32) IX_ETH_DB_NUMBER_OF_PORTS : 1);
currentPort = showAllPorts ? 0 : portID;
while (currentPort != IX_ETH_DB_NUMBER_OF_PORTS)
{
/* display port info */
ixEthDBPortInfoShow(currentPort, recordFilter);
/* next port */
currentPort = showAllPorts ? currentPort + 1 : IX_ETH_DB_NUMBER_OF_PORTS;
}
return IX_ETH_DB_SUCCESS;
}

View File

@ -1,303 +0,0 @@
/**
* @file IxEthDBSearch.c
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
extern HashTable dbHashtable;
/**
* @brief matches two database records based on their MAC addresses
*
* @param untypedReference record to match against
* @param untypedEntry record to match
*
* @return true if the match is successful or false otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry)
{
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
MacDescriptor *reference = (MacDescriptor *) untypedReference;
/* check accepted record types */
if ((entry->type & reference->type) == 0) return false;
return (ixEthDBAddressCompare((UINT8 *) entry->macAddress, (UINT8 *) reference->macAddress) == 0);
}
/**
* @brief matches two database records based on their MAC addresses
* and VLAN IDs
*
* @param untypedReference record to match against
* @param untypedEntry record to match
*
* @return true if the match is successful or false otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry)
{
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
MacDescriptor *reference = (MacDescriptor *) untypedReference;
/* check accepted record types */
if ((entry->type & reference->type) == 0) return false;
return (IX_ETH_DB_GET_VLAN_ID(entry->recordData.filteringVlanData.ieee802_1qTag) ==
IX_ETH_DB_GET_VLAN_ID(reference->recordData.filteringVlanData.ieee802_1qTag)) &&
(ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
}
/**
* @brief matches two database records based on their MAC addresses
* and port IDs
*
* @param untypedReference record to match against
* @param untypedEntry record to match
*
* @return true if the match is successful or false otherwise
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry)
{
MacDescriptor *entry = (MacDescriptor *) untypedEntry;
MacDescriptor *reference = (MacDescriptor *) untypedReference;
/* check accepted record types */
if ((entry->type & reference->type) == 0) return false;
return (entry->portID == reference->portID) &&
(ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
}
/**
* @brief dummy matching function, registered for safety
*
* @param reference record to match against (unused)
* @param entry record to match (unused)
*
* This function is registered in the matching functions
* array on invalid types. Calling it will display an
* error message, indicating an error in the component logic.
*
* @return false
*
* @internal
*/
IX_ETH_DB_PUBLIC
BOOL ixEthDBNullMatch(void *reference, void *entry)
{
/* display an error message */
ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "DB: (Search) The NullMatch function was called, wrong key type?\n", 0, 0, 0, 0, 0, 0);
return false;
}
/**
* @brief registers hash matching methods
*
* @param matchFunctions table of match functions to be populated
*
* This function registers the available record matching functions
* by indexing them on record types into the given function array.
*
* Note that it is compulsory to call this in ixEthDBInit(),
* otherwise hashtable searching and removal will not work
*
* @return number of registered functions
*
* @internal
*/
IX_ETH_DB_PUBLIC
UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions)
{
UINT32 i;
/* safety first */
for ( i = 0 ; i < IX_ETH_DB_MAX_KEY_INDEX + 1 ; i++)
{
matchFunctions[i] = ixEthDBNullMatch;
}
/* register MAC search method */
matchFunctions[IX_ETH_DB_MAC_KEY] = ixEthDBAddressRecordMatch;
/* register MAC/PortID search method */
matchFunctions[IX_ETH_DB_MAC_PORT_KEY] = ixEthDBPortRecordMatch;
/* register MAC/VLAN ID search method */
matchFunctions[IX_ETH_DB_MAC_VLAN_KEY] = ixEthDBVlanRecordMatch;
return 3; /* three methods */
}
/**
* @brief search a record in the Ethernet datbase
*
* @param macAddress MAC address to perform the search on
* @param typeFilter type of records to consider for matching
*
* @warning if searching is successful an implicit write lock
* to the search result is granted, therefore unlock the
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
*
* @see ixEthDBReleaseHashNode()
*
* @return the search result, or NULL if a record with the given
* MAC address was not found
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
{
HashNode *searchResult = NULL;
MacDescriptor reference;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
if (macAddress == NULL)
{
return NULL;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
/* set acceptable record types */
reference.type = typeFilter;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult));
return searchResult;
}
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
{
MacDescriptor reference;
IxEthDBStatus result;
TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
if (macAddress == NULL)
{
return IX_ETH_DB_INVALID_ARG;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
/* set acceptable record types */
reference.type = typeFilter;
result = ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference);
return result;
}
/**
* @brief search a record in the Ethernet datbase
*
* @param macAddress MAC address to perform the search on
* @param portID port ID to perform the search on
* @param typeFilter type of records to consider for matching
*
* @warning if searching is successful an implicit write lock
* to the search result is granted, therefore unlock the
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
*
* @see ixEthDBReleaseHashNode()
*
* @return the search result, or NULL if a record with the given
* MAC address/port ID combination was not found
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter)
{
HashNode *searchResult = NULL;
MacDescriptor reference;
if (macAddress == NULL)
{
return NULL;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
reference.portID = portID;
/* set acceptable record types */
reference.type = typeFilter;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult));
return searchResult;
}
/**
* @brief search a record in the Ethernet datbase
*
* @param macAddress MAC address to perform the search on
* @param vlanID VLAN ID to perform the search on
* @param typeFilter type of records to consider for matching
*
* @warning if searching is successful an implicit write lock
* to the search result is granted, therefore unlock the
* entry using @ref ixEthDBReleaseHashNode() as soon as possible.
*
* @see ixEthDBReleaseHashNode()
*
* @return the search result, or NULL if a record with the given
* MAC address/VLAN ID combination was not found
*
* @internal
*/
IX_ETH_DB_PUBLIC
HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter)
{
HashNode *searchResult = NULL;
MacDescriptor reference;
if (macAddress == NULL)
{
return NULL;
}
/* fill search fields */
memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
reference.recordData.filteringVlanData.ieee802_1qTag =
IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID);
/* set acceptable record types */
reference.type = typeFilter;
BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult));
return searchResult;
}

View File

@ -1,83 +0,0 @@
/**
* @file IxEthDBSpanningTree.c
*
* @brief Implementation of the STP API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/**
* @brief sets the STP blocking state of a port
*
* @param portID ID of the port
* @param blocked true to block the port or false to unblock it
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
{
IxNpeMhMessage message;
IX_STATUS result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
ixEthDBPortInfo[portID].stpBlocked = blocked;
FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked);
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief retrieves the STP blocking state of a port
*
* @param portID ID of the port
* @param blocked address to write the blocked status into
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
IX_ETH_DB_CHECK_REFERENCE(blocked);
*blocked = ixEthDBPortInfo[portID].stpBlocked;
return IX_ETH_DB_SUCCESS;
}

View File

@ -1,96 +0,0 @@
/**
* @file ethUtil.c
*
* @brief Utility functions
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxFeatureCtrl.h"
#include "IxEthDB_p.h"
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portID)
{
/* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if ((portID == 0) &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
return IX_ETH_DB_FAIL;
}
if ((portID == 1) &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
return IX_ETH_DB_FAIL;
}
if ((portID == 2) &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
return IX_ETH_DB_FAIL;
}
}
return IX_ETH_DB_SUCCESS;
}
IX_ETH_DB_PUBLIC
BOOL ixEthDBCheckSingleBitValue(UINT32 value)
{
#if (CPU != SIMSPARCSOLARIS) && !defined (__wince)
UINT32 shift;
/* use the count-leading-zeros XScale instruction */
__asm__ ("clz %0, %1\n" : "=r" (shift) : "r" (value));
return ((value << shift) == 0x80000000UL);
#else
while (value != 0)
{
if (value == 1) return true;
else if ((value & 1) == 1) return false;
value >>= 1;
}
return false;
#endif
}
const char *mac2string(const unsigned char *mac)
{
static char str[19];
if (mac == NULL)
{
return NULL;
}
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return str;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,456 +0,0 @@
/**
* @file IxEthDBAPI.c
*
* @brief Implementation of the public API
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxEthDB_p.h"
/* forward prototypes */
IX_ETH_DB_PUBLIC
MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations);
/**
* @brief sets the BBSID value for the WiFi header conversion feature
*
* @param portID ID of the port
* @param bbsid pointer to the 6-byte BBSID value
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
{
IxNpeMhMessage message;
IX_STATUS result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
IX_ETH_DB_CHECK_REFERENCE(bbsid);
memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr));
FILL_SETBBSID_MSG(message, portID, bbsid);
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief updates the Frame Control and Duration/ID WiFi header
* conversion parameters in an NPE
*
* @param portID ID of the port
*
* This function will send a message to the NPE updating the
* frame conversion parameters for 802.3 => 802.11 header conversion.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or IX_ETH_DB_FAIL otherwise
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID)
{
IxNpeMhMessage message;
IX_STATUS result;
FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID);
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
return result;
}
/**
* @brief sets the Duration/ID WiFi frame header conversion parameter
*
* @param portID ID of the port
* @param durationID 16-bit value containing the new Duration/ID parameter
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID;
return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
}
/**
* @brief sets the Frame Control WiFi frame header conversion parameter
*
* @param portID ID of the port
* @param durationID 16-bit value containing the new Frame Control parameter
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
{
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16);
return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
}
/**
* @brief removes a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to remove
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
recordTemplate.portID = portID;
return ixEthDBRemove(&recordTemplate, NULL);
}
/**
* @brief adds a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to add
* @param gatewayMacAddr address of the gateway (or
* NULL if this is a station record)
*
* This function adds a record of type AP_TO_AP (gateway is not NULL)
* or AP_TO_STA (gateway is NULL) in the main database as a
* WiFi header conversion record.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*
* @internal
*/
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
{
MacDescriptor recordTemplate;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_REFERENCE(macAddr);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
recordTemplate.portID = portID;
if (gatewayMacAddr != NULL)
{
memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr));
recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP;
}
else
{
memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr));
recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA;
}
return ixEthDBAdd(&recordTemplate, NULL);
}
/**
* @brief adds a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to add
* @param gatewayMacAddr address of the gateway
*
* This function adds a record of type AP_TO_AP
* in the main database as a WiFi header conversion record.
*
* This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
{
IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr);
return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr);
}
/**
* @brief adds a WiFi header conversion record
*
* @param portID ID of the port
* @param macAddr MAC address of the record to add
*
* This function adds a record of type AP_TO_STA
* in the main database as a WiFi header conversion record.
*
* This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
*
* Note that this function is documented in the main
* component header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed
* successfully or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
return ixEthDBWiFiEntryAdd(portID, macAddr, NULL);
}
/**
* @brief selects a set of gateways from a tree of
* WiFi header conversion records
*
* @param stations binary tree containing pointers to WiFi header
* conversion records
*
* This function browses through the input binary tree, identifies
* records of type AP_TO_AP, clones these records and appends them
* to a vine (a single right-branch binary tree) which is returned
* as result. A maximum of MAX_GW_SIZE entries containing gateways
* will be cloned from the original tree.
*
* @return vine (linear binary tree) containing record
* clones of AP_TO_AP type, which have a gateway field
*
* @internal
*/
IX_ETH_DB_PUBLIC
MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations)
{
MacTreeNodeStack *stack;
MacTreeNode *gateways, *insertionPlace;
UINT32 gwIndex = 1; /* skip the empty root */
if (stations == NULL)
{
return NULL;
}
stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
if (stack == NULL)
{
ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n");
return NULL;
}
/* initialize root node */
gateways = insertionPlace = NULL;
/* start browsing the station tree */
NODE_STACK_INIT(stack);
/* initialize stack by pushing the tree root at offset 0 */
NODE_STACK_PUSH(stack, stations, 0);
while (NODE_STACK_NONEMPTY(stack))
{
MacTreeNode *node;
UINT32 offset;
NODE_STACK_POP(stack, node, offset);
/* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */
if (offset > (MAX_GW_SIZE - 1)) break;
/* check if this record has a gateway address */
if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
{
/* found a record, create an insertion place */
if (insertionPlace != NULL)
{
insertionPlace->right = ixEthDBAllocMacTreeNode();
insertionPlace = insertionPlace->right;
}
else
{
gateways = ixEthDBAllocMacTreeNode();
insertionPlace = gateways;
}
if (insertionPlace == NULL)
{
/* no nodes left, bail out with what we have */
ixOsalCacheDmaFree(stack);
return gateways;
}
/* clone the original record for the gateway tree */
insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor);
/* insert and update the offset in the original record */
node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++;
}
/* browse the tree */
if (node->left != NULL)
{
NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
}
if (node->right != NULL)
{
NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
}
}
ixOsalCacheDmaFree(stack);
return gateways;
}
/**
* @brief downloads the WiFi header conversion table to an NPE
*
* @param portID ID of the port
*
* This function prepares the WiFi header conversion tables and
* downloads them to the specified NPE port.
*
* The header conversion tables consist in the main table of
* addresses and the secondary table of gateways. AP_TO_AP records
* from the first table contain index fields into the second table
* for gateway selection.
*
* Note that this function is documented in the main component
* header file, IxEthDB.h.
*
* @return IX_ETH_DB_SUCCESS if the operation completed successfully
* or an appropriate error message otherwise
*/
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
{
IxEthDBPortMap query;
MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL;
IxNpeMhMessage message;
PortInfo *portInfo;
IX_STATUS result;
IX_ETH_DB_CHECK_PORT(portID);
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
portInfo = &ixEthDBPortInfo[portID];
SET_DEPENDENCY_MAP(query, portID);
ixEthDBUpdateLock();
stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE);
gateways = ixEthDBGatewaySelect(stations);
/* clean up gw area */
memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0);
/* write all gateways */
gateway = gateways;
while (gateway != NULL)
{
ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone)
+ gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE),
gateway);
gateway = gateway->right;
}
/* free the gateway tree */
if (gateways != NULL)
{
ixEthDBFreeMacTreeNode(gateways);
}
FILL_SETAPMACTABLE_MSG(message,
IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone));
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
if (result == IX_SUCCESS)
{
/* update the main tree (the stations tree) */
portInfo->updateMethod.searchTree = stations;
result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD);
}
ixEthDBUpdateUnlock();
return result;
}

View File

@ -1,473 +0,0 @@
/**
* @file IxEthMii.c
*
* @author Intel Corporation
* @date
*
* @brief MII control functions
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxEthAcc.h"
#include "IxEthMii_p.h"
#ifdef __wince
#include "IxOsPrintf.h"
#endif
/* Array to store the phy IDs of the discovered phys */
PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR];
/*********************************************************
*
* Scan for PHYs on the MII bus. This function returns
* an array of booleans, one for each PHY address.
* If a PHY is found at a particular address, the
* corresponding entry in the array is set to true.
*
*/
PUBLIC IX_STATUS
ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
{
UINT32 i;
UINT16 regval, regvalId1, regvalId2;
/*Search for PHYs on the MII*/
/*Search for existant phys on the MDIO bus*/
if ((phyPresent == NULL) ||
(maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR))
{
return IX_FAIL;
}
/* fill the array */
for(i=0;
i<IXP425_ETH_ACC_MII_MAX_ADDR;
i++)
{
phyPresent[i] = false;
}
/* iterate through the PHY addresses */
for(i=0;
maxPhyCount > 0 && i<IXP425_ETH_ACC_MII_MAX_ADDR;
i++)
{
ixEthMiiPhyId[i] = IX_ETH_MII_INVALID_PHY_ID;
if(ixEthAccMiiReadRtn(i,
IX_ETH_MII_CTRL_REG,
&regval) == IX_ETH_ACC_SUCCESS)
{
if((regval & 0xffff) != 0xffff)
{
maxPhyCount--;
/*Need to read the register twice here to flush PHY*/
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, &regvalId1);
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, &regvalId1);
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID2_REG, &regvalId2);
ixEthMiiPhyId[i] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
if ((ixEthMiiPhyId[i] == IX_ETH_MII_KS8995_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT971_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT972_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973A3_PHY_ID)
|| (ixEthMiiPhyId[i] == IX_ETH_MII_LXT9785_PHY_ID)
)
{
/* supported phy */
phyPresent[i] = true;
} /* end of if(ixEthMiiPhyId) */
else
{
if (ixEthMiiPhyId[i] != IX_ETH_MII_INVALID_PHY_ID)
{
/* unsupported phy */
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixEthMiiPhyScan : unexpected Mii PHY ID %8.8x\n",
ixEthMiiPhyId[i], 2, 3, 4, 5, 6);
ixEthMiiPhyId[i] = IX_ETH_MII_UNKNOWN_PHY_ID;
phyPresent[i] = true;
}
}
}
}
}
return IX_SUCCESS;
}
/************************************************************
*
* Configure the PHY at the specified address
*
*/
PUBLIC IX_STATUS
ixEthMiiPhyConfig(UINT32 phyAddr,
BOOL speed100,
BOOL fullDuplex,
BOOL autonegotiate)
{
UINT16 regval=0;
/* parameter check */
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
{
/*
* set the control register
*/
if(autonegotiate)
{
regval |= IX_ETH_MII_CR_AUTO_EN | IX_ETH_MII_CR_RESTART;
}
else
{
if(speed100)
{
regval |= IX_ETH_MII_CR_100;
}
if(fullDuplex)
{
regval |= IX_ETH_MII_CR_FDX;
}
} /* end of if-else() */
if (ixEthAccMiiWriteRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
regval) == IX_ETH_ACC_SUCCESS)
{
return IX_SUCCESS;
}
} /* end of if(phyAddr) */
return IX_FAIL;
}
/******************************************************************
*
* Enable the PHY Loopback at the specified address
*/
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackEnable (UINT32 phyAddr)
{
UINT16 regval ;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
{
/* read/write the control register */
if(ixEthAccMiiReadRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
&regval)
== IX_ETH_ACC_SUCCESS)
{
if(ixEthAccMiiWriteRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
regval | IX_ETH_MII_CR_LOOPBACK)
== IX_ETH_ACC_SUCCESS)
{
return IX_SUCCESS;
}
}
}
return IX_FAIL;
}
/******************************************************************
*
* Disable the PHY Loopback at the specified address
*/
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackDisable (UINT32 phyAddr)
{
UINT16 regval ;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
{
/* read/write the control register */
if(ixEthAccMiiReadRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
&regval)
== IX_ETH_ACC_SUCCESS)
{
if(ixEthAccMiiWriteRtn (phyAddr,
IX_ETH_MII_CTRL_REG,
regval & (~IX_ETH_MII_CR_LOOPBACK))
== IX_ETH_ACC_SUCCESS)
{
return IX_SUCCESS;
}
}
}
return IX_FAIL;
}
/******************************************************************
*
* Reset the PHY at the specified address
*/
PUBLIC IX_STATUS
ixEthMiiPhyReset(UINT32 phyAddr)
{
UINT32 timeout;
UINT16 regval;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
{
if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973A3_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
)
{
/* use the control register to reset the phy */
ixEthAccMiiWriteRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_RESET);
/* poll until the reset bit is cleared */
timeout = 0;
do
{
ixOsalSleep (IX_ETH_MII_RESET_POLL_MS);
/* read the control register and check for timeout */
ixEthAccMiiReadRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
&regval);
if ((regval & IX_ETH_MII_CR_RESET) == 0)
{
/* timeout bit is self-cleared */
break;
}
timeout += IX_ETH_MII_RESET_POLL_MS;
}
while (timeout < IX_ETH_MII_RESET_DELAY_MS);
/* check for timeout */
if (timeout >= IX_ETH_MII_RESET_DELAY_MS)
{
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_NORM_EN);
return IX_FAIL;
}
return IX_SUCCESS;
} /* end of if(ixEthMiiPhyId) */
else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID)
{
/* reset bit is reserved, just reset the control register */
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_NORM_EN);
return IX_SUCCESS;
}
else
{
/* unknown PHY, set the control register reset bit,
* wait 2 s. and clear the control register.
*/
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_RESET);
ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS);
ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
IX_ETH_MII_CR_NORM_EN);
return IX_SUCCESS;
} /* end of if-else(ixEthMiiPhyId) */
} /* end of if(phyAddr) */
return IX_FAIL;
}
/*****************************************************************
*
* Link state query functions
*/
PUBLIC IX_STATUS
ixEthMiiLinkStatus(UINT32 phyAddr,
BOOL *linkUp,
BOOL *speed100,
BOOL *fullDuplex,
BOOL *autoneg)
{
UINT16 ctrlRegval, statRegval, regval, regval4, regval5;
/* check the parameters */
if ((linkUp == NULL) ||
(speed100 == NULL) ||
(fullDuplex == NULL) ||
(autoneg == NULL))
{
return IX_FAIL;
}
*linkUp = false;
*speed100 = false;
*fullDuplex = false;
*autoneg = false;
if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
{
if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
)
{
/* --------------------------------------------------*/
/* Retrieve information from PHY specific register */
/* --------------------------------------------------*/
if (ixEthAccMiiReadRtn(phyAddr,
IX_ETH_MII_STAT2_REG,
&regval) != IX_ETH_ACC_SUCCESS)
{
return IX_FAIL;
}
*linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0);
*speed100 = ((regval & IX_ETH_MII_SR2_100) != 0);
*fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0);
*autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0);
return IX_SUCCESS;
} /* end of if(ixEthMiiPhyId) */
else
{
/* ----------------------------------------------------*/
/* Retrieve information from status and ctrl registers */
/* ----------------------------------------------------*/
if (ixEthAccMiiReadRtn(phyAddr,
IX_ETH_MII_CTRL_REG,
&ctrlRegval) != IX_ETH_ACC_SUCCESS)
{
return IX_FAIL;
}
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &statRegval);
*linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0);
if (*linkUp)
{
*autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) &&
((statRegval & IX_ETH_MII_SR_AUTO_SEL) != 0) &&
((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0);
if (*autoneg)
{
/* mask the current stat values with the capabilities */
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, &regval4);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, &regval5);
/* merge the flags from the 3 registers */
regval = (statRegval & ((regval4 & regval5) << 6));
/* initialise from status register values */
if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0)
{
/* 100 Base X full dplx */
*speed100 = true;
*fullDuplex = true;
return IX_SUCCESS;
}
if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0)
{
/* 100 Base X half dplx */
*speed100 = true;
return IX_SUCCESS;
}
if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0)
{
/* 10 mb full dplx */
*fullDuplex = true;
return IX_SUCCESS;
}
if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0)
{
/* 10 mb half dplx */
return IX_SUCCESS;
}
} /* end of if(autoneg) */
else
{
/* autonegotiate not complete, return setup parameters */
*speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0);
*fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0);
}
} /* end of if(linkUp) */
} /* end of if-else(ixEthMiiPhyId) */
} /* end of if(phyAddr) */
else
{
return IX_FAIL;
} /* end of if-else(phyAddr) */
return IX_SUCCESS;
}
/*****************************************************************
*
* Link state display functions
*/
PUBLIC IX_STATUS
ixEthMiiPhyShow (UINT32 phyAddr)
{
BOOL linkUp, speed100, fullDuplex, autoneg;
UINT16 cregval;
UINT16 sregval;
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &sregval);
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_CTRL_REG, &cregval);
/* get link information */
if (ixEthMiiLinkStatus(phyAddr,
&linkUp,
&speed100,
&fullDuplex,
&autoneg) != IX_ETH_ACC_SUCCESS)
{
printf("PHY Status unknown\n");
return IX_FAIL;
}
printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]);
printf( " Status reg: %4.4x\n",sregval);
printf( " control reg: %4.4x\n",cregval);
/* display link information */
printf("PHY Status:\n");
printf(" Link is %s\n",
(linkUp ? "Up" : "Down"));
if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0)
{
printf(" Remote fault detected\n");
}
printf(" Auto Negotiation %s\n",
(autoneg ? "Completed" : "Not Completed"));
printf("PHY Configuration:\n");
printf(" Speed %sMb/s\n",
(speed100 ? "100" : "10"));
printf(" %s Duplex\n",
(fullDuplex ? "Full" : "Half"));
printf(" Auto Negotiation %s\n",
(autoneg ? "Enabled" : "Disabled"));
return IX_SUCCESS;
}

View File

@ -1,398 +0,0 @@
/**
* @file IxFeatureCtrl.c
*
* @author Intel Corporation
* @date 29-Jan-2003
*
* @brief Feature Control Public API Implementation
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxVersionId.h"
#include "IxFeatureCtrl.h"
/* Macro to read from the Feature Control Register */
#define IX_FEATURE_CTRL_READ(result) \
do { \
ixFeatureCtrlExpMap(); \
(result) = IX_OSAL_READ_LONG(ixFeatureCtrlRegister); \
} while (0)
/* Macro to write to the Feature Control Register */
#define IX_FEATURE_CTRL_WRITE(value) \
do { \
ixFeatureCtrlExpMap(); \
IX_OSAL_WRITE_LONG(ixFeatureCtrlRegister, (value)); \
} while (0)
/*
* This is the offset of the feature register relative to the base of the
* Expansion Bus Controller MMR.
*/
#define IX_FEATURE_CTRL_REG_OFFSET (0x00000028)
/* Boolean to mark the fact that the EXP_CONFIG address space was mapped */
PRIVATE BOOL ixFeatureCtrlExpCfgRegionMapped = false;
/* Pointer holding the virtual address of the Feature Control Register */
PRIVATE VUINT32 *ixFeatureCtrlRegister = NULL;
/* Place holder to store the software configuration */
PRIVATE BOOL swConfiguration[IX_FEATURECTRL_SWCONFIG_MAX];
/* Flag to control swConfiguration[] is initialized once */
PRIVATE BOOL swConfigurationFlag = false ;
/* Array containing component mask values */
#ifdef __ixp42X
UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
(0x1<<IX_FEATURECTRL_RCOMP),
(0x1<<IX_FEATURECTRL_USB),
(0x1<<IX_FEATURECTRL_HASH),
(0x1<<IX_FEATURECTRL_AES),
(0x1<<IX_FEATURECTRL_DES),
(0x1<<IX_FEATURECTRL_HDLC),
(0x1<<IX_FEATURECTRL_AAL),
(0x1<<IX_FEATURECTRL_HSS),
(0x1<<IX_FEATURECTRL_UTOPIA),
(0x1<<IX_FEATURECTRL_ETH0),
(0x1<<IX_FEATURECTRL_ETH1),
(0x1<<IX_FEATURECTRL_NPEA),
(0x1<<IX_FEATURECTRL_NPEB),
(0x1<<IX_FEATURECTRL_NPEC),
(0x1<<IX_FEATURECTRL_PCI),
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
(0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
(0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2),
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE
};
#elif defined (__ixp46X)
UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
(0x1<<IX_FEATURECTRL_RCOMP),
(0x1<<IX_FEATURECTRL_USB),
(0x1<<IX_FEATURECTRL_HASH),
(0x1<<IX_FEATURECTRL_AES),
(0x1<<IX_FEATURECTRL_DES),
(0x1<<IX_FEATURECTRL_HDLC),
IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE, /* AAL component is always on */
(0x1<<IX_FEATURECTRL_HSS),
(0x1<<IX_FEATURECTRL_UTOPIA),
(0x1<<IX_FEATURECTRL_ETH0),
(0x1<<IX_FEATURECTRL_ETH1),
(0x1<<IX_FEATURECTRL_NPEA),
(0x1<<IX_FEATURECTRL_NPEB),
(0x1<<IX_FEATURECTRL_NPEC),
(0x1<<IX_FEATURECTRL_PCI),
(0x1<<IX_FEATURECTRL_ECC_TIMESYNC),
(0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
(0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2), /* NOT TO BE USED */
(0x1<<IX_FEATURECTRL_USB_HOST_CONTROLLER),
(0x1<<IX_FEATURECTRL_NPEA_ETH),
(0x1<<IX_FEATURECTRL_NPEB_ETH),
(0x1<<IX_FEATURECTRL_RSA),
(0x3<<IX_FEATURECTRL_XSCALE_MAX_FREQ),
(0x1<<IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2)
};
#endif /* __ixp42X */
/**
* Forward declaration
*/
PRIVATE
void ixFeatureCtrlExpMap(void);
PRIVATE
void ixFeatureCtrlSwConfigurationInit(void);
/**
* Function to map EXP_CONFIG space
*/
PRIVATE
void ixFeatureCtrlExpMap(void)
{
UINT32 expCfgBaseAddress = 0;
/* If the EXP Configuration space has already been mapped then
* return */
if (ixFeatureCtrlExpCfgRegionMapped == true)
{
return;
}
/* Map (get virtual address) for the EXP_CONFIG space */
expCfgBaseAddress = (UINT32)
(IX_OSAL_MEM_MAP(IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE,
IX_OSAL_IXP400_EXP_REG_MAP_SIZE));
/* Assert that the mapping operation succeeded */
IX_OSAL_ASSERT(expCfgBaseAddress);
/* Set the address of the Feature register */
ixFeatureCtrlRegister =
(VUINT32 *) (expCfgBaseAddress + IX_FEATURE_CTRL_REG_OFFSET);
/* Mark the fact that the EXP_CONFIG space has already been mapped */
ixFeatureCtrlExpCfgRegionMapped = true;
}
/**
* Function definition: ixFeatureCtrlSwConfigurationInit
* This function will only initialize software configuration once.
*/
PRIVATE void ixFeatureCtrlSwConfigurationInit(void)
{
UINT32 i;
if (false == swConfigurationFlag)
{
for (i=0; i<IX_FEATURECTRL_SWCONFIG_MAX ; i++)
{
/* By default, all software configuration are enabled */
swConfiguration[i]= true ;
}
/*Make sure this function only initializes swConfiguration[] once*/
swConfigurationFlag = true ;
}
}
/**
* Function definition: ixFeatureCtrlRead
*/
IxFeatureCtrlReg
ixFeatureCtrlRead (void)
{
IxFeatureCtrlReg result;
#if CPU!=SIMSPARCSOLARIS
/* Read the feature control register */
IX_FEATURE_CTRL_READ(result);
return result;
#else
/* Return an invalid value for VxWorks simulation */
result = 0xFFFFFFFF;
return result;
#endif
}
/**
* Function definition: ixFeatureCtrlWrite
*/
void
ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg)
{
#if CPU!=SIMSPARCSOLARIS
/* Write value to feature control register */
IX_FEATURE_CTRL_WRITE(expUnitReg);
#endif
}
/**
* Function definition: ixFeatureCtrlHwCapabilityRead
*/
IxFeatureCtrlReg
ixFeatureCtrlHwCapabilityRead (void)
{
IxFeatureCtrlReg currentReg, hwCapability;
/* Capture a copy of feature control register */
currentReg = ixFeatureCtrlRead();
/* Try to enable all hardware components.
* Only software disable hardware can be enabled again */
ixFeatureCtrlWrite(0);
/* Read feature control register to know the hardware capability. */
hwCapability = ixFeatureCtrlRead();
/* Restore initial feature control value */
ixFeatureCtrlWrite(currentReg);
/* return Hardware Capability */
return hwCapability;
}
/**
* Function definition: ixFeatureCtrlComponentCheck
*/
IX_STATUS
ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType)
{
IxFeatureCtrlReg expUnitReg;
UINT32 mask = 0;
/* Lookup mask of component */
mask=componentMask[componentType];
/* Check if mask is available or not */
if(IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE == mask)
{
return IX_FEATURE_CTRL_COMPONENT_DISABLED;
}
if(IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE == mask)
{
return IX_FEATURE_CTRL_COMPONENT_ENABLED;
}
/* Read feature control register to know current hardware capability. */
expUnitReg = ixFeatureCtrlRead();
/* For example: To check for Hashing Coprocessor (bit-2)
* expUniteg = 0x0010
* ~expUnitReg = 0x1101
* componentType = 0x0100
* ~expUnitReg & componentType = 0x0100 (Not zero)
*/
/*
* Inverse the bit value because available component is 0 in value
*/
expUnitReg = ~expUnitReg ;
if (expUnitReg & mask)
{
return (IX_FEATURE_CTRL_COMPONENT_ENABLED);
}
else
{
return (IX_FEATURE_CTRL_COMPONENT_DISABLED);
}
}
/**
* Function definition: ixFeatureCtrlProductIdRead
*/
IxFeatureCtrlProductId
ixFeatureCtrlProductIdRead ()
{
#if CPU!=SIMSPARCSOLARIS
IxFeatureCtrlProductId pdId = 0 ;
/* Use ARM instruction to move register0 from coprocessor to ARM register */
#ifndef __wince
__asm__("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(pdId) :);
#else
#ifndef IN_KERNEL
BOOL mode;
#endif
extern IxFeatureCtrlProductId AsmixFeatureCtrlProductIdRead();
#ifndef IN_KERNEL
mode = SetKMode(true);
#endif
pdId = AsmixFeatureCtrlProductIdRead();
#ifndef IN_KERNEL
SetKMode(mode);
#endif
#endif
return (pdId);
#else
/* Return an invalid value for VxWorks simulation */
return 0xffffffff;
#endif
}
/**
* Function definition: ixFeatureCtrlDeviceRead
*/
IxFeatureCtrlDeviceId
ixFeatureCtrlDeviceRead ()
{
return ((ixFeatureCtrlProductIdRead() >> IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET)
& IX_FEATURE_CTRL_DEVICE_TYPE_MASK);
} /* End function ixFeatureCtrlDeviceRead */
/**
* Function definition: ixFeatureCtrlSwConfigurationCheck
*/
IX_STATUS
ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType)
{
if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)
{
ixOsalLog(IX_OSAL_LOG_LVL_WARNING,
IX_OSAL_LOG_DEV_STDOUT,
"FeatureCtrl: Invalid software configuraiton input.\n",
0, 0, 0, 0, 0, 0);
return IX_FEATURE_CTRL_SWCONFIG_DISABLED;
}
/* The function will only initialize once. */
ixFeatureCtrlSwConfigurationInit();
/* Check and return software configuration */
return ((swConfiguration[(UINT32)swConfigType] == true) ? IX_FEATURE_CTRL_SWCONFIG_ENABLED: IX_FEATURE_CTRL_SWCONFIG_DISABLED);
}
/**
* Function definition: ixFeatureCtrlSwConfigurationWrite
*/
void
ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled)
{
if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)
{
ixOsalLog(IX_OSAL_LOG_LVL_WARNING,
IX_OSAL_LOG_DEV_STDOUT,
"FeatureCtrl: Invalid software configuraiton input.\n",
0, 0, 0, 0, 0, 0);
return;
}
/* The function will only initialize once. */
ixFeatureCtrlSwConfigurationInit();
/* Write software configuration */
swConfiguration[(UINT32)swConfigType]=enabled ;
}
/**
* Function definition: ixFeatureCtrlIxp400SwVersionShow
*/
void
ixFeatureCtrlIxp400SwVersionShow (void)
{
printf ("\nIXP400 Software Release %s %s\n\n", IX_VERSION_ID, IX_VERSION_INTERNAL_ID);
}
/**
* Function definition: ixFeatureCtrlSoftwareBuildGet
*/
IxFeatureCtrlBuildDevice
ixFeatureCtrlSoftwareBuildGet (void)
{
#ifdef __ixp42X
return IX_FEATURE_CTRL_SW_BUILD_IXP42X;
#else
return IX_FEATURE_CTRL_SW_BUILD_IXP46X;
#endif
}

View File

@ -1,916 +0,0 @@
/**
* @file IxNpeDl.c
*
* @author Intel Corporation
* @date 08 January 2002
*
* @brief This file contains the implementation of the public API for the
* IXP425 NPE Downloader component
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required
*/
/*
* Put the user defined include files required
*/
#include "IxNpeDl.h"
#include "IxNpeDlImageMgr_p.h"
#include "IxNpeDlNpeMgr_p.h"
#include "IxNpeDlMacros_p.h"
#include "IxFeatureCtrl.h"
#include "IxOsal.h"
/*
* #defines used in this file
*/
#define IMAGEID_MAJOR_NUMBER_DEFAULT 0
#define IMAGEID_MINOR_NUMBER_DEFAULT 0
/*
* Typedefs whose scope is limited to this file.
*/
typedef struct
{
BOOL validImage;
IxNpeDlImageId imageId;
} IxNpeDlNpeState;
/* module statistics counters */
typedef struct
{
UINT32 attemptedDownloads;
UINT32 successfulDownloads;
UINT32 criticalFailDownloads;
} IxNpeDlStats;
/*
* Variable declarations global to this file only. Externs are followed
* by static variables.
*/
static IxNpeDlNpeState ixNpeDlNpeState[IX_NPEDL_NPEID_MAX] =
{
{false, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
{false, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
{false, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}
};
static IxNpeDlStats ixNpeDlStats;
/*
* Software guard to prevent NPE from being started multiple times.
*/
static BOOL ixNpeDlNpeStarted[IX_NPEDL_NPEID_MAX] ={false, false, false} ;
/*
* static function prototypes.
*/
PRIVATE IX_STATUS
ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, UINT32 imageId);
/*
* Function definition: ixNpeDlImageDownload
*/
PUBLIC IX_STATUS
ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
BOOL verify)
{
UINT32 imageSize;
UINT32 *imageCodePtr = NULL;
IX_STATUS status;
IxNpeDlNpeId npeId = imageIdPtr->npeId;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageDownload\n");
ixNpeDlStats.attemptedDownloads++;
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n");
}
else
{
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
}
} /* end of if(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEB)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEC)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
} /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/
/* stop and reset the NPE */
if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId))
{
IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
return IX_FAIL;
}
/* Locate image */
status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr,
&imageSize);
if (IX_SUCCESS == status)
{
/*
* If download was successful, store image Id in list of
* currently loaded images. If a critical error occured
* during download, record that the NPE has an invalid image
*/
status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr,
verify);
if (IX_SUCCESS == status)
{
ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
ixNpeDlNpeState[npeId].validImage = true;
ixNpeDlStats.successfulDownloads++;
status = ixNpeDlNpeExecutionStart (npeId);
}
else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
(status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
{
ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
ixNpeDlNpeState[npeId].validImage = false;
ixNpeDlStats.criticalFailDownloads++;
}
} /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
} /* end of if-else(npeId) */ /* condition: parameter checks ok */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageDownload : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlAvailableImagesCountGet
*/
PUBLIC IX_STATUS
ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlAvailableImagesCountGet\n");
/* Check input parameters */
if (numImagesPtr == NULL)
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - "
"invalid parameter\n");
}
else
{
/*
* Use ImageMgr module to get no. of images listed in Image Library Header.
* If NULL is passed as imageListPtr parameter to following function,
* it will only fill number of images into numImagesPtr
*/
status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr);
} /* end of if-else(numImagesPtr) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlAvailableImagesCountGet : "
"status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlAvailableImagesListGet
*/
PUBLIC IX_STATUS
ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
UINT32 *listSizePtr)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlAvailableImagesListGet\n");
/* Check input parameters */
if ((imageIdListPtr == NULL) || (listSizePtr == NULL))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - "
"invalid parameter\n");
}
else
{
/* Call ImageMgr to get list of images listed in Image Library Header */
status = ixNpeDlImageMgrImageListExtract (imageIdListPtr,
listSizePtr);
} /* end of if-else(imageIdListPtr) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlAvailableImagesListGet : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlLoadedImageGet
*/
PUBLIC IX_STATUS
ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
IxNpeDlImageId *imageIdPtr)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlLoadedImageGet\n");
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n");
}
else
{
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEB &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEC &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
} /* end of if not IXP42x-A0 silicon */
if (ixNpeDlNpeState[npeId].validImage)
{
/* use npeId to get imageId from list of currently loaded
images */
*imageIdPtr = ixNpeDlNpeState[npeId].imageId;
}
else
{
status = IX_FAIL;
} /* end of if-else(ixNpeDlNpeState) */
} /* end of if-else(npeId) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlLoadedImageGet : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlLatestImageGet
*/
PUBLIC IX_STATUS
ixNpeDlLatestImageGet (
IxNpeDlNpeId npeId,
IxNpeDlFunctionalityId functionalityId,
IxNpeDlImageId *imageIdPtr)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlLatestImageGet\n");
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) ||
(npeId < 0) ||
(imageIdPtr == NULL))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - "
"invalid parameter\n");
} /* end of if(npeId) */
else
{
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEB &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
if (npeId == IX_NPEDL_NPEID_NPEC &&
(ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED))
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
" not exist\n");
return IX_SUCCESS;
} /* end of if(npeId) */
} /* end of if not IXP42x-A0 silicon */
imageIdPtr->npeId = npeId;
imageIdPtr->functionalityId = functionalityId;
imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT;
imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT;
/* Call ImageMgr to get list of images listed in Image Library Header */
status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr);
} /* end of if-else(npeId) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlLatestImageGet : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeStopAndReset
*/
PUBLIC IX_STATUS
ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeStopAndReset\n");
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
/*
* Check whether NPE is present
*/
if (IX_NPEDL_NPEID_NPEA == npeId)
{
/* Check whether NPE A is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE A does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n");
return IX_SUCCESS;
}
} /* end of if(IX_NPEDL_NPEID_NPEA) */
else if (IX_NPEDL_NPEID_NPEB == npeId)
{
/* Check whether NPE B is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE B does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEB) */
else if (IX_NPEDL_NPEID_NPEC == npeId)
{
/* Check whether NPE C is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE C does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEC) */
else
{
/* Invalid NPE ID */
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n");
status = IX_NPEDL_PARAM_ERR;
} /* end of if-else(IX_NPEDL_NPEID_NPEC) */
} /* end of if not IXP42x-A0 Silicon */
if (status == IX_SUCCESS)
{
/* call NpeMgr function to stop the NPE */
status = ixNpeDlNpeMgrNpeStop (npeId);
if (status == IX_SUCCESS)
{
/* call NpeMgr function to reset the NPE */
status = ixNpeDlNpeMgrNpeReset (npeId);
}
} /* end of if(status) */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeStopAndReset : status = %d\n", status);
if (IX_SUCCESS == status)
{
/* Indicate NPE has been stopped */
ixNpeDlNpeStarted[npeId] = false ;
}
return status;
}
/*
* Function definition: ixNpeDlNpeExecutionStart
*/
PUBLIC IX_STATUS
ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeExecutionStart\n");
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
/*
* Check whether NPE is present
*/
if (IX_NPEDL_NPEID_NPEA == npeId)
{
/* Check whether NPE A is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE A does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n");
return IX_SUCCESS;
}
} /* end of if(IX_NPEDL_NPEID_NPEA) */
else if (IX_NPEDL_NPEID_NPEB == npeId)
{
/* Check whether NPE B is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE B does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEB) */
else if (IX_NPEDL_NPEID_NPEC == npeId)
{
/* Check whether NPE C is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE C does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEC) */
else
{
/* Invalid NPE ID */
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n");
return IX_NPEDL_PARAM_ERR;
} /* end of if-else(IX_NPEDL_NPEID_NPEC) */
} /* end of if not IXP42x-A0 Silicon */
if (true == ixNpeDlNpeStarted[npeId])
{
/* NPE has been started. */
return IX_SUCCESS ;
}
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* call NpeMgr function to start the NPE */
status = ixNpeDlNpeMgrNpeStart (npeId);
if (IX_SUCCESS == status)
{
/* Indicate NPE has started */
ixNpeDlNpeStarted[npeId] = true ;
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeExecutionStart : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeExecutionStop
*/
PUBLIC IX_STATUS
ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeExecutionStop\n");
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
/*
* Check whether NPE is present
*/
if (IX_NPEDL_NPEID_NPEA == npeId)
{
/* Check whether NPE A is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE A does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n");
return IX_SUCCESS;
}
} /* end of if(IX_NPEDL_NPEID_NPEA) */
else if (IX_NPEDL_NPEID_NPEB == npeId)
{
/* Check whether NPE B is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE B does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEB) */
else if (IX_NPEDL_NPEID_NPEC == npeId)
{
/* Check whether NPE C is present */
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
/* NPE C does not present */
IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n");
return IX_SUCCESS;
}
} /* end of elseif(IX_NPEDL_NPEID_NPEC) */
else
{
/* Invalid NPE ID */
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n");
status = IX_NPEDL_PARAM_ERR;
} /* end of if-else(IX_NPEDL_NPEID_NPEC) */
} /* end of if not IXP42X-AO Silicon */
if (status == IX_SUCCESS)
{
/* call NpeMgr function to stop the NPE */
status = ixNpeDlNpeMgrNpeStop (npeId);
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeExecutionStop : status = %d\n",
status);
if (IX_SUCCESS == status)
{
/* Indicate NPE has been stopped */
ixNpeDlNpeStarted[npeId] = false ;
}
return status;
}
/*
* Function definition: ixNpeDlUnload
*/
PUBLIC IX_STATUS
ixNpeDlUnload (void)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlUnload\n");
status = ixNpeDlNpeMgrUninit();
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlUnload : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlStatsShow
*/
PUBLIC void
ixNpeDlStatsShow (void)
{
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\nixNpeDlStatsShow:\n"
"\tDownloads Attempted by user: %u\n"
"\tSuccessful Downloads: %u\n"
"\tFailed Downloads (due to Critical Error): %u\n\n",
ixNpeDlStats.attemptedDownloads,
ixNpeDlStats.successfulDownloads,
ixNpeDlStats.criticalFailDownloads,
0,0,0);
ixNpeDlImageMgrStatsShow ();
ixNpeDlNpeMgrStatsShow ();
}
/*
* Function definition: ixNpeDlStatsReset
*/
PUBLIC void
ixNpeDlStatsReset (void)
{
ixNpeDlStats.attemptedDownloads = 0;
ixNpeDlStats.successfulDownloads = 0;
ixNpeDlStats.criticalFailDownloads = 0;
ixNpeDlImageMgrStatsReset ();
ixNpeDlNpeMgrStatsReset ();
}
/*
* Function definition: ixNpeDlNpeInitAndStartInternal
*/
PRIVATE IX_STATUS
ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary,
UINT32 imageId)
{
UINT32 imageSize;
UINT32 *imageCodePtr = NULL;
IX_STATUS status;
IxNpeDlNpeId npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId);
IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId);
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeInitAndStartInternal\n");
ixNpeDlStats.attemptedDownloads++;
/* Check input parameter device correctness */
if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) ||
(deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
"invalid parameter\n");
} /* End valid device id checking */
/* Check input parameters */
else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
"invalid parameter\n");
}
else
{
/* Ensure initialisation has been completed */
ixNpeDlNpeMgrInit();
/* Checking if image being loaded is meant for device that is running.
* Image is forward compatible. i.e Image built for IXP42X should run
* on IXP46X but not vice versa.*/
if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK))
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
"Device type mismatch. NPE Image not "
"meant for device in use \n");
return IX_NPEDL_DEVICE_ERR;
}/* if statement - matching image device and current device */
/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
(ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
{
if (npeId == IX_NPEDL_NPEID_NPEA)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
" not exist\n");
return IX_SUCCESS;
}
} /* end of if(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEB)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
else if (npeId == IX_NPEDL_NPEID_NPEC)
{
if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
IX_FEATURE_CTRL_COMPONENT_DISABLED)
{
IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
" does not exist\n");
return IX_SUCCESS;
}
} /* end of elseif(npeId) */
} /* end of if not IXP42X-A0 Silicon */
/* stop and reset the NPE */
status = ixNpeDlNpeStopAndReset (npeId);
if (IX_SUCCESS != status)
{
IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
return status;
}
/* Locate image */
status = ixNpeDlImageMgrImageFind (imageLibrary, imageId,
&imageCodePtr, &imageSize);
if (IX_SUCCESS == status)
{
/*
* If download was successful, store image Id in list of
* currently loaded images. If a critical error occured
* during download, record that the NPE has an invalid image
*/
status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, true);
if (IX_SUCCESS == status)
{
ixNpeDlNpeState[npeId].validImage = true;
ixNpeDlStats.successfulDownloads++;
status = ixNpeDlNpeExecutionStart (npeId);
}
else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
(status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
{
ixNpeDlNpeState[npeId].validImage = false;
ixNpeDlStats.criticalFailDownloads++;
}
/* NOTE - The following section of code is here to support
* a deprecated function ixNpeDlLoadedImageGet(). When that
* function is removed from the API, this code should be revised.
*/
ixNpeDlNpeState[npeId].imageId.npeId = npeId;
ixNpeDlNpeState[npeId].imageId.functionalityId =
IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId);
ixNpeDlNpeState[npeId].imageId.major =
IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId);
ixNpeDlNpeState[npeId].imageId.minor =
IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId);
} /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
} /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeInitAndStartInternal : "
"status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlCustomImageNpeInitAndStart
*/
PUBLIC IX_STATUS
ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
UINT32 imageId)
{
IX_STATUS status;
if (imageLibrary == NULL)
{
status = IX_NPEDL_PARAM_ERR;
IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart "
"- invalid parameter\n");
}
else
{
status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId);
} /* end of if-else(imageLibrary) */
return status;
}
/*
* Function definition: ixNpeDlNpeInitAndStart
*/
PUBLIC IX_STATUS
ixNpeDlNpeInitAndStart (UINT32 imageId)
{
return ixNpeDlNpeInitAndStartInternal (NULL, imageId);
}
/*
* Function definition: ixNpeDlLoadedImageFunctionalityGet
*/
PUBLIC IX_STATUS
ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
UINT8 *functionalityId)
{
/* Check input parameters */
if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
"- invalid parameter\n");
return IX_NPEDL_PARAM_ERR;
}
if (functionalityId == NULL)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
"- invalid parameter\n");
return IX_NPEDL_PARAM_ERR;
}
if (ixNpeDlNpeState[npeId].validImage)
{
*functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId;
return IX_SUCCESS;
}
else
{
return IX_FAIL;
}
}

View File

@ -1,663 +0,0 @@
/**
* @file IxNpeDlImageMgr.c
*
* @author Intel Corporation
* @date 09 January 2002
*
* @brief This file contains the implementation of the private API for the
* IXP425 NPE Downloader ImageMgr module
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
#include "IxOsal.h"
/*
* Put the user defined include files required.
*/
#include "IxNpeDlImageMgr_p.h"
#include "IxNpeDlMacros_p.h"
/*
* define the flag which toggles the firmare inclusion
*/
#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1
#include "IxNpeMicrocode.h"
/*
* Indicates the start of an NPE Image, in new NPE Image Library format.
* 2 consecutive occurances indicates the end of the NPE Image Library
*/
#define NPE_IMAGE_MARKER 0xfeedf00d
/*
* Typedefs whose scope is limited to this file.
*/
/*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* TO BE DEPRECATED IN A FUTURE RELEASE
*/
typedef struct
{
UINT32 size;
UINT32 offset;
UINT32 id;
} IxNpeDlImageMgrImageEntry;
/*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* TO BE DEPRECATED IN A FUTURE RELEASE
*/
typedef union
{
IxNpeDlImageMgrImageEntry image;
UINT32 eohMarker;
} IxNpeDlImageMgrHeaderEntry;
/*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* TO BE DEPRECATED IN A FUTURE RELEASE
*/
typedef struct
{
UINT32 signature;
/* 1st entry in the header (there may be more than one) */
IxNpeDlImageMgrHeaderEntry entry[1];
} IxNpeDlImageMgrImageLibraryHeader;
/*
* NPE Image Header definition, used in new NPE Image Library format
*/
typedef struct
{
UINT32 marker;
UINT32 id;
UINT32 size;
} IxNpeDlImageMgrImageHeader;
/* module statistics counters */
typedef struct
{
UINT32 invalidSignature;
UINT32 imageIdListOverflow;
UINT32 imageIdNotFound;
} IxNpeDlImageMgrStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
static IxNpeDlImageMgrStats ixNpeDlImageMgrStats;
static UINT32* getIxNpeMicroCodeImageLibrary(void)
{
char *s;
if ((s = getenv("npe_ucode")) != NULL)
return (UINT32*) simple_strtoul(s, NULL, 16);
else
return NULL;
}
/*
* static function prototypes.
*/
PRIVATE BOOL
ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary);
PRIVATE void
ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId);
PRIVATE BOOL
ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB);
PRIVATE BOOL
ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB);
#if 0
PRIVATE IX_STATUS
ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize);
/*
* Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrMicrocodeImageLibraryOverride (
UINT32 *clientImageLibrary)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n");
if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary))
{
IxNpeMicroCodeImageLibrary = clientImageLibrary;
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: "
"Client-supplied image has invalid signature\n");
status = IX_FAIL;
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n",
status);
return status;
}
#endif
/*
* Function definition: ixNpeDlImageMgrImageListExtract
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrImageListExtract (
IxNpeDlImageId *imageListPtr,
UINT32 *numImages)
{
UINT32 rawImageId;
IxNpeDlImageId formattedImageId;
IX_STATUS status = IX_SUCCESS;
UINT32 imageCount = 0;
IxNpeDlImageMgrImageLibraryHeader *header;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrImageListExtract\n");
header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary();
if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary()))
{
/* for each image entry in the image header ... */
while (header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER)
{
/*
* if the image list container from calling function has capacity,
* add the image id to the list
*/
if ((imageListPtr != NULL) && (imageCount < *numImages))
{
rawImageId = header->entry[imageCount].image.id;
ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
imageListPtr[imageCount] = formattedImageId;
}
/* imageCount reflects no. of image entries in image library header */
imageCount++;
}
/*
* if image list container from calling function was too small to
* contain all image ids in the header, set return status to FAIL
*/
if ((imageListPtr != NULL) && (imageCount > *numImages))
{
status = IX_FAIL;
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
"number of Ids found exceeds list capacity\n");
ixNpeDlImageMgrStats.imageIdListOverflow++;
}
/* return number of image ids found in image library header */
*numImages = imageCount;
}
else
{
status = IX_FAIL;
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
"invalid signature in image\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrImageListExtract: status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrImageLocate
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrImageLocate (
IxNpeDlImageId *imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
{
UINT32 imageOffset;
UINT32 rawImageId;
IxNpeDlImageId formattedImageId;
/* used to index image entries in image library header */
UINT32 imageCount = 0;
IX_STATUS status = IX_FAIL;
IxNpeDlImageMgrImageLibraryHeader *header;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrImageLocate\n");
header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary();
if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary()))
{
/* for each image entry in the image library header ... */
while (header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER)
{
rawImageId = header->entry[imageCount].image.id;
ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
/* if a match for imageId is found in the image library header... */
if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId))
{
/*
* get pointer to the image in the image library using offset from
* 1st word in image library
*/
UINT32 *tmp=getIxNpeMicroCodeImageLibrary();
imageOffset = header->entry[imageCount].image.offset;
*imagePtr = &tmp[imageOffset];
/* get the image size */
*imageSize = header->entry[imageCount].image.size;
status = IX_SUCCESS;
break;
}
imageCount++;
}
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
}
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
"invalid signature in image library\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrLatestImageExtract
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
IX_STATUS
ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
{
UINT32 imageCount = 0;
UINT32 rawImageId;
IxNpeDlImageId formattedImageId;
IX_STATUS status = IX_FAIL;
IxNpeDlImageMgrImageLibraryHeader *header;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrLatestImageExtract\n");
header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary();
if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary()))
{
/* for each image entry in the image library header ... */
while (header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER)
{
rawImageId = header->entry[imageCount].image.id;
ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
/*
* if a match for the npe Id and functionality Id of the imageId is
* found in the image library header...
*/
if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId))
{
if(imageId->major <= formattedImageId.major)
{
if(imageId->minor < formattedImageId.minor)
{
imageId->minor = formattedImageId.minor;
}
imageId->major = formattedImageId.major;
}
status = IX_SUCCESS;
}
imageCount++;
}
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
}
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: "
"invalid signature in image library\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlImageMgrSignatureCheck
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE BOOL
ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary)
{
IxNpeDlImageMgrImageLibraryHeader *header =
(IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary;
BOOL result = true;
if (!header || header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE)
{
result = false;
ixNpeDlImageMgrStats.invalidSignature++;
}
return result;
}
/*
* Function definition: ixNpeDlImageMgrImageIdFormat
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE void
ixNpeDlImageMgrImageIdFormat (
UINT32 rawImageId,
IxNpeDlImageId *imageId)
{
imageId->npeId = (rawImageId >>
IX_NPEDL_IMAGEID_NPEID_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
imageId->functionalityId = (rawImageId >>
IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
imageId->major = (rawImageId >>
IX_NPEDL_IMAGEID_MAJOR_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
imageId->minor = (rawImageId >>
IX_NPEDL_IMAGEID_MINOR_OFFSET) &
IX_NPEDL_NPEIMAGE_FIELD_MASK;
}
/*
* Function definition: ixNpeDlImageMgrImageIdCompare
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE BOOL
ixNpeDlImageMgrImageIdCompare (
IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB)
{
if ((imageIdA->npeId == imageIdB->npeId) &&
(imageIdA->functionalityId == imageIdB->functionalityId) &&
(imageIdA->major == imageIdB->major) &&
(imageIdA->minor == imageIdB->minor))
{
return true;
}
else
{
return false;
}
}
/*
* Function definition: ixNpeDlImageMgrNpeFunctionIdCompare
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE BOOL
ixNpeDlImageMgrNpeFunctionIdCompare (
IxNpeDlImageId *imageIdA,
IxNpeDlImageId *imageIdB)
{
if ((imageIdA->npeId == imageIdB->npeId) &&
(imageIdA->functionalityId == imageIdB->functionalityId))
{
return true;
}
else
{
return false;
}
}
/*
* Function definition: ixNpeDlImageMgrStatsShow
*/
void
ixNpeDlImageMgrStatsShow (void)
{
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\nixNpeDlImageMgrStatsShow:\n"
"\tInvalid Image Signatures: %u\n"
"\tImage Id List capacity too small: %u\n"
"\tImage Id not found: %u\n\n",
ixNpeDlImageMgrStats.invalidSignature,
ixNpeDlImageMgrStats.imageIdListOverflow,
ixNpeDlImageMgrStats.imageIdNotFound,
0,0,0);
}
/*
* Function definition: ixNpeDlImageMgrStatsReset
*/
void
ixNpeDlImageMgrStatsReset (void)
{
ixNpeDlImageMgrStats.invalidSignature = 0;
ixNpeDlImageMgrStats.imageIdListOverflow = 0;
ixNpeDlImageMgrStats.imageIdNotFound = 0;
}
#if 0
/*
* Function definition: ixNpeDlImageMgrImageFind_legacy
*
* FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
* AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
*/
PRIVATE IX_STATUS
ixNpeDlImageMgrImageFind_legacy (
UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
{
UINT32 imageOffset;
/* used to index image entries in image library header */
UINT32 imageCount = 0;
IX_STATUS status = IX_FAIL;
IxNpeDlImageMgrImageLibraryHeader *header;
BOOL imageFound = false;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlImageMgrImageFind\n");
/* If user didn't specify a library to use, use the default
* one from IxNpeMicrocode.h
*/
if (imageLibrary == NULL)
{
imageLibrary = IxNpeMicroCodeImageLibrary;
}
if (ixNpeDlImageMgrSignatureCheck (imageLibrary))
{
header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary;
/* for each image entry in the image library header ... */
while ((header->entry[imageCount].eohMarker !=
IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound))
{
/* if a match for imageId is found in the image library header... */
if (imageId == header->entry[imageCount].image.id)
{
/*
* get pointer to the image in the image library using offset from
* 1st word in image library
*/
imageOffset = header->entry[imageCount].image.offset;
*imagePtr = &imageLibrary[imageOffset];
/* get the image size */
*imageSize = header->entry[imageCount].image.size;
status = IX_SUCCESS;
imageFound = true;
}
imageCount++;
}
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
}
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"invalid signature in image library\n");
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlImageMgrImageFind: status = %d\n", status);
return status;
}
#endif
/*
* Function definition: ixNpeDlImageMgrImageFind
*/
IX_STATUS
ixNpeDlImageMgrImageFind (
UINT32 *imageLibrary,
UINT32 imageId,
UINT32 **imagePtr,
UINT32 *imageSize)
{
IxNpeDlImageMgrImageHeader *image;
UINT32 offset = 0;
/* If user didn't specify a library to use, use the default
* one from IxNpeMicrocode.h
*/
if (imageLibrary == NULL)
{
#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
if (ixNpeMicrocode_binaryArray == NULL)
{
printk (KERN_ERR "ixp400.o: ERROR, no Microcode found in memory\n");
return IX_FAIL;
}
else
{
imageLibrary = ixNpeMicrocode_binaryArray;
}
#else
imageLibrary = getIxNpeMicroCodeImageLibrary();
if (imageLibrary == NULL)
{
printf ("npe: ERROR, no Microcode found in memory\n");
return IX_FAIL;
}
#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */
}
#if 0
/* For backward's compatibility with previous image format */
if (ixNpeDlImageMgrSignatureCheck(imageLibrary))
{
return ixNpeDlImageMgrImageFind_legacy(imageLibrary,
imageId,
imagePtr,
imageSize);
}
#endif
while (*(imageLibrary+offset) == NPE_IMAGE_MARKER)
{
image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset);
offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32);
if (image->id == imageId)
{
*imagePtr = imageLibrary + offset;
*imageSize = image->size;
return IX_SUCCESS;
}
/* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */
else if (image->id == NPE_IMAGE_MARKER)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"imageId not found in image library header\n");
ixNpeDlImageMgrStats.imageIdNotFound++;
/* reached end of library, image not found */
return IX_FAIL;
}
offset += image->size;
}
/* If we get here, our image library may be corrupted */
IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
"image library format may be invalid or corrupted\n");
return IX_FAIL;
}

View File

@ -1,907 +0,0 @@
/**
* @file IxNpeDlNpeMgr.c
*
* @author Intel Corporation
* @date 09 January 2002
*
* @brief This file contains the implementation of the private API for the
* IXP425 NPE Downloader NpeMgr module
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeDl.h"
#include "IxNpeDlNpeMgr_p.h"
#include "IxNpeDlNpeMgrUtils_p.h"
#include "IxNpeDlNpeMgrEcRegisters_p.h"
#include "IxNpeDlMacros_p.h"
#include "IxFeatureCtrl.h"
/*
* #defines and macros used in this file.
*/
#define IX_NPEDL_BYTES_PER_WORD 4
/* used to read download map from version in microcode image */
#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000
#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001
#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002
#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F
/*
* masks used to extract address info from State information context
* register addresses as read from microcode image
*/
#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F
#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0
/* LSB offset of Context Number field in State-Info Context Address */
#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4
/* size (in words) of single State Information entry (ctxt reg address|data) */
#define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2
#define IX_NPEDL_RESET_NPE_PARITY 0x0800
#define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF
#define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF
/*
* Typedefs whose scope is limited to this file.
*/
typedef struct
{
UINT32 type;
UINT32 offset;
} IxNpeDlNpeMgrDownloadMapBlockEntry;
typedef union
{
IxNpeDlNpeMgrDownloadMapBlockEntry block;
UINT32 eodmMarker;
} IxNpeDlNpeMgrDownloadMapEntry;
typedef struct
{
/* 1st entry in the download map (there may be more than one) */
IxNpeDlNpeMgrDownloadMapEntry entry[1];
} IxNpeDlNpeMgrDownloadMap;
/* used to access an instruction or data block in a microcode image */
typedef struct
{
UINT32 npeMemAddress;
UINT32 size;
UINT32 data[1];
} IxNpeDlNpeMgrCodeBlock;
/* used to access each Context Reg entry state-information block */
typedef struct
{
UINT32 addressInfo;
UINT32 value;
} IxNpeDlNpeMgrStateInfoCtxtRegEntry;
/* used to access a state-information block in a microcode image */
typedef struct
{
UINT32 size;
IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
} IxNpeDlNpeMgrStateInfoBlock;
/* used to store some useful NPE information for easy access */
typedef struct
{
UINT32 baseAddress;
UINT32 insMemSize;
UINT32 dataMemSize;
} IxNpeDlNpeInfo;
/* used to distinguish instruction and data memory operations */
typedef enum
{
IX_NPEDL_MEM_TYPE_INSTRUCTION = 0,
IX_NPEDL_MEM_TYPE_DATA
} IxNpeDlNpeMemType;
/* used to hold a reset value for a particular ECS register */
typedef struct
{
UINT32 regAddr;
UINT32 regResetVal;
} IxNpeDlEcsRegResetValue;
/* prototype of function to write either Instruction or Data memory */
typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress,
UINT32 npeMemAddress,
UINT32 npeMemData,
BOOL verify);
/* module statistics counters */
typedef struct
{
UINT32 instructionBlocksLoaded;
UINT32 dataBlocksLoaded;
UINT32 stateInfoBlocksLoaded;
UINT32 criticalNpeErrors;
UINT32 criticalMicrocodeErrors;
UINT32 npeStarts;
UINT32 npeStops;
UINT32 npeResets;
} IxNpeDlNpeMgrStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
static IxNpeDlNpeInfo ixNpeDlNpeInfo[] =
{
{
0,
IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
},
{
0,
IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
},
{
0,
IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
}
};
/* contains Reset values for Context Store Registers */
static UINT32 ixNpeDlCtxtRegResetValues[] =
{
IX_NPEDL_CTXT_REG_RESET_STEVT,
IX_NPEDL_CTXT_REG_RESET_STARTPC,
IX_NPEDL_CTXT_REG_RESET_REGMAP,
IX_NPEDL_CTXT_REG_RESET_CINDEX,
};
/* contains Reset values for Context Store Registers */
static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] =
{
{IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET},
{IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET},
{IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET},
{IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET},
{IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET},
{IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET},
{IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET},
{IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET},
{IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET},
{IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET},
{IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET},
{IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET},
{IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET}
};
static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;
/* Set when NPE register memory has been mapped */
static BOOL ixNpeDlMemInitialised = false;
/*
* static function prototypes.
*/
PRIVATE IX_STATUS
ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress,
IxNpeDlNpeMgrCodeBlock *codeBlockPtr,
BOOL verify, IxNpeDlNpeMemType npeMemType);
PRIVATE IX_STATUS
ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress,
IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr,
BOOL verify);
PRIVATE BOOL
ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset,
UINT32 expectedBitsSet);
PRIVATE UINT32
ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);
/*
* Function definition: ixNpeDlNpeMgrBaseAddressGet
*/
PRIVATE UINT32
ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId)
{
IX_OSAL_ASSERT (ixNpeDlMemInitialised);
return ixNpeDlNpeInfo[npeId].baseAddress;
}
/*
* Function definition: ixNpeDlNpeMgrInit
*/
void
ixNpeDlNpeMgrInit (void)
{
/* Only map the memory once */
if (!ixNpeDlMemInitialised)
{
UINT32 virtAddr;
/* map the register memory for NPE-A */
virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA,
IX_OSAL_IXP400_NPEA_MAP_SIZE);
IX_OSAL_ASSERT(virtAddr);
ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr;
/* map the register memory for NPE-B */
virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB,
IX_OSAL_IXP400_NPEB_MAP_SIZE);
IX_OSAL_ASSERT(virtAddr);
ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr;
/* map the register memory for NPE-C */
virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC,
IX_OSAL_IXP400_NPEC_MAP_SIZE);
IX_OSAL_ASSERT(virtAddr);
ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr;
ixNpeDlMemInitialised = true;
}
}
/*
* Function definition: ixNpeDlNpeMgrUninit
*/
IX_STATUS
ixNpeDlNpeMgrUninit (void)
{
if (!ixNpeDlMemInitialised)
{
return IX_FAIL;
}
IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress);
IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress);
IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress);
ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0;
ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0;
ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0;
ixNpeDlMemInitialised = false;
return IX_SUCCESS;
}
/*
* Function definition: ixNpeDlNpeMgrImageLoad
*/
IX_STATUS
ixNpeDlNpeMgrImageLoad (
IxNpeDlNpeId npeId,
UINT32 *imageCodePtr,
BOOL verify)
{
UINT32 npeBaseAddress;
IxNpeDlNpeMgrDownloadMap *downloadMap;
UINT32 *blockPtr;
UINT32 mapIndex = 0;
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrImageLoad\n");
/* get base memory address of NPE from npeId */
npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
/* check execution status of NPE to verify NPE Stop was successful */
if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
IX_NPEDL_EXCTL_STATUS_STOP))
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - "
"NPE was not stopped before download\n");
status = IX_FAIL;
}
else
{
/*
* Read Download Map, checking each block type and calling
* appropriate function to perform download
*/
downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
while ((downloadMap->entry[mapIndex].eodmMarker !=
IX_NPEDL_END_OF_DOWNLOAD_MAP)
&& (status == IX_SUCCESS))
{
/* calculate pointer to block to be downloaded */
blockPtr = imageCodePtr +
downloadMap->entry[mapIndex].block.offset;
switch (downloadMap->entry[mapIndex].block.type)
{
case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
(IxNpeDlNpeMgrCodeBlock *)blockPtr,
verify,
IX_NPEDL_MEM_TYPE_INSTRUCTION);
break;
case IX_NPEDL_BLOCK_TYPE_DATA:
status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
(IxNpeDlNpeMgrCodeBlock *)blockPtr,
verify, IX_NPEDL_MEM_TYPE_DATA);
break;
case IX_NPEDL_BLOCK_TYPE_STATE:
status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress,
(IxNpeDlNpeMgrStateInfoBlock *) blockPtr,
verify);
break;
default:
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: "
"unknown block type in download map\n");
status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
break;
}
mapIndex++;
}/* loop: for each entry in download map, while status == SUCCESS */
}/* condition: NPE stopped before attempting download */
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrImageLoad : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrMemLoad
*/
PRIVATE IX_STATUS
ixNpeDlNpeMgrMemLoad (
IxNpeDlNpeId npeId,
UINT32 npeBaseAddress,
IxNpeDlNpeMgrCodeBlock *blockPtr,
BOOL verify,
IxNpeDlNpeMemType npeMemType)
{
UINT32 npeMemAddress;
UINT32 blockSize;
UINT32 memSize = 0;
IxNpeDlNpeMgrMemWrite memWriteFunc = NULL;
UINT32 localIndex = 0;
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrMemLoad\n");
/*
* select NPE EXCTL reg read/write commands depending on memory
* type (instruction/data) to be accessed
*/
if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
{
memSize = ixNpeDlNpeInfo[npeId].insMemSize;
memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite;
}
else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
{
memSize = ixNpeDlNpeInfo[npeId].dataMemSize;
memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite;
}
/*
* NPE memory is loaded contiguously from each block, so only address
* of 1st word in block is needed
*/
npeMemAddress = blockPtr->npeMemAddress;
/* number of words of instruction/data microcode in block to download */
blockSize = blockPtr->size;
if ((npeMemAddress + blockSize) > memSize)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
"Block size too big for NPE memory\n");
status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
}
else
{
for (localIndex = 0; localIndex < blockSize; localIndex++)
{
status = memWriteFunc (npeBaseAddress, npeMemAddress,
blockPtr->data[localIndex], verify);
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
"write to NPE memory failed\n");
status = IX_NPEDL_CRITICAL_NPE_ERR;
ixNpeDlNpeMgrStats.criticalNpeErrors++;
break; /* abort download */
}
/* increment target (word)address in NPE memory */
npeMemAddress++;
}
}/* condition: block size will fit in NPE memory */
if (status == IX_SUCCESS)
{
if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
{
ixNpeDlNpeMgrStats.instructionBlocksLoaded++;
}
else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
{
ixNpeDlNpeMgrStats.dataBlocksLoaded++;
}
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrStateInfoLoad
*/
PRIVATE IX_STATUS
ixNpeDlNpeMgrStateInfoLoad (
UINT32 npeBaseAddress,
IxNpeDlNpeMgrStateInfoBlock *blockPtr,
BOOL verify)
{
UINT32 blockSize;
UINT32 ctxtRegAddrInfo;
UINT32 ctxtRegVal;
IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
UINT32 ctxtNum; /* identifies Context number (0-16) */
UINT32 i;
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrStateInfoLoad\n");
/* block size contains number of words of state-info in block */
blockSize = blockPtr->size;
ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
/* for each state-info context register entry in block */
for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++)
{
/* each state-info entry is 2 words (address, value) in length */
ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo;
ctxtRegVal = (blockPtr->ctxtRegEntry[i]).value;
ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >>
IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
/* error-check Context Register No. and Context Number values */
/* NOTE that there is no STEVT register for Context 0 */
if ((ctxtReg < 0) ||
(ctxtReg >= IX_NPEDL_CTXT_REG_MAX) ||
(ctxtNum > IX_NPEDL_CTXT_NUM_MAX) ||
((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
"invalid Context Register Address\n");
status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
break; /* abort download */
}
status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg,
ctxtRegVal, verify);
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
"write of state-info to NPE failed\n");
status = IX_NPEDL_CRITICAL_NPE_ERR;
ixNpeDlNpeMgrStats.criticalNpeErrors++;
break; /* abort download */
}
}/* loop: for each context reg entry in State Info block */
ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
if (status == IX_SUCCESS)
{
ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++;
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrNpeReset
*/
IX_STATUS
ixNpeDlNpeMgrNpeReset (
IxNpeDlNpeId npeId)
{
UINT32 npeBaseAddress;
IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
UINT32 ctxtNum; /* identifies Context number (0-16) */
UINT32 regAddr;
UINT32 regVal;
UINT32 localIndex;
UINT32 indexMax;
IX_STATUS status = IX_SUCCESS;
IxFeatureCtrlReg unitFuseReg;
UINT32 ixNpeConfigCtrlRegVal;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrNpeReset\n");
/* get base memory address of NPE from npeId */
npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
/* pre-store the NPE Config Control Register Value */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
ixNpeConfigCtrlRegVal |= 0x3F000000;
/* disable the parity interrupt */
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
/*
* clear the FIFOs
*/
while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
IX_NPEDL_REG_OFFSET_WFIFO,
IX_NPEDL_MASK_WFIFO_VALID))
{
/* read from the Watch-point FIFO until empty */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
&regVal);
}
while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
IX_NPEDL_REG_OFFSET_STAT,
IX_NPEDL_MASK_STAT_OFNE))
{
/* read from the outFIFO until empty */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
&regVal);
}
while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
IX_NPEDL_REG_OFFSET_STAT,
IX_NPEDL_MASK_STAT_IFNE))
{
/*
* step execution of the NPE intruction to read inFIFO using
* the Debug Executing Context stack
*/
status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
IX_NPEDL_INSTR_RD_FIFO, 0, 0);
if (IX_SUCCESS != status)
{
return status;
}
}
/*
* Reset the mailbox reg
*/
/* ...from XScale side */
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
IX_NPEDL_REG_RESET_MBST);
/* ...from NPE side */
status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
if (IX_SUCCESS != status)
{
return status;
}
/*
* Reset the physical registers in the NPE register file:
* Note: no need to save/restore REGMAP for Context 0 here
* since all Context Store regs are reset in subsequent code
*/
for (regAddr = 0;
(regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
regAddr++)
{
/* for each physical register in the NPE reg file, write 0 : */
status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
0, true);
if (status != IX_SUCCESS)
{
return status; /* abort reset */
}
}
/*
* Reset the context store:
*/
for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
{
/* set each context's Context Store registers to reset values: */
for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
{
/* NOTE that there is no STEVT register for Context 0 */
if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
{
regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
ctxtReg, regVal, true);
if (status != IX_SUCCESS)
{
return status; /* abort reset */
}
}
}
}
ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
/* write Reset values to Execution Context Stack registers */
indexMax = sizeof (ixNpeDlEcsRegResetValues) /
sizeof (IxNpeDlEcsRegResetValue);
for (localIndex = 0; localIndex < indexMax; localIndex++)
{
regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
}
/* clear the profile counter */
ixNpeDlNpeMgrCommandIssue (npeBaseAddress,
IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
/* clear registers EXCT, AP0, AP1, AP2 and AP3 */
for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
regAddr <= IX_NPEDL_REG_OFFSET_AP3;
regAddr += IX_NPEDL_BYTES_PER_WORD)
{
IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
}
/* Reset the Watch-count register */
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
/*
* WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
*/
/*
* Call the feature control API to fused out and reset the NPE and its
* coprocessor - to reset internal states and remove parity error
*/
unitFuseReg = ixFeatureCtrlRead ();
unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
ixFeatureCtrlWrite (unitFuseReg);
/* call the feature control API to un-fused and un-reset the NPE & COP */
unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
ixFeatureCtrlWrite (unitFuseReg);
/*
* Call NpeMgr function to stop the NPE again after the Feature Control
* has unfused and Un-Reset the NPE and its associated Coprocessors
*/
status = ixNpeDlNpeMgrNpeStop (npeId);
/* restore NPE configuration bus Control Register - Parity Settings */
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL,
(ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
ixNpeDlNpeMgrStats.npeResets++;
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrNpeStart
*/
IX_STATUS
ixNpeDlNpeMgrNpeStart (
IxNpeDlNpeId npeId)
{
UINT32 npeBaseAddress;
UINT32 ecsRegVal;
BOOL npeRunning;
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrNpeStart\n");
/* get base memory address of NPE from npeId */
npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
/*
* ensure only Background Context Stack Level is Active by turning off
* the Active bit in each of the other Executing Context Stack levels
*/
ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0,
ecsRegVal);
ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0,
ecsRegVal);
ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
IX_NPEDL_ECS_DBG_CTXT_REG_0);
ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
ecsRegVal);
/* clear the pipeline */
ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
/* start NPE execution by issuing command through EXCTL register on NPE */
ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START);
/*
* check execution status of NPE to verify NPE Start operation was
* successful
*/
npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
IX_NPEDL_REG_OFFSET_EXCTL,
IX_NPEDL_EXCTL_STATUS_RUN);
if (npeRunning)
{
ixNpeDlNpeMgrStats.npeStarts++;
}
else
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: "
"failed to start NPE execution\n");
status = IX_FAIL;
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrNpeStop
*/
IX_STATUS
ixNpeDlNpeMgrNpeStop (
IxNpeDlNpeId npeId)
{
UINT32 npeBaseAddress;
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrNpeStop\n");
/* get base memory address of NPE from npeId */
npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
/* stop NPE execution by issuing command through EXCTL register on NPE */
ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP);
/* verify that NPE Stop was successful */
if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
IX_NPEDL_EXCTL_STATUS_STOP))
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: "
"failed to stop NPE execution\n");
status = IX_FAIL;
}
ixNpeDlNpeMgrStats.npeStops++;
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrBitsSetCheck
*/
PRIVATE BOOL
ixNpeDlNpeMgrBitsSetCheck (
UINT32 npeBaseAddress,
UINT32 regOffset,
UINT32 expectedBitsSet)
{
UINT32 regVal;
IX_NPEDL_REG_READ (npeBaseAddress, regOffset, &regVal);
return expectedBitsSet == (expectedBitsSet & regVal);
}
/*
* Function definition: ixNpeDlNpeMgrStatsShow
*/
void
ixNpeDlNpeMgrStatsShow (void)
{
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\nixNpeDlNpeMgrStatsShow:\n"
"\tInstruction Blocks loaded: %u\n"
"\tData Blocks loaded: %u\n"
"\tState Information Blocks loaded: %u\n"
"\tCritical NPE errors: %u\n"
"\tCritical Microcode errors: %u\n",
ixNpeDlNpeMgrStats.instructionBlocksLoaded,
ixNpeDlNpeMgrStats.dataBlocksLoaded,
ixNpeDlNpeMgrStats.stateInfoBlocksLoaded,
ixNpeDlNpeMgrStats.criticalNpeErrors,
ixNpeDlNpeMgrStats.criticalMicrocodeErrors,
0);
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\tSuccessful NPE Starts: %u\n"
"\tSuccessful NPE Stops: %u\n"
"\tSuccessful NPE Resets: %u\n\n",
ixNpeDlNpeMgrStats.npeStarts,
ixNpeDlNpeMgrStats.npeStops,
ixNpeDlNpeMgrStats.npeResets,
0,0,0);
ixNpeDlNpeMgrUtilsStatsShow ();
}
/*
* Function definition: ixNpeDlNpeMgrStatsReset
*/
void
ixNpeDlNpeMgrStatsReset (void)
{
ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0;
ixNpeDlNpeMgrStats.dataBlocksLoaded = 0;
ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0;
ixNpeDlNpeMgrStats.criticalNpeErrors = 0;
ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0;
ixNpeDlNpeMgrStats.npeStarts = 0;
ixNpeDlNpeMgrStats.npeStops = 0;
ixNpeDlNpeMgrStats.npeResets = 0;
ixNpeDlNpeMgrUtilsStatsReset ();
}

View File

@ -1,782 +0,0 @@
/**
* @file IxNpeDlNpeMgrUtils.c
*
* @author Intel Corporation
* @date 18 February 2002
*
* @brief This file contains the implementation of the private API for the
* IXP425 NPE Downloader NpeMgr Utils module
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
#define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
* retries before
* timeout
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeDl.h"
#include "IxNpeDlNpeMgrUtils_p.h"
#include "IxNpeDlNpeMgrEcRegisters_p.h"
#include "IxNpeDlMacros_p.h"
/*
* #defines and macros used in this file.
*/
/* used to bit-mask a number of bytes */
#define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD 0x000000FF
#define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF
#define IX_NPEDL_MASK_FULL_WORD 0xFFFFFFFF
#define IX_NPEDL_BYTES_PER_WORD 4
#define IX_NPEDL_BYTES_PER_SHORT 2
#define IX_NPEDL_REG_SIZE_BYTE 8
#define IX_NPEDL_REG_SIZE_SHORT 16
#define IX_NPEDL_REG_SIZE_WORD 32
/*
* Introduce extra read cycles after issuing read command to NPE
* so that we read the register after the NPE has updated it
* This is to overcome race condition between XScale and NPE
*/
#define IX_NPEDL_DELAY_READ_CYCLES 2
/*
* To mask top three MSBs of 32bit word to download into NPE IMEM
*/
#define IX_NPEDL_MASK_UNUSED_IMEM_BITS 0x1FFFFFFF;
/*
* typedefs
*/
typedef struct
{
UINT32 regAddress;
UINT32 regSize;
} IxNpeDlCtxtRegAccessInfo;
/* module statistics counters */
typedef struct
{
UINT32 insMemWrites;
UINT32 insMemWriteFails;
UINT32 dataMemWrites;
UINT32 dataMemWriteFails;
UINT32 ecsRegWrites;
UINT32 ecsRegReads;
UINT32 dbgInstructionExecs;
UINT32 contextRegWrites;
UINT32 physicalRegWrites;
UINT32 nextPcWrites;
} IxNpeDlNpeMgrUtilsStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
/*
* contains useful address and function pointers to read/write Context Regs,
* eliminating some switch or if-else statements in places
*/
static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] =
{
{
IX_NPEDL_CTXT_REG_ADDR_STEVT,
IX_NPEDL_REG_SIZE_BYTE
},
{
IX_NPEDL_CTXT_REG_ADDR_STARTPC,
IX_NPEDL_REG_SIZE_SHORT
},
{
IX_NPEDL_CTXT_REG_ADDR_REGMAP,
IX_NPEDL_REG_SIZE_SHORT
},
{
IX_NPEDL_CTXT_REG_ADDR_CINDEX,
IX_NPEDL_REG_SIZE_BYTE
}
};
static UINT32 ixNpeDlSavedExecCount = 0;
static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;
static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;
/*
* static function prototypes.
*/
PRIVATE __inline__ void
ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
UINT32 addr, UINT32 data);
PRIVATE __inline__ UINT32
ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);
PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);
PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
UINT32 regVal, UINT32 regSize,
UINT32 ctxtNum, BOOL verify);
/*
* Function definition: ixNpeDlNpeMgrWriteCommandIssue
*/
PRIVATE __inline__ void
ixNpeDlNpeMgrWriteCommandIssue (
UINT32 npeBaseAddress,
UINT32 cmd,
UINT32 addr,
UINT32 data)
{
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data);
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
}
/*
* Function definition: ixNpeDlNpeMgrReadCommandIssue
*/
PRIVATE __inline__ UINT32
ixNpeDlNpeMgrReadCommandIssue (
UINT32 npeBaseAddress,
UINT32 cmd,
UINT32 addr)
{
UINT32 data = 0;
int i;
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++)
{
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data);
}
return data;
}
/*
* Function definition: ixNpeDlNpeMgrInsMemWrite
*/
IX_STATUS
ixNpeDlNpeMgrInsMemWrite (
UINT32 npeBaseAddress,
UINT32 insMemAddress,
UINT32 insMemData,
BOOL verify)
{
UINT32 insMemDataRtn;
ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
IX_NPEDL_EXCTL_CMD_WR_INS_MEM,
insMemAddress, insMemData);
if (verify)
{
/* write invalid data to this reg, so we can see if we're reading
the EXDATA register too early */
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA,
~insMemData);
/*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/
insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
IX_NPEDL_EXCTL_CMD_RD_INS_MEM,
insMemAddress);
insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
if (insMemData != insMemDataRtn)
{
ixNpeDlNpeMgrUtilsStats.insMemWriteFails++;
return IX_FAIL;
}
}
ixNpeDlNpeMgrUtilsStats.insMemWrites++;
return IX_SUCCESS;
}
/*
* Function definition: ixNpeDlNpeMgrDataMemWrite
*/
IX_STATUS
ixNpeDlNpeMgrDataMemWrite (
UINT32 npeBaseAddress,
UINT32 dataMemAddress,
UINT32 dataMemData,
BOOL verify)
{
ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
IX_NPEDL_EXCTL_CMD_WR_DATA_MEM,
dataMemAddress, dataMemData);
if (verify)
{
/* write invalid data to this reg, so we can see if we're reading
the EXDATA register too early */
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData);
if (dataMemData !=
ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
IX_NPEDL_EXCTL_CMD_RD_DATA_MEM,
dataMemAddress))
{
ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++;
return IX_FAIL;
}
}
ixNpeDlNpeMgrUtilsStats.dataMemWrites++;
return IX_SUCCESS;
}
/*
* Function definition: ixNpeDlNpeMgrExecAccRegWrite
*/
void
ixNpeDlNpeMgrExecAccRegWrite (
UINT32 npeBaseAddress,
UINT32 regAddress,
UINT32 regData)
{
ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
IX_NPEDL_EXCTL_CMD_WR_ECS_REG,
regAddress, regData);
ixNpeDlNpeMgrUtilsStats.ecsRegWrites++;
}
/*
* Function definition: ixNpeDlNpeMgrExecAccRegRead
*/
UINT32
ixNpeDlNpeMgrExecAccRegRead (
UINT32 npeBaseAddress,
UINT32 regAddress)
{
ixNpeDlNpeMgrUtilsStats.ecsRegReads++;
return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
IX_NPEDL_EXCTL_CMD_RD_ECS_REG,
regAddress);
}
/*
* Function definition: ixNpeDlNpeMgrCommandIssue
*/
void
ixNpeDlNpeMgrCommandIssue (
UINT32 npeBaseAddress,
UINT32 command)
{
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrCommandIssue\n");
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command);
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrCommandIssue\n");
}
/*
* Function definition: ixNpeDlNpeMgrDebugInstructionPreExec
*/
void
ixNpeDlNpeMgrDebugInstructionPreExec(
UINT32 npeBaseAddress)
{
/* turn off the halt bit by clearing Execution Count register. */
/* save reg contents 1st and restore later */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
&ixNpeDlSavedExecCount);
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0);
/* ensure that IF and IE are on (temporarily), so that we don't end up
* stepping forever */
ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
IX_NPEDL_ECS_DBG_CTXT_REG_2);
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
(ixNpeDlSavedEcsDbgCtxtReg2 |
IX_NPEDL_MASK_ECS_DBG_REG_2_IF |
IX_NPEDL_MASK_ECS_DBG_REG_2_IE));
}
/*
* Function definition: ixNpeDlNpeMgrDebugInstructionExec
*/
IX_STATUS
ixNpeDlNpeMgrDebugInstructionExec(
UINT32 npeBaseAddress,
UINT32 npeInstruction,
UINT32 ctxtNum,
UINT32 ldur)
{
UINT32 ecsDbgRegVal;
UINT32 oldWatchcount, newWatchcount;
UINT32 retriesCount = 0;
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrDebugInstructionExec\n");
/* set the Active bit, and the LDUR, in the debug level */
ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE |
(ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR);
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
ecsDbgRegVal);
/*
* set CCTXT at ECS DEBUG L3 to specify in which context to execute the
* instruction, and set SELCTXT at ECS DEBUG Level to specify which context
* store to access.
* Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
*/
ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) |
(ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT);
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1,
ecsDbgRegVal);
/* clear the pipeline */
ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
/* load NPE instruction into the instruction register */
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG,
npeInstruction);
/* we need this value later to wait for completion of NPE execution step */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount);
/* issue a Step One command via the Execution Control register */
ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP);
/* Watch Count register increments when NPE completes an instruction */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
&newWatchcount);
/*
* force the XScale to wait until the NPE has finished execution step
* NOTE that this delay will be very small, just long enough to allow a
* single NPE instruction to complete execution; if instruction execution
* is not completed before timeout retries, exit the while loop
*/
while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
&& (newWatchcount == oldWatchcount))
{
/* Watch Count register increments when NPE completes an instruction */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
&newWatchcount);
retriesCount++;
}
if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
{
ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++;
}
else
{
/* Return timeout status as the instruction has not been executed
* after maximum retries */
status = IX_NPEDL_CRITICAL_NPE_ERR;
}
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrDebugInstructionExec\n");
return status;
}
/*
* Function definition: ixNpeDlNpeMgrDebugInstructionPostExec
*/
void
ixNpeDlNpeMgrDebugInstructionPostExec(
UINT32 npeBaseAddress)
{
/* clear active bit in debug level */
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
0);
/* clear the pipeline */
ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
/* restore Execution Count register contents. */
IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
ixNpeDlSavedExecCount);
/* restore IF and IE bits to original values */
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
ixNpeDlSavedEcsDbgCtxtReg2);
}
/*
* Function definition: ixNpeDlNpeMgrLogicalRegRead
*/
PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegRead (
UINT32 npeBaseAddress,
UINT32 regAddr,
UINT32 regSize,
UINT32 ctxtNum,
UINT32 *regVal)
{
IX_STATUS status = IX_SUCCESS;
UINT32 npeInstruction = 0;
UINT32 mask = 0;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrLogicalRegRead\n");
switch (regSize)
{
case IX_NPEDL_REG_SIZE_BYTE:
npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE;
mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break;
case IX_NPEDL_REG_SIZE_SHORT:
npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT;
mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break;
case IX_NPEDL_REG_SIZE_WORD:
npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD;
mask = IX_NPEDL_MASK_FULL_WORD; break;
}
/* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */
npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) |
(regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
/* step execution of NPE intruction using Debug Executing Context stack */
status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction,
ctxtNum, IX_NPEDL_RD_INSTR_LDUR);
if (IX_SUCCESS != status)
{
return status;
}
/* read value of register from Execution Data register */
IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, regVal);
/* align value from left to right */
*regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrLogicalRegRead\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeDlNpeMgrLogicalRegWrite
*/
PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegWrite (
UINT32 npeBaseAddress,
UINT32 regAddr,
UINT32 regVal,
UINT32 regSize,
UINT32 ctxtNum,
BOOL verify)
{
UINT32 npeInstruction = 0;
UINT32 mask = 0;
IX_STATUS status = IX_SUCCESS;
UINT32 retRegVal;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrLogicalRegWrite\n");
if (regSize == IX_NPEDL_REG_SIZE_WORD)
{
/* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */
/* Write upper half-word (short) to |d0|d1| */
status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr,
regVal >> IX_NPEDL_REG_SIZE_SHORT,
IX_NPEDL_REG_SIZE_SHORT,
ctxtNum, verify);
if (IX_SUCCESS != status)
{
return status;
}
/* Write lower half-word (short) to |d2|d3| */
status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
regAddr + IX_NPEDL_BYTES_PER_SHORT,
regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD,
IX_NPEDL_REG_SIZE_SHORT,
ctxtNum, verify);
if (IX_SUCCESS != status)
{
return status;
}
}
else
{
switch (regSize)
{
case IX_NPEDL_REG_SIZE_BYTE:
npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE;
mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break;
case IX_NPEDL_REG_SIZE_SHORT:
npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT;
mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break;
}
/* mask out any redundant bits, so verify will work later */
regVal &= mask;
/* fill dest operand field of instruction with destination reg addr */
npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
/* fill src operand field of instruction with least-sig 5 bits of val*/
npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) <<
IX_NPEDL_OFFSET_INSTR_SRC);
/* fill coprocessor field of instruction with most-sig 11 bits of val*/
npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
/* step execution of NPE intruction using Debug ECS */
status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction,
ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
if (IX_SUCCESS != status)
{
return status;
}
}/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */
if (verify)
{
status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
regSize, ctxtNum, &retRegVal);
if (IX_SUCCESS == status)
{
if (regVal != retRegVal)
{
status = IX_FAIL;
}
}
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrPhysicalRegWrite
*/
IX_STATUS
ixNpeDlNpeMgrPhysicalRegWrite (
UINT32 npeBaseAddress,
UINT32 regAddr,
UINT32 regValue,
BOOL verify)
{
IX_STATUS status;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrPhysicalRegWrite\n");
/*
* There are 32 physical registers used in an NPE. These are
* treated as 16 pairs of 32-bit registers. To write one of the pair,
* write the pair number (0-16) to the REGMAP for Context 0. Then write
* the value to register 0 or 4 in the regfile, depending on which
* register of the pair is to be written
*/
/*
* set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16)
* of physical registers to write
*/
status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
IX_NPEDL_CTXT_REG_ADDR_REGMAP,
(regAddr >>
IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP),
IX_NPEDL_REG_SIZE_SHORT, 0, verify);
if (status == IX_SUCCESS)
{
/* regAddr = 0 or 4 */
regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) *
IX_NPEDL_BYTES_PER_WORD;
status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue,
IX_NPEDL_REG_SIZE_WORD, 0, verify);
}
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: "
"error writing to physical register\n");
}
ixNpeDlNpeMgrUtilsStats.physicalRegWrites++;
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrCtxtRegWrite
*/
IX_STATUS
ixNpeDlNpeMgrCtxtRegWrite (
UINT32 npeBaseAddress,
UINT32 ctxtNum,
IxNpeDlCtxtRegNum ctxtReg,
UINT32 ctxtRegVal,
BOOL verify)
{
UINT32 tempRegVal;
UINT32 ctxtRegAddr;
UINT32 ctxtRegSize;
IX_STATUS status = IX_SUCCESS;
IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
"Entering ixNpeDlNpeMgrCtxtRegWrite\n");
/*
* Context 0 has no STARTPC. Instead, this value is used to set
* NextPC for Background ECS, to set where NPE starts executing code
*/
if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC))
{
/* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */
tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
IX_NPEDL_ECS_BG_CTXT_REG_0);
tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) &
IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress,
IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal);
ixNpeDlNpeMgrUtilsStats.nextPcWrites++;
}
else
{
ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress;
ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize;
status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr,
ctxtRegVal, ctxtRegSize,
ctxtNum, verify);
if (status != IX_SUCCESS)
{
IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: "
"error writing to context store register\n");
}
ixNpeDlNpeMgrUtilsStats.contextRegWrites++;
}
IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
"Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n",
status);
return status;
}
/*
* Function definition: ixNpeDlNpeMgrUtilsStatsShow
*/
void
ixNpeDlNpeMgrUtilsStatsShow (void)
{
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\nixNpeDlNpeMgrUtilsStatsShow:\n"
"\tInstruction Memory writes: %u\n"
"\tInstruction Memory writes failed: %u\n"
"\tData Memory writes: %u\n"
"\tData Memory writes failed: %u\n",
ixNpeDlNpeMgrUtilsStats.insMemWrites,
ixNpeDlNpeMgrUtilsStats.insMemWriteFails,
ixNpeDlNpeMgrUtilsStats.dataMemWrites,
ixNpeDlNpeMgrUtilsStats.dataMemWriteFails,
0,0);
ixOsalLog (IX_OSAL_LOG_LVL_USER,
IX_OSAL_LOG_DEV_STDOUT,
"\tExecuting Context Stack Register writes: %u\n"
"\tExecuting Context Stack Register reads: %u\n"
"\tPhysical Register writes: %u\n"
"\tContext Store Register writes: %u\n"
"\tExecution Backgound Context NextPC writes: %u\n"
"\tDebug Instructions Executed: %u\n\n",
ixNpeDlNpeMgrUtilsStats.ecsRegWrites,
ixNpeDlNpeMgrUtilsStats.ecsRegReads,
ixNpeDlNpeMgrUtilsStats.physicalRegWrites,
ixNpeDlNpeMgrUtilsStats.contextRegWrites,
ixNpeDlNpeMgrUtilsStats.nextPcWrites,
ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs);
}
/*
* Function definition: ixNpeDlNpeMgrUtilsStatsReset
*/
void
ixNpeDlNpeMgrUtilsStatsReset (void)
{
ixNpeDlNpeMgrUtilsStats.insMemWrites = 0;
ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0;
ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0;
ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0;
ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0;
ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0;
ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0;
ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0;
ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0;
ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0;
}

View File

@ -1,558 +0,0 @@
/**
* @file IxNpeMh.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the public API for the
* IXP425 NPE Message Handler component.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMh.h"
#include "IxNpeMhConfig_p.h"
#include "IxNpeMhReceive_p.h"
#include "IxNpeMhSend_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
#include "IxNpeMhUnsolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE BOOL ixNpeMhInitialized = false;
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
/*
* Function definition: ixNpeMhInitialize
*/
PUBLIC IX_STATUS ixNpeMhInitialize (
IxNpeMhNpeInterrupts npeInterrupts)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhInitialize\n");
/* check the npeInterrupts parameter */
if ((npeInterrupts != IX_NPEMH_NPEINTERRUPTS_NO) &&
(npeInterrupts != IX_NPEMH_NPEINTERRUPTS_YES))
{
IX_NPEMH_ERROR_REPORT ("Illegal npeInterrupts parameter value\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* initialize the Receive module */
ixNpeMhReceiveInitialize ();
/* initialize the Solicited Callback Manager module */
ixNpeMhSolicitedCbMgrInitialize ();
/* initialize the Unsolicited Callback Manager module */
ixNpeMhUnsolicitedCbMgrInitialize ();
/* initialize the Configuration module
*
* NOTE: This module was originally configured before the
* others, but the sequence was changed so that interrupts
* would only be enabled after the handler functions were
* set up. The above modules need to be initialised to
* handle the NPE interrupts. See SCR #2231.
*/
ixNpeMhConfigInitialize (npeInterrupts);
ixNpeMhInitialized = true;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhInitialize\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhUnload
*/
PUBLIC IX_STATUS ixNpeMhUnload (void)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnload\n");
if (!ixNpeMhInitialized)
{
return IX_FAIL;
}
/* Uninitialize the Configuration module */
ixNpeMhConfigUninit ();
ixNpeMhInitialized = false;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnload\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhUnsolicitedCallbackRegister
*/
PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
IxNpeMhNpeId npeId,
IxNpeMhMessageId messageId,
IxNpeMhCallback unsolicitedCallback)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCallbackRegister\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* check the messageId parameter */
if ((messageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (messageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Message ID is out of range\n");
return IX_FAIL;
}
/* the unsolicitedCallback parameter is allowed to be NULL */
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* save the unsolicited callback for the message ID */
ixNpeMhUnsolicitedCbMgrCallbackSave (
npeId, messageId, unsolicitedCallback);
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCallbackRegister\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhUnsolicitedCallbackForRangeRegister
*/
PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
IxNpeMhNpeId npeId,
IxNpeMhMessageId minMessageId,
IxNpeMhMessageId maxMessageId,
IxNpeMhCallback unsolicitedCallback)
{
IxNpeMhMessageId messageId;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCallbackForRangeRegister\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* check the minMessageId parameter */
if ((minMessageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (minMessageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Min message ID is out of range\n");
return IX_FAIL;
}
/* check the maxMessageId parameter */
if ((maxMessageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (maxMessageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Max message ID is out of range\n");
return IX_FAIL;
}
/* check the semantics of the message range parameters */
if (minMessageId > maxMessageId)
{
IX_NPEMH_ERROR_REPORT ("Min message ID greater than max message "
"ID\n");
return IX_FAIL;
}
/* the unsolicitedCallback parameter is allowed to be NULL */
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* for each message ID in the range ... */
for (messageId = minMessageId; messageId <= maxMessageId; messageId++)
{
/* save the unsolicited callback for the message ID */
ixNpeMhUnsolicitedCbMgrCallbackSave (
npeId, messageId, unsolicitedCallback);
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCallbackForRangeRegister\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhMessageSend
*/
PUBLIC IX_STATUS ixNpeMhMessageSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
UINT32 maxSendRetries)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhMessageSend\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* send the message */
status = ixNpeMhSendMessageSend (npeId, message, maxSendRetries);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhMessageSend"
" : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeMhMessageWithResponseSend
*/
PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback solicitedCallback,
UINT32 maxSendRetries)
{
IX_STATUS status = IX_SUCCESS;
IxNpeMhCallback unsolicitedCallback = NULL;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhMessageWithResponseSend\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* the solicitecCallback parameter is allowed to be NULL. this */
/* signifies the client is not interested in the response message */
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* check the solicitedMessageId parameter */
if ((solicitedMessageId < IX_NPEMH_MIN_MESSAGE_ID)
|| (solicitedMessageId > IX_NPEMH_MAX_MESSAGE_ID))
{
IX_NPEMH_ERROR_REPORT ("Solicited message ID is out of range\n");
return IX_FAIL;
}
/* check the solicitedMessageId parameter. if an unsolicited */
/* callback has been registered for the specified message ID then */
/* report an error and return failure */
ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
npeId, solicitedMessageId, &unsolicitedCallback);
if (unsolicitedCallback != NULL)
{
IX_NPEMH_ERROR_REPORT ("Solicited message ID conflicts with "
"unsolicited message ID\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* send the message */
status = ixNpeMhSendMessageWithResponseSend (
npeId, message, solicitedMessageId, solicitedCallback,
maxSendRetries);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhMessageWithResponseSend"
" : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeMhMessagesReceive
*/
PUBLIC IX_STATUS ixNpeMhMessagesReceive (
IxNpeMhNpeId npeId)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhMessagesReceive\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* get the lock to prevent other clients from entering */
ixNpeMhConfigLockGet (npeId);
/* receive messages from the NPE */
status = ixNpeMhReceiveMessagesReceive (npeId);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to receive message\n");
}
/* release the lock to allow other clients back in */
ixNpeMhConfigLockRelease (npeId);
IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhMessagesReceive"
" : status = %d\n", status);
return status;
}
/*
* Function definition: ixNpeMhShow
*/
PUBLIC IX_STATUS ixNpeMhShow (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhShow\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* note we don't get the lock here as printing the statistics */
/* to a console may take some time and we don't want to impact */
/* system performance. this means that the statistics displayed */
/* may be in a state of flux and make not represent a consistent */
/* snapshot. */
/* display a header */
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
"Current state of NPE ID %d:\n\n", npeId, 0, 0, 0, 0, 0);
/* show the current state of each module */
/* show the current state of the Configuration module */
ixNpeMhConfigShow (npeId);
/* show the current state of the Receive module */
ixNpeMhReceiveShow (npeId);
/* show the current state of the Send module */
ixNpeMhSendShow (npeId);
/* show the current state of the Solicited Callback Manager module */
ixNpeMhSolicitedCbMgrShow (npeId);
/* show the current state of the Unsolicited Callback Manager module */
ixNpeMhUnsolicitedCbMgrShow (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhShow\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhShowReset
*/
PUBLIC IX_STATUS ixNpeMhShowReset (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhShowReset\n");
/* check that we are initialized */
if (!ixNpeMhInitialized)
{
IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
return IX_FAIL;
}
/* check the npeId parameter */
if (!ixNpeMhConfigNpeIdIsValid (npeId))
{
IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
return IX_FAIL;
}
/* parameters are ok ... */
/* note we don't get the lock here as resetting the statistics */
/* shouldn't impact system performance. */
/* reset the current state of each module */
/* reset the current state of the Configuration module */
ixNpeMhConfigShowReset (npeId);
/* reset the current state of the Receive module */
ixNpeMhReceiveShowReset (npeId);
/* reset the current state of the Send module */
ixNpeMhSendShowReset (npeId);
/* reset the current state of the Solicited Callback Manager module */
ixNpeMhSolicitedCbMgrShowReset (npeId);
/* reset the current state of the Unsolicited Callback Manager module */
ixNpeMhUnsolicitedCbMgrShowReset (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhShowReset\n");
return IX_SUCCESS;
}

View File

@ -1,584 +0,0 @@
/**
* @file IxNpeMhConfig.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Configuration module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhConfig_p.h"
/*
* #defines and macros used in this file.
*/
#define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
* retries before
* timeout
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhConfigStats
*
* @brief This structure is used to maintain statistics for the
* Configuration module.
*/
typedef struct
{
UINT32 outFifoReads; /**< outFifo reads */
UINT32 inFifoWrites; /**< inFifo writes */
UINT32 maxInFifoFullRetries; /**< max retries if inFIFO full */
UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */
} IxNpeMhConfigStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
{
{
0,
IX_NPEMH_NPEA_INT,
0,
0,
0,
0,
0,
NULL,
false
},
{
0,
IX_NPEMH_NPEB_INT,
0,
0,
0,
0,
0,
NULL,
false
},
{
0,
IX_NPEMH_NPEC_INT,
0,
0,
0,
0,
0,
NULL,
false
}
};
PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
PRIVATE
void ixNpeMhConfigIsr (void *parameter);
/*
* Function definition: ixNpeMhConfigIsr
*/
PRIVATE
void ixNpeMhConfigIsr (void *parameter)
{
IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
UINT32 ofint;
volatile UINT32 *statusReg =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigIsr\n");
/* get the OFINT (OutFifo interrupt) bit of the status register */
IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
/* if the OFINT status bit is set */
if (ofint)
{
/* if there is an ISR registered for this NPE */
if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
{
/* invoke the ISR routine */
ixNpeMhConfigNpeInfo[npeId].isr (npeId);
}
else
{
/* if we don't service the interrupt the NPE will continue */
/* to trigger the interrupt indefinitely */
IX_NPEMH_ERROR_REPORT ("No ISR registered to service "
"interrupt\n");
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigIsr\n");
}
/*
* Function definition: ixNpeMhConfigInitialize
*/
void ixNpeMhConfigInitialize (
IxNpeMhNpeInterrupts npeInterrupts)
{
IxNpeMhNpeId npeId;
UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigInitialize\n");
/* Request a mapping for the NPE-A config register address space */
virtualAddr[IX_NPEMH_NPEID_NPEA] =
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE,
IX_OSAL_IXP400_NPEA_MAP_SIZE);
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]);
/* Request a mapping for the NPE-B config register address space */
virtualAddr[IX_NPEMH_NPEID_NPEB] =
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE,
IX_OSAL_IXP400_NPEB_MAP_SIZE);
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]);
/* Request a mapping for the NPE-C config register address space */
virtualAddr[IX_NPEMH_NPEID_NPEC] =
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE,
IX_OSAL_IXP400_NPEC_MAP_SIZE);
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]);
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* declare a convenience pointer */
IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
/* store the virtual addresses of the NPE registers for later use */
npeInfo->virtualRegisterBase = virtualAddr[npeId];
npeInfo->statusRegister = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET;
npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET;
npeInfo->inFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
/* for test purposes - to verify the register addresses */
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register = "
"0x%08X\n", npeId, npeInfo->statusRegister);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = "
"0x%08X\n", npeId, npeInfo->controlRegister);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register = "
"0x%08X\n", npeId, npeInfo->inFifoRegister);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = "
"0x%08X\n", npeId, npeInfo->outFifoRegister);
/* connect our ISR to the NPE interrupt */
(void) ixOsalIrqBind (
npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
/* initialise a mutex for this NPE */
(void) ixOsalMutexInit (&npeInfo->mutex);
/* if we should service the NPE's "outFIFO not empty" interrupt */
if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
{
/* enable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInterruptEnable (npeId);
}
else
{
/* disable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInterruptDisable (npeId);
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigInitialize\n");
}
/*
* Function definition: ixNpeMhConfigUninit
*/
void ixNpeMhConfigUninit (void)
{
IxNpeMhNpeId npeId;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigUninit\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* declare a convenience pointer */
IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
/* disconnect ISR */
ixOsalIrqUnbind(npeInfo->interruptId);
/* destroy mutex associated with this NPE */
ixOsalMutexDestroy(&npeInfo->mutex);
IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
npeInfo->virtualRegisterBase = 0;
npeInfo->statusRegister = 0;
npeInfo->controlRegister = 0;
npeInfo->inFifoRegister = 0;
npeInfo->outFifoRegister = 0;
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigUninit\n");
}
/*
* Function definition: ixNpeMhConfigIsrRegister
*/
void ixNpeMhConfigIsrRegister (
IxNpeMhNpeId npeId,
IxNpeMhConfigIsr isr)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigIsrRegister\n");
/* check if there is already an ISR registered for this NPE */
if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
}
/* save the ISR routine with the NPE info */
ixNpeMhConfigNpeInfo[npeId].isr = isr;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigIsrRegister\n");
}
/*
* Function definition: ixNpeMhConfigNpeInterruptEnable
*/
BOOL ixNpeMhConfigNpeInterruptEnable (
IxNpeMhNpeId npeId)
{
UINT32 ofe;
volatile UINT32 *controlReg =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
/* get the OFE (OutFifoEnable) bit of the control register */
IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
/* if the interrupt is disabled then we must enable it */
if (!ofe)
{
/* set the OFE (OutFifoEnable) bit of the control register */
/* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
/* time for the write to have effect */
IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
(IX_NPEMH_NPE_CTL_OFE |
IX_NPEMH_NPE_CTL_OFEWE),
(IX_NPEMH_NPE_CTL_OFE |
IX_NPEMH_NPE_CTL_OFEWE));
}
/* return the previous state of the interrupt */
return (ofe != 0);
}
/*
* Function definition: ixNpeMhConfigNpeInterruptDisable
*/
BOOL ixNpeMhConfigNpeInterruptDisable (
IxNpeMhNpeId npeId)
{
UINT32 ofe;
volatile UINT32 *controlReg =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
/* get the OFE (OutFifoEnable) bit of the control register */
IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
/* if the interrupt is enabled then we must disable it */
if (ofe)
{
/* unset the OFE (OutFifoEnable) bit of the control register */
/* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
/* time for the write to have effect */
IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
(0 |
IX_NPEMH_NPE_CTL_OFEWE),
(IX_NPEMH_NPE_CTL_OFE |
IX_NPEMH_NPE_CTL_OFEWE));
}
/* return the previous state of the interrupt */
return (ofe != 0);
}
/*
* Function definition: ixNpeMhConfigMessageIdGet
*/
IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
IxNpeMhMessage message)
{
/* return the most-significant byte of the first word of the */
/* message */
return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
}
/*
* Function definition: ixNpeMhConfigNpeIdIsValid
*/
BOOL ixNpeMhConfigNpeIdIsValid (
IxNpeMhNpeId npeId)
{
/* check that the npeId parameter is within the range of valid IDs */
return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
}
/*
* Function definition: ixNpeMhConfigLockGet
*/
void ixNpeMhConfigLockGet (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigLockGet\n");
/* lock the mutex for this NPE */
(void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex,
IX_OSAL_WAIT_FOREVER);
/* disable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
ixNpeMhConfigNpeInterruptDisable (npeId);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigLockGet\n");
}
/*
* Function definition: ixNpeMhConfigLockRelease
*/
void ixNpeMhConfigLockRelease (
IxNpeMhNpeId npeId)
{
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhConfigLockRelease\n");
/* if the interrupt was previously enabled */
if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
{
/* enable the NPE's "outFIFO not empty" interrupt */
ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
ixNpeMhConfigNpeInterruptEnable (npeId);
}
/* unlock the mutex for this NPE */
(void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhConfigLockRelease\n");
}
/*
* Function definition: ixNpeMhConfigInFifoWrite
*/
IX_STATUS ixNpeMhConfigInFifoWrite (
IxNpeMhNpeId npeId,
IxNpeMhMessage message)
{
volatile UINT32 *npeInFifo =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
UINT32 retriesCount = 0;
/* write the first word of the message to the NPE's inFIFO */
IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
/* need to wait for room to write second word - see SCR #493,
poll for maximum number of retries, if exceed maximum
retries, exit from while loop */
while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
&& ixNpeMhConfigInFifoIsFull (npeId))
{
retriesCount++;
}
/* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
{
return IX_NPEMH_CRITICAL_NPE_ERR;
}
/* write the second word of the message to the NPE's inFIFO */
IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
/* record in the stats the maximum number of retries needed */
if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
{
ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
}
/* update statistical info */
ixNpeMhConfigStats[npeId].inFifoWrites++;
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhConfigOutFifoRead
*/
IX_STATUS ixNpeMhConfigOutFifoRead (
IxNpeMhNpeId npeId,
IxNpeMhMessage *message)
{
volatile UINT32 *npeOutFifo =
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
UINT32 retriesCount = 0;
/* read the first word of the message from the NPE's outFIFO */
IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
/* need to wait for NPE to write second word - see SCR #493
poll for maximum number of retries, if exceed maximum
retries, exit from while loop */
while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
&& ixNpeMhConfigOutFifoIsEmpty (npeId))
{
retriesCount++;
}
/* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
{
return IX_NPEMH_CRITICAL_NPE_ERR;
}
/* read the second word of the message from the NPE's outFIFO */
IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
/* record in the stats the maximum number of retries needed */
if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
{
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
}
/* update statistical info */
ixNpeMhConfigStats[npeId].outFifoReads++;
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhConfigShow
*/
void ixNpeMhConfigShow (
IxNpeMhNpeId npeId)
{
/* show the message fifo read counter */
IX_NPEMH_SHOW ("Message FIFO reads",
ixNpeMhConfigStats[npeId].outFifoReads);
/* show the message fifo write counter */
IX_NPEMH_SHOW ("Message FIFO writes",
ixNpeMhConfigStats[npeId].inFifoWrites);
/* show the max retries performed when inFIFO full */
IX_NPEMH_SHOW ("Max inFIFO Full retries",
ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
/* show the max retries performed when outFIFO empty */
IX_NPEMH_SHOW ("Max outFIFO Empty retries",
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
/* show the current status of the inFifo */
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
"InFifo is %s and %s\n",
(ixNpeMhConfigInFifoIsEmpty (npeId) ?
(int) "EMPTY" : (int) "NOT EMPTY"),
(ixNpeMhConfigInFifoIsFull (npeId) ?
(int) "FULL" : (int) "NOT FULL"),
0, 0, 0, 0);
/* show the current status of the outFifo */
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
"OutFifo is %s and %s\n",
(ixNpeMhConfigOutFifoIsEmpty (npeId) ?
(int) "EMPTY" : (int) "NOT EMPTY"),
(ixNpeMhConfigOutFifoIsFull (npeId) ?
(int) "FULL" : (int) "NOT FULL"),
0, 0, 0, 0);
}
/*
* Function definition: ixNpeMhConfigShowReset
*/
void ixNpeMhConfigShowReset (
IxNpeMhNpeId npeId)
{
/* reset the message fifo read counter */
ixNpeMhConfigStats[npeId].outFifoReads = 0;
/* reset the message fifo write counter */
ixNpeMhConfigStats[npeId].inFifoWrites = 0;
/* reset the max inFIFO Full retries counter */
ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
/* reset the max outFIFO empty retries counter */
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;
}

View File

@ -1,296 +0,0 @@
/**
* @file IxNpeMhReceive.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Receive module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhConfig_p.h"
#include "IxNpeMhReceive_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
#include "IxNpeMhUnsolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhReceiveStats
*
* @brief This structure is used to maintain statistics for the Receive
* module.
*/
typedef struct
{
UINT32 isrs; /**< receive ISR invocations */
UINT32 receives; /**< receive messages invocations */
UINT32 messages; /**< messages received */
UINT32 solicited; /**< solicited messages received */
UINT32 unsolicited; /**< unsolicited messages received */
UINT32 callbacks; /**< callbacks invoked */
} IxNpeMhReceiveStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
PRIVATE
void ixNpeMhReceiveIsr (int npeId);
PRIVATE
void ixNpeMhReceiveIsr (int npeId)
{
int lockKey;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveIsr\n");
lockKey = ixOsalIrqLock ();
/* invoke the message receive routine to get messages from the NPE */
ixNpeMhReceiveMessagesReceive (npeId);
/* update statistical info */
ixNpeMhReceiveStats[npeId].isrs++;
ixOsalIrqUnlock (lockKey);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveIsr\n");
}
/*
* Function definition: ixNpeMhReceiveInitialize
*/
void ixNpeMhReceiveInitialize (void)
{
IxNpeMhNpeId npeId = 0;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveInitialize\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* register our internal ISR for the NPE to handle "outFIFO not */
/* empty" interrupts */
ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr);
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveInitialize\n");
}
/*
* Function definition: ixNpeMhReceiveMessagesReceive
*/
IX_STATUS ixNpeMhReceiveMessagesReceive (
IxNpeMhNpeId npeId)
{
IxNpeMhMessage message = { { 0, 0 } };
IxNpeMhMessageId messageId = 0;
IxNpeMhCallback callback = NULL;
IX_STATUS status;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhReceiveMessagesReceive\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].receives++;
/* while the NPE has messages in its outFIFO */
while (!ixNpeMhConfigOutFifoIsEmpty (npeId))
{
/* read a message from the NPE's outFIFO */
status = ixNpeMhConfigOutFifoRead (npeId, &message);
if (IX_SUCCESS != status)
{
return status;
}
/* get the ID of the message */
messageId = ixNpeMhConfigMessageIdGet (message);
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG,
"Received message from NPE %d with ID 0x%02X\n",
npeId, messageId);
/* update statistical info */
ixNpeMhReceiveStats[npeId].messages++;
/* try to find a matching unsolicited callback for this message. */
/* we assume the message is unsolicited. only if there is no */
/* unsolicited callback for this message type do we assume the */
/* message is solicited. it is much faster to check for an */
/* unsolicited callback, so doing this check first should result */
/* in better performance. */
ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
npeId, messageId, &callback);
if (callback != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
"Found matching unsolicited callback\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].unsolicited++;
}
/* if no unsolicited callback was found try to find a matching */
/* solicited callback for this message */
if (callback == NULL)
{
ixNpeMhSolicitedCbMgrCallbackRetrieve (
npeId, messageId, &callback);
if (callback != NULL)
{
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
"Found matching solicited callback\n");
/* update statistical info */
ixNpeMhReceiveStats[npeId].solicited++;
}
}
/* if a callback (either unsolicited or solicited) was found */
if (callback != NULL)
{
/* invoke the callback to pass the message back to the client */
callback (npeId, message);
/* update statistical info */
ixNpeMhReceiveStats[npeId].callbacks++;
}
else /* no callback (neither unsolicited nor solicited) was found */
{
IX_NPEMH_TRACE2 (IX_NPEMH_WARNING,
"No matching callback for NPE %d"
" and ID 0x%02X, discarding message\n",
npeId, messageId);
/* the message will be discarded. this is normal behaviour */
/* if the client passes a NULL solicited callback when */
/* sending a message. this indicates that the client is not */
/* interested in receiving the response. alternatively a */
/* NULL callback here may signify an unsolicited message */
/* with no appropriate registered callback. */
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhReceiveMessagesReceive\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhReceiveShow
*/
void ixNpeMhReceiveShow (
IxNpeMhNpeId npeId)
{
/* show the ISR invocation counter */
IX_NPEMH_SHOW ("Receive ISR invocations",
ixNpeMhReceiveStats[npeId].isrs);
/* show the receive message invocation counter */
IX_NPEMH_SHOW ("Receive messages invocations",
ixNpeMhReceiveStats[npeId].receives);
/* show the message received counter */
IX_NPEMH_SHOW ("Messages received",
ixNpeMhReceiveStats[npeId].messages);
/* show the solicited message counter */
IX_NPEMH_SHOW ("Solicited messages received",
ixNpeMhReceiveStats[npeId].solicited);
/* show the unsolicited message counter */
IX_NPEMH_SHOW ("Unsolicited messages received",
ixNpeMhReceiveStats[npeId].unsolicited);
/* show the callback invoked counter */
IX_NPEMH_SHOW ("Callbacks invoked",
ixNpeMhReceiveStats[npeId].callbacks);
/* show the message discarded counter */
IX_NPEMH_SHOW ("Received messages discarded",
(ixNpeMhReceiveStats[npeId].messages -
ixNpeMhReceiveStats[npeId].callbacks));
}
/*
* Function definition: ixNpeMhReceiveShowReset
*/
void ixNpeMhReceiveShowReset (
IxNpeMhNpeId npeId)
{
/* reset the ISR invocation counter */
ixNpeMhReceiveStats[npeId].isrs = 0;
/* reset the receive message invocation counter */
ixNpeMhReceiveStats[npeId].receives = 0;
/* reset the message received counter */
ixNpeMhReceiveStats[npeId].messages = 0;
/* reset the solicited message counter */
ixNpeMhReceiveStats[npeId].solicited = 0;
/* reset the unsolicited message counter */
ixNpeMhReceiveStats[npeId].unsolicited = 0;
/* reset the callback invoked counter */
ixNpeMhReceiveStats[npeId].callbacks = 0;
}

View File

@ -1,283 +0,0 @@
/**
* @file IxNpeMhSend.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Send module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhConfig_p.h"
#include "IxNpeMhSend_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/**
* @def IX_NPEMH_INFIFO_RETRY_DELAY_US
*
* @brief Amount of time (uSecs) to delay between retries
* while inFIFO is Full when attempting to send a message
*/
#define IX_NPEMH_INFIFO_RETRY_DELAY_US (1)
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhSendStats
*
* @brief This structure is used to maintain statistics for the Send
* module.
*/
typedef struct
{
UINT32 sends; /**< send invocations */
UINT32 sendWithResponses; /**< send with response invocations */
UINT32 queueFulls; /**< fifo queue full occurrences */
UINT32 queueFullRetries; /**< fifo queue full retry occurrences */
UINT32 maxQueueFullRetries; /**< max fifo queue full retries */
UINT32 callbackFulls; /**< callback list full occurrences */
} IxNpeMhSendStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
PRIVATE
BOOL ixNpeMhSendInFifoIsFull(
IxNpeMhNpeId npeId,
UINT32 maxSendRetries);
/*
* Function definition: ixNpeMhSendInFifoIsFull
*/
PRIVATE
BOOL ixNpeMhSendInFifoIsFull(
IxNpeMhNpeId npeId,
UINT32 maxSendRetries)
{
BOOL isFull = false;
UINT32 numRetries = 0;
/* check the NPE's inFIFO */
isFull = ixNpeMhConfigInFifoIsFull (npeId);
/* we retry a few times, just to give the NPE a chance to read from */
/* the FIFO if the FIFO is currently full */
while (isFull && (numRetries++ < maxSendRetries))
{
if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT)
{
/* Delay here for as short a time as possible (1 us). */
/* Adding a delay here should ensure we are not hogging */
/* the AHB bus while we are retrying */
ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
}
/* re-check the NPE's inFIFO */
isFull = ixNpeMhConfigInFifoIsFull (npeId);
/* update statistical info */
ixNpeMhSendStats[npeId].queueFullRetries++;
}
/* record the highest number of retries that occurred */
if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries)
{
ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries;
}
if (isFull)
{
/* update statistical info */
ixNpeMhSendStats[npeId].queueFulls++;
}
return isFull;
}
/*
* Function definition: ixNpeMhSendMessageSend
*/
IX_STATUS ixNpeMhSendMessageSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
UINT32 maxSendRetries)
{
IX_STATUS status;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSendMessageSend\n");
/* update statistical info */
ixNpeMhSendStats[npeId].sends++;
/* check if the NPE's inFIFO is full - if so return an error */
if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
{
IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
return IX_FAIL;
}
/* write the message to the NPE's inFIFO */
status = ixNpeMhConfigInFifoWrite (npeId, message);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSendMessageSend\n");
return status;
}
/*
* Function definition: ixNpeMhSendMessageWithResponseSend
*/
IX_STATUS ixNpeMhSendMessageWithResponseSend (
IxNpeMhNpeId npeId,
IxNpeMhMessage message,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback solicitedCallback,
UINT32 maxSendRetries)
{
IX_STATUS status = IX_SUCCESS;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSendMessageWithResponseSend\n");
/* update statistical info */
ixNpeMhSendStats[npeId].sendWithResponses++;
/* sr: this sleep will call the receive routine (no interrupts used!!!) */
ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
/* check if the NPE's inFIFO is full - if so return an error */
if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
{
IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
return IX_FAIL;
}
/* save the solicited callback */
status = ixNpeMhSolicitedCbMgrCallbackSave (
npeId, solicitedMessageId, solicitedCallback);
if (status != IX_SUCCESS)
{
IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n");
/* update statistical info */
ixNpeMhSendStats[npeId].callbackFulls++;
return status;
}
/* write the message to the NPE's inFIFO */
status = ixNpeMhConfigInFifoWrite (npeId, message);
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSendMessageWithResponseSend\n");
return status;
}
/*
* Function definition: ixNpeMhSendShow
*/
void ixNpeMhSendShow (
IxNpeMhNpeId npeId)
{
/* show the message send invocation counter */
IX_NPEMH_SHOW ("Send invocations",
ixNpeMhSendStats[npeId].sends);
/* show the message send with response invocation counter */
IX_NPEMH_SHOW ("Send with response invocations",
ixNpeMhSendStats[npeId].sendWithResponses);
/* show the fifo queue full occurrence counter */
IX_NPEMH_SHOW ("Fifo queue full occurrences",
ixNpeMhSendStats[npeId].queueFulls);
/* show the fifo queue full retry occurrence counter */
IX_NPEMH_SHOW ("Fifo queue full retry occurrences",
ixNpeMhSendStats[npeId].queueFullRetries);
/* show the fifo queue full maximum retries counter */
IX_NPEMH_SHOW ("Maximum fifo queue full retries",
ixNpeMhSendStats[npeId].maxQueueFullRetries);
/* show the callback list full occurrence counter */
IX_NPEMH_SHOW ("Solicited callback list full occurrences",
ixNpeMhSendStats[npeId].callbackFulls);
}
/*
* Function definition: ixNpeMhSendShowReset
*/
void ixNpeMhSendShowReset (
IxNpeMhNpeId npeId)
{
/* reset the message send invocation counter */
ixNpeMhSendStats[npeId].sends = 0;
/* reset the message send with response invocation counter */
ixNpeMhSendStats[npeId].sendWithResponses = 0;
/* reset the fifo queue full occurrence counter */
ixNpeMhSendStats[npeId].queueFulls = 0;
/* reset the fifo queue full retry occurrence counter */
ixNpeMhSendStats[npeId].queueFullRetries = 0;
/* reset the max fifo queue full retries counter */
ixNpeMhSendStats[npeId].maxQueueFullRetries = 0;
/* reset the callback list full occurrence counter */
ixNpeMhSendStats[npeId].callbackFulls = 0;
}

View File

@ -1,334 +0,0 @@
/**
* @file IxNpeMhSolicitedCbMgr.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for the
* Solicited Callback Manager module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#ifndef IXNPEMHCONFIG_P_H
# define IXNPEMHSOLICITEDCBMGR_C
#else
# error "Error, IxNpeMhConfig_p.h should not be included before this definition."
#endif
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhSolicitedCbMgr_p.h"
#include "IxNpeMhConfig_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhSolicitedCallbackListEntry
*
* @brief This structure is used to store the information associated with
* an entry in the callback list. This consists of the ID of the send
* message (which indicates the ID of the corresponding response message)
* and the callback function pointer itself.
*
*/
typedef struct IxNpeMhSolicitedCallbackListEntry
{
/** message ID */
IxNpeMhMessageId messageId;
/** callback function pointer */
IxNpeMhCallback callback;
/** pointer to next entry in the list */
struct IxNpeMhSolicitedCallbackListEntry *next;
} IxNpeMhSolicitedCallbackListEntry;
/**
* @struct IxNpeMhSolicitedCallbackList
*
* @brief This structure is used to maintain the list of response
* callbacks. The number of entries in this list will be variable, and
* they will be stored in a linked list fashion for ease of addition and
* removal. The entries themselves are statically allocated, and are
* organised into a "free" list and a "callback" list. Adding an entry
* means taking an entry from the "free" list and adding it to the
* "callback" list. Removing an entry means removing it from the
* "callback" list and returning it to the "free" list.
*/
typedef struct
{
/** pointer to the head of the free list */
IxNpeMhSolicitedCallbackListEntry *freeHead;
/** pointer to the head of the callback list */
IxNpeMhSolicitedCallbackListEntry *callbackHead;
/** pointer to the tail of the callback list */
IxNpeMhSolicitedCallbackListEntry *callbackTail;
/** array of entries - the first entry is used as a dummy entry to */
/* avoid the scenario of having an empty list, hence '+ 1' */
IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1];
} IxNpeMhSolicitedCallbackList;
/**
* @struct IxNpeMhSolicitedCbMgrStats
*
* @brief This structure is used to maintain statistics for the Solicited
* Callback Manager module.
*/
typedef struct
{
UINT32 saves; /**< callback list saves */
UINT32 retrieves; /**< callback list retrieves */
} IxNpeMhSolicitedCbMgrStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhSolicitedCallbackList
ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES];
PRIVATE IxNpeMhSolicitedCbMgrStats
ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
/*
* Function definition: ixNpeMhSolicitedCbMgrInitialize
*/
void ixNpeMhSolicitedCbMgrInitialize (void)
{
IxNpeMhNpeId npeId;
UINT32 localIndex;
IxNpeMhSolicitedCallbackList *list = NULL;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSolicitedCbMgrInitialize\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* initialise a pointer to the list for convenience */
list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
/* for each entry in the list, after the dummy entry ... */
for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++)
{
/* initialise the entry */
list->entries[localIndex].messageId = 0x00;
list->entries[localIndex].callback = NULL;
/* if this entry is before the last entry */
if (localIndex < IX_NPEMH_MAX_CALLBACKS)
{
/* chain this entry to the following entry */
list->entries[localIndex].next = &(list->entries[localIndex + 1]);
}
else /* this entry is the last entry */
{
/* the last entry isn't chained to anything */
list->entries[localIndex].next = NULL;
}
}
/* set the free list pointer to point to the first real entry */
/* (all real entries begin chained together on the free list) */
list->freeHead = &(list->entries[1]);
/* set the callback list pointers to point to the dummy entry */
/* (the callback list is initially empty) */
list->callbackHead = &(list->entries[0]);
list->callbackTail = &(list->entries[0]);
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSolicitedCbMgrInitialize\n");
}
/*
* Function definition: ixNpeMhSolicitedCbMgrCallbackSave
*/
IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
IxNpeMhNpeId npeId,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback solicitedCallback)
{
IxNpeMhSolicitedCallbackList *list = NULL;
IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhSolicitedCbMgrCallbackSave\n");
/* initialise a pointer to the list for convenience */
list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
/* check to see if there are any entries in the free list */
if (list->freeHead == NULL)
{
IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n");
return IX_FAIL;
}
/* there is an entry in the free list we can use */
/* update statistical info */
ixNpeMhSolicitedCbMgrStats[npeId].saves++;
/* remove a callback entry from the start of the free list */
callbackEntry = list->freeHead;
list->freeHead = callbackEntry->next;
/* fill in the callback entry with the new data */
callbackEntry->messageId = solicitedMessageId;
callbackEntry->callback = solicitedCallback;
/* the new callback entry will be added to the tail of the callback */
/* list, so it isn't chained to anything */
callbackEntry->next = NULL;
/* chain new callback entry to the last entry of the callback list */
list->callbackTail->next = callbackEntry;
list->callbackTail = callbackEntry;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhSolicitedCbMgrCallbackSave\n");
return IX_SUCCESS;
}
/*
* Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve
*/
void ixNpeMhSolicitedCbMgrCallbackRetrieve (
IxNpeMhNpeId npeId,
IxNpeMhMessageId solicitedMessageId,
IxNpeMhCallback *solicitedCallback)
{
IxNpeMhSolicitedCallbackList *list = NULL;
IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL;
/* initialise a pointer to the list for convenience */
list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
/* initialise the callback entry to the first entry of the callback */
/* list - we must skip over the dummy entry, which is the previous */
callbackEntry = list->callbackHead->next;
previousEntry = list->callbackHead;
/* traverse the callback list looking for an entry with a matching */
/* message ID. note we also save the previous entry's pointer to */
/* allow us to unchain the matching entry from the callback list */
while ((callbackEntry != NULL) &&
(callbackEntry->messageId != solicitedMessageId))
{
previousEntry = callbackEntry;
callbackEntry = callbackEntry->next;
}
/* if we didn't find a matching callback entry */
if (callbackEntry == NULL)
{
/* return a NULL callback in the outgoing parameter */
*solicitedCallback = NULL;
}
else /* we found a matching callback entry */
{
/* update statistical info */
ixNpeMhSolicitedCbMgrStats[npeId].retrieves++;
/* return the callback in the outgoing parameter */
*solicitedCallback = callbackEntry->callback;
/* unchain callback entry by chaining previous entry to next */
previousEntry->next = callbackEntry->next;
/* if the callback entry is at the tail of the list */
if (list->callbackTail == callbackEntry)
{
/* update the tail of the callback list */
list->callbackTail = previousEntry;
}
/* re-initialise the callback entry */
callbackEntry->messageId = 0x00;
callbackEntry->callback = NULL;
/* add the callback entry to the start of the free list */
callbackEntry->next = list->freeHead;
list->freeHead = callbackEntry;
}
}
/*
* Function definition: ixNpeMhSolicitedCbMgrShow
*/
void ixNpeMhSolicitedCbMgrShow (
IxNpeMhNpeId npeId)
{
/* show the solicited callback list save counter */
IX_NPEMH_SHOW ("Solicited callback list saves",
ixNpeMhSolicitedCbMgrStats[npeId].saves);
/* show the solicited callback list retrieve counter */
IX_NPEMH_SHOW ("Solicited callback list retrieves",
ixNpeMhSolicitedCbMgrStats[npeId].retrieves);
}
/*
* Function definition: ixNpeMhSolicitedCbMgrShowReset
*/
void ixNpeMhSolicitedCbMgrShowReset (
IxNpeMhNpeId npeId)
{
/* reset the solicited callback list save counter */
ixNpeMhSolicitedCbMgrStats[npeId].saves = 0;
/* reset the solicited callback list retrieve counter */
ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0;
}

View File

@ -1,222 +0,0 @@
/**
* @file IxNpeMhUnsolicitedCbMgr.c
*
* @author Intel Corporation
* @date 18 Jan 2002
*
* @brief This file contains the implementation of the private API for
* the Unsolicited Callback Manager module.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Put the system defined include files required.
*/
/*
* Put the user defined include files required.
*/
#include "IxOsal.h"
#include "IxNpeMhMacros_p.h"
#include "IxNpeMhUnsolicitedCbMgr_p.h"
/*
* #defines and macros used in this file.
*/
/*
* Typedefs whose scope is limited to this file.
*/
/**
* @struct IxNpeMhUnsolicitedCallbackTable
*
* @brief This structure is used to maintain the list of registered
* callbacks. One entry exists for each message ID, and a NULL entry will
* signify that no callback has been registered for that ID.
*/
typedef struct
{
/** array of entries */
IxNpeMhCallback entries[IX_NPEMH_MAX_MESSAGE_ID + 1];
} IxNpeMhUnsolicitedCallbackTable;
/**
* @struct IxNpeMhUnsolicitedCbMgrStats
*
* @brief This structure is used to maintain statistics for the Unsolicited
* Callback Manager module.
*/
typedef struct
{
UINT32 saves; /**< callback table saves */
UINT32 overwrites; /**< callback table overwrites */
} IxNpeMhUnsolicitedCbMgrStats;
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
PRIVATE IxNpeMhUnsolicitedCallbackTable
ixNpeMhUnsolicitedCallbackTables[IX_NPEMH_NUM_NPES];
PRIVATE IxNpeMhUnsolicitedCbMgrStats
ixNpeMhUnsolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
/*
* Extern function prototypes.
*/
/*
* Static function prototypes.
*/
/*
* Function definition: ixNpeMhUnsolicitedCbMgrInitialize
*/
void ixNpeMhUnsolicitedCbMgrInitialize (void)
{
IxNpeMhNpeId npeId = 0;
IxNpeMhUnsolicitedCallbackTable *table = NULL;
IxNpeMhMessageId messageId = 0;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCbMgrInitialize\n");
/* for each NPE ... */
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
{
/* initialise a pointer to the table for convenience */
table = &ixNpeMhUnsolicitedCallbackTables[npeId];
/* for each message ID ... */
for (messageId = IX_NPEMH_MIN_MESSAGE_ID;
messageId <= IX_NPEMH_MAX_MESSAGE_ID; messageId++)
{
/* initialise the callback for this message ID to NULL */
table->entries[messageId] = NULL;
}
}
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCbMgrInitialize\n");
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrCallbackSave
*/
void ixNpeMhUnsolicitedCbMgrCallbackSave (
IxNpeMhNpeId npeId,
IxNpeMhMessageId unsolicitedMessageId,
IxNpeMhCallback unsolicitedCallback)
{
IxNpeMhUnsolicitedCallbackTable *table = NULL;
/* initialise a pointer to the table for convenience */
table = &ixNpeMhUnsolicitedCallbackTables[npeId];
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
"ixNpeMhUnsolicitedCbMgrCallbackSave\n");
/* update statistical info */
ixNpeMhUnsolicitedCbMgrStats[npeId].saves++;
/* check if there is a callback already registered for this NPE and */
/* message ID */
if (table->entries[unsolicitedMessageId] != NULL)
{
/* if we are overwriting an existing callback */
if (unsolicitedCallback != NULL)
{
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Unsolicited callback "
"overwriting existing callback for NPE ID %d "
"message ID 0x%02X\n", npeId, unsolicitedMessageId);
}
else /* if we are clearing an existing callback */
{
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NULL unsolicited callback "
"clearing existing callback for NPE ID %d "
"message ID 0x%02X\n", npeId, unsolicitedMessageId);
}
/* update statistical info */
ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites++;
}
/* save the callback into the table */
table->entries[unsolicitedMessageId] = unsolicitedCallback;
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
"ixNpeMhUnsolicitedCbMgrCallbackSave\n");
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrCallbackRetrieve
*/
void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
IxNpeMhNpeId npeId,
IxNpeMhMessageId unsolicitedMessageId,
IxNpeMhCallback *unsolicitedCallback)
{
IxNpeMhUnsolicitedCallbackTable *table = NULL;
/* initialise a pointer to the table for convenience */
table = &ixNpeMhUnsolicitedCallbackTables[npeId];
/* retrieve the callback from the table */
*unsolicitedCallback = table->entries[unsolicitedMessageId];
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrShow
*/
void ixNpeMhUnsolicitedCbMgrShow (
IxNpeMhNpeId npeId)
{
/* show the unsolicited callback table save counter */
IX_NPEMH_SHOW ("Unsolicited callback table saves",
ixNpeMhUnsolicitedCbMgrStats[npeId].saves);
/* show the unsolicited callback table overwrite counter */
IX_NPEMH_SHOW ("Unsolicited callback table overwrites",
ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites);
}
/*
* Function definition: ixNpeMhUnsolicitedCbMgrShowReset
*/
void ixNpeMhUnsolicitedCbMgrShowReset (
IxNpeMhNpeId npeId)
{
/* reset the unsolicited callback table save counter */
ixNpeMhUnsolicitedCbMgrStats[npeId].saves = 0;
/* reset the unsolicited callback table overwrite counter */
ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites = 0;
}

View File

@ -1,776 +0,0 @@
/**
* @file IxOsalBufferMgt.c
*
* @brief Default buffer pool management and buffer management
* Implementation.
*
* Design Notes:
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* OS may choose to use default bufferMgt by defining
* IX_OSAL_USE_DEFAULT_BUFFER_MGT in IxOsalOsBufferMgt.h
*/
#include "IxOsal.h"
#define IX_OSAL_BUFFER_FREE_PROTECTION /* Define this to enable Illegal MBuf Freed Protection*/
/*
* The implementation is only used when the following
* is defined.
*/
#ifdef IX_OSAL_USE_DEFAULT_BUFFER_MGT
#define IX_OSAL_MBUF_SYS_SIGNATURE (0x8BADF00D)
#define IX_OSAL_MBUF_SYS_SIGNATURE_MASK (0xEFFFFFFF)
#define IX_OSAL_MBUF_USED_FLAG (0x10000000)
#define IX_OSAL_MBUF_SYS_SIGNATURE_INIT(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = (UINT32)IX_OSAL_MBUF_SYS_SIGNATURE
/*
* This implementation is protect, the buffer pool management's ixOsalMBufFree
* against an invalid MBUF pointer argument that already has been freed earlier
* or in other words resides in the free pool of MBUFs. This added feature,
* checks the MBUF "USED" FLAG. The Flag tells if the MBUF is still not freed
* back to the Buffer Pool.
* Disable this feature for performance reasons by undef
* IX_OSAL_BUFFER_FREE_PROTECTION macro.
*/
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&(IX_OSAL_MBUF_SYS_SIGNATURE_MASK) )
#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) do { \
IX_OSAL_MBUF_SIGNATURE (bufPtr)&(~IX_OSAL_MBUF_SYS_SIGNATURE_MASK);\
IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_SYS_SIGNATURE; \
}while(0)
#define IX_OSAL_MBUF_SET_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_USED_FLAG
#define IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)&=~IX_OSAL_MBUF_USED_FLAG
#define IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&IX_OSAL_MBUF_USED_FLAG)
#else
#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)
#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = IX_OSAL_MBUF_SYS_SIGNATURE
#endif /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
/*
* A unit of 32, used to provide bit-shift for pool
* management. Needs some work if users want more than 32 pools.
*/
#define IX_OSAL_BUFF_FREE_BITS 32
PRIVATE UINT32 ixOsalBuffFreePools[IX_OSAL_MBUF_MAX_POOLS /
IX_OSAL_BUFF_FREE_BITS];
PUBLIC IX_OSAL_MBUF_POOL ixOsalBuffPools[IX_OSAL_MBUF_MAX_POOLS];
static int ixOsalBuffPoolsInUse = 0;
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
PRIVATE IX_OSAL_MBUF *
ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
UINT32 dataSizeAligned,
IX_OSAL_MBUF_POOL *poolPtr);
#endif
PRIVATE IX_OSAL_MBUF_POOL * ixOsalPoolAlloc (void);
/*
* Function definition: ixOsalPoolAlloc
*/
/****************************/
PRIVATE IX_OSAL_MBUF_POOL *
ixOsalPoolAlloc (void)
{
register unsigned int i = 0;
/*
* Scan for the first free buffer. Free buffers are indicated by 0
* on the corrsponding bit in ixOsalBuffFreePools.
*/
if (ixOsalBuffPoolsInUse >= IX_OSAL_MBUF_MAX_POOLS)
{
/*
* Fail to grab a ptr this time
*/
return NULL;
}
while (ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] &
(1 << (i % IX_OSAL_BUFF_FREE_BITS)))
i++;
/*
* Free buffer found. Mark it as busy and initialize.
*/
ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] |=
(1 << (i % IX_OSAL_BUFF_FREE_BITS));
memset (&ixOsalBuffPools[i], 0, sizeof (IX_OSAL_MBUF_POOL));
ixOsalBuffPools[i].poolIdx = i;
ixOsalBuffPoolsInUse++;
return &ixOsalBuffPools[i];
}
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
PRIVATE IX_OSAL_MBUF *
ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
UINT32 dataSizeAligned,
IX_OSAL_MBUF_POOL *poolPtr)
{
UINT8 *dataPtr;
IX_OSAL_MBUF *realMbufPtr;
/* Allocate cache-aligned memory for mbuf header */
realMbufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (mbufSizeAligned);
IX_OSAL_ASSERT (realMbufPtr != NULL);
memset (realMbufPtr, 0, mbufSizeAligned);
/* Allocate cache-aligned memory for mbuf data */
dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (dataSizeAligned);
IX_OSAL_ASSERT (dataPtr != NULL);
memset (dataPtr, 0, dataSizeAligned);
/* Fill in mbuf header fields */
IX_OSAL_MBUF_MDATA (realMbufPtr) = dataPtr;
IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (realMbufPtr) = (UINT32)dataPtr;
IX_OSAL_MBUF_MLEN (realMbufPtr) = dataSizeAligned;
IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (realMbufPtr) = dataSizeAligned;
IX_OSAL_MBUF_NET_POOL (realMbufPtr) = (IX_OSAL_MBUF_POOL *) poolPtr;
IX_OSAL_MBUF_SYS_SIGNATURE_INIT(realMbufPtr);
/* update some statistical information */
poolPtr->mbufMemSize += mbufSizeAligned;
poolPtr->dataMemSize += dataSizeAligned;
return realMbufPtr;
}
#endif /* #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY */
/*
* Function definition: ixOsalBuffPoolInit
*/
PUBLIC IX_OSAL_MBUF_POOL *
ixOsalPoolInit (UINT32 count, UINT32 size, const char *name)
{
/* These variables are only used if UX_OSAL_BUFFER_ALLOC_SEPERATELY
* is defined .
*/
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
UINT32 i, mbufSizeAligned, dataSizeAligned;
IX_OSAL_MBUF *currentMbufPtr = NULL;
#else
void *poolBufPtr;
void *poolDataPtr;
int mbufMemSize;
int dataMemSize;
#endif
IX_OSAL_MBUF_POOL *poolPtr = NULL;
if (count <= 0)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "count = 0 \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (name == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "NULL name \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): "
"ERROR - name length should be no greater than %d \n",
IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
return NULL;
}
/* OS can choose whether to allocate all buffers all together (if it
* can handle a huge single alloc request), or to allocate buffers
* separately by the defining IX_OSAL_BUFFER_ALLOC_SEPARATELY.
*/
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
/* Get a pool Ptr */
poolPtr = ixOsalPoolAlloc ();
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "Fail to Get PoolPtr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
mbufSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
dataSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN(size);
poolPtr->nextFreeBuf = NULL;
poolPtr->mbufMemPtr = NULL;
poolPtr->dataMemPtr = NULL;
poolPtr->bufDataSize = dataSizeAligned;
poolPtr->totalBufsInPool = count;
poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
strcpy (poolPtr->name, name);
for (i = 0; i < count; i++)
{
/* create an mbuf */
currentMbufPtr = ixOsalBuffPoolMbufInit (mbufSizeAligned,
dataSizeAligned,
poolPtr);
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
/* Set the Buffer USED Flag. If not, ixOsalMBufFree will fail.
ixOsalMbufFree used here is in a special case whereby, it's
used to add MBUF to the Pool. By specification, ixOsalMbufFree
deallocates an allocated MBUF from Pool.
*/
IX_OSAL_MBUF_SET_USED_FLAG(currentMbufPtr);
#endif
/* Add it to the pool */
ixOsalMbufFree (currentMbufPtr);
/* flush the pool information to RAM */
IX_OSAL_CACHE_FLUSH (currentMbufPtr, mbufSizeAligned);
}
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool = count;
#else
/* Otherwise allocate buffers in a continuous block fashion */
poolBufPtr = IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC (count, mbufMemSize);
IX_OSAL_ASSERT (poolBufPtr != NULL);
poolDataPtr =
IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC (count, size, dataMemSize);
IX_OSAL_ASSERT (poolDataPtr != NULL);
poolPtr = ixOsalNoAllocPoolInit (poolBufPtr, poolDataPtr,
count, size, name);
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalPoolInit(): " "Fail to get pool ptr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
#endif /* IX_OSAL_BUFFER_ALLOC_SEPARATELY */
return poolPtr;
}
PUBLIC IX_OSAL_MBUF_POOL *
ixOsalNoAllocPoolInit (void *poolBufPtr,
void *poolDataPtr, UINT32 count, UINT32 size, const char *name)
{
UINT32 i, mbufSizeAligned, sizeAligned;
IX_OSAL_MBUF *currentMbufPtr = NULL;
IX_OSAL_MBUF *nextMbufPtr = NULL;
IX_OSAL_MBUF_POOL *poolPtr = NULL;
/*
* check parameters
*/
if (poolBufPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - NULL poolBufPtr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (count <= 0)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - count must > 0 \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (name == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - NULL name ptr \n", 0, 0, 0, 0, 0, 0);
return NULL;
}
if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalNoAllocPoolInit(): "
"ERROR - name length should be no greater than %d \n",
IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
return NULL;
}
poolPtr = ixOsalPoolAlloc ();
if (poolPtr == NULL)
{
return NULL;
}
/*
* Adjust sizes to ensure alignment on cache line boundaries
*/
mbufSizeAligned =
IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
/*
* clear the mbuf memory area
*/
memset (poolBufPtr, 0, mbufSizeAligned * count);
if (poolDataPtr != NULL)
{
/*
* Adjust sizes to ensure alignment on cache line boundaries
*/
sizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
/*
* clear the data memory area
*/
memset (poolDataPtr, 0, sizeAligned * count);
}
else
{
sizeAligned = 0;
}
/*
* initialise pool fields
*/
strcpy ((poolPtr)->name, name);
poolPtr->dataMemPtr = poolDataPtr;
poolPtr->mbufMemPtr = poolBufPtr;
poolPtr->bufDataSize = sizeAligned;
poolPtr->totalBufsInPool = count;
poolPtr->mbufMemSize = mbufSizeAligned * count;
poolPtr->dataMemSize = sizeAligned * count;
currentMbufPtr = (IX_OSAL_MBUF *) poolBufPtr;
poolPtr->nextFreeBuf = currentMbufPtr;
for (i = 0; i < count; i++)
{
if (i < (count - 1))
{
nextMbufPtr =
(IX_OSAL_MBUF *) ((unsigned) currentMbufPtr +
mbufSizeAligned);
}
else
{ /* last mbuf in chain */
nextMbufPtr = NULL;
}
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (currentMbufPtr) = nextMbufPtr;
IX_OSAL_MBUF_NET_POOL (currentMbufPtr) = poolPtr;
IX_OSAL_MBUF_SYS_SIGNATURE_INIT(currentMbufPtr);
if (poolDataPtr != NULL)
{
IX_OSAL_MBUF_MDATA (currentMbufPtr) = poolDataPtr;
IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(currentMbufPtr) = (UINT32) poolDataPtr;
IX_OSAL_MBUF_MLEN (currentMbufPtr) = sizeAligned;
IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(currentMbufPtr) = sizeAligned;
poolDataPtr = (void *) ((unsigned) poolDataPtr + sizeAligned);
}
currentMbufPtr = nextMbufPtr;
}
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool = count;
poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC;
return poolPtr;
}
/*
* Get a mbuf ptr from the pool
*/
PUBLIC IX_OSAL_MBUF *
ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * poolPtr)
{
int lock;
IX_OSAL_MBUF *newBufPtr = NULL;
/*
* check parameters
*/
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalMbufAlloc(): "
"ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
return NULL;
}
lock = ixOsalIrqLock ();
newBufPtr = poolPtr->nextFreeBuf;
if (newBufPtr)
{
poolPtr->nextFreeBuf =
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr);
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr) = NULL;
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool--;
}
else
{
/* Return NULL to indicate to caller that request is denied. */
ixOsalIrqUnlock (lock);
return NULL;
}
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
/* Set Buffer Used Flag to indicate state.*/
IX_OSAL_MBUF_SET_USED_FLAG(newBufPtr);
#endif
ixOsalIrqUnlock (lock);
return newBufPtr;
}
PUBLIC IX_OSAL_MBUF *
ixOsalMbufFree (IX_OSAL_MBUF * bufPtr)
{
int lock;
IX_OSAL_MBUF_POOL *poolPtr;
IX_OSAL_MBUF *nextBufPtr = NULL;
/*
* check parameters
*/
if (bufPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalMbufFree(): "
"ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
return NULL;
}
lock = ixOsalIrqLock ();
#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
/* Prevention for Buffer freed more than once*/
if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr))
{
return NULL;
}
IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr);
#endif
poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr);
/*
* check the mbuf wrapper signature (if mbuf wrapper was used)
*/
if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
{
IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE),
"ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature.");
}
nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr);
IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf;
poolPtr->nextFreeBuf = bufPtr;
/*
* update the number of free buffers in the pool
*/
poolPtr->freeBufsInPool++;
ixOsalIrqUnlock (lock);
return nextBufPtr;
}
PUBLIC void
ixOsalMbufChainFree (IX_OSAL_MBUF * bufPtr)
{
while ((bufPtr = ixOsalMbufFree (bufPtr)));
}
/*
* Function definition: ixOsalBuffPoolShow
*/
PUBLIC void
ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * poolPtr)
{
IX_OSAL_MBUF *nextBufPtr;
int count = 0;
int lock;
/*
* check parameters
*/
if (poolPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolShow(): "
"ERROR - Invalid Parameter", 0, 0, 0, 0, 0, 0);
/*
* return IX_FAIL;
*/
return;
}
lock = ixOsalIrqLock ();
count = poolPtr->freeBufsInPool;
nextBufPtr = poolPtr->nextFreeBuf;
ixOsalIrqUnlock (lock);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
IX_OSAL_LOG_DEV_STDOUT, "=== POOL INFORMATION ===\n", 0, 0, 0,
0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Name: %s\n",
(unsigned int) poolPtr->name, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Allocation Type: %d\n",
(unsigned int) poolPtr->poolAllocType, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Mbuf Mem Usage (bytes): %d\n",
(unsigned int) poolPtr->mbufMemSize, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Pool Data Mem Usage (bytes): %d\n",
(unsigned int) poolPtr->dataMemSize, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Mbuf Data Capacity (bytes): %d\n",
(unsigned int) poolPtr->bufDataSize, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Total Mbufs in Pool: %d\n",
(unsigned int) poolPtr->totalBufsInPool, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Available Mbufs: %d\n", (unsigned int) count, 0,
0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Next Available Mbuf: %p\n", (unsigned int) nextBufPtr,
0, 0, 0, 0, 0);
if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC)
{
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
IX_OSAL_LOG_DEV_STDOUT,
"Mbuf Mem Area Start address: %p\n",
(unsigned int) poolPtr->mbufMemPtr, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
"Data Mem Area Start address: %p\n",
(unsigned int) poolPtr->dataMemPtr, 0, 0, 0, 0, 0);
}
}
PUBLIC void
ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr)
{
IX_OSAL_MBUF_POOL *poolPtr;
UINT8 *poolDataPtr;
if (bufPtr == NULL)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolBufDataPtrReset"
": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
return;
}
poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr);
poolDataPtr = poolPtr->dataMemPtr;
if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
{
if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolBufDataPtrReset"
": invalid mbuf, cannot reset mData pointer\n", 0, 0,
0, 0, 0, 0);
return;
}
IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr);
}
else
{
if (poolDataPtr)
{
unsigned int bufSize = poolPtr->bufDataSize;
unsigned int bufDataAddr =
(unsigned int) IX_OSAL_MBUF_MDATA (bufPtr);
unsigned int poolDataAddr = (unsigned int) poolDataPtr;
/*
* the pointer is still pointing somewhere in the mbuf payload.
* This operation moves the pointer to the beginning of the
* mbuf payload
*/
bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize;
IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr];
}
else
{
ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolBufDataPtrReset"
": cannot be used if user supplied NULL pointer for pool data area "
"when pool was created\n", 0, 0, 0, 0, 0, 0);
return;
}
}
}
/*
* Function definition: ixOsalBuffPoolUninit
*/
PUBLIC IX_STATUS
ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool)
{
if (!pool)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0);
return IX_FAIL;
}
if (pool->freeBufsInPool != pool->totalBufsInPool)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
"ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n",
0, 0, 0, 0, 0, 0);
return IX_FAIL;
}
if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
{
#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
UINT32 i;
IX_OSAL_MBUF* pBuf;
pBuf = pool->nextFreeBuf;
/* Freed the Buffer one by one till all the Memory is freed*/
for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){
IX_OSAL_MBUF* pBufTemp;
pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf);
/* Freed MBUF Data Memory area*/
IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) );
/* Freed MBUF Struct Memory area*/
IX_OSAL_CACHE_DMA_FREE(pBuf);
pBuf = pBufTemp;
}
#else
IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr);
IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr);
#endif
}
ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &=
~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS));
ixOsalBuffPoolsInUse--;
return IX_SUCCESS;
}
/*
* Function definition: ixOsalBuffPoolDataAreaSizeGet
*/
PUBLIC UINT32
ixOsalBuffPoolDataAreaSizeGet (int count, int size)
{
UINT32 memorySize;
memorySize = count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
return memorySize;
}
/*
* Function definition: ixOsalBuffPoolMbufAreaSizeGet
*/
PUBLIC UINT32
ixOsalBuffPoolMbufAreaSizeGet (int count)
{
UINT32 memorySize;
memorySize =
count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
return memorySize;
}
/*
* Function definition: ixOsalBuffPoolFreeCountGet
*/
PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr)
{
return poolPtr->freeBufsInPool;
}
#endif /* IX_OSAL_USE_DEFAULT_BUFFER_MGT */

View File

@ -1,307 +0,0 @@
/**
* @file IxOsalIoMem.c
*
* @brief OS-independent IO/Mem implementation
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/* Access to the global mem map is only allowed in this file */
#define IxOsalIoMem_C
#include "IxOsal.h"
#define SEARCH_PHYSICAL_ADDRESS (1)
#define SEARCH_VIRTUAL_ADDRESS (2)
/*
* Searches for map using one of the following criteria:
*
* - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
* - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
* - correct coherency
*
* Returns a pointer to the map or NULL if a suitable map is not found.
*/
PRIVATE IxOsalMemoryMap *
ixOsalMemMapFind (UINT32 requestedAddress,
UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
{
UINT32 mapIndex;
UINT32 numMapElements = ARRAY_SIZE(ixOsalGlobalMemoryMap);
for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
{
IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
&& requestedAddress >= map->physicalAddress
&& (requestedAddress + size) <= (map->physicalAddress + map->size)
&& (map->mapEndianType & requestedEndianType) != 0)
{
return map;
}
else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
&& requestedAddress >= map->virtualAddress
&& requestedAddress <= (map->virtualAddress + map->size)
&& (map->mapEndianType & requestedEndianType) != 0)
{
return map;
}
else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
{
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT,
"Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
}
}
/*
* not found
*/
return NULL;
}
/*
* This function maps an I/O mapped physical memory zone of the given size
* into a virtual memory zone accessible by the caller and returns a cookie -
* the start address of the virtual memory zone.
* IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
* virtual address.
* The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
* finished using this zone (e.g. on driver unload) using the cookie as
* parameter.
* The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
* the mapped memory, adding the necessary offsets to the address cookie.
*
* Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
* instead.
*/
PUBLIC void *
ixOsalIoMemMap (UINT32 requestedAddress,
UINT32 size, IxOsalMapEndianessType requestedEndianType)
{
IxOsalMemoryMap *map;
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT,
"OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
if (requestedEndianType == IX_OSAL_LE)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
0, 0, 0, 0, 0, 0);
return (NULL);
}
map = ixOsalMemMapFind (requestedAddress,
size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
if (map != NULL)
{
UINT32 offset = requestedAddress - map->physicalAddress;
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
IX_OSAL_LOG_DEV_STDOUT,
":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
map->physicalAddress, map->virtualAddress,
map->size, map->refCount, map->mapEndianType, 0);
if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
{
if (map->mapFunction != NULL)
{
map->mapFunction (map);
if (map->virtualAddress == 0)
{
/*
* failed
*/
ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
return NULL;
}
}
else
{
/*
* error, no map function for a dynamic map
*/
ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: No map function for a dynamic map - "
"[addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
return NULL;
}
}
/*
* increment reference count
*/
map->refCount++;
return (void *) (map->virtualAddress + offset);
}
/*
* requested address is not described in the global memory map
*/
ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
requestedAddress, size, requestedEndianType, 0, 0, 0);
return NULL;
}
/*
* This function unmaps a previously mapped I/O memory zone using
* the cookie obtained in the mapping operation. The memory zone in question
* becomes unavailable to the caller once unmapped and the cookie should be
* discarded.
*
* This function cannot fail if the given parameter is correct and does not
* return a value.
*
* Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
* instead.
*/
PUBLIC void
ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
{
IxOsalMemoryMap *map;
if (endianType == IX_OSAL_LE)
{
ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
0, 0, 0, 0, 0, 0);
return;
}
if (requestedAddress == 0)
{
/*
* invalid virtual address
*/
return;
}
map =
ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
endianType);
if (map != NULL)
{
if (map->refCount > 0)
{
/*
* decrement reference count
*/
map->refCount--;
if (map->refCount == 0)
{
/*
* no longer used, deallocate
*/
if (map->type == IX_OSAL_DYNAMIC_MAP
&& map->unmapFunction != NULL)
{
map->unmapFunction (map);
}
}
}
}
else
{
ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
IX_OSAL_LOG_DEV_STDERR,
"OSAL: ixOsServMemUnmap didn't find the requested map "
"[virt addr 0x%x: endianType %d], ignoring call\n",
requestedAddress, endianType, 0, 0, 0, 0);
}
}
/*
* This function Converts a virtual address into a physical
* address, including the dynamically mapped memory.
*
* Parameters virtAddr - virtual address to convert
* Return value: corresponding physical address, or NULL
* if there is no physical address addressable
* by the given virtual address
* OS: VxWorks, Linux, WinCE, QNX, eCos
* Reentrant: Yes
* IRQ safe: Yes
*/
PUBLIC UINT32
ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
{
IxOsalMemoryMap *map =
ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
requestedCoherency);
if (map != NULL)
{
return map->physicalAddress + virtualAddress - map->virtualAddress;
}
else
{
return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
}
}
/*
* This function Converts a virtual address into a physical
* address, including the dynamically mapped memory.
*
* Parameters virtAddr - virtual address to convert
* Return value: corresponding physical address, or NULL
* if there is no physical address addressable
* by the given virtual address
* OS: VxWorks, Linux, WinCE, QNX, eCos
* Reentrant: Yes
* IRQ safe: Yes
*/
PUBLIC UINT32
ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
{
IxOsalMemoryMap *map =
ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
requestedCoherency);
if (map != NULL)
{
return map->virtualAddress + physicalAddress - map->physicalAddress;
}
else
{
return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
}
}

View File

@ -1,43 +0,0 @@
/**
* @file IxOsalOsCacheMMU.c (linux)
*
* @brief Cache MemAlloc and MemFree.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include <malloc.h>
/*
* Allocate on a cache line boundary (null pointers are
* not affected by this operation). This operation is NOT cache safe.
*/
void *
ixOsalCacheDmaMalloc (UINT32 n)
{
return malloc(n);
}
/*
*
*/
void
ixOsalCacheDmaFree (void *ptr)
{
free(ptr);
}

View File

@ -1,55 +0,0 @@
/**
* @file IxOsalOsMsgQ.c (eCos)
*
* @brief OS-specific Message Queue implementation.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
/*******************************
* Public functions
*******************************/
PUBLIC IX_STATUS
ixOsalMessageQueueCreate (IxOsalMessageQueue * queue,
UINT32 msgCount, UINT32 msgLen)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMessageQueueDelete (IxOsalMessageQueue * queue)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMessageQueueSend (IxOsalMessageQueue * queue, UINT8 * message)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMessageQueueReceive (IxOsalMessageQueue * queue, UINT8 * message)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}

View File

@ -1,209 +0,0 @@
/**
* @file IxOsalOsSemaphore.c (eCos)
*
* @brief Implementation for semaphore and mutex.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
#include "IxNpeMhReceive_p.h"
/* Define a large number */
#define IX_OSAL_MAX_LONG (0x7FFFFFFF)
/* Max timeout in MS, used to guard against possible overflow */
#define IX_OSAL_MAX_TIMEOUT_MS (IX_OSAL_MAX_LONG/HZ)
PUBLIC IX_STATUS
ixOsalSemaphoreInit (IxOsalSemaphore * sid, UINT32 start_value)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_SUCCESS;
}
/**
* DESCRIPTION: If the semaphore is 'empty', the calling thread is blocked.
* If the semaphore is 'full', it is taken and control is returned
* to the caller. If the time indicated in 'timeout' is reached,
* the thread will unblock and return an error indication. If the
* timeout is set to 'IX_OSAL_WAIT_NONE', the thread will never block;
* if it is set to 'IX_OSAL_WAIT_FOREVER', the thread will block until
* the semaphore is available.
*
*
*/
PUBLIC IX_STATUS
ixOsalSemaphoreWait (IxOsalOsSemaphore * sid, INT32 timeout)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_SUCCESS;
}
/*
* Attempt to get semaphore, return immediately,
* no error info because users expect some failures
* when using this API.
*/
PUBLIC IX_STATUS
ixOsalSemaphoreTryWait (IxOsalSemaphore * sid)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
/**
*
* DESCRIPTION: This function causes the next available thread in the pend queue
* to be unblocked. If no thread is pending on this semaphore, the
* semaphore becomes 'full'.
*/
PUBLIC IX_STATUS
ixOsalSemaphorePost (IxOsalSemaphore * sid)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalSemaphoreDestroy (IxOsalSemaphore * sid)
{
diag_printf("%s called\n", __FUNCTION__);
return IX_FAIL;
}
/****************************
* Mutex
****************************/
static void drv_mutex_init(IxOsalMutex *mutex)
{
*mutex = 0;
}
static void drv_mutex_destroy(IxOsalMutex *mutex)
{
*mutex = -1;
}
static int drv_mutex_trylock(IxOsalMutex *mutex)
{
int result = true;
if (*mutex == 1)
result = false;
return result;
}
static void drv_mutex_unlock(IxOsalMutex *mutex)
{
if (*mutex == 1)
printf("Trying to unlock unlocked mutex!");
*mutex = 0;
}
PUBLIC IX_STATUS
ixOsalMutexInit (IxOsalMutex * mutex)
{
drv_mutex_init(mutex);
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout)
{
int tries;
if (timeout == IX_OSAL_WAIT_NONE) {
if (drv_mutex_trylock(mutex))
return IX_SUCCESS;
else
return IX_FAIL;
}
tries = (timeout * 1000) / 50;
while (1) {
if (drv_mutex_trylock(mutex))
return IX_SUCCESS;
if (timeout != IX_OSAL_WAIT_FOREVER && tries-- <= 0)
break;
udelay(50);
}
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMutexUnlock (IxOsalMutex * mutex)
{
drv_mutex_unlock(mutex);
return IX_SUCCESS;
}
/*
* Attempt to get mutex, return immediately,
* no error info because users expect some failures
* when using this API.
*/
PUBLIC IX_STATUS
ixOsalMutexTryLock (IxOsalMutex * mutex)
{
if (drv_mutex_trylock(mutex))
return IX_SUCCESS;
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalMutexDestroy (IxOsalMutex * mutex)
{
drv_mutex_destroy(mutex);
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalFastMutexInit (IxOsalFastMutex * mutex)
{
return ixOsalMutexInit(mutex);
}
PUBLIC IX_STATUS ixOsalFastMutexTryLock(IxOsalFastMutex *mutex)
{
return ixOsalMutexTryLock(mutex);
}
PUBLIC IX_STATUS
ixOsalFastMutexUnlock (IxOsalFastMutex * mutex)
{
return ixOsalMutexUnlock(mutex);
}
PUBLIC IX_STATUS
ixOsalFastMutexDestroy (IxOsalFastMutex * mutex)
{
return ixOsalMutexDestroy(mutex);
}

View File

@ -1,227 +0,0 @@
/**
* @file IxOsalOsServices.c (linux)
*
* @brief Implementation for Irq, Mem, sleep.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include <config.h>
#include <common.h>
#include "IxOsal.h"
#include <IxEthAcc.h>
#include <IxEthDB.h>
#include <IxNpeDl.h>
#include <IxQMgr.h>
#include <IxNpeMh.h>
static char *traceHeaders[] = {
"",
"[fatal] ",
"[error] ",
"[warning] ",
"[message] ",
"[debug1] ",
"[debug2] ",
"[debug3] ",
"[all]"
};
/* by default trace all but debug message */
PRIVATE int ixOsalCurrLogLevel = IX_OSAL_LOG_LVL_MESSAGE;
/**************************************
* Irq services
*************************************/
PUBLIC IX_STATUS
ixOsalIrqBind (UINT32 vector, IxOsalVoidFnVoidPtr routine, void *parameter)
{
return IX_FAIL;
}
PUBLIC IX_STATUS
ixOsalIrqUnbind (UINT32 vector)
{
return IX_FAIL;
}
PUBLIC UINT32
ixOsalIrqLock ()
{
return 0;
}
/* Enable interrupts and task scheduling,
* input parameter: irqEnable status returned
* by ixOsalIrqLock().
*/
PUBLIC void
ixOsalIrqUnlock (UINT32 lockKey)
{
}
PUBLIC UINT32
ixOsalIrqLevelSet (UINT32 level)
{
return IX_FAIL;
}
PUBLIC void
ixOsalIrqEnable (UINT32 irqLevel)
{
}
PUBLIC void
ixOsalIrqDisable (UINT32 irqLevel)
{
}
/*********************
* Log function
*********************/
INT32
ixOsalLog (IxOsalLogLevel level,
IxOsalLogDevice device,
char *format, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
{
/*
* Return -1 for custom display devices
*/
if ((device != IX_OSAL_LOG_DEV_STDOUT)
&& (device != IX_OSAL_LOG_DEV_STDERR))
{
debug("ixOsalLog: only IX_OSAL_LOG_DEV_STDOUT and IX_OSAL_LOG_DEV_STDERR are supported \n");
return (IX_OSAL_LOG_ERROR);
}
if (level <= ixOsalCurrLogLevel && level != IX_OSAL_LOG_LVL_NONE)
{
#if 0 /* sr: U-Boots printf or debug doesn't return a length */
int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : diag_printf(traceHeaders[level - 1]);
return headerByteCount + diag_printf (format, arg1, arg2, arg3, arg4, arg5, arg6);
#else
int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : strlen(traceHeaders[level - 1]);
return headerByteCount + strlen(format);
#endif
}
else
{
/*
* Return error
*/
return (IX_OSAL_LOG_ERROR);
}
}
PUBLIC UINT32
ixOsalLogLevelSet (UINT32 level)
{
UINT32 oldLevel;
/*
* Check value first
*/
if ((level < IX_OSAL_LOG_LVL_NONE) || (level > IX_OSAL_LOG_LVL_ALL))
{
ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
IX_OSAL_LOG_DEV_STDOUT,
"ixOsalLogLevelSet: Log Level is between %d and%d \n",
IX_OSAL_LOG_LVL_NONE, IX_OSAL_LOG_LVL_ALL, 0, 0, 0, 0);
return IX_OSAL_LOG_LVL_NONE;
}
oldLevel = ixOsalCurrLogLevel;
ixOsalCurrLogLevel = level;
return oldLevel;
}
/**************************************
* Task services
*************************************/
PUBLIC void
ixOsalBusySleep (UINT32 microseconds)
{
udelay(microseconds);
}
PUBLIC void
ixOsalSleep (UINT32 milliseconds)
{
if (milliseconds != 0) {
#if 1
/*
* sr: We poll while we wait because interrupts are off in U-Boot
* and CSR expects messages, etc to be dispatched while sleeping.
*/
int i;
IxQMgrDispatcherFuncPtr qDispatcherFunc;
ixQMgrDispatcherLoopGet(&qDispatcherFunc);
while (milliseconds--) {
for (i = 1; i <= 2; i++)
ixNpeMhMessagesReceive(i);
(*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP);
udelay(1000);
}
#endif
}
}
/**************************************
* Memory functions
*************************************/
void *
ixOsalMemAlloc (UINT32 size)
{
return (void *)0;
}
void
ixOsalMemFree (void *ptr)
{
}
/*
* Copy count bytes from src to dest ,
* returns pointer to the dest mem zone.
*/
void *
ixOsalMemCopy (void *dest, void *src, UINT32 count)
{
IX_OSAL_ASSERT (dest != NULL);
IX_OSAL_ASSERT (src != NULL);
return (memcpy (dest, src, count));
}
/*
* Fills a memory zone with a given constant byte,
* returns pointer to the memory zone.
*/
void *
ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count)
{
IX_OSAL_ASSERT (ptr != NULL);
return (memset (ptr, filler, count));
}

View File

@ -1,74 +0,0 @@
/**
* @file IxOsalOsThread.c (eCos)
*
* @brief OS-specific thread implementation.
*
*
* @par
* IXP400 SW Release version 1.5
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#include "IxOsal.h"
/* Thread attribute is ignored */
PUBLIC IX_STATUS
ixOsalThreadCreate (IxOsalThread * ptrTid,
IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg)
{
return IX_SUCCESS;
}
/*
* Start thread after given its thread handle
*/
PUBLIC IX_STATUS
ixOsalThreadStart (IxOsalThread * tId)
{
/* Thread already started upon creation */
return IX_SUCCESS;
}
/*
* In Linux threadKill does not actually destroy the thread,
* it will stop the signal handling.
*/
PUBLIC IX_STATUS
ixOsalThreadKill (IxOsalThread * tid)
{
return IX_SUCCESS;
}
PUBLIC void
ixOsalThreadExit (void)
{
}
PUBLIC IX_STATUS
ixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority)
{
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalThreadSuspend (IxOsalThread * tId)
{
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixOsalThreadResume (IxOsalThread * tId)
{
return IX_SUCCESS;
}

View File

@ -1,939 +0,0 @@
/*
* @file: IxQMgrAqmIf.c
*
* @author Intel Corporation
* @date 30-Oct-2001
*
* @brief This component provides a set of functions for
* perfoming I/O on the AQM hardware.
*
* Design Notes:
* These functions are intended to be as fast as possible
* and as a result perform NO PARAMETER CHECKING.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Inlines are compiled as function when this is defined.
* N.B. Must be placed before #include of "IxQMgrAqmIf_p.h
*/
#ifndef IXQMGRAQMIF_P_H
# define IXQMGRAQMIF_C
#else
# error
#endif
/*
* User defined include files.
*/
#include "IxOsal.h"
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrLog_p.h"
/*
* #defines and macros used in this file.
*/
/* These defines are the bit offsets of the various fields of
* the queue configuration register
*/
#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET 0x00
#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET 0x07
#define IX_QMGR_Q_CONFIG_BADDR_OFFSET 0x0E
#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET 0x16
#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET 0x18
#define IX_QMGR_Q_CONFIG_NE_OFFSET 0x1A
#define IX_QMGR_Q_CONFIG_NF_OFFSET 0x1D
#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN 0x40
#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT 0x6
#define IX_QMGR_NE_NF_CLEAR_MASK 0x03FFFFFF
#define IX_QMGR_NE_MASK 0x7
#define IX_QMGR_NF_MASK 0x7
#define IX_QMGR_SIZE_MASK 0x3
#define IX_QMGR_ENTRY_SIZE_MASK 0x3
#define IX_QMGR_BADDR_MASK 0x003FC000
#define IX_QMGR_RDPTR_MASK 0x7F
#define IX_QMGR_WRPTR_MASK 0x7F
#define IX_QMGR_RDWRPTR_MASK 0x00003FFF
#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
/* Base address of AQM SRAM */
#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))
/* Min buffer size used for generating buffer size in QUECONFIG */
#define IX_QMGR_MIN_BUFFER_SIZE 16
/* Reset values of QMgr hardware registers */
#define IX_QMGR_QUELOWSTAT_RESET_VALUE 0x33333333
#define IX_QMGR_QUEUOSTAT_RESET_VALUE 0x00000000
#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE 0xFFFFFFFF
#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE 0x00000000
#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
#define IX_QMGR_QUEIEREG_RESET_VALUE 0x00000000
#define IX_QMGR_QINTREG_RESET_VALUE 0xFFFFFFFF
#define IX_QMGR_QUECONFIG_RESET_VALUE 0x00000000
#define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE
#define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
(((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\
IX_QMGR_QUECONFIG_BASE_OFFSET)
#define IX_QMGR_ENTRY1_OFFSET 0
#define IX_QMGR_ENTRY2_OFFSET 1
#define IX_QMGR_ENTRY4_OFFSET 3
/*
* Variable declarations global to this file. Externs are followed by
* statics.
*/
UINT32 aqmBaseAddress = 0;
/* Store addresses and bit-masks for certain queue access and status registers.
* This is to facilitate inlining of QRead, QWrite and QStatusGet functions
* in IxQMgr,h
*/
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES];
UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID];
UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID];
UINT32 ixQMgrAqmIfQueLowStatBitsMask;
UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID];
UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID];
/*
* Fast mutexes, one for each queue, used to protect peek & poke functions
*/
IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES];
/*
* Function prototypes
*/
PRIVATE unsigned
watermarkToAqmWatermark (IxQMgrWMLevel watermark );
PRIVATE unsigned
entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize);
PRIVATE unsigned
bufferSizeToAqmBufferSize (unsigned bufferSizeInWords);
PRIVATE void
ixQMgrAqmIfRegistersReset (void);
PRIVATE void
ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
UINT32 configRegWord,
unsigned int qEntrySizeInwords,
unsigned int qSizeInWords,
UINT32 **address);
/*
* Function definitions
*/
void
ixQMgrAqmIfInit (void)
{
UINT32 aqmVirtualAddr;
int i;
/* The value of aqmBaseAddress depends on the logical address
* assigned by the MMU.
*/
aqmVirtualAddr =
(UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS,
IX_OSAL_IXP400_QMGR_MAP_SIZE);
IX_OSAL_ASSERT (aqmVirtualAddr);
ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr);
ixQMgrAqmIfRegistersReset ();
for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
{
ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]);
/********************************************************************
* Register addresses and bit masks are calculated and stored here to
* facilitate inlining of QRead, QWrite and QStatusGet functions in
* IxQMgr.h.
* These calculations are normally performed dynamically in inlined
* functions in IxQMgrAqmIf_p.h, and their semantics are reused here.
*/
/* AQM Queue access reg addresses, per queue */
ixQMgrAqmIfQueAccRegAddr[i] =
(UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr =
(volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr =
(volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i));
/* AQM Queue lower-group (0-31), only */
if (i < IX_QMGR_MIN_QUEUPP_QID)
{
/* AQM Q underflow/overflow status register addresses, per queue */
ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr =
(volatile UINT32 *)(aqmBaseAddress +
IX_QMGR_QUEUOSTAT0_OFFSET +
((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) *
IX_QMGR_NUM_BYTES_PER_WORD));
/* AQM Q underflow status bit masks for status register per queue */
ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask =
(IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) <<
((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
(BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
/* AQM Q overflow status bit masks for status register, per queue */
ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask =
(IX_QMGR_OVERFLOW_BIT_OFFSET + 1) <<
((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
(BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
/* AQM Q lower-group (0-31) status register addresses, per queue */
ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress +
IX_QMGR_QUELOWSTAT0_OFFSET +
((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
IX_QMGR_NUM_BYTES_PER_WORD);
/* AQM Q lower-group (0-31) status register bit offset */
ixQMgrAqmIfQueLowStatBitsOffset[i] =
(i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) *
(BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
}
else /* AQM Q upper-group (32-63), only */
{
/* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */
ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
(1 << (i - IX_QMGR_MIN_QUEUPP_QID));
/* AQM Q upper-group (32-63) Full status register bit masks */
ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
(1 << (i - IX_QMGR_MIN_QUEUPP_QID));
}
}
/* AQM Q lower-group (0-31) status register bit mask */
ixQMgrAqmIfQueLowStatBitsMask = (1 <<
(BITS_PER_WORD /
IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1;
/* AQM Q upper-group (32-63) Nearly Empty status register address */
ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET;
/* AQM Q upper-group (32-63) Full status register address */
ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET;
}
/*
* Uninitialise the AqmIf module by unmapping memory, etc
*/
void
ixQMgrAqmIfUninit (void)
{
UINT32 virtAddr;
ixQMgrAqmIfBaseAddressGet (&virtAddr);
IX_OSAL_MEM_UNMAP (virtAddr);
ixQMgrAqmIfBaseAddressSet (0);
}
/*
* Set the the logical base address of AQM
*/
void
ixQMgrAqmIfBaseAddressSet (UINT32 address)
{
aqmBaseAddress = address;
}
/*
* Get the logical base address of AQM
*/
void
ixQMgrAqmIfBaseAddressGet (UINT32 *address)
{
*address = aqmBaseAddress;
}
/*
* Get the logical base address of AQM SRAM
*/
void
ixQMgrAqmIfSramBaseAddressGet (UINT32 *address)
{
*address = aqmBaseAddress +
IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET;
}
/*
* This function will write the status bits of a queue
* specified by qId.
*/
void
ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId,
UINT32 registerBaseAddrOffset,
unsigned queuesPerRegWord,
UINT32 value)
{
volatile UINT32 *registerAddress;
UINT32 registerWord;
UINT32 statusBitsMask;
UINT32 bitsPerQueue;
bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;
/*
* Calculate the registerAddress
* multiple queues split accross registers
*/
registerAddress = (UINT32*)(aqmBaseAddress +
registerBaseAddrOffset +
((qId / queuesPerRegWord) *
IX_QMGR_NUM_BYTES_PER_WORD));
/* Read the current data */
ixQMgrAqmIfWordRead (registerAddress, &registerWord);
if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) &&
(qId == IX_QMGR_QUEUE_0) )
{
statusBitsMask = 0x7 ;
/* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3 */
value &= 0x7 ;
}
else
{
/* Calculate the mask for the status bits for this queue. */
statusBitsMask = ((1 << bitsPerQueue) - 1);
statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
/* Mask out bits in value that would overwrite other q data */
value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
value &= statusBitsMask;
}
/* Mask out bits to write to */
registerWord &= ~statusBitsMask;
/* Set the write bits */
registerWord |= value;
/*
* Write the data
*/
ixQMgrAqmIfWordWrite (registerAddress, registerWord);
}
/*
* This function generates the parameters that can be used to
* check if a Qs status matches the specified source select.
* It calculates which status word to check (statusWordOffset),
* the value to check the status against (checkValue) and the
* mask (mask) to mask out all but the bits to check in the status word.
*/
void
ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
IxQMgrSourceId srcSel,
unsigned int *statusWordOffset,
UINT32 *checkValue,
UINT32 *mask)
{
UINT32 shiftVal;
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
switch (srcSel)
{
case IX_QMGR_Q_SOURCE_ID_E:
*checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK;
*mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
break;
case IX_QMGR_Q_SOURCE_ID_NE:
*checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK;
*mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
break;
case IX_QMGR_Q_SOURCE_ID_NF:
*checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK;
*mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
break;
case IX_QMGR_Q_SOURCE_ID_F:
*checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK;
*mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
break;
case IX_QMGR_Q_SOURCE_ID_NOT_E:
*checkValue = 0;
*mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
break;
case IX_QMGR_Q_SOURCE_ID_NOT_NE:
*checkValue = 0;
*mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
break;
case IX_QMGR_Q_SOURCE_ID_NOT_NF:
*checkValue = 0;
*mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
break;
case IX_QMGR_Q_SOURCE_ID_NOT_F:
*checkValue = 0;
*mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
break;
default:
/* Should never hit */
IX_OSAL_ASSERT(0);
break;
}
/* One nibble of status per queue so need to shift the
* check value and mask out to the correct position.
*/
shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
IX_QMGR_QUELOWSTAT_BITS_PER_Q;
/* Calculate the which status word to check from the qId,
* 8 Qs status per word
*/
*statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD;
*checkValue <<= shiftVal;
*mask <<= shiftVal;
}
else
{
/* One status word */
*statusWordOffset = 0;
/* Single bits per queue and int source bit hardwired NE,
* Qs start at 32.
*/
*mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID);
*checkValue = *mask;
}
}
void
ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId)
{
volatile UINT32 *registerAddress;
UINT32 registerWord;
UINT32 actualBitOffset;
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
}
else
{
registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
}
actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
ixQMgrAqmIfWordRead (registerAddress, &registerWord);
ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset));
}
void
ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId)
{
volatile UINT32 *registerAddress;
UINT32 registerWord;
UINT32 actualBitOffset;
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
}
else
{
registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
}
actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
ixQMgrAqmIfWordRead (registerAddress, &registerWord);
ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
}
void
ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
IxQMgrQSizeInWords qSizeInWords,
IxQMgrQEntrySizeInWords entrySizeInWords,
UINT32 freeSRAMAddress)
{
volatile UINT32 *cfgAddress = NULL;
UINT32 qCfg = 0;
UINT32 baseAddress = 0;
unsigned aqmEntrySize = 0;
unsigned aqmBufferSize = 0;
/* Build config register */
aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords);
qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) <<
IX_QMGR_Q_CONFIG_ESIZE_OFFSET;
aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords);
qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET;
/* baseAddress, calculated relative to aqmBaseAddress and start address */
baseAddress = freeSRAMAddress -
(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
/* Verify base address aligned to a 16 word boundary */
if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0)
{
IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n");
}
/* Now convert it to a 16 word pointer as required by QUECONFIG register */
baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET);
cfgAddress = (UINT32*)(aqmBaseAddress +
IX_QMGR_Q_CONFIG_ADDR_GET(qId));
/* NOTE: High and Low watermarks are set to zero */
ixQMgrAqmIfWordWrite (cfgAddress, qCfg);
}
void
ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
unsigned int numEntries,
UINT32 *baseAddress,
unsigned int *ne,
unsigned int *nf,
UINT32 *readPtr,
UINT32 *writePtr)
{
UINT32 qcfg;
UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
unsigned int qEntrySizeInwords;
unsigned int qSizeInWords;
UINT32 *readPtr_ = NULL;
/* Read the queue configuration register */
ixQMgrAqmIfWordRead (cfgAddress, &qcfg);
/* Extract the base address */
*baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >>
(IX_QMGR_Q_CONFIG_BADDR_OFFSET));
/* Base address is a 16 word pointer from the start of AQM SRAM.
* Convert to absolute word address.
*/
*baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
*baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET;
/*
* Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries......
* If ne > 0 ==> neInEntries = 2^(ne - 1)
* If ne == 0 ==> neInEntries = 0
* The same applies.
*/
*ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK;
*nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK;
if (0 != *ne)
{
*ne = 1 << (*ne - 1);
}
if (0 != *nf)
{
*nf = 1 << (*nf - 1);
}
/* Get the queue entry size in words */
qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
/* Get the queue size in words */
qSizeInWords = ixQMgrQSizeInWordsGet (qId);
ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/,
qcfg,
qEntrySizeInwords,
qSizeInWords,
&readPtr_);
*readPtr = (UINT32)readPtr_;
*readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */
*writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK;
*writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD));
return;
}
unsigned
ixQMgrAqmIfLog2 (unsigned number)
{
unsigned count = 0;
/*
* N.B. this function will return 0
* for ixQMgrAqmIfLog2 (0)
*/
while (number/2)
{
number /=2;
count++;
}
return count;
}
void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void)
{
volatile UINT32 *registerAddress;
UINT32 registerWord;
/*
* Calculate the registerAddress
* multiple queues split accross registers
*/
registerAddress = (UINT32*)(aqmBaseAddress +
IX_QMGR_INT0SRCSELREG0_OFFSET);
/* Read the current data */
ixQMgrAqmIfWordRead (registerAddress, &registerWord);
/* Set the write bits */
registerWord |= (1<<IX_QMGR_INT0SRCSELREG0_BIT3) ;
/*
* Write the data
*/
ixQMgrAqmIfWordWrite (registerAddress, registerWord);
}
void
ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
IxQMgrSourceId sourceId)
{
ixQMgrAqmIfQRegisterBitsWrite (qId,
IX_QMGR_INT0SRCSELREG0_OFFSET,
IX_QMGR_INTSRC_NUM_QUE_PER_WORD,
sourceId);
}
void
ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
unsigned ne,
unsigned nf)
{
volatile UINT32 *address = 0;
UINT32 value = 0;
unsigned aqmNeWatermark = 0;
unsigned aqmNfWatermark = 0;
address = (UINT32*)(aqmBaseAddress +
IX_QMGR_Q_CONFIG_ADDR_GET(qId));
aqmNeWatermark = watermarkToAqmWatermark (ne);
aqmNfWatermark = watermarkToAqmWatermark (nf);
/* Read the current watermarks */
ixQMgrAqmIfWordRead (address, &value);
/* Clear out the old watermarks */
value &= IX_QMGR_NE_NF_CLEAR_MASK;
/* Generate the value to write */
value |= (aqmNeWatermark << IX_QMGR_Q_CONFIG_NE_OFFSET) |
(aqmNfWatermark << IX_QMGR_Q_CONFIG_NF_OFFSET);
ixQMgrAqmIfWordWrite (address, value);
}
PRIVATE void
ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
UINT32 configRegWord,
unsigned int qEntrySizeInwords,
unsigned int qSizeInWords,
UINT32 **address)
{
UINT32 readPtr;
UINT32 baseAddress;
UINT32 *topOfAqmSram;
topOfAqmSram = ((UINT32 *)aqmBaseAddress + IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS);
/* Extract the base address */
baseAddress = (UINT32)((configRegWord & IX_QMGR_BADDR_MASK) >>
(IX_QMGR_Q_CONFIG_BADDR_OFFSET));
/* Base address is a 16 word pointer from the start of AQM SRAM.
* Convert to absolute word address.
*/
baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET);
/* Extract the read pointer. Read pointer is a word pointer */
readPtr = (UINT32)((configRegWord >>
IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK);
/* Read/Write pointers(word pointers) are offsets from the queue buffer space base address.
* Calculate the absolute read pointer address. NOTE: Queues are circular buffers.
*/
readPtr = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */
*address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD)));
switch (qEntrySizeInwords)
{
case IX_QMGR_Q_ENTRY_SIZE1:
IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram);
break;
case IX_QMGR_Q_ENTRY_SIZE2:
IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram);
break;
case IX_QMGR_Q_ENTRY_SIZE4:
IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram);
break;
default:
IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet");
break;
}
}
IX_STATUS
ixQMgrAqmIfQPeek (IxQMgrQId qId,
unsigned int entryIndex,
unsigned int *entry)
{
UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
UINT32 *entryAddress = NULL;
UINT32 configRegWordOnEntry;
UINT32 configRegWordOnExit;
unsigned int qEntrySizeInwords;
unsigned int qSizeInWords;
/* Get the queue entry size in words */
qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
/* Get the queue size in words */
qSizeInWords = ixQMgrQSizeInWordsGet (qId);
/* Read the config register */
ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
/* Get the entry address */
ixQMgrAqmIfEntryAddressGet (entryIndex,
configRegWordOnEntry,
qEntrySizeInwords,
qSizeInWords,
&entryAddress);
/* Get the lock or return busy */
if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
{
return IX_FAIL;
}
while(qEntrySizeInwords--)
{
ixQMgrAqmIfWordRead (entryAddress++, entry++);
}
/* Release the lock */
ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
/* Read the config register */
ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
/* Check that the read and write pointers have not changed */
if (configRegWordOnEntry != configRegWordOnExit)
{
return IX_FAIL;
}
return IX_SUCCESS;
}
IX_STATUS
ixQMgrAqmIfQPoke (IxQMgrQId qId,
unsigned entryIndex,
unsigned int *entry)
{
UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
UINT32 *entryAddress = NULL;
UINT32 configRegWordOnEntry;
UINT32 configRegWordOnExit;
unsigned int qEntrySizeInwords;
unsigned int qSizeInWords;
/* Get the queue entry size in words */
qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
/* Get the queue size in words */
qSizeInWords = ixQMgrQSizeInWordsGet (qId);
/* Read the config register */
ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
/* Get the entry address */
ixQMgrAqmIfEntryAddressGet (entryIndex,
configRegWordOnEntry,
qEntrySizeInwords,
qSizeInWords,
&entryAddress);
/* Get the lock or return busy */
if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
{
return IX_FAIL;
}
/* Else read the entry directly from SRAM. This will not move the read pointer */
while(qEntrySizeInwords--)
{
ixQMgrAqmIfWordWrite (entryAddress++, *entry++);
}
/* Release the lock */
ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
/* Read the config register */
ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
/* Check that the read and write pointers have not changed */
if (configRegWordOnEntry != configRegWordOnExit)
{
return IX_FAIL;
}
return IX_SUCCESS;
}
PRIVATE unsigned
watermarkToAqmWatermark (IxQMgrWMLevel watermark )
{
unsigned aqmWatermark = 0;
/*
* Watermarks 0("000"),1("001"),2("010"),4("011"),
* 8("100"),16("101"),32("110"),64("111")
*/
aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2);
return aqmWatermark;
}
PRIVATE unsigned
entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize)
{
/* entrySize 1("00"),2("01"),4("10") */
return (ixQMgrAqmIfLog2 (entrySize));
}
PRIVATE unsigned
bufferSizeToAqmBufferSize (unsigned bufferSizeInWords)
{
/* bufferSize 16("00"),32("01),64("10"),128("11") */
return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE));
}
/*
* Reset AQM registers to default values.
*/
PRIVATE void
ixQMgrAqmIfRegistersReset (void)
{
volatile UINT32 *qConfigWordAddress = NULL;
unsigned int i;
/*
* Need to initialize AQM hardware registers to an initial
* value as init may have been called as a result of a soft
* reset. i.e. soft reset does not reset hardware registers.
*/
/* Reset queues 0..31 status registers 0..3 */
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET),
IX_QMGR_QUELOWSTAT_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET),
IX_QMGR_QUELOWSTAT_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET),
IX_QMGR_QUELOWSTAT_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET),
IX_QMGR_QUELOWSTAT_RESET_VALUE);
/* Reset underflow/overflow status registers 0..1 */
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET),
IX_QMGR_QUEUOSTAT_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET),
IX_QMGR_QUEUOSTAT_RESET_VALUE);
/* Reset queues 32..63 nearly empty status registers */
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET),
IX_QMGR_QUEUPPSTAT0_RESET_VALUE);
/* Reset queues 32..63 full status registers */
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET),
IX_QMGR_QUEUPPSTAT1_RESET_VALUE);
/* Reset int0 status flag source select registers 0..3 */
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET),
IX_QMGR_INT0SRCSELREG_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET),
IX_QMGR_INT0SRCSELREG_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET),
IX_QMGR_INT0SRCSELREG_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET),
IX_QMGR_INT0SRCSELREG_RESET_VALUE);
/* Reset queue interrupt enable register 0..1 */
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET),
IX_QMGR_QUEIEREG_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET),
IX_QMGR_QUEIEREG_RESET_VALUE);
/* Reset queue interrupt register 0..1 */
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET),
IX_QMGR_QINTREG_RESET_VALUE);
ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET),
IX_QMGR_QINTREG_RESET_VALUE);
/* Reset queue configuration words 0..63 */
qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++)
{
ixQMgrAqmIfWordWrite(qConfigWordAddress,
IX_QMGR_QUECONFIG_RESET_VALUE);
/* Next word */
qConfigWordAddress++;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,209 +0,0 @@
/**
* @file IxQMgrInit.c
*
* @author Intel Corporation
* @date 30-Oct-2001
*
* @brief: Provided initialization of the QMgr component and its subcomponents.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* System defined include files.
*/
/*
* User defined include files.
*/
#include "IxOsal.h"
#include "IxQMgr.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDispatcher_p.h"
#include "IxQMgrLog_p.h"
#include "IxQMgrQAccess_p.h"
#include "IxQMgrDefines_p.h"
#include "IxQMgrAqmIf_p.h"
/*
* Set to true if initialized
* N.B. global so integration/unit tests can reinitialize
*/
BOOL qMgrIsInitialized = false;
/*
* Function definitions.
*/
IX_STATUS
ixQMgrInit (void)
{
if (qMgrIsInitialized)
{
IX_QMGR_LOG0("ixQMgrInit: IxQMgr already initialised\n");
return IX_FAIL;
}
/* Initialise the QCfg component */
ixQMgrQCfgInit ();
/* Initialise the Dispatcher component */
ixQMgrDispatcherInit ();
/* Initialise the Access component */
ixQMgrQAccessInit ();
/* Initialization complete */
qMgrIsInitialized = true;
return IX_SUCCESS;
}
IX_STATUS
ixQMgrUnload (void)
{
if (!qMgrIsInitialized)
{
return IX_FAIL;
}
/* Uninitialise the QCfg component */
ixQMgrQCfgUninit ();
/* Uninitialization complete */
qMgrIsInitialized = false;
return IX_SUCCESS;
}
void
ixQMgrShow (void)
{
IxQMgrQCfgStats *qCfgStats = NULL;
IxQMgrDispatcherStats *dispatcherStats = NULL;
int i;
UINT32 lowIntRegRead, upIntRegRead;
qCfgStats = ixQMgrQCfgStatsGet ();
dispatcherStats = ixQMgrDispatcherStatsGet ();
ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUELOW_GROUP, &lowIntRegRead);
ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUEUPP_GROUP, &upIntRegRead);
printf("Generic Stats........\n");
printf("=====================\n");
printf("Loop Run Count..........%u\n",dispatcherStats->loopRunCnt);
printf("Watermark set count.....%d\n", qCfgStats->wmSetCnt);
printf("===========================================\n");
printf("On the fly Interrupt Register Stats........\n");
printf("===========================================\n");
printf("Lower Interrupt Register............0x%08x\n",lowIntRegRead);
printf("Upper Interrupt Register............0x%08x\n",upIntRegRead);
printf("==============================================\n");
printf("Queue Specific Stats........\n");
printf("============================\n");
for (i=0; i<IX_QMGR_MAX_NUM_QUEUES; i++)
{
if (ixQMgrQIsConfigured(i))
{
ixQMgrQShow(i);
}
}
printf("============================\n");
}
IX_STATUS
ixQMgrQShow (IxQMgrQId qId)
{
IxQMgrQCfgStats *qCfgStats = NULL;
IxQMgrDispatcherStats *dispatcherStats = NULL;
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
dispatcherStats = ixQMgrDispatcherStatsGet ();
qCfgStats = ixQMgrQCfgQStatsGet (qId);
printf("QId %d\n", qId);
printf("======\n");
printf(" IxQMgrQCfg Stats\n");
printf(" Name..................... \"%s\"\n", qCfgStats->qStats[qId].qName);
printf(" Size in words............ %u\n", qCfgStats->qStats[qId].qSizeInWords);
printf(" Entry size in words...... %u\n", qCfgStats->qStats[qId].qEntrySizeInWords);
printf(" Nearly empty watermark... %u\n", qCfgStats->qStats[qId].ne);
printf(" Nearly full watermark.... %u\n", qCfgStats->qStats[qId].nf);
printf(" Number of full entries... %u\n", qCfgStats->qStats[qId].numEntries);
printf(" Sram base address........ 0x%X\n", qCfgStats->qStats[qId].baseAddress);
printf(" Read pointer............. 0x%X\n", qCfgStats->qStats[qId].readPtr);
printf(" Write pointer............ 0x%X\n", qCfgStats->qStats[qId].writePtr);
#ifndef NDEBUG
if (dispatcherStats->queueStats[qId].notificationEnabled)
{
char *localEvent = "none ????";
switch (dispatcherStats->queueStats[qId].srcSel)
{
case IX_QMGR_Q_SOURCE_ID_E:
localEvent = "Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NE:
localEvent = "Nearly Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NF:
localEvent = "Nearly Full";
break;
case IX_QMGR_Q_SOURCE_ID_F:
localEvent = "Full";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_E:
localEvent = "Not Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_NE:
localEvent = "Not Nearly Empty";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_NF:
localEvent = "Not Nearly Full";
break;
case IX_QMGR_Q_SOURCE_ID_NOT_F:
localEvent = "Not Full";
break;
default :
break;
}
printf(" Notifications localEvent...... %s\n", localEvent);
}
else
{
printf(" Notifications............ not enabled\n");
}
printf(" IxQMgrDispatcher Stats\n");
printf(" Callback count................%d\n",
dispatcherStats->queueStats[qId].callbackCnt);
printf(" Priority change count.........%d\n",
dispatcherStats->queueStats[qId].priorityChangeCnt);
printf(" Interrupt no callback count...%d\n",
dispatcherStats->queueStats[qId].intNoCallbackCnt);
printf(" Interrupt lost callback count...%d\n",
dispatcherStats->queueStats[qId].intLostCallbackCnt);
#endif
return IX_SUCCESS;
}

View File

@ -1,772 +0,0 @@
/**
* @file IxQMgrQAccess.c
*
* @author Intel Corporation
* @date 30-Oct-2001
*
* @brief This file contains functions for putting entries on a queue and
* removing entries from a queue.
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* Inlines are compiled as function when this is defined.
* N.B. Must be placed before #include of "IxQMgr.h"
*/
#ifndef IXQMGR_H
# define IXQMGRQACCESS_C
#else
# error
#endif
/*
* System defined include files.
*/
/*
* User defined include files.
*/
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrQAccess_p.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDefines_p.h"
/*
* Global variables and extern definitions
*/
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
/*
* Function definitions.
*/
void
ixQMgrQAccessInit (void)
{
}
IX_STATUS
ixQMgrQReadWithChecks (IxQMgrQId qId,
UINT32 *entry)
{
IxQMgrQEntrySizeInWords entrySizeInWords;
IxQMgrQInlinedReadWriteInfo *infoPtr;
if (NULL == entry)
{
return IX_QMGR_PARAMETER_ERROR;
}
/* Check QId */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
/* Get the q entry size in words */
entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);
/* reset the current read count if the counter wrapped around
* (unsigned arithmetic)
*/
infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries)
{
infoPtr->qReadCount = 0;
}
/* Check if underflow occurred on the read */
if (ixQMgrAqmIfUnderflowCheck (qId))
{
return IX_QMGR_Q_UNDERFLOW;
}
return IX_SUCCESS;
}
/* this function reads the remaining of the q entry
* for queues configured with many words.
* (the first word of the entry is already read
* in the inlined function and the entry pointer already
* incremented
*/
IX_STATUS
ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
UINT32 *entry)
{
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 entrySize = infoPtr->qEntrySizeInWords;
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
while (--entrySize)
{
/* read the entry and accumulate the result */
*(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr);
}
/* underflow is available for lower queues only */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* check the underflow status */
if (status & infoPtr->qUflowStatBitMask)
{
/* the queue is empty
* clear the underflow status bit if it was set
*/
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qUflowStatBitMask);
return IX_QMGR_Q_UNDERFLOW;
}
}
return IX_SUCCESS;
}
IX_STATUS
ixQMgrQWriteWithChecks (IxQMgrQId qId,
UINT32 *entry)
{
IxQMgrQEntrySizeInWords entrySizeInWords;
IxQMgrQInlinedReadWriteInfo *infoPtr;
if (NULL == entry)
{
return IX_QMGR_PARAMETER_ERROR;
}
/* Check QId */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
/* Get the q entry size in words */
entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
ixQMgrAqmIfQPush (qId, entrySizeInWords, entry);
/* reset the current read count if the counter wrapped around
* (unsigned arithmetic)
*/
infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries)
{
infoPtr->qWriteCount = infoPtr->qSizeInEntries;
}
/* Check if overflow occurred on the write*/
if (ixQMgrAqmIfOverflowCheck (qId))
{
return IX_QMGR_Q_OVERFLOW;
}
return IX_SUCCESS;
}
IX_STATUS
ixQMgrQPeek (IxQMgrQId qId,
unsigned int entryIndex,
UINT32 *entry)
{
unsigned int numEntries;
#ifndef NDEBUG
if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID))
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
#endif
if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
{
return IX_FAIL;
}
if (entryIndex >= numEntries) /* entryIndex starts at 0 */
{
return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
}
return ixQMgrAqmIfQPeek (qId, entryIndex, entry);
}
IX_STATUS
ixQMgrQPoke (IxQMgrQId qId,
unsigned entryIndex,
UINT32 *entry)
{
unsigned int numEntries;
#ifndef NDEBUG
if ((NULL == entry) || (entryIndex > 128))
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
#endif
if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
{
return IX_FAIL;
}
if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */
{
return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
}
return ixQMgrAqmIfQPoke (qId, entryIndex, entry);
}
IX_STATUS
ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
IxQMgrQStatus *qStatus)
{
if (NULL == qStatus)
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!ixQMgrQIsConfigured (qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
ixQMgrAqmIfQueStatRead (qId, qStatus);
return IX_SUCCESS;
}
IX_STATUS
ixQMgrQNumEntriesGet (IxQMgrQId qId,
unsigned *numEntriesPtr)
{
UINT32 qPtrs;
UINT32 qStatus;
unsigned numEntries;
IxQMgrQInlinedReadWriteInfo *infoPtr;
#ifndef NDEBUG
if (NULL == numEntriesPtr)
{
return IX_QMGR_PARAMETER_ERROR;
}
/* Check QId */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
#endif
/* get fast access data */
infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
/* get snapshot */
qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
/* Mod subtraction of pointers to get number of words in Q. */
numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f;
if (numEntries == 0)
{
/*
* Could mean either full or empty queue
* so look at status
*/
ixQMgrAqmIfQueStatRead (qId, &qStatus);
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK)
{
/* Empty */
*numEntriesPtr = 0;
}
else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
{
/* Full */
*numEntriesPtr = infoPtr->qSizeInEntries;
}
else
{
/*
* Queue status and read/write pointers are volatile.
* The queue state has changed since we took the
* snapshot of the read and write pointers.
* Client can retry if they wish
*/
*numEntriesPtr = 0;
return IX_QMGR_WARNING;
}
}
else /* It is an upper queue which does not have an empty status bit maintained */
{
if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
{
/* The queue is Full at the time of snapshot. */
*numEntriesPtr = infoPtr->qSizeInEntries;
}
else
{
/* The queue is either empty, either moving,
* Client can retry if they wish
*/
*numEntriesPtr = 0;
return IX_QMGR_WARNING;
}
}
}
else
{
*numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1);
}
return IX_SUCCESS;
}
#if defined(__wince) && defined(NO_INLINE_APIS)
PUBLIC IX_STATUS
ixQMgrQRead (IxQMgrQId qId,
UINT32 *entryPtr)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 entry, entrySize;
/* get a new entry */
entrySize = infoPtr->qEntrySizeInWords;
entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
{
*entryPtr = entry;
/* process the remaining part of the entry */
return ixQMgrQReadMWordsMinus1(qId, entryPtr);
}
/* underflow is available for lower queues only */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* the counter of queue entries is decremented. In happy
* day scenario there are many entries in the queue
* and the counter does not reach zero.
*/
if (infoPtr->qReadCount-- == 0)
{
/* There is maybe no entry in the queue
* qReadCount is now negative, but will be corrected before
* the function returns.
*/
UINT32 qPtrs; /* queue internal pointers */
/* when a queue is empty, the hw guarantees to return
* a null value. If the value is not null, the queue is
* not empty.
*/
if (entry == 0)
{
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* check the underflow status */
if (status & infoPtr->qUflowStatBitMask)
{
/* the queue is empty
* clear the underflow status bit if it was set
*/
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qUflowStatBitMask);
*entryPtr = 0;
infoPtr->qReadCount = 0;
return IX_QMGR_Q_UNDERFLOW;
}
}
/* store the result */
*entryPtr = entry;
/* No underflow occured : someone is filling the queue
* or the queue contains null entries.
* The current counter needs to be
* updated from the current number of entries in the queue
*/
/* get snapshot of queue pointers */
qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
/* Mod subtraction of pointers to get number of words in Q. */
qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
if (qPtrs == 0)
{
/* no entry in the queue */
infoPtr->qReadCount = 0;
}
else
{
/* convert the number of words inside the queue
* to a number of entries
*/
infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
}
return IX_SUCCESS;
}
}
*entryPtr = entry;
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQBurstRead (IxQMgrQId qId,
UINT32 numEntries,
UINT32 *entries)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 nullCheckEntry;
if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
{
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
/* the code is optimized to take care of data dependencies:
* Durig a read, there are a few cycles needed to get the
* read complete. During these cycles, it is poossible to
* do some CPU, e.g. increment pointers and decrement
* counters.
*/
/* fetch a queue entry */
nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
/* iterate the specified number of queue entries */
while (--numEntries)
{
/* check the result of the previous read */
if (nullCheckEntry == 0)
{
/* if we read a NULL entry, stop. We have underflowed */
break;
}
else
{
/* write the entry */
*entries = nullCheckEntry;
/* fetch next entry */
nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);
/* increment the write address */
entries++;
}
}
/* write the pre-fetched entry */
*entries = nullCheckEntry;
}
else
{
IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
/* read the specified number of queue entries */
nullCheckEntry = 0;
while (numEntries--)
{
int i;
for (i = 0; i < entrySizeInWords; i++)
{
*entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);
nullCheckEntry |= *entries++;
}
/* if we read a NULL entry, stop. We have underflowed */
if (nullCheckEntry == 0)
{
break;
}
nullCheckEntry = 0;
}
}
/* reset the current read count : next access to the read function
* will force a underflow status check
*/
infoPtr->qWriteCount = 0;
/* Check if underflow occurred on the read */
if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
if (status & infoPtr->qUflowStatBitMask)
{
/* clear the underflow status bit if it was set */
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qUflowStatBitMask);
return IX_QMGR_Q_UNDERFLOW;
}
}
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQWrite (IxQMgrQId qId,
UINT32 *entry)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 entrySize;
/* write the entry */
IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
entrySize = infoPtr->qEntrySizeInWords;
if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
{
/* process the remaining part of the entry */
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
while (--entrySize)
{
++entry;
IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);
}
entrySize = infoPtr->qEntrySizeInWords;
}
/* overflow is available for lower queues only */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
UINT32 qSize = infoPtr->qSizeInEntries;
/* increment the current number of entries in the queue
* and check for overflow
*/
if (infoPtr->qWriteCount++ == qSize)
{
/* the queue may have overflow */
UINT32 qPtrs; /* queue internal pointers */
/* get the queue status */
UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* read the status twice because the status may
* not be immediately ready after the write operation
*/
if ((status & infoPtr->qOflowStatBitMask) ||
((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
& infoPtr->qOflowStatBitMask))
{
/* the queue is full, clear the overflow status
* bit if it was set
*/
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qOflowStatBitMask);
infoPtr->qWriteCount = infoPtr->qSizeInEntries;
return IX_QMGR_Q_OVERFLOW;
}
/* No overflow occured : someone is draining the queue
* and the current counter needs to be
* updated from the current number of entries in the queue
*/
/* get q pointer snapshot */
qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
/* Mod subtraction of pointers to get number of words in Q. */
qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
if (qPtrs == 0)
{
/* the queue may be full at the time of the
* snapshot. Next access will check
* the overflow status again.
*/
infoPtr->qWriteCount = qSize;
}
else
{
/* convert the number of words to a number of entries */
if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
{
infoPtr->qWriteCount = qPtrs & (qSize - 1);
}
else
{
infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
}
}
}
}
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQBurstWrite (IxQMgrQId qId,
unsigned numEntries,
UINT32 *entries)
{
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
UINT32 status;
/* update the current write count */
infoPtr->qWriteCount += numEntries;
if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
{
volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
while (numEntries--)
{
IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);
entries++;
}
}
else
{
IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
int i;
/* write each queue entry */
while (numEntries--)
{
/* write the queueEntrySize number of words for each entry */
for (i = 0; i < entrySizeInWords; i++)
{
IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
entries++;
}
}
}
/* check if the write count overflows */
if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
{
/* reset the current write count */
infoPtr->qWriteCount = infoPtr->qSizeInEntries;
}
/* Check if overflow occurred on the write operation */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
/* get the queue status */
status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
/* read the status twice because the status may
* not be ready at the time of the write
*/
if ((status & infoPtr->qOflowStatBitMask) ||
((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
& infoPtr->qOflowStatBitMask))
{
/* clear the underflow status bit if it was set */
IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
status & ~infoPtr->qOflowStatBitMask);
return IX_QMGR_Q_OVERFLOW;
}
}
return IX_SUCCESS;
}
PUBLIC IX_STATUS
ixQMgrQStatusGet (IxQMgrQId qId,
IxQMgrQStatus *qStatus)
{
/* read the status of a queue in the range 0-31 */
if (qId < IX_QMGR_MIN_QUEUPP_QID)
{
extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;
UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask;
UINT32 underflowBitMask = infoPtr->qUflowStatBitMask;
UINT32 overflowBitMask = infoPtr->qOflowStatBitMask;
/* read the status register for this queue */
*qStatus = IX_OSAL_READ_LONG(lowStatRegAddr);
/* mask out the status bits relevant only to this queue */
*qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
/* Check if the queue has overflowed */
if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)
{
/* clear the overflow status bit if it was set */
IX_OSAL_WRITE_LONG(qUOStatRegAddr,
(IX_OSAL_READ_LONG(qUOStatRegAddr) &
~overflowBitMask));
*qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;
}
/* Check if the queue has underflowed */
if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask)
{
/* clear the underflow status bit if it was set */
IX_OSAL_WRITE_LONG(qUOStatRegAddr,
(IX_OSAL_READ_LONG(qUOStatRegAddr) &
~underflowBitMask));
*qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;
}
}
else /* read status of a queue in the range 32-63 */
{
extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
/* Reset the status bits */
*qStatus = 0;
/* Check if the queue is nearly empty */
if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
{
*qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
}
/* Check if the queue is full */
if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
{
*qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
}
}
return IX_SUCCESS;
}
#endif /* def NO_INLINE_APIS */

View File

@ -1,519 +0,0 @@
/**
* @file QMgrQCfg.c
*
* @author Intel Corporation
* @date 30-Oct-2001
*
* @brief This modules provides an interface for setting up the static
* configuration of AQM queues.This file contains the following
* functions:
*
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*
* System defined include files.
*/
/*
* User defined include files.
*/
#include "IxOsal.h"
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDefines_p.h"
/*
* #defines and macros used in this file.
*/
#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
/* Total size of SRAM */
#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
/*
* Check that qId is a valid queue identifier. This is provided to
* make the code easier to read.
*/
#define IX_QMGR_QID_IS_VALID(qId) \
(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
/*
* Typedefs whose scope is limited to this file.
*/
/*
* This struct describes an AQM queue.
* N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
* as these are requested by Access in the data path. sizeInEntries is
* not required by the data path so it can be calculated dynamically.
*
*/
typedef struct
{
char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/
IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */
IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
BOOL isConfigured; /* This flag is true if the queue has
* been configured
*/
} IxQMgrCfgQ;
/*
* Variable declarations global to this file. Externs are followed by
* statics.
*/
extern UINT32 * ixQMgrAqmIfQueAccRegAddr[];
/* Store data required to inline read and write access
*/
IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
/* This pointer holds the starting address of AQM SRAM not used by
* the AQM queues.
*/
static UINT32 freeSramAddress=0;
/* 4 words of zeroed memory for inline access */
static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
static BOOL cfgInitialized = false;
static IxOsalMutex ixQMgrQCfgMutex;
/*
* Statistics
*/
static IxQMgrQCfgStats stats;
/*
* Function declarations
*/
PRIVATE BOOL
watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
PRIVATE BOOL
qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
PRIVATE BOOL
qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
/*
* Function definitions.
*/
void
ixQMgrQCfgInit (void)
{
int loopIndex;
for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
{
/* info for code inlining */
ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
/* info for code inlining */
ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
}
/* Initialise the AqmIf component */
ixQMgrAqmIfInit ();
/* Reset all queues to have queue name = NULL, entry size = 0 and
* isConfigured = false
*/
for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
{
strcpy (cfgQueueInfo[loopIndex].qName, "");
cfgQueueInfo[loopIndex].qSizeInWords = 0;
cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
cfgQueueInfo[loopIndex].isConfigured = false;
/* Statistics */
stats.qStats[loopIndex].isConfigured = false;
stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
}
/* Statistics */
stats.wmSetCnt = 0;
ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
ixOsalMutexInit(&ixQMgrQCfgMutex);
cfgInitialized = true;
}
void
ixQMgrQCfgUninit (void)
{
cfgInitialized = false;
/* Uninitialise the AqmIf component */
ixQMgrAqmIfUninit ();
}
IX_STATUS
ixQMgrQConfig (char *qName,
IxQMgrQId qId,
IxQMgrQSizeInWords qSizeInWords,
IxQMgrQEntrySizeInWords qEntrySizeInWords)
{
UINT32 aqmLocalBaseAddress;
if (!cfgInitialized)
{
return IX_FAIL;
}
if (!IX_QMGR_QID_IS_VALID(qId))
{
return IX_QMGR_INVALID_Q_ID;
}
else if (NULL == qName)
{
return IX_QMGR_PARAMETER_ERROR;
}
else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
{
return IX_QMGR_PARAMETER_ERROR;
}
else if (!qSizeInWordsIsOk (qSizeInWords))
{
return IX_QMGR_INVALID_QSIZE;
}
else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
{
return IX_QMGR_INVALID_Q_ENTRY_SIZE;
}
else if (cfgQueueInfo[qId].isConfigured)
{
return IX_QMGR_Q_ALREADY_CONFIGURED;
}
ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
/* Write the config register */
ixQMgrAqmIfQueCfgWrite (qId,
qSizeInWords,
qEntrySizeInWords,
freeSramAddress);
strcpy (cfgQueueInfo[qId].qName, qName);
cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
/* store pre-computed information in the same cache line
* to facilitate inlining of QRead and QWrite functions
* in IxQMgr.h
*/
ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries =
(UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
/* Calculate the new freeSramAddress from the size of the queue
* currently being configured.
*/
freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
/* Get the virtual SRAM address */
ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
IX_QMGR_QUE_BUFFER_SPACE_SIZE);
/* The queue is now configured */
cfgQueueInfo[qId].isConfigured = true;
ixOsalMutexUnlock(&ixQMgrQCfgMutex);
#ifndef NDEBUG
/* Update statistics */
stats.qStats[qId].isConfigured = true;
stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
#endif
return IX_SUCCESS;
}
IxQMgrQSizeInWords
ixQMgrQSizeInWordsGet (IxQMgrQId qId)
{
/* No parameter checking as this is used on the data path */
return (cfgQueueInfo[qId].qSizeInWords);
}
IX_STATUS
ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
unsigned *qSizeInEntries)
{
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
if(NULL == qSizeInEntries)
{
return IX_QMGR_PARAMETER_ERROR;
}
*qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
(UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
return IX_SUCCESS;
}
IxQMgrQEntrySizeInWords
ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
{
/* No parameter checking as this is used on the data path */
return (cfgQueueInfo[qId].qEntrySizeInWords);
}
IX_STATUS
ixQMgrWatermarkSet (IxQMgrQId qId,
IxQMgrWMLevel ne,
IxQMgrWMLevel nf)
{
IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
IxQMgrQStatus qStatusOnExit; /* to this function */
if (!ixQMgrQIsConfigured(qId))
{
return IX_QMGR_Q_NOT_CONFIGURED;
}
if (!watermarkLevelIsOk (qId, ne))
{
return IX_QMGR_INVALID_Q_WM;
}
if (!watermarkLevelIsOk (qId, nf))
{
return IX_QMGR_INVALID_Q_WM;
}
/* Get the current queue status */
ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
#ifndef NDEBUG
/* Update statistics */
stats.wmSetCnt++;
#endif
ixQMgrAqmIfWatermarkSet (qId,
ne,
nf);
/* Get the current queue status */
ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
/* If the status has changed return a warning */
if (qStatusOnEntry != qStatusOnExit)
{
return IX_QMGR_WARNING;
}
return IX_SUCCESS;
}
IX_STATUS
ixQMgrAvailableSramAddressGet (UINT32 *address,
unsigned *sizeOfFreeRam)
{
UINT32 aqmLocalBaseAddress;
if ((NULL == address)||(NULL == sizeOfFreeRam))
{
return IX_QMGR_PARAMETER_ERROR;
}
if (!cfgInitialized)
{
return IX_FAIL;
}
*address = freeSramAddress;
/* Get the virtual SRAM address */
ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
/*
* Calculate the size in bytes of free sram
* i.e. current free SRAM virtual pointer from
* (base + total size)
*/
*sizeOfFreeRam =
(aqmLocalBaseAddress +
IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
freeSramAddress;
if (0 == *sizeOfFreeRam)
{
return IX_QMGR_NO_AVAILABLE_SRAM;
}
return IX_SUCCESS;
}
BOOL
ixQMgrQIsConfigured (IxQMgrQId qId)
{
if (!IX_QMGR_QID_IS_VALID(qId))
{
return false;
}
return cfgQueueInfo[qId].isConfigured;
}
IxQMgrQCfgStats*
ixQMgrQCfgStatsGet (void)
{
return &stats;
}
IxQMgrQCfgStats*
ixQMgrQCfgQStatsGet (IxQMgrQId qId)
{
unsigned int ne;
unsigned int nf;
UINT32 baseAddress;
UINT32 readPtr;
UINT32 writePtr;
stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
{
if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
{
IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
}
}
ixQMgrAqmIfQueCfgRead (qId,
stats.qStats[qId].numEntries,
&baseAddress,
&ne,
&nf,
&readPtr,
&writePtr);
stats.qStats[qId].baseAddress = baseAddress;
stats.qStats[qId].ne = ne;
stats.qStats[qId].nf = nf;
stats.qStats[qId].readPtr = readPtr;
stats.qStats[qId].writePtr = writePtr;
return &stats;
}
/*
* Static function definitions
*/
PRIVATE BOOL
watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
{
unsigned qSizeInEntries;
switch (level)
{
case IX_QMGR_Q_WM_LEVEL0:
case IX_QMGR_Q_WM_LEVEL1:
case IX_QMGR_Q_WM_LEVEL2:
case IX_QMGR_Q_WM_LEVEL4:
case IX_QMGR_Q_WM_LEVEL8:
case IX_QMGR_Q_WM_LEVEL16:
case IX_QMGR_Q_WM_LEVEL32:
case IX_QMGR_Q_WM_LEVEL64:
break;
default:
return false;
}
/* Check watermark is not bigger than the qSizeInEntries */
ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
if ((unsigned)level > qSizeInEntries)
{
return false;
}
return true;
}
PRIVATE BOOL
qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
{
BOOL status;
switch (qSize)
{
case IX_QMGR_Q_SIZE16:
case IX_QMGR_Q_SIZE32:
case IX_QMGR_Q_SIZE64:
case IX_QMGR_Q_SIZE128:
status = true;
break;
default:
status = false;
break;
}
return status;
}
PRIVATE BOOL
qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
{
BOOL status;
switch (entrySize)
{
case IX_QMGR_Q_ENTRY_SIZE1:
case IX_QMGR_Q_ENTRY_SIZE2:
case IX_QMGR_Q_ENTRY_SIZE4:
status = true;
break;
default:
status = false;
break;
}
return status;
}

View File

@ -1,60 +0,0 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
LOCAL_CFLAGS += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux
CFLAGS += $(LOCAL_CFLAGS)
CPPFLAGS += $(LOCAL_CFLAGS) # needed for depend
obj-y := npe.o \
miiphy.o \
IxOsalBufferMgt.o \
IxOsalIoMem.o \
IxOsalOsCacheMMU.o \
IxOsalOsMsgQ.o \
IxOsalOsSemaphore.o \
IxOsalOsServices.o \
IxOsalOsThread.o \
IxEthAcc.o \
IxEthAccCommon.o \
IxEthAccControlInterface.o \
IxEthAccDataPlane.o \
IxEthAccMac.o \
IxEthAccMii.o \
IxEthDBAPI.o \
IxEthDBAPISupport.o \
IxEthDBCore.o \
IxEthDBEvents.o \
IxEthDBFeatures.o \
IxEthDBFirewall.o \
IxEthDBHashtable.o \
IxEthDBLearning.o \
IxEthDBMem.o \
IxEthDBNPEAdaptor.o \
IxEthDBPortUpdate.o \
IxEthDBReports.o \
IxEthDBSearch.o \
IxEthDBSpanningTree.o \
IxEthDBUtil.o \
IxEthDBVlan.o \
IxEthDBWiFi.o \
IxEthMii.o \
IxQMgrAqmIf.o \
IxQMgrDispatcher.o \
IxQMgrInit.o \
IxQMgrQAccess.o \
IxQMgrQCfg.o \
IxFeatureCtrl.o \
IxNpeDl.o \
IxNpeDlImageMgr.o \
IxNpeDlNpeMgr.o \
IxNpeDlNpeMgrUtils.o \
IxNpeMh.o \
IxNpeMhConfig.o \
IxNpeMhReceive.o \
IxNpeMhSend.o \
IxNpeMhSolicitedCbMgr.o \
IxNpeMhUnsolicitedCbMgr.o

View File

@ -1,47 +0,0 @@
/**
* @file IxAssert.h
*
* @date 21-MAR-2002 (replaced by OSAL)
*
* @brief This file contains assert and ensure macros used by the IXP400 software
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxAssert IXP400 Assertion Macros (IxAssert) API
*
* @brief Assertion support
*
* @{
*/
#ifndef IXASSERT_H
#ifndef __doxygen_HIDE
#define IXASSERT_H
#endif /* __doxygen_HIDE */
#include "IxOsalBackward.h"
#endif /* IXASSERT_H */
/**
* @} addtogroup IxAssert
*/

View File

@ -1,480 +0,0 @@
/**
* @file IxAtmSch.h
*
* @date 23-NOV-2001
*
* @brief Header file for the IXP400 ATM Traffic Shaper
*
* This component demonstrates an ATM Traffic Shaper implementation. It
* will perform shaping on upto 12 ports and total of 44 VCs accross all ports,
* 32 are intended for AAL0/5 and 12 for OAM (1 per port).
* The supported traffic types are;1 rt-VBR VC where PCR = SCR.
* (Effectively CBR) and Up-to 44 VBR VCs.
*
* This component models the ATM ports and VCs and is capable of producing
* a schedule of ATM cells per port which can be supplied to IxAtmdAcc
* for execution on the data path.
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*
* @sa IxAtmm.h
*
*/
/**
* @defgroup IxAtmSch IXP400 ATM Transmit Scheduler (IxAtmSch) API
*
* @brief IXP400 ATM scheduler component Public API
*
* @{
*/
#ifndef IXATMSCH_H
#define IXATMSCH_H
#include "IxOsalTypes.h"
#include "IxAtmTypes.h"
/*
* #defines and macros used in this file.
*/
/* Return codes */
/**
* @ingroup IxAtmSch
*
* @def IX_ATMSCH_RET_NOT_ADMITTED
* @brief Indicates that CAC function has rejected VC registration due
* to insufficient line capacity.
*/
#define IX_ATMSCH_RET_NOT_ADMITTED 2
/**
* @ingroup IxAtmSch
*
* @def IX_ATMSCH_RET_QUEUE_FULL
* @brief Indicates that the VC queue is full, no more demand can be
* queued at this time.
*/
#define IX_ATMSCH_RET_QUEUE_FULL 3
/**
* @ingroup IxAtmSch
*
* @def IX_ATMSCH_RET_QUEUE_EMPTY
* @brief Indicates that all VC queues on this port are empty and
* therefore there are no cells to be scheduled at this time.
*/
#define IX_ATMSCH_RET_QUEUE_EMPTY 4
/*
* Function declarations
*/
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchInit(void)
*
* @brief This function is used to initialize the ixAtmSch component. It
* should be called before any other IxAtmSch API function.
*
* @param None
*
* @return
* - <b>IX_SUCCESS :</b> indicates that
* -# The ATM scheduler component has been successfully initialized.
* -# The scheduler is ready to accept Port modelling requests.
* - <b>IX_FAIL :</b> Some internal error has prevented the scheduler component
* from initialising.
*/
PUBLIC IX_STATUS
ixAtmSchInit(void);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchPortModelInitialize( IxAtmLogicalPort port,
unsigned int portRate,
unsigned int minCellsToSchedule)
*
* @brief This function shall be called first to initialize an ATM port before
* any other ixAtmSch API calls may be made for that port.
*
* @param port @ref IxAtmLogicalPort [in] - The specific port to initialize. Valid
* values range from 0 to IX_UTOPIA_MAX_PORTS - 1, representing a
* maximum of IX_UTOPIA_MAX_PORTS possible ports.
*
* @param portRate unsigned int [in] - Value indicating the upstream capacity
* of the indicated port. The value should be supplied in
* units of ATM (53 bytes) cells per second.
* A port rate of 800Kbits/s is the equivalent
* of 1886 cells per second
*
* @param minCellsToSchedule unsigned int [in] - This parameter specifies the minimum
* number of cells which the scheduler will put in a schedule
* table for this port. This value sets the worst case CDVT for VCs
* on this port i.e. CDVT = 1*minCellsToSchedule/portRate.
* @return
* - <b>IX_SUCCESS :</b> indicates that
* -# The ATM scheduler has been successfully initialized.
* -# The requested port model has been established.
* -# The scheduler is ready to accept VC modelling requests
* on the ATM port.
* - <b>IX_FAIL :</b> indicates the requested port could not be
* initialized. */
PUBLIC IX_STATUS
ixAtmSchPortModelInitialize( IxAtmLogicalPort port,
unsigned int portRate,
unsigned int minCellsToSchedule);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchPortRateModify( IxAtmLogicalPort port,
unsigned int portRate)
*
* @brief This function is called to modify the portRate on a
* previously initialized port, typically in the event that
* the line condition of the port changes.
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port which is to be
* modified.
*
* @param portRate unsigned int [in] - Value indicating the new upstream
* capacity for this port in cells/second.
* A port rate of 800Kbits/s is the equivalent
* of 1886 cells per second
*
* @return
* - <b>IX_SUCCESS :</b> The port rate has been successfully modified.<br>
* - <b>IX_FAIL :</b> The port rate could not be modified, either
* because the input data was invalid, or the new port rate is
* insufficient to support established ATM VC contracts on this
* port.
*
* @warning The IxAtmSch component will validate the supplied port
* rate is sufficient to support all established VC
* contracts on the port. If the new port rate is
* insufficient to support all established contracts then
* the request to modify the port rate will be rejected.
* In this event, the user is expected to remove
* established contracts using the ixAtmSchVcModelRemove
* interface and then retry this interface.
*
* @sa ixAtmSchVcModelRemove() */
PUBLIC IX_STATUS
ixAtmSchPortRateModify( IxAtmLogicalPort port,
unsigned int portRate);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchVcModelSetup( IxAtmLogicalPort port,
IxAtmTrafficDescriptor *trafficDesc,
IxAtmSchedulerVcId *vcId)
*
* @brief A client calls this interface to set up an upstream
* (transmitting) virtual connection model (VC) on the
* specified ATM port. This function also provides the
* virtual * connection admission control (CAC) service to the
* client.
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream
* VC is to be established.
*
* @param *trafficDesc @ref IxAtmTrafficDescriptor [in] - Pointer to a structure
* describing the requested traffic contract of the VC to be
* established. This structure contains the typical ATM
* traffic descriptor values (e.g. PCR, SCR, MBS, CDVT, etc.)
* defined by the ATM standard.
*
* @param *vcId @ref IxAtmSchedulerVcId [out] - This value will be filled with the
* port-unique identifier for this virtual connection. A
* valid identification is a non-negative number.
*
* @return
* - <b>IX_SUCCESS :</b> The VC has been successfully established on
* this port. The client may begin to submit demand on this VC.
* - <b>IX_ATMSCH_RET_NOT_ADMITTED :</b> The VC cannot be established
* on this port because there is insufficient upstream capacity
* available to support the requested traffic contract descriptor
* - <b>IX_FAIL :</b>Input data are invalid. VC has not been
* established.
*/
PUBLIC IX_STATUS
ixAtmSchVcModelSetup( IxAtmLogicalPort port,
IxAtmTrafficDescriptor *trafficDesc,
IxAtmSchedulerVcId *vcId);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchVcConnIdSet( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId,
IxAtmConnId vcUserConnId)
*
* @brief A client calls this interface to set the vcUserConnId for a VC on
* the specified ATM port. This vcUserConnId will default to
* IX_ATM_IDLE_CELLS_CONNID if this function is not called for a VC.
* Hence if the client does not call this function for a VC then only idle
* cells will be scheduled for this VC.
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream
* VC is has been established.
*
* @param vcId @ref IxAtmSchedulerVcId [in] - This is the unique identifier for this virtual
* connection. A valid identification is a non-negative number and is
* all ports.
*
* @param vcUserConnId @ref IxAtmConnId [in] - The connId is used to refer to a VC in schedule
* table entries. It is treated as the Id by which the scheduler client
* knows the VC. It is used in any communicatations from the Scheduler
* to the scheduler user e.g. schedule table entries.
*
* @return
* - <b>IX_SUCCESS :</b> The id has successfully been set.
* - <b>IX_FAIL :</b>Input data are invalid. connId id is not established.
*/
PUBLIC IX_STATUS
ixAtmSchVcConnIdSet( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId,
IxAtmConnId vcUserConnId);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchVcModelRemove( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId)
*
* @brief Interface called by the client to remove a previously
* established VC on a particular port.
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
* removed is established.
*
* @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be removed. This is the
* value returned by the @ref ixAtmSchVcModelSetup call which
* established the relevant VC.
*
* @return
* - <b>IX_SUCCESS :</b> The VC has been successfully removed from
* this port. It is no longer modelled on this port.
* - <b>IX_FAIL :</b>Input data are invalid. The VC is still being modeled
* by the traffic shaper.
*
* @sa ixAtmSchVcModelSetup()
*/
PUBLIC IX_STATUS
ixAtmSchVcModelRemove( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchVcQueueUpdate( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId,
unsigned int numberOfCells)
*
* @brief The client calls this function to notify IxAtmSch that the
* user of a VC has submitted cells for transmission.
*
* This information is stored, aggregated from a number of calls to
* ixAtmSchVcQueueUpdate and eventually used in the call to
* ixAtmSchTableUpdate.
*
* Normally IxAtmSch will update the VC queue by adding the number of
* cells to the current queue length. However, if IxAtmSch
* determines that the user has over-submitted for the VC and
* exceeded its transmission quota the queue request can be rejected.
* The user should resubmit the request later when the queue has been
* depleted.
*
* This implementation of ixAtmSchVcQueueUpdate uses no operating
* system or external facilities, either directly or indirectly.
* This allows clients to call this function form within an interrupt handler.
*
* This interface is structurally compatible with the
* IxAtmdAccSchQueueUpdate callback type definition required for
* IXP400 ATM scheduler interoperability.
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
* updated is established.
*
* @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be updated. This is the
* value returned by the @ref ixAtmSchVcModelSetup call which
* established the relevant VC.
*
* @param numberOfCells unsigned int [in] - Indicates how many ATM cells should
* be added to the queue for this VC.
*
* @return
* - <b>IX_SUCCESS :</b> The VC queue has been successfully updated.
* - <b>IX_ATMSCH_RET_QUEUE_FULL :</b> The VC queue has reached a
* preset limit. This indicates the client has over-submitted
* and exceeded its transmission quota. The request is
* rejected. The VC queue is not updated. The VC user is
* advised to resubmit the request later.
* - <b>IX_FAIL :</b> The input are invalid. No VC queue is updated.
*
* @warning IxAtmSch assumes that the calling software ensures that
* calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
* ixAtmSchTableUpdate are both self and mutually exclusive
* for the same port.
*
* @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */
PUBLIC IX_STATUS
ixAtmSchVcQueueUpdate( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId,
unsigned int numberOfCells);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchVcQueueClear( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId)
*
* @brief The client calls this function to remove all currently
* queued cells from a registered VC. The pending cell count
* for the specified VC is reset to zero.
*
* This interface is structurally compatible with the
* IxAtmdAccSchQueueClear callback type definition required for
* IXP400 ATM scheduler interoperability.
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
* cleared is established.
*
* @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be cleared. This is the
* value returned by the @ref ixAtmSchVcModelSetup call which
* established the relevant VC.
*
* @return
* - <b>IX_SUCCESS :</b> The VC queue has been successfully cleared.
* - <b>IX_FAIL :</b> The input are invalid. No VC queue is modified.
*
* @warning IxAtmSch assumes that the calling software ensures that
* calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
* ixAtmSchTableUpdate are both self and mutually exclusive
* for the same port.
*
* @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */
PUBLIC IX_STATUS
ixAtmSchVcQueueClear( IxAtmLogicalPort port,
IxAtmSchedulerVcId vcId);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchTableUpdate( IxAtmLogicalPort port,
unsigned int maxCells,
IxAtmScheduleTable **rettable)
*
* @brief The client calls this function to request an update of the
* schedule table for a particular ATM port.
*
* This is called when the client decides it needs a new sequence of
* cells to send (probably because the transmit queue is near to
* empty for this ATM port). The scheduler will use its stored
* information on the cells submitted for transmit (i.e. data
* supplied via @ref ixAtmSchVcQueueUpdate function) with the traffic
* descriptor information of all established VCs on the ATM port to
* decide the sequence of cells to be sent and fill the schedule
* table for a period of time into the future.
*
* IxAtmSch will guarantee a minimum of minCellsToSchedule if there
* is at least one cell ready to send. If there are no cells then
* IX_ATMSCH_RET_QUEUE_EMPTY is returned.
*
* This implementation of ixAtmSchTableUpdate uses no operating
* system or external facilities, either directly or indirectly.
* This allows clients to call this function form within an FIQ
* interrupt handler.
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port for which requested
* schedule table is to be generated.
*
* @param maxCells unsigned [in] - Specifies the maximum number of cells
* that must be scheduled in the supplied table during any
* call to the interface.
*
* @param **table @ref IxAtmScheduleTable [out] - A pointer to an area of
* storage is returned which contains the generated
* schedule table. The client should not modify the
* contents of this table.
*
* @return
* - <b>IX_SUCCESS :</b> The schedule table has been published.
* Currently there is at least one VC queue that is nonempty.
* - <b>IX_ATMSCH_RET_QUEUE_EMPTY :</b> Currently all VC queues on
* this port are empty. The schedule table returned is set to
* NULL. The client is not expected to invoke this function
* again until more cells have been submitted on this port
* through the @ref ixAtmSchVcQueueUpdate function.
* - <b>IX_FAIL :</b> The input are invalid. No action is taken.
*
* @warning IxAtmSch assumes that the calling software ensures that
* calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
* ixAtmSchTableUpdate are both self and mutually exclusive
* for the same port.
*
* @warning Subsequent calls to this function for the same port will
* overwrite the contents of previously supplied schedule
* tables. The client must be completely finished with the
* previously supplied schedule table before calling this
* function again for the same port.
*
* @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */
PUBLIC IX_STATUS
ixAtmSchTableUpdate( IxAtmLogicalPort port,
unsigned int maxCells,
IxAtmScheduleTable **rettable);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchShow(void)
*
* @brief Utility function which will print statistics on the current
* and accumulated state of VCs and traffic in the ATM
* scheduler component. Output is sent to the default output
* device.
*
* @param none
* @return none
*/
PUBLIC void
ixAtmSchShow(void);
/**
* @ingroup IxAtmSch
*
* @fn ixAtmSchStatsClear(void)
*
* @brief Utility function which will reset all counter statistics in
* the ATM scheduler to zero.
*
* @param none
* @return none
*/
PUBLIC void
ixAtmSchStatsClear(void);
#endif
/* IXATMSCH_H */
/** @} */

View File

@ -1,385 +0,0 @@
/**
* @file IxAtmTypes.h
*
* @date 24-MAR-2002
*
* @brief This file contains Atm types common to a number of Atm components.
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/* ------------------------------------------------------
Doxygen group definitions
------------------------------------------------------ */
/**
* @defgroup IxAtmTypes IXP400 ATM Types (IxAtmTypes)
*
* @brief The common set of types used in many Atm components
*
* @{ */
#ifndef IXATMTYPES_H
#define IXATMTYPES_H
#include "IxNpeA.h"
/**
* @enum IxAtmLogicalPort
*
* @brief Logical Port Definitions :
*
* Only 1 port is available in SPHY configuration
* 12 ports are enabled in MPHY configuration
*
*/
typedef enum
{
IX_UTOPIA_PORT_0 = 0, /**< Port 0 */
#ifdef IX_NPE_MPHYMULTIPORT
IX_UTOPIA_PORT_1, /**< Port 1 */
IX_UTOPIA_PORT_2, /**< Port 2 */
IX_UTOPIA_PORT_3, /**< Port 3 */
IX_UTOPIA_PORT_4, /**< Port 4 */
IX_UTOPIA_PORT_5, /**< Port 5 */
IX_UTOPIA_PORT_6, /**< Port 6 */
IX_UTOPIA_PORT_7, /**< Port 7 */
IX_UTOPIA_PORT_8, /**< Port 8 */
IX_UTOPIA_PORT_9, /**< Port 9 */
IX_UTOPIA_PORT_10, /**< Port 10 */
IX_UTOPIA_PORT_11, /**< Port 11 */
#endif /* IX_NPE_MPHY */
IX_UTOPIA_MAX_PORTS /**< Not a port - just a definition for the
* maximum possible ports
*/
} IxAtmLogicalPort;
/**
* @def IX_ATM_CELL_PAYLOAD_SIZE
* @brief Size of a ATM cell payload
*/
#define IX_ATM_CELL_PAYLOAD_SIZE (48)
/**
* @def IX_ATM_CELL_SIZE
* @brief Size of a ATM cell, including header
*/
#define IX_ATM_CELL_SIZE (53)
/**
* @def IX_ATM_CELL_SIZE_NO_HEC
* @brief Size of a ATM cell, excluding HEC byte
*/
#define IX_ATM_CELL_SIZE_NO_HEC (IX_ATM_CELL_SIZE - 1)
/**
* @def IX_ATM_OAM_CELL_SIZE_NO_HEC
* @brief Size of a OAM cell, excluding HEC byte
*/
#define IX_ATM_OAM_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC
/**
* @def IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE
* @brief Size of a AAL0 48 Cell payload
*/
#define IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE
/**
* @def IX_ATM_AAL5_CELL_PAYLOAD_SIZE
* @brief Size of a AAL5 Cell payload
*/
#define IX_ATM_AAL5_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE
/**
* @def IX_ATM_AAL0_52_CELL_SIZE_NO_HEC
* @brief Size of a AAL0 52 Cell, excluding HEC byte
*/
#define IX_ATM_AAL0_52_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC
/**
* @def IX_ATM_MAX_VPI
* @brief Maximum value of an ATM VPI
*/
#define IX_ATM_MAX_VPI 255
/**
* @def IX_ATM_MAX_VCI
* @brief Maximum value of an ATM VCI
*/
#define IX_ATM_MAX_VCI 65535
/**
* @def IX_ATM_MAX_NUM_AAL_VCS
* @brief Maximum number of active AAL5/AAL0 VCs in the system
*/
#define IX_ATM_MAX_NUM_AAL_VCS 32
/**
* @def IX_ATM_MAX_NUM_VC
* @brief Maximum number of active AAL5/AAL0 VCs in the system
* The use of this macro is depreciated, it is retained for
* backward compatiblity. For current software release
* and beyond the define IX_ATM_MAX_NUM_AAL_VC should be used.
*/
#define IX_ATM_MAX_NUM_VC IX_ATM_MAX_NUM_AAL_VCS
/**
* @def IX_ATM_MAX_NUM_OAM_TX_VCS
* @brief Maximum number of active OAM Tx VCs in the system,
* 1 OAM VC per port
*/
#define IX_ATM_MAX_NUM_OAM_TX_VCS IX_UTOPIA_MAX_PORTS
/**
* @def IX_ATM_MAX_NUM_OAM_RX_VCS
* @brief Maximum number of active OAM Rx VCs in the system,
* 1 OAM VC shared accross all ports
*/
#define IX_ATM_MAX_NUM_OAM_RX_VCS 1
/**
* @def IX_ATM_MAX_NUM_AAL_OAM_TX_VCS
* @brief Maximum number of active AAL5/AAL0/OAM Tx VCs in the system
*/
#define IX_ATM_MAX_NUM_AAL_OAM_TX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_TX_VCS)
/**
* @def IX_ATM_MAX_NUM_AAL_OAM_RX_VCS
* @brief Maximum number of active AAL5/AAL0/OAM Rx VCs in the system
*/
#define IX_ATM_MAX_NUM_AAL_OAM_RX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_RX_VCS)
/**
* @def IX_ATM_IDLE_CELLS_CONNID
* @brief VC Id used to indicate idle cells in the returned schedule table.
*/
#define IX_ATM_IDLE_CELLS_CONNID 0
/**
* @def IX_ATM_CELL_HEADER_VCI_GET
* @brief get the VCI field from a cell header
*/
#define IX_ATM_CELL_HEADER_VCI_GET(cellHeader) \
(((cellHeader) >> 4) & IX_OAM_VCI_BITS_MASK);
/**
* @def IX_ATM_CELL_HEADER_VPI_GET
* @brief get the VPI field from a cell header
*/
#define IX_ATM_CELL_HEADER_VPI_GET(cellHeader) \
(((cellHeader) >> 20) & IX_OAM_VPI_BITS_MASK);
/**
* @def IX_ATM_CELL_HEADER_PTI_GET
* @brief get the PTI field from a cell header
*/
#define IX_ATM_CELL_HEADER_PTI_GET(cellHeader) \
((cellHeader) >> 1) & IX_OAM_PTI_BITS_MASK;
/**
* @typedef IxAtmCellHeader
*
* @brief ATM Cell Header, does not contain 4 byte HEC, added by NPE-A
*/
typedef unsigned int IxAtmCellHeader;
/**
* @enum IxAtmServiceCategory
*
* @brief Enumerated type representing available ATM service categories.
* For more informatoin on these categories, see "Traffic Management
* Specification" v4.1, published by the ATM Forum -
* http://www.atmforum.com
*/
typedef enum
{
IX_ATM_CBR, /**< Constant Bit Rate */
IX_ATM_RTVBR, /**< Real Time Variable Bit Rate */
IX_ATM_VBR, /**< Variable Bit Rate */
IX_ATM_UBR, /**< Unspecified Bit Rate */
IX_ATM_ABR /**< Available Bit Rate (not supported) */
} IxAtmServiceCategory;
/**
*
* @enum IxAtmRxQueueId
*
* @brief Rx Queue Type for RX traffic
*
* IxAtmRxQueueId defines the queues involved for receiving data.
*
* There are two queues to facilitate prioritisation handling
* and processing the 2 queues with different algorithms and
* constraints
*
* e.g. : one queue can carry voice (or time-critical traffic), the
* other queue can carry non-voice traffic
*
*/
typedef enum
{
IX_ATM_RX_A = 0, /**< RX queue A */
IX_ATM_RX_B, /**< RX queue B */
IX_ATM_MAX_RX_STREAMS /**< Maximum number of RX streams */
} IxAtmRxQueueId;
/**
* @brief Structure describing an ATM traffic contract for a Virtual
* Connection (VC).
*
* Structure is used to specify the requested traffic contract for a
* VC to the IxAtmSch component using the @ref ixAtmSchVcModelSetup
* interface.
*
* These parameters are defined by the ATM forum working group
* (http://www.atmforum.com).
*
* @note Typical values for a voice channel 64 Kbit/s
* - atmService @a IX_ATM_RTVBR
* - pcr 400 (include IP overhead, and AAL5 trailer)
* - cdvt 5000000 (5 ms)
* - scr = pcr
*
* @note Typical values for a data channel 800 Kbit/s
* - atmService @a IX_ATM_UBR
* - pcr 1962 (include IP overhead, and AAL5 trailer)
* - cdvt 5000000 (5 ms)
*
*/
typedef struct
{
IxAtmServiceCategory atmService; /**< ATM service category */
unsigned pcr; /**< Peak Cell Rate - cells per second */
unsigned cdvt; /**< Cell Delay Variation Tolerance - in nanoseconds */
unsigned scr; /**< Sustained Cell Rate - cells per second */
unsigned mbs; /**< Max Burst Size - cells */
unsigned mcr; /**< Minimum Cell Rate - cells per second */
unsigned mfs; /**< Max Frame Size - cells */
} IxAtmTrafficDescriptor;
/**
* @typedef IxAtmConnId
*
* @brief ATM VC data connection identifier.
*
* This is is generated by IxAtmdAcc when a successful connection is
* made on a VC. The is the ID by which IxAtmdAcc knows an active
* VC and should be used in IxAtmdAcc API calls to reference a
* specific VC.
*/
typedef unsigned int IxAtmConnId;
/**
* @typedef IxAtmSchedulerVcId
*
* @brief ATM VC scheduling connection identifier.
*
* This id is generated and used by ATM Tx controller, generally
* the traffic shaper (e.g. IxAtmSch). The IxAtmdAcc component
* will request one of these Ids whenever a data connection on
* a Tx VC is requested. This ID will be used in callbacks to
* the ATM Transmission Ctrl s/w (e.g. IxAtmm) to reference a
* particular VC.
*/
typedef int IxAtmSchedulerVcId;
/**
* @typedef IxAtmNpeRxVcId
*
* @brief ATM Rx VC identifier used by the ATM Npe.
*
* This Id is generated by IxAtmdAcc when a successful data connection
* is made on a rx VC.
*/
typedef unsigned int IxAtmNpeRxVcId;
/**
* @brief ATM Schedule Table entry
*
* This IxAtmScheduleTableEntry is used by an ATM scheduler to inform
* IxAtmdAcc about the data to transmit (in term of cells per VC)
*
* This structure defines
* @li the number of cells to be transmitted (numberOfCells)
* @li the VC connection to be used for transmission (connId).
*
* @note - When the connection Id value is IX_ATM_IDLE_CELLS_CONNID, the
* corresponding number of idle cells will be transmitted to the hardware.
*
*/
typedef struct
{
IxAtmConnId connId; /**< connection Id
*
* Identifier of VC from which cells are to be transmitted.
* When this valus is IX_ATM_IDLE_CELLS_CONNID, this indicates
* that the system should transmit the specified number
* of idle cells. Unknown connIds result in the transmission
* idle cells.
*/
unsigned int numberOfCells; /**< number of cells to transmit
*
* The number of contiguous cells to schedule from this VC
* at this point. The valid range is from 1 to
* @a IX_ATM_SCHEDULETABLE_MAXCELLS_PER_ENTRY. This
* number can swap over mbufs and pdus. OverSchduling results
* in the transmission of idle cells.
*/
} IxAtmScheduleTableEntry;
/**
* @brief This structure defines a schedule table which gives details
* on which data (from which VCs) should be transmitted for a
* forthcoming period of time for a particular port and the
* order in which that data should be transmitted.
*
* The schedule table consists of a series of entries each of which
* will schedule one or more cells from a particular registered VC.
* The total number of cells scheduled and the total number of
* entries in the table are also indicated.
*
*/
typedef struct
{
unsigned tableSize; /**< Number of entries
*
* Indicates the total number of
* entries in the table.
*/
unsigned totalCellSlots; /**< Number of cells
*
* Indicates the total number of ATM
* cells which are scheduled by all the
* entries in the table.
*/
IxAtmScheduleTableEntry *table; /**< Pointer to schedule entries
*
* Pointer to an array
* containing tableSize entries
*/
} IxAtmScheduleTable;
#endif /* IXATMTYPES_H */
/**
* @} defgroup IxAtmTypes
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,771 +0,0 @@
/**
* @file IxAtmm.h
*
* @date 3-DEC-2001
*
* @brief Header file for the IXP400 ATM Manager component (IxAtmm)
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/**
* @defgroup IxAtmm IXP400 ATM Manager (IxAtmm) API
*
* @brief IXP400 ATM Manager component Public API
*
* @{
*/
#ifndef IXATMM_H
#define IXATMM_H
/*
* Put the user defined include files required
*/
#include "IxAtmSch.h"
#include "IxOsalTypes.h"
/*
* #defines and macros used in this file.
*/
/**
* @def IX_ATMM_RET_ALREADY_INITIALIZED
*
* @brief Component has already been initialized
*/
#define IX_ATMM_RET_ALREADY_INITIALIZED 2
/**
* @def IX_ATMM_RET_INVALID_PORT
*
* @brief Specified port does not exist or is out of range */
#define IX_ATMM_RET_INVALID_PORT 3
/**
* @def IX_ATMM_RET_INVALID_VC_DESCRIPTOR
*
* @brief The VC description does not adhere to ATM standards */
#define IX_ATMM_RET_INVALID_VC_DESCRIPTOR 4
/**
* @def IX_ATMM_RET_VC_CONFLICT
*
* @brief The VPI/VCI values supplied are either reserved, or they
* conflict with a previously registered VC on this port */
#define IX_ATMM_RET_VC_CONFLICT 5
/**
* @def IX_ATMM_RET_PORT_CAPACITY_IS_FULL
*
* @brief The virtual connection cannot be established on the port
* because the remaining port capacity is not sufficient to
* support it */
#define IX_ATMM_RET_PORT_CAPACITY_IS_FULL 6
/**
* @def IX_ATMM_RET_NO_SUCH_VC
*
* @brief No registered VC, as described by the supplied VCI/VPI or
* VC identifier values, exists on this port */
#define IX_ATMM_RET_NO_SUCH_VC 7
/**
* @def IX_ATMM_RET_INVALID_VC_ID
*
* @brief The specified VC identifier is out of range. */
#define IX_ATMM_RET_INVALID_VC_ID 8
/**
* @def IX_ATMM_RET_INVALID_PARAM_PTR
*
* @brief A pointer parameter was NULL. */
#define IX_ATMM_RET_INVALID_PARAM_PTR 9
/**
* @def IX_ATMM_UTOPIA_SPHY_ADDR
*
* @brief The phy address when in SPHY mode */
#define IX_ATMM_UTOPIA_SPHY_ADDR 31
/**
* @def IX_ATMM_THREAD_PRI_HIGH
*
* @brief The value of high priority thread */
#define IX_ATMM_THREAD_PRI_HIGH 90
/*
* Typedefs whose scope is limited to this file.
*/
/** @brief Definition for use in the @ref IxAtmmVc structure.
* Indicates the direction of a VC */
typedef enum
{
IX_ATMM_VC_DIRECTION_TX=0, /**< Atmm Vc direction transmit*/
IX_ATMM_VC_DIRECTION_RX, /**< Atmm Vc direction receive*/
IX_ATMM_VC_DIRECTION_INVALID /**< Atmm Vc direction invalid*/
} IxAtmmVcDirection;
/** @brief Definition for use with @ref IxAtmmVcChangeCallback
* callback. Indicates that the event type represented by the
* callback for this VC. */
typedef enum
{
IX_ATMM_VC_CHANGE_EVENT_REGISTER=0, /**< Atmm Vc event register*/
IX_ATMM_VC_CHANGE_EVENT_DEREGISTER, /**< Atmm Vc event de-register*/
IX_ATMM_VC_CHANGE_EVENT_INVALID /**< Atmm Vc event invalid*/
} IxAtmmVcChangeEvent;
/** @brief Definitions for use with @ref ixAtmmUTOPIAInit interface to
* indicate that UTOPIA loopback should be enabled or disabled
* on initialisation. */
typedef enum
{
IX_ATMM_UTOPIA_LOOPBACK_DISABLED=0, /**< Atmm Utopia loopback mode disabled*/
IX_ATMM_UTOPIA_LOOPBACK_ENABLED, /**< Atmm Utopia loopback mode enabled*/
IX_ATMM_UTOPIA_LOOPBACK_INVALID /**< Atmm Utopia loopback mode invalid*/
} IxAtmmUtopiaLoopbackMode;
/** @brief This structure describes the required attributes of a
* virtual connection.
*/
typedef struct {
unsigned vpi; /**< VPI value of this virtual connection */
unsigned vci; /**< VCI value of this virtual connection. */
IxAtmmVcDirection direction; /**< VC direction */
/** Traffic descriptor of this virtual connection. This structure
* is defined by the @ref IxAtmSch component. */
IxAtmTrafficDescriptor trafficDesc;
} IxAtmmVc;
/** @brief Definitions for use with @ref ixAtmmUtopiaInit interface to
* indicate that UTOPIA multi-phy/single-phy mode is used.
*/
typedef enum
{
IX_ATMM_MPHY_MODE = 0, /**< Atmm phy mode mphy*/
IX_ATMM_SPHY_MODE, /**< Atmm phy mode sphy*/
IX_ATMM_PHY_MODE_INVALID /**< Atmm phy mode invalid*/
} IxAtmmPhyMode;
/** @brief Structure contains port-specific information required to
* initialize IxAtmm, and specifically, the IXP400 UTOPIA
* Level-2 device. */
typedef struct {
unsigned reserved_1:11; /**< [31:21] Should be zero */
unsigned UtopiaTxPhyAddr:5; /**< [20:16] Address of the
* transmit (Tx) PHY for this
* port on the 5-bit UTOPIA
* Level-2 address bus */
unsigned reserved_2:11; /**< [15:5] Should be zero */
unsigned UtopiaRxPhyAddr:5; /**< [4:0] Address of the receive
* (Rx) PHY for this port on the
* 5-bit UTOPIA Level-2
* address bus */
} IxAtmmPortCfg;
/** @brief Callback type used with @ref ixAtmmVcChangeCallbackRegister interface
* Defines a callback type which will be used to notify registered
* users of registration/deregistration events on a particular port
*
* @param eventType @ref IxAtmmVcChangeEvent [in] - Event indicating
* whether the VC supplied has been added or
* removed
*
* @param port @ref IxAtmLogicalPort [in] - Specifies the port on which the event has
* occurred
*
* @param vcChanged @ref IxAtmmVc* [in] - Pointer to a structure which gives
* details of the VC which has been added
* or removed on the port
*/
typedef void (*IxAtmmVcChangeCallback) (IxAtmmVcChangeEvent eventType,
IxAtmLogicalPort port,
const IxAtmmVc* vcChanged);
/*
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
/*
* Extern function prototypes
*/
/*
* Function declarations
*/
/**
* @ingroup IxAtmm
*
* @fn ixAtmmInit (void)
*
* @brief Interface to initialize the IxAtmm software component. Can
* be called once only.
*
* Must be called before any other IxAtmm API is called.
*
* @param "none"
*
* @return @li IX_SUCCESS : IxAtmm has been successfully initialized.
* Calls to other IxAtmm interfaces may now be performed.
* @return @li IX_FAIL : IxAtmm has already been initialized.
*/
PUBLIC IX_STATUS
ixAtmmInit (void);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmUtopiaInit (unsigned numPorts,
IxAtmmPhyMode phyMode,
IxAtmmPortCfg portCfgs[],
IxAtmmUtopiaLoopbackMode loopbackMode)
*
* @brief Interface to initialize the UTOPIA Level-2 ATM coprocessor
* for the specified number of physical ports. The function
* must be called before the ixAtmmPortInitialize interface
* can operate successfully.
*
* @param numPorts unsigned [in] - Indicates the total number of logical
* ports that are active on the device. Up to 12 ports are
* supported.
*
* @param phyMode @ref IxAtmmPhyMode [in] - Put the Utopia coprocessor in SPHY
* or MPHY mode.
*
* @param portCfgs[] @ref IxAtmmPortCfg [in] - Pointer to an array of elements
* detailing the UTOPIA specific port characteristics. The
* length of the array must be equal to the number of ports
* activated. ATM ports are referred to by the relevant
* offset in this array in all subsequent IxAtmm interface
* calls.
*
* @param loopbackMode @ref IxAtmmUtopiaLoopbackMode [in] - Value must be one of
* @ref IX_ATMM_UTOPIA_LOOPBACK_ENABLED or @ref
* IX_ATMM_UTOPIA_LOOPBACK_DISABLED indicating whether
* loopback should be enabled on the device. Loopback can
* only be supported on a single PHY, therefore the numPorts
* parameter must be 1 if loopback is enabled.
*
* @return @li IX_SUCCESS : Indicates that the UTOPIA device has been
* successfully initialized for the supplied ports.
* @return @li IX_ATMM_RET_ALREADY_INITIALIZED : The UTOPIA device has
* already been initialized.
* @return @li IX_FAIL : The supplied parameters are invalid or have been
* rejected by the UTOPIA-NPE device.
*
* @warning
* This interface may only be called once.
* Port identifiers are assumed to range from 0 to (numPorts - 1) in all
* instances.
* In all subsequent calls to interfaces supplied by IxAtmm, the specified
* port value is expected to represent the offset in the portCfgs array
* specified in this interface. i.e. The first port in this array will
* subsequently be represented as port 0, the second port as port 1,
* and so on.*/
PUBLIC IX_STATUS
ixAtmmUtopiaInit (unsigned numPorts,
IxAtmmPhyMode phyMode,
IxAtmmPortCfg portCfgs[],
IxAtmmUtopiaLoopbackMode loopbackMode);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmPortInitialize (IxAtmLogicalPort port,
unsigned txPortRate,
unsigned rxPortRate)
*
* @brief The interface is called following @ref ixAtmmUtopiaInit ()
* and before calls to any other IxAtmm interface. It serves
* to activate the registered ATM port with IxAtmm.
*
* The transmit and receive port rates are specified in bits per
* second. This translates to ATM cells per second according to the
* following formula: CellsPerSecond = portRate / (53*8) The
* IXP400 device supports only 53 byte cells. The client shall make
* sure that the off-chip physical layer device has already been
* initialized.
*
* IxAtmm will configure IxAtmdAcc and IxAtmSch to enable scheduling
* on the port.
*
* This interface must be called once for each active port in the
* system. The first time the interface is invoked, it will configure
* the mechanism by which the handling of transmit, transmit-done and
* receive are driven with the IxAtmdAcc component.
*
* This function is reentrant.
*
* @note The minimum tx rate that will be accepted is 424 bit/s which equates
* to 1 cell (53 bytes) per second.
*
* @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be
* initialized.
*
* @param txPortRate unsigned [in] - Value specifies the
* transmit port rate for this port in
* bits/second. This value is used by the ATM Scheduler
* component is evaluating VC access requests for the port.
*
* @param rxPortRate unsigned [in] - Value specifies the
* receive port rate for this port in bits/second.
*
* @return @li IX_SUCCESS : The specificed ATM port has been successfully
* initialized. IxAtmm is ready to accept VC registrations on
* this port.
*
* @return @li IX_ATMM_RET_ALREADY_INITIALIZED : ixAtmmPortInitialize has
* already been called successfully on this port. The current
* call is rejected.
*
* @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
* input is not valid. The request is rejected.
*
* @return @li IX_FAIL : IxAtmm could not initialize the port because the
* inputs are not understood.
*
* @sa ixAtmmPortEnable, ixAtmmPortDisable
*
*/
PUBLIC IX_STATUS
ixAtmmPortInitialize (IxAtmLogicalPort port,
unsigned txPortRate,
unsigned rxPortRate);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmPortModify (IxAtmLogicalPort port,
unsigned txPortRate,
unsigned rxPortRate)
*
* @brief A client may call this interface to change the existing
* port rate (expressed in bits/second) on an established ATM
* port.
*
* @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be
* initialized.
*
* @param txPortRate unsigned [in] - Value specifies the``
* transmit port rate for this port in
* bits/second. This value is used by the ATM Scheduler
* component is evaluating VC access requests for the port.
*
* @param rxPortRate unsigned [in] - Value specifies the
* receive port rate for this port in
* bits/second.
*
* @return @li IX_SUCCESS : The indicated ATM port rates have been
* successfully modified.
*
* @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
* input is not valid. The request is rejected.
*
* @return @li IX_FAIL : IxAtmm could not update the port because the
* inputs are not understood, or the interface was called before
* the port was initialized. */
PUBLIC IX_STATUS
ixAtmmPortModify (IxAtmLogicalPort port,
unsigned txPortRate,
unsigned rxPortRate);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmPortQuery (IxAtmLogicalPort port,
unsigned *txPortRate,
unsigned *rxPortRate);
*
* @brief The client may call this interface to request details on
* currently registered transmit and receive rates for an ATM
* port.
*
* @param port @ref IxAtmLogicalPort [in] - Value identifies the port from which the
* rate details are requested.
*
* @param *txPortRate unsigned [out] - Pointer to a value
* which will be filled with the value of the transmit port
* rate specified in bits/second.
*
* @param *rxPortRate unsigned [out] - Pointer to a value
* which will be filled with the value of the receive port
* rate specified in bits/second.
*
* @return @li IX_SUCCESS : The information requested on the specified
* port has been successfully supplied in the output.
*
* @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
* input is not valid. The request is rejected.
*
* @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
* NULL.
*
* @return @li IX_FAIL : IxAtmm could not update the port because the
* inputs are not understood, or the interface was called before
* the port was initialized. */
PUBLIC IX_STATUS
ixAtmmPortQuery (IxAtmLogicalPort port,
unsigned *txPortRate,
unsigned *rxPortRate);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmPortEnable(IxAtmLogicalPort port)
*
* @brief The client call this interface to enable transmit for an ATM
* port. At initialisation, all the ports are disabled.
*
* @param port @ref IxAtmLogicalPort [in] - Value identifies the port
*
* @return @li IX_SUCCESS : Transmission over this port is started.
*
* @return @li IX_FAIL : The port parameter is not valid, or the
* port is already enabled
*
* @note - When a port is disabled, Rx and Tx VC Connect requests will fail
*
* @note - This function uses system resources and should not be used
* inside an interrupt context.
*
* @sa ixAtmmPortDisable */
PUBLIC IX_STATUS
ixAtmmPortEnable(IxAtmLogicalPort port);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmPortDisable(IxAtmLogicalPort port)
*
* @brief The client call this interface to disable transmit for an ATM
* port. At initialisation, all the ports are disabled.
*
* @param port @ref IxAtmLogicalPort [in] - Value identifies the port
*
* @return @li IX_SUCCESS : Transmission over this port is stopped.
*
* @return @li IX_FAIL : The port parameter is not valid, or the
* port is already disabled
*
* @note - When a port is disabled, Rx and Tx VC Connect requests will fail
*
* @note - This function call does not stop RX traffic. It is supposed
* that this function is invoked when a serious problem
* is detected (e.g. physical layer broken). Then, the RX traffic
* is not passing.
*
* @note - This function is blocking until the hw acknowledge that the
* transmission is stopped.
*
* @note - This function uses system resources and should not be used
* inside an interrupt context.
*
* @sa ixAtmmPortEnable */
PUBLIC IX_STATUS
ixAtmmPortDisable(IxAtmLogicalPort port);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmVcRegister (IxAtmLogicalPort port,
IxAtmmVc *vcToAdd,
IxAtmSchedulerVcId *vcId)
*
* @brief This interface is used to register an ATM Virtual
* Connection on the specified ATM port.
*
* Each call to this interface registers a unidirectional virtual
* connection with the parameters specified. If a bi-directional VC
* is needed, the function should be called twice (once for each
* direction, Tx & Rx) where the VPI and VCI and port parameters in
* each call are identical.
*
* With the addition of each new VC to a port, a series of
* callback functions are invoked by the IxAtmm component to notify
* possible external components of the change. The callback functions
* are registered using the @ref ixAtmmVcChangeCallbackRegister interface.
*
* The IxAtmSch component is notified of the registration of transmit
* VCs.
*
* @param port @ref IxAtmLogicalPort [in] - Identifies port on which the specified VC is
* to be registered.
*
* @param *vcToAdd @ref IxAtmmVc [in] - Pointer to an @ref IxAtmmVc structure
* containing a description of the VC to be registered. The
* client shall fill the vpi, vci and direction and relevant
* trafficDesc members of this structure before calling this
* function.
*
* @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which is filled
* with the per-port unique identifier value for this VC.
* This identifier will be required when a request is
* made to deregister or change this VC. VC identifiers
* for transmit VCs will have a value between 0-43,
* i.e. 32 data Tx VCs + 12 OAM Tx Port VCs.
* Receive VCs will have a value between 44-66,
* i.e. 32 data Rx VCs + 1 OAM Rx VC.
*
* @return @li IX_SUCCESS : The VC has been successfully registered on
* this port. The VC is ready for a client to configure IxAtmdAcc
* for receive and transmit operations on the VC.
* @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
* input is not valid or has not been initialized. The request
* is rejected.
* @return @li IX_ATMM_RET_INVALID_VC_DESCRIPTOR : The descriptor
* pointed to by vcToAdd is invalid. The registration request
* is rejected.
* @return @li IX_ATMM_RET_VC_CONFLICT : The VC requested conflicts with
* reserved VPI and/or VCI values or with another VC already activated
* on this port.
* @return @li IX_ATMM_RET_PORT_CAPACITY_IS_FULL : The VC cannot be
* registered in the port becuase the port capacity is
* insufficient to support the requested ATM traffic contract.
* The registration request is rejected.
* @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
* NULL.
*
* @warning IxAtmm has no capability of signaling or negotiating a virtual
* connection. Negotiation of the admission of the VC to the network
* is beyond the scope of this function. This is assumed to be
* performed by the calling client, if appropriate,
* before or after this function is called.
*/
PUBLIC IX_STATUS
ixAtmmVcRegister (IxAtmLogicalPort port,
IxAtmmVc *vcToAdd,
IxAtmSchedulerVcId *vcId);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId)
*
* @brief Function called by a client to deregister a VC from the
* system.
*
* With the removal of each new VC from a port, a series of
* registered callback functions are invoked by the IxAtmm component
* to notify possible external components of the change. The callback
* functions are registered using the @ref ixAtmmVcChangeCallbackRegister.
*
* The IxAtmSch component is notified of the removal of transmit VCs.
*
* @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
* removed is currently registered.
*
* @param vcId @ref IxAtmSchedulerVcId [in] - VC identifier value of the VC to
* be deregistered. This value was supplied to the client when
the VC was originally registered. This value can also be
queried from the IxAtmm component through the @ref ixAtmmVcQuery
* interface.
*
* @return @li IX_SUCCESS : The specified VC has been successfully
* removed from this port.
* @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
* input is not valid or has not been initialized. The request
* is rejected.
* @return @li IX_FAIL : There is no registered VC associated with the
* supplied identifier registered on this port. */
PUBLIC IX_STATUS
ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmVcQuery (IxAtmLogicalPort port,
unsigned vpi,
unsigned vci,
IxAtmmVcDirection direction,
IxAtmSchedulerVcId *vcId,
IxAtmmVc *vcDesc)
*
* @brief This interface supplies information about an active VC on a
* particular port when supplied with the VPI, VCI and
* direction of that VC.
*
* @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
* queried is currently registered.
*
* @param vpi unsigned [in] - ATM VPI value of the requested VC.
*
* @param vci unsigned [in] - ATM VCI value of the requested VC.
*
* @param direction @ref IxAtmmVcDirection [in] - One of @ref
* IX_ATMM_VC_DIRECTION_TX or @ref IX_ATMM_VC_DIRECTION_RX
* indicating the direction (Tx or Rx) of the requested VC.
*
* @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which will be
* filled with the VC identifier value for the requested
* VC (as returned by @ref ixAtmmVcRegister), if it
* exists on this port.
*
* @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure
* which will be filled with the specific details of the
* requested VC, if it exists on this port.
*
* @return @li IX_SUCCESS : The specified VC has been found on this port
* and the requested details have been returned.
* @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
* input is not valid or has not been initialized. The request
* is rejected.
* @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified
* port which matches the search criteria (VPI, VCI, direction)
* given. No data is returned.
* @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
* NULL.
*
*/
PUBLIC IX_STATUS
ixAtmmVcQuery (IxAtmLogicalPort port,
unsigned vpi,
unsigned vci,
IxAtmmVcDirection direction,
IxAtmSchedulerVcId *vcId,
IxAtmmVc *vcDesc);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc)
*
* @brief This interface supplies information about an active VC on a
* particular port when supplied with a vcId for that VC.
*
* @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
* queried is currently registered.
*
* @param vcId @ref IxAtmSchedulerVcId [in] - Value returned by @ref ixAtmmVcRegister which
* uniquely identifies the requested VC on this port.
*
* @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure
* which will be filled with the specific details of the
* requested VC, if it exists on this port.
*
* @return @li IX_SUCCESS : The specified VC has been found on this port
* and the requested details have been returned.
* @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
* input is not valid or has not been initialized. The request
* is rejected.
* @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified
* port which matches the supplied identifier. No data is
* returned.
* @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
* NULL.
*/
PUBLIC IX_STATUS
ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback)
*
* @brief This interface is invoked to supply a function to IxAtmm
* which will be called to notify the client if a new VC is
* registered with IxAtmm or an existing VC is removed.
*
* The callback, when invoked, will run within the context of the call
* to @ref ixAtmmVcRegister or @ref ixAtmmVcDeregister which caused
* the change of state.
*
* A maximum of 32 calbacks may be registered in with IxAtmm.
*
* @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies
* with the @ref IxAtmmVcChangeCallback definition. This
* function will be invoked by IxAtmm with the appropiate
* parameters for the relevant VC when any VC has been
* registered or deregistered with IxAtmm.
*
* @return @li IX_SUCCESS : The specified callback has been registered
* successfully with IxAtmm and will be invoked when appropriate.
* @return @li IX_FAIL : Either the supplied callback is invalid, or
* IxAtmm has already registered 32 and connot accommodate
* any further registrations of this type. The request is
* rejected.
*
* @warning The client must not call either the @ref
* ixAtmmVcRegister or @ref ixAtmmVcDeregister interfaces
* from within the supplied callback function. */
PUBLIC IX_STATUS ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback)
*
* @brief This interface is invoked to deregister a previously supplied
* callback function.
*
* @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies
* with the @ref IxAtmmVcChangeCallback definition. This
* function will removed from the table of callbacks.
*
* @return @li IX_SUCCESS : The specified callback has been deregistered
* successfully from IxAtmm.
* @return @li IX_FAIL : Either the supplied callback is invalid, or
* is not currently registered with IxAtmm.
*/
PUBLIC IX_STATUS
ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmUtopiaStatusShow (void)
*
* @brief Display utopia status counters
*
* @param "none"
*
* @return @li IX_SUCCESS : Show function was successful
* @return @li IX_FAIL : Internal failure
*/
PUBLIC IX_STATUS
ixAtmmUtopiaStatusShow (void);
/**
* @ingroup IxAtmm
*
* @fn ixAtmmUtopiaCfgShow (void)
*
* @brief Display utopia information(config registers and status registers)
*
* @param "none"
*
* @return @li IX_SUCCESS : Show function was successful
* @return @li IX_FAIL : Internal failure
*/
PUBLIC IX_STATUS
ixAtmmUtopiaCfgShow (void);
#endif
/* IXATMM_H */
/** @} */

View File

@ -1,236 +0,0 @@
/**
* @file IxDmaAcc.h
*
* @date 15 October 2002
*
* @brief API of the IXP400 DMA Access Driver Component (IxDma)
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/*---------------------------------------------------------------------
Doxygen group definitions
---------------------------------------------------------------------*/
#ifndef IXDMAACC_H
#define IXDMAACC_H
#include "IxOsal.h"
#include "IxNpeDl.h"
/**
* @defgroup IxDmaTypes IXP400 DMA Types (IxDmaTypes)
* @brief The common set of types used in the DMA component
* @{
*/
/**
* @ingroup IxDmaTypes
* @enum IxDmaReturnStatus
* @brief Dma return status definitions
*/
typedef enum
{
IX_DMA_SUCCESS = IX_SUCCESS, /**< DMA Transfer Success */
IX_DMA_FAIL = IX_FAIL, /**< DMA Transfer Fail */
IX_DMA_INVALID_TRANSFER_WIDTH, /**< Invalid transfer width */
IX_DMA_INVALID_TRANSFER_LENGTH, /**< Invalid transfer length */
IX_DMA_INVALID_TRANSFER_MODE, /**< Invalid transfer mode */
IX_DMA_INVALID_ADDRESS_MODE, /**< Invalid address mode */
IX_DMA_REQUEST_FIFO_FULL /**< DMA request queue is full */
} IxDmaReturnStatus;
/**
* @ingroup IxDmaTypes
* @enum IxDmaTransferMode
* @brief Dma transfer mode definitions
* @note Copy and byte swap, and copy and reverse modes only support multiples of word data length.
*/
typedef enum
{
IX_DMA_COPY_CLEAR = 0, /**< copy and clear source*/
IX_DMA_COPY, /**< copy */
IX_DMA_COPY_BYTE_SWAP, /**< copy and byte swap (endian) */
IX_DMA_COPY_REVERSE, /**< copy and reverse */
IX_DMA_TRANSFER_MODE_INVALID /**< Invalid transfer mode */
} IxDmaTransferMode;
/**
* @ingroup IxDmaTypes
* @enum IxDmaAddressingMode
* @brief Dma addressing mode definitions
* @note Fixed source address to fixed destination address addressing mode is not supported.
*/
typedef enum
{
IX_DMA_INC_SRC_INC_DST = 0, /**< Incremental source address to incremental destination address */
IX_DMA_INC_SRC_FIX_DST, /**< Incremental source address to incremental destination address */
IX_DMA_FIX_SRC_INC_DST, /**< Incremental source address to incremental destination address */
IX_DMA_FIX_SRC_FIX_DST, /**< Incremental source address to incremental destination address */
IX_DMA_ADDRESSING_MODE_INVALID /**< Invalid Addressing Mode */
} IxDmaAddressingMode;
/**
* @ingroup IxDmaTypes
* @enum IxDmaTransferWidth
* @brief Dma transfer width definitions
* @Note Fixed addresses (either source or destination) do not support burst transfer width.
*/
typedef enum
{
IX_DMA_32_SRC_32_DST = 0, /**< 32-bit src to 32-bit dst */
IX_DMA_32_SRC_16_DST, /**< 32-bit src to 16-bit dst */
IX_DMA_32_SRC_8_DST, /**< 32-bit src to 8-bit dst */
IX_DMA_16_SRC_32_DST, /**< 16-bit src to 32-bit dst */
IX_DMA_16_SRC_16_DST, /**< 16-bit src to 16-bit dst */
IX_DMA_16_SRC_8_DST, /**< 16-bit src to 8-bit dst */
IX_DMA_8_SRC_32_DST, /**< 8-bit src to 32-bit dst */
IX_DMA_8_SRC_16_DST, /**< 8-bit src to 16-bit dst */
IX_DMA_8_SRC_8_DST, /**< 8-bit src to 8-bit dst */
IX_DMA_8_SRC_BURST_DST, /**< 8-bit src to burst dst - Not supported for fixed destination address */
IX_DMA_16_SRC_BURST_DST, /**< 16-bit src to burst dst - Not supported for fixed destination address */
IX_DMA_32_SRC_BURST_DST, /**< 32-bit src to burst dst - Not supported for fixed destination address */
IX_DMA_BURST_SRC_8_DST, /**< burst src to 8-bit dst - Not supported for fixed source address */
IX_DMA_BURST_SRC_16_DST, /**< burst src to 16-bit dst - Not supported for fixed source address */
IX_DMA_BURST_SRC_32_DST, /**< burst src to 32-bit dst - Not supported for fixed source address*/
IX_DMA_BURST_SRC_BURST_DST, /**< burst src to burst dst - Not supported for fixed source and destination address
*/
IX_DMA_TRANSFER_WIDTH_INVALID /**< Invalid transfer width */
} IxDmaTransferWidth;
/**
* @ingroup IxDmaTypes
* @enum IxDmaNpeId
* @brief NpeId numbers to identify NPE A, B or C
*/
typedef enum
{
IX_DMA_NPEID_NPEA = 0, /**< Identifies NPE A */
IX_DMA_NPEID_NPEB, /**< Identifies NPE B */
IX_DMA_NPEID_NPEC, /**< Identifies NPE C */
IX_DMA_NPEID_MAX /**< Total Number of NPEs */
} IxDmaNpeId;
/* @} */
/**
* @defgroup IxDmaAcc IXP400 DMA Access Driver (IxDmaAcc) API
*
* @brief The public API for the IXP400 IxDmaAcc component
*
* @{
*/
/**
* @ingroup IxDmaAcc
* @brief DMA Request Id type
*/
typedef UINT32 IxDmaAccRequestId;
/**
* @ingroup IxDmaAcc
* @def IX_DMA_REQUEST_FULL
* @brief DMA request queue is full
* This constant is a return value used to tell the user that the IxDmaAcc
* queue is full.
*
*/
#define IX_DMA_REQUEST_FULL 16
/**
* @ingroup IxDmaAcc
* @brief DMA completion notification
* This function is called to notify a client that the DMA has been completed
* @param status @ref IxDmaReturnStatus [out] - reporting to client
*
*/
typedef void (*IxDmaAccDmaCompleteCallback) (IxDmaReturnStatus status);
/**
* @ingroup IxDmaAcc
*
* @fn ixDmaAccInit(IxNpeDlNpeId npeId)
*
* @brief Initialise the DMA Access component
* This function will initialise the DMA Access component internals
* @param npeId @ref IxNpeDlNpeId [in] - NPE to use for Dma Transfer
* @return @li IX_SUCCESS succesfully initialised the component
* @return @li IX_FAIL Initialisation failed for some unspecified
* internal reason.
*/
PUBLIC IX_STATUS
ixDmaAccInit(IxNpeDlNpeId npeId);
/**
* @ingroup IxDmaAcc
*
* @fn ixDmaAccDmaTransfer(
IxDmaAccDmaCompleteCallback callback,
UINT32 SourceAddr,
UINT32 DestinationAddr,
UINT16 TransferLength,
IxDmaTransferMode TransferMode,
IxDmaAddressingMode AddressingMode,
IxDmaTransferWidth TransferWidth)
*
* @brief Perform DMA transfer
* This function will perform DMA transfer between devices within the
* IXP400 memory map.
* @note The following are restrictions for IxDmaAccDmaTransfer:
* @li The function is non re-entrant.
* @li The function assumes host devices are operating in big-endian mode.
* @li Fixed address does not suport burst transfer width
* @li Fixed source address to fixed destinatiom address mode is not suported
* @li The incrementing source address for expansion bus will not support a burst transfer width and copy and clear mode
*
* @param callback @ref IxDmaAccDmaCompleteCallback [in] - function pointer to be stored and called when the DMA transfer is completed. This cannot be NULL.
* @param SourceAddr UINT32 [in] - Starting address of DMA source. Must be a valid IXP400 memory map address.
* @param DestinationAddr UINT32 [in] - Starting address of DMA destination. Must be a valid IXP400 memory map address.
* @param TransferLength UINT16 [in] - The size of DMA data transfer. The range must be from 1-64Kbyte
* @param TransferMode @ref IxDmaTransferMode [in] - The DMA transfer mode
* @param AddressingMode @ref IxDmaAddressingMode [in] - The DMA addressing mode
* @param TransferWidth @ref IxDmaTransferWidth [in] - The DMA transfer width
*
* @return @li IX_DMA_SUCCESS Notification that the DMA request is succesful
* @return @li IX_DMA_FAIL IxDmaAcc not yet initialised or some internal error has occured
* @return @li IX_DMA_INVALID_TRANSFER_WIDTH Transfer width is nit valid
* @return @li IX_DMA_INVALID_TRANSFER_LENGTH Transfer length outside of valid range
* @return @li IX_DMA_INVALID_TRANSFER_MODE Transfer Mode not valid
* @return @li IX_DMA_REQUEST_FIFO_FULL IxDmaAcc request queue is full
*/
PUBLIC IxDmaReturnStatus
ixDmaAccDmaTransfer(
IxDmaAccDmaCompleteCallback callback,
UINT32 SourceAddr,
UINT32 DestinationAddr,
UINT16 TransferLength,
IxDmaTransferMode TransferMode,
IxDmaAddressingMode AddressingMode,
IxDmaTransferWidth TransferWidth);
/**
* @ingroup IxDmaAcc
*
* @fn ixDmaAccShow(void)
*
* @brief Display some component information for debug purposes
* Show some internal operation information relating to the DMA service.
* At a minimum the following will show.
* - the number of the DMA pend (in queue)
* @param None
* @return @li None
*/
PUBLIC IX_STATUS
ixDmaAccShow(void);
#endif /* IXDMAACC_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,221 +0,0 @@
/**
* @file IxEthAccDataPlane_p.h
*
* @author Intel Corporation
* @date 12-Feb-2002
*
* @brief Internal Header file for IXP425 Ethernet Access component.
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthAccDataPlane_p_H
#define IxEthAccDataPlane_p_H
#include <IxOsal.h>
#include <IxQMgr.h>
/**
* @addtogroup IxEthAccPri
*@{
*/
/* typedefs global to this file*/
typedef struct
{
IX_OSAL_MBUF *pHead;
IX_OSAL_MBUF *pTail;
}IxEthAccDataPlaneQList;
/**
* @struct IxEthAccDataPlaneStats
* @brief Statistics data structure associated with the data plane
*
*/
typedef struct
{
UINT32 addToSwQ;
UINT32 removeFromSwQ;
UINT32 unchainedTxMBufs;
UINT32 chainedTxMBufs;
UINT32 unchainedTxDoneMBufs;
UINT32 chainedTxDoneMBufs;
UINT32 unchainedRxMBufs;
UINT32 chainedRxMBufs;
UINT32 unchainedRxFreeMBufs;
UINT32 chainedRxFreeMBufs;
UINT32 rxCallbackCounter;
UINT32 rxCallbackBurstRead;
UINT32 txDoneCallbackCounter;
UINT32 unexpectedError;
} IxEthAccDataPlaneStats;
/**
* @fn ixEthAccMbufFromSwQ
* @brief used during disable steps to convert mbufs from
* swq format, ready to be pushed into hw queues for NPE,
* back into XScale format
*/
IX_OSAL_MBUF *ixEthAccMbufFromSwQ(IX_OSAL_MBUF *mbuf);
/**
* @fn ixEthAccDataPlaneShow
* @brief Show function (for data plane statistics
*/
void ixEthAccDataPlaneShow(void);
/*
* lock dataplane when atomic operation is required
*/
#define IX_ETH_ACC_DATA_PLANE_LOCK(arg) arg = ixOsalIrqLock();
#define IX_ETH_ACC_DATA_PLANE_UNLOCK(arg) ixOsalIrqUnlock(arg);
/*
* Use MBUF fields
*/
#define IX_ETHACC_NE_SHARED(mBufPtr) \
((IxEthAccNe *)&((mBufPtr)->ix_ne))
#if 1
#define IX_ETHACC_NE_NEXT(mBufPtr) (mBufPtr)->ix_ne.reserved[0]
/* tm - wrong!! len and pkt_len are in the second word - #define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[3] */
#define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[1]
#define IX_ETHACC_NE_DATA(mBufPtr)(mBufPtr)->ix_ne.reserved[2]
#else
#define IX_ETHACC_NE_NEXT(mBufPtr) \
IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_next
#define IX_ETHACC_NE_LEN(mBufPtr) \
IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_lengths
#define IX_ETHACC_NE_DATA(mBufPtr) \
IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_data
#endif
/*
* Use MBUF next pointer field to chain data.
*/
#define IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER(mbuf) (mbuf)->ix_ctrl.ix_chain
#define IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(mbuf_list) ((mbuf_list.pHead) == NULL)
#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(mbuf_list,mbuf_to_add) \
do { \
int lockVal; \
IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \
if ( (mbuf_list.pHead) != NULL ) \
{ \
(IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add))) = (mbuf_list.pHead);\
(mbuf_list.pHead) = (mbuf_to_add); \
} \
else { \
(mbuf_list.pTail) = (mbuf_list.pHead) = (mbuf_to_add); \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
} \
IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
} while(0)
#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(mbuf_list,mbuf_to_add) \
do { \
int lockVal; \
IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \
if ( (mbuf_list.pHead) == NULL ) \
{ \
(mbuf_list.pHead) = mbuf_to_add; \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
} \
else { \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_list.pTail)) = (mbuf_to_add); \
IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
} \
(mbuf_list.pTail) = mbuf_to_add; \
IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
} while (0)
#define IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(mbuf_list,mbuf_to_rem) \
do { \
int lockVal; \
IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
if ( (mbuf_list.pHead) != NULL ) \
{ \
IX_ETH_ACC_STATS_INC(ixEthAccDataStats.removeFromSwQ); \
(mbuf_to_rem) = (mbuf_list.pHead) ; \
(mbuf_list.pHead) = (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_rem)));\
} \
else { \
(mbuf_to_rem) = NULL; \
} \
IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
} while (0)
/**
* @brief message handler QManager entries for NPE id => port ID conversion (NPE_B => 0, NPE_C => 1)
*/
#define IX_ETH_ACC_PORT_TO_NPE_ID(port) \
ixEthAccPortData[(port)].npeId
#define IX_ETH_ACC_NPE_TO_PORT_ID(npe) ((npe == 0 ? 2 : (npe == 1 ? 0 : ( npe == 2 ? 1 : -1 ))))
#define IX_ETH_ACC_PORT_TO_TX_Q_ID(port) \
ixEthAccPortData[(port)].ixEthAccTxData.txQueue
#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(port) \
ixEthAccPortData[(port)].ixEthAccRxData.rxFreeQueue
#define IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE : IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE))
#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE : IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE ))
/* Flush the mbufs chain and all data pointed to by the mbuf */
#ifndef NDEBUG
#define IX_ETH_ACC_STATS_INC(x) (x++)
#else
#define IX_ETH_ACC_STATS_INC(x)
#endif
#define IX_ETH_ACC_MAX_TX_FRAMES_TO_SUBMIT 128
void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
void ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
#endif /* IxEthAccDataPlane_p_H */
/**
*@}
*/

View File

@ -1,224 +0,0 @@
/*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthAccMac_p_H
#define IxEthAccMac_p_H
#include "IxOsal.h"
#define IX_ETH_ACC_MAX_MULTICAST_ADDRESSES 256
#define IX_ETH_ACC_NUM_PORTS 3
#define IX_ETH_ACC_MAX_FRAME_SIZE_DEFAULT 1536
#define IX_ETH_ACC_MAX_FRAME_SIZE_UPPER_RANGE (65536-64)
#define IX_ETH_ACC_MAX_FRAME_SIZE_LOWER_RANGE 64
/*
*
* MAC register definitions
*
*/
#define IX_ETH_ACC_MAC_0_BASE IX_OSAL_IXP400_ETHA_PHYS_BASE
#define IX_ETH_ACC_MAC_1_BASE IX_OSAL_IXP400_ETHB_PHYS_BASE
#define IX_ETH_ACC_MAC_2_BASE IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE
#define IX_ETH_ACC_MAC_TX_CNTRL1 0x000
#define IX_ETH_ACC_MAC_TX_CNTRL2 0x004
#define IX_ETH_ACC_MAC_RX_CNTRL1 0x010
#define IX_ETH_ACC_MAC_RX_CNTRL2 0x014
#define IX_ETH_ACC_MAC_RANDOM_SEED 0x020
#define IX_ETH_ACC_MAC_THRESH_P_EMPTY 0x030
#define IX_ETH_ACC_MAC_THRESH_P_FULL 0x038
#define IX_ETH_ACC_MAC_BUF_SIZE_TX 0x040
#define IX_ETH_ACC_MAC_TX_DEFER 0x050
#define IX_ETH_ACC_MAC_RX_DEFER 0x054
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1 0x060
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2 0x064
#define IX_ETH_ACC_MAC_SLOT_TIME 0x070
#define IX_ETH_ACC_MAC_MDIO_CMD_1 0x080
#define IX_ETH_ACC_MAC_MDIO_CMD_2 0x084
#define IX_ETH_ACC_MAC_MDIO_CMD_3 0x088
#define IX_ETH_ACC_MAC_MDIO_CMD_4 0x08c
#define IX_ETH_ACC_MAC_MDIO_STS_1 0x090
#define IX_ETH_ACC_MAC_MDIO_STS_2 0x094
#define IX_ETH_ACC_MAC_MDIO_STS_3 0x098
#define IX_ETH_ACC_MAC_MDIO_STS_4 0x09c
#define IX_ETH_ACC_MAC_ADDR_MASK_1 0x0A0
#define IX_ETH_ACC_MAC_ADDR_MASK_2 0x0A4
#define IX_ETH_ACC_MAC_ADDR_MASK_3 0x0A8
#define IX_ETH_ACC_MAC_ADDR_MASK_4 0x0AC
#define IX_ETH_ACC_MAC_ADDR_MASK_5 0x0B0
#define IX_ETH_ACC_MAC_ADDR_MASK_6 0x0B4
#define IX_ETH_ACC_MAC_ADDR_1 0x0C0
#define IX_ETH_ACC_MAC_ADDR_2 0x0C4
#define IX_ETH_ACC_MAC_ADDR_3 0x0C8
#define IX_ETH_ACC_MAC_ADDR_4 0x0CC
#define IX_ETH_ACC_MAC_ADDR_5 0x0D0
#define IX_ETH_ACC_MAC_ADDR_6 0x0D4
#define IX_ETH_ACC_MAC_INT_CLK_THRESH 0x0E0
#define IX_ETH_ACC_MAC_UNI_ADDR_1 0x0F0
#define IX_ETH_ACC_MAC_UNI_ADDR_2 0x0F4
#define IX_ETH_ACC_MAC_UNI_ADDR_3 0x0F8
#define IX_ETH_ACC_MAC_UNI_ADDR_4 0x0FC
#define IX_ETH_ACC_MAC_UNI_ADDR_5 0x100
#define IX_ETH_ACC_MAC_UNI_ADDR_6 0x104
#define IX_ETH_ACC_MAC_CORE_CNTRL 0x1FC
/*
*
*Bit definitions
*
*/
/* TX Control Register 1*/
#define IX_ETH_ACC_TX_CNTRL1_TX_EN BIT(0)
#define IX_ETH_ACC_TX_CNTRL1_DUPLEX BIT(1)
#define IX_ETH_ACC_TX_CNTRL1_RETRY BIT(2)
#define IX_ETH_ACC_TX_CNTRL1_PAD_EN BIT(3)
#define IX_ETH_ACC_TX_CNTRL1_FCS_EN BIT(4)
#define IX_ETH_ACC_TX_CNTRL1_2DEFER BIT(5)
#define IX_ETH_ACC_TX_CNTRL1_RMII BIT(6)
/* TX Control Register 2 */
#define IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK 0xf
/* RX Control Register 1 */
#define IX_ETH_ACC_RX_CNTRL1_RX_EN BIT(0)
#define IX_ETH_ACC_RX_CNTRL1_PADSTRIP_EN BIT(1)
#define IX_ETH_ACC_RX_CNTRL1_CRC_EN BIT(2)
#define IX_ETH_ACC_RX_CNTRL1_PAUSE_EN BIT(3)
#define IX_ETH_ACC_RX_CNTRL1_LOOP_EN BIT(4)
#define IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN BIT(5)
#define IX_ETH_ACC_RX_CNTRL1_RX_RUNT_EN BIT(6)
#define IX_ETH_ACC_RX_CNTRL1_BCAST_DIS BIT(7)
/* RX Control Register 2 */
#define IX_ETH_ACC_RX_CNTRL2_DEFER_EN BIT(0)
/* Core Control Register */
#define IX_ETH_ACC_CORE_RESET BIT(0)
#define IX_ETH_ACC_CORE_RX_FIFO_FLUSH BIT(1)
#define IX_ETH_ACC_CORE_TX_FIFO_FLUSH BIT(2)
#define IX_ETH_ACC_CORE_SEND_JAM BIT(3)
#define IX_ETH_ACC_CORE_MDC_EN BIT(4)
/* 1st bit of 1st MAC octet */
#define IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ( 1)
/*
*
* Default values
*
*/
#define IX_ETH_ACC_TX_CNTRL1_DEFAULT (IX_ETH_ACC_TX_CNTRL1_TX_EN | \
IX_ETH_ACC_TX_CNTRL1_RETRY | \
IX_ETH_ACC_TX_CNTRL1_FCS_EN | \
IX_ETH_ACC_TX_CNTRL1_2DEFER | \
IX_ETH_ACC_TX_CNTRL1_PAD_EN)
#define IX_ETH_ACC_TX_MAX_RETRIES_DEFAULT 0x0f
#define IX_ETH_ACC_RX_CNTRL1_DEFAULT (IX_ETH_ACC_RX_CNTRL1_CRC_EN \
| IX_ETH_ACC_RX_CNTRL1_RX_EN)
#define IX_ETH_ACC_RX_CNTRL2_DEFAULT 0x0
/* Thresholds determined by NPE firmware FS */
#define IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT 0x12
#define IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT 0x30
/* Number of bytes that must be in the tx fifo before
transmission commences*/
#define IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT 0x8
/* One-part deferral values */
#define IX_ETH_ACC_MAC_TX_DEFER_DEFAULT 0x15
#define IX_ETH_ACC_MAC_RX_DEFER_DEFAULT 0x16
/* Two-part deferral values... */
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT 0x08
#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT 0x07
/* This value applies to MII */
#define IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT 0x80
/* This value applies to RMII */
#define IX_ETH_ACC_MAC_SLOT_TIME_RMII_DEFAULT 0xFF
#define IX_ETH_ACC_MAC_ADDR_MASK_DEFAULT 0xFF
#define IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT 0x1
/*The following is a value chosen at random*/
#define IX_ETH_ACC_RANDOM_SEED_DEFAULT 0x8
/*By default we must configure the MAC to generate the
MDC clock*/
#define IX_ETH_ACC_CORE_DEFAULT (IX_ETH_ACC_CORE_MDC_EN)
#define IXP425_ETH_ACC_MAX_PHY 2
#define IXP425_ETH_ACC_MAX_AN_ENTRIES 20
#define IX_ETH_ACC_MAC_RESET_DELAY 1
#define IX_ETH_ACC_MAC_ALL_BITS_SET 0xFF
#define IX_ETH_ACC_MAC_MSGID_SHL 24
#define IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS 20
#define IX_ETH_ACC_PORT_DISABLE_DELAY_COUNT 200 /* 4 seconds timeout */
#define IX_ETH_ACC_PORT_DISABLE_RETRY_COUNT 3
#define IX_ETH_ACC_MIB_STATS_DELAY_MSECS 2000 /* 2 seconds delay for ethernet stats */
/*Register access macros*/
#if (CPU == SIMSPARCSOLARIS)
extern void registerWriteStub (UINT32 base, UINT32 offset, UINT32 val);
extern UINT32 registerReadStub (UINT32 base, UINT32 offset);
#define REG_WRITE(b,o,v) registerWriteStub(b, o, v)
#define REG_READ(b,o,v) do { v = registerReadStub(b, o); } while (0)
#else
#define REG_WRITE(b,o,v) IX_OSAL_WRITE_LONG((volatile UINT32 *)(b + o), v)
#define REG_READ(b,o,v) (v = IX_OSAL_READ_LONG((volatile UINT32 *)(b + o)))
#endif
void ixEthAccMacUnload(void);
IxEthAccStatus ixEthAccMacMemInit(void);
/* MAC core loopback */
IxEthAccStatus ixEthAccPortLoopbackEnable(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortLoopbackDisable(IxEthAccPortId portId);
/* MAC core traffic control */
IxEthAccStatus ixEthAccPortTxEnablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortTxDisablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortRxEnablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortRxDisablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccPortMacResetPriv(IxEthAccPortId portId);
/* NPE software loopback */
IxEthAccStatus ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId);
IxEthAccStatus ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId);
#endif /*IxEthAccMac_p_H*/

View File

@ -1,73 +0,0 @@
/**
* @file IxEthAccMii_p.h
*
* @author Intel Corporation
* @date
*
* @brief MII Header file
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
#ifndef IxEthAccMii_p_H
#define IxEthAccMii_p_H
/* MII definitions - these have been verified against the LXT971 and LXT972 PHYs*/
#define IXP425_ETH_ACC_MII_MAX_REG 32 /* max register per phy */
#define IX_ETH_ACC_MII_REG_SHL 16
#define IX_ETH_ACC_MII_ADDR_SHL 21
/* Definitions for MII access routines*/
#define IX_ETH_ACC_MII_GO BIT(31)
#define IX_ETH_ACC_MII_WRITE BIT(26)
#define IX_ETH_ACC_MII_TIMEOUT_10TH_SECS 5
#define IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS 100
#define IX_ETH_ACC_MII_READ_FAIL BIT(31)
#define IX_ETH_ACC_MII_PHY_DEF_DELAY 300 /* max delay before link up, etc. */
#define IX_ETH_ACC_MII_PHY_NO_DELAY 0x0 /* do not delay */
#define IX_ETH_ACC_MII_PHY_NULL 0xff /* PHY is not present */
#define IX_ETH_ACC_MII_PHY_DEF_ADDR 0x0 /* default PHY's logical address */
#ifndef IX_ETH_ACC_MII_MONITOR_DELAY
# define IX_ETH_ACC_MII_MONITOR_DELAY 0x5 /* in seconds */
#endif
/* Register definition */
#define IX_ETH_ACC_MII_CTRL_REG 0x0 /* Control Register */
#define IX_ETH_ACC_MII_STAT_REG 0x1 /* Status Register */
#define IX_ETH_ACC_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */
#define IX_ETH_ACC_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */
#define IX_ETH_ACC_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */
/* Advertisement Register */
#define IX_ETH_ACC_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */
/* partner ability Register */
#define IX_ETH_ACC_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */
/* Expansion Register */
#define IX_ETH_ACC_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */
/* next-page transmit Register */
IxEthAccStatus ixEthAccMdioShow (void);
IxEthAccStatus ixEthAccMiiInit(void);
void ixEthAccMiiUnload(void);
#endif /*IxEthAccMii_p_H*/

View File

@ -1,113 +0,0 @@
/**
* @file IxEthAccQueueAssign_p.h
*
* @author Intel Corporation
* @date 06-Mar-2002
*
* @brief Mapping from QMgr Q's to internal assignment
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/**
* @addtogroup IxEthAccPri
*@{
*/
/*
* Os/System dependancies.
*/
#include "IxOsal.h"
/*
* Intermodule dependancies
*/
#include "IxQMgr.h"
#include "IxQueueAssignments.h"
/* Check range of Q's assigned to this component. */
#if IX_ETH_ACC_RX_FRAME_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID ) | \
IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_TX_FRAME_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_TX_FRAME_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
IX_ETH_ACC_TX_FRAME_DONE_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID)
#error "Not all Ethernet Access Queues are betweem 1-31, requires full functionalty Q's unless otherwise validated "
#endif
/**
*
* @typedef IxEthAccQregInfo
*
* @brief
*
*/
typedef struct
{
IxQMgrQId qId;
char *qName;
IxQMgrCallback qCallback;
IxQMgrCallbackId callbackTag;
IxQMgrQSizeInWords qSize;
IxQMgrQEntrySizeInWords qWords;
BOOL qNotificationEnableAtStartup;
IxQMgrSourceId qConditionSource;
IxQMgrWMLevel AlmostEmptyThreshold;
IxQMgrWMLevel AlmostFullThreshold;
} IxEthAccQregInfo;
/*
* Prototypes for all QM callbacks.
*/
/*
* Rx Callbacks
*/
IX_ETH_ACC_PUBLIC
void ixEthRxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
IX_ETH_ACC_PUBLIC
void ixEthRxMultiBufferQMCallback(IxQMgrQId, IxQMgrCallbackId);
IX_ETH_ACC_PUBLIC
void ixEthRxFreeQMCallback(IxQMgrQId, IxQMgrCallbackId);
/*
* Tx Callback.
*/
IX_ETH_ACC_PUBLIC
void ixEthTxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
IX_ETH_ACC_PUBLIC
void ixEthTxFrameDoneQMCallback(IxQMgrQId, IxQMgrCallbackId );
#define IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY (IX_QMGR_Q_PRIORITY_0) /* Highest priority */
/*
* Queue watermarks
*/
#define IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E )
#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E )

View File

@ -1,301 +0,0 @@
/**
* @file IxEthAcc_p.h
*
* @author Intel Corporation
* @date 12-Feb-2002
*
* @brief Internal Header file for IXP425 Ethernet Access component.
*
* Design Notes:
*
*
* @par
* IXP400 SW Release version 2.0
*
* -- Copyright Notice --
*
* @par
* Copyright 2001-2005, Intel Corporation.
* All rights reserved.
*
* @par
* SPDX-License-Identifier: BSD-3-Clause
* @par
* -- End of Copyright Notice --
*/
/**
* @addtogroup IxEthAccPri
*@{
*/
#ifndef IxEthAcc_p_H
#define IxEthAcc_p_H
/*
* Os/System dependancies.
*/
#include "IxOsal.h"
/*
* Intermodule dependancies
*/
#include "IxNpeDl.h"
#include "IxQMgr.h"
#include "IxEthNpe.h"
/*
* Intra module dependancies
*/
#include "IxEthAccDataPlane_p.h"
#include "IxEthAccMac_p.h"
#define INLINE __inline__
#ifdef NDEBUG
#define IX_ETH_ACC_PRIVATE static
#else
#define IX_ETH_ACC_PRIVATE
#endif /* ndef NDEBUG */
#define IX_ETH_ACC_PUBLIC
#define IX_ETH_ACC_IS_PORT_VALID(port) ((port) < IX_ETH_ACC_NUMBER_OF_PORTS ? true : false )
#ifndef NDEBUG
#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#else
#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) {}
#endif
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccInitDataPlane(void);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrQueuesConfig(void);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries);
/* prototypes for the private control plane functions (used by the control interface wrapper) */
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressGetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinAllPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeavePriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeaveAllPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShowPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC void ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeSetPriv(IxEthAccPortId portId, IxEthAccDuplexMode mode);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeGetPriv(IxEthAccPortId portId, IxEthAccDuplexMode *mode);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched);
IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline sched);
/**
* @struct ixEthAccRxDataStats
* @brief Stats data structures for data path. - Not obtained from h/w
*
*/
typedef struct
{
UINT32 rxFrameClientCallback;
UINT32 rxFreeRepOK;
UINT32 rxFreeRepDelayed;
UINT32 rxFreeRepFromSwQOK;
UINT32 rxFreeRepFromSwQDelayed;
UINT32 rxFreeLateNotificationEnabled;
UINT32 rxFreeLowCallback;
UINT32 rxFreeOverflow;
UINT32 rxFreeLock;
UINT32 rxDuringDisable;
UINT32 rxSwQDuringDisable;
UINT32 rxUnlearnedMacAddress;
UINT32 rxPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
UINT32 rxUnexpectedError;
UINT32 rxFiltered;
} IxEthAccRxDataStats;
/**
* @struct IxEthAccTxDataStats
* @brief Stats data structures for data path. - Not obtained from h/w
*
*/
typedef struct
{
UINT32 txQOK;
UINT32 txQDelayed;
UINT32 txFromSwQOK;
UINT32 txFromSwQDelayed;
UINT32 txLowThreshCallback;
UINT32 txDoneClientCallback;
UINT32 txDoneClientCallbackDisable;
UINT32 txOverflow;
UINT32 txLock;
UINT32 txPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
UINT32 txLateNotificationEnabled;
UINT32 txDoneDuringDisable;
UINT32 txDoneSwQDuringDisable;
UINT32 txUnexpectedError;
} IxEthAccTxDataStats;
/* port Disable state machine : list of states */
typedef enum
{
/* general port states */
DISABLED = 0,
ACTIVE,
/* particular Tx/Rx states */
REPLENISH,
RECEIVE,
TRANSMIT,
TRANSMIT_DONE
} IxEthAccPortDisableState;
typedef struct
{
BOOL fullDuplex;
BOOL rxFCSAppend;
BOOL txFCSAppend;
BOOL txPADAppend;
BOOL enabled;
BOOL promiscuous;
BOOL joinAll;
IxOsalMutex ackMIBStatsLock;
IxOsalMutex ackMIBStatsResetLock;
IxOsalMutex MIBStatsGetAccessLock;
IxOsalMutex MIBStatsGetResetAccessLock;
IxOsalMutex npeLoopbackMessageLock;
IxEthAccMacAddr mcastAddrsTable[IX_ETH_ACC_MAX_MULTICAST_ADDRESSES];
UINT32 mcastAddrIndex;
IX_OSAL_MBUF *portDisableTxMbufPtr;
IX_OSAL_MBUF *portDisableRxMbufPtr;
volatile IxEthAccPortDisableState portDisableState;
volatile IxEthAccPortDisableState rxState;
volatile IxEthAccPortDisableState txState;
BOOL initDone;
BOOL macInitialised;
} IxEthAccMacState;
/**
* @struct IxEthAccRxInfo
* @brief System-wide data structures associated with the data plane.
*
*/
typedef struct
{
IxQMgrQId higherPriorityQueue[IX_QMGR_MAX_NUM_QUEUES]; /**< higher priority queue list */
IxEthAccSchedulerDiscipline schDiscipline; /**< Receive Xscale QoS type */
} IxEthAccInfo;
/**
* @struct IxEthAccRxDataInfo
* @brief Per Port data structures associated with the receive data plane.
*
*/
typedef struct
{
IxQMgrQId rxFreeQueue; /**< rxFree Queue for this port */
IxEthAccPortRxCallback rxCallbackFn;
UINT32 rxCallbackTag;
IxEthAccDataPlaneQList freeBufferList;
IxEthAccPortMultiBufferRxCallback rxMultiBufferCallbackFn;
UINT32 rxMultiBufferCallbackTag;
BOOL rxMultiBufferCallbackInUse;
IxEthAccRxDataStats stats; /**< Receive s/w stats */
} IxEthAccRxDataInfo;
/**
* @struct IxEthAccTxDataInfo
* @brief Per Port data structures associated with the transmit data plane.
*
*/
typedef struct
{
IxEthAccPortTxDoneCallback txBufferDoneCallbackFn;
UINT32 txCallbackTag;
IxEthAccDataPlaneQList txQ[IX_ETH_ACC_NUM_TX_PRIORITIES]; /**< Transmit Q */
IxEthAccSchedulerDiscipline schDiscipline; /**< Transmit Xscale QoS */
IxQMgrQId txQueue; /**< txQueue for this port */
IxEthAccTxDataStats stats; /**< Transmit s/w stats */
} IxEthAccTxDataInfo;
/**
* @struct IxEthAccPortDataInfo
* @brief Per Port data structures associated with the port data plane.
*
*/
typedef struct
{
BOOL portInitialized;
UINT32 npeId; /**< NpeId for this port */
IxEthAccTxDataInfo ixEthAccTxData; /**< Transmit data control structures */
IxEthAccRxDataInfo ixEthAccRxData; /**< Receive data control structures */
} IxEthAccPortDataInfo;
extern IxEthAccPortDataInfo ixEthAccPortData[];
#define IX_ETH_IS_PORT_INITIALIZED(port) (ixEthAccPortData[port].portInitialized)
extern BOOL ixEthAccServiceInit;
#define IX_ETH_ACC_IS_SERVICE_INITIALIZED() (ixEthAccServiceInit == true )
/*
* Maximum number of frames to consume from the Rx Frame Q.
*/
#define IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK (128)
/*
* Max number of times to load the Rx Free Q from callback.
*/
#define IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD (256) /* Set greater than depth of h/w Q + drain time at line rate */
/*
* Max number of times to read from the Tx Done Q in one sitting.
*/
#define IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK (256)
/*
* Max number of times to take buffers from S/w queues and write them to the H/w Tx
* queues on receipt of a Tx low threshold callback
*/
#define IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK (16)
#define IX_ETH_ACC_FLUSH_CACHE(addr,size) IX_OSAL_CACHE_FLUSH((addr),(size))
#define IX_ETH_ACC_INVALIDATE_CACHE(addr,size) IX_OSAL_CACHE_INVALIDATE((addr),(size))
#define IX_ETH_ACC_MEMSET(start,value,size) memset(start,value,size)
#endif /* ndef IxEthAcc_p_H */

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More