Merge branch 'u-boot-pxa/master' into 'u-boot-arm/master'
This commit is contained in:
2
MAKEALL
2
MAKEALL
@@ -398,8 +398,6 @@ LIST_at91="$(targets_by_soc at91)"
|
||||
|
||||
LIST_pxa="$(targets_by_cpu pxa)"
|
||||
|
||||
LIST_ixp="$(targets_by_cpu ixp)"
|
||||
|
||||
#########################################################################
|
||||
## SPEAr Systems
|
||||
#########################################################################
|
||||
|
||||
1
Makefile
1
Makefile
@@ -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
1
README
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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*) }
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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*) }
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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*) }
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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*) }
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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*) }
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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(®val);
|
||||
|
||||
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(®val);
|
||||
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(®val);
|
||||
|
||||
/*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, ®val);
|
||||
printf(" Control Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, ®val);
|
||||
printf(" Status Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, ®val);
|
||||
printf(" PHY ID1 Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, ®val);
|
||||
printf(" PHY ID2 Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, ®val);
|
||||
printf(" Auto Neg ADS Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, ®val);
|
||||
printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, ®val);
|
||||
printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, ®val);
|
||||
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(®val);
|
||||
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(®val);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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,
|
||||
®val) == 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, ®valId1);
|
||||
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, ®valId1);
|
||||
ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID2_REG, ®valId2);
|
||||
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,
|
||||
®val)
|
||||
== 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,
|
||||
®val)
|
||||
== 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,
|
||||
®val);
|
||||
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,
|
||||
®val) != 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, ®val4);
|
||||
ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, ®val5);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
®Val);
|
||||
}
|
||||
|
||||
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,
|
||||
®Val);
|
||||
}
|
||||
|
||||
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, ®Val);
|
||||
|
||||
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 ();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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, ®isterWord);
|
||||
|
||||
|
||||
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, ®isterWord);
|
||||
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, ®isterWord);
|
||||
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, ®isterWord);
|
||||
|
||||
/* 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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/** @} */
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
/** @} */
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
|
||||
/**
|
||||
*@}
|
||||
*/
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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*/
|
||||
@@ -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 )
|
||||
@@ -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
Reference in New Issue
Block a user